EpScript 实现原理
epScript 实现的底层原理
epScript 脚本(*.eps
) 可以通过 euddraft 编译成遵循一定规则使用 eudplib 扩展库的 Python 脚本(*.py
),这些 Python 脚本执行之后会生成以星际 EUD 触发器作为基本操作指令的目标代码文件
无论你在 epScript 中写什么样的代码,最终都会转换成一个或多个的触发器,任何 epScript 的条件分支都是额外的触发器。
需要深入研究触发器字节码结构可参考:
虚拟触发器(Virtual Triggers)
运行时无法获取 Scenario.chk 中的 TRIG 节(Section) 在内存中的位置,因此无法在运行时对触发器进行动态的流程控制。
但好在天无绝人之路, jjf28 发帖称只需要将触发器的字节码写入到内存中任何能访问的位置,然后将其添加到触发器链表中,它们就会正常工作,他将这些不在 TRIG 节(Section)中的触发器称之为虚拟触发器(Virtual Triggers)。
trgk 提出 STR 节(Section)在运行时会作为一个整体加载到内存中,而在生成 chk 时可以知道所有其中内容的相对地址,并且可以在运行时获取到 STR 节(Section)在内存中的地址,因此如果将触发器写入到 STR 节(Section)则可以在运行时轻易获取它们彼此的内存地址。以实现在运行时进行动态的条件判断和流程控制。eudplib 正是基于此设计的条件控制流程。
数学运算
常规触发器是没有完备的数学运算功能的,可以使用的工具是动作(Actions)中设置数字修改方法(Number Modifiers)的增加(Add)和减少(Substract)方法 —— 它们用于增加/减少玩家资源或者死亡数等等。
上一节,已经可用于实现了条件控制流程,eudplib 基于此使用 SetDeaths 的
- 循环增加(Add) 指定次数实现整数乘法
- 循环减少(Substract) 指定次数实现整数除法
当然实现过程中的优化很多,对不同的量(区别于运行时会发生变化的量和编译时可以确定值的常量)的处理方法不一样,不需要运行时确定的量可以在编译期通过 Python 运算结果,降低运行时的运算量。
更复杂的数学运算涉及更复杂的算法,基本原理就是用触发流程来模拟,可以参考:
变量存储位置
参考虚拟触发器,在 STR 节(Section)中开辟一片区域用于存储变量。