开始一个想法#
模块提供指示和数据,X4在适当的时间读取. 它不需要一个主要文件, 导航数据被载入资源,MD等待条件,AI运行行为, Lua 处理用户界面.
引擎是游戏的可执行部分:它创建物体,计算运动,存储世界并执行暴露于脚本中的操作. 完全来源不在一个模块文件中. 扩展使用支持的格式和API. API是与系统交互的可用方法,例如阅读对象的名字或发送事件.
这本指南涵盖了定期调整. 新的例子是解释性的,并且没有在游戏中单独执行. 根据安装的X4 9.00文件,
为什么多种语言都参与其中#
不同的工作需要不同的代表性. 机身值可以方便地作为数据存储;事件反应需要处理器;按需要一个小工具和点击函数.
| 层 | 典型的位置 | 工作 |
|---|---|---|
| XML 数据 | assets/, libraries/, t/ |
产品,商品和翻译文本 |
| XML 差异 | 匹配目标资源路径 | 修改文件中选择部分 |
| Mission Director | md/*.xml |
应对事件,执行世界逻辑 |
| 人工智能脚本 | aiscripts/*.xml |
演员的行为和命令 |
| Lua 互联网 | ui/*.lua, 已注册 ui.xml |
窗户,表表和输入 |
| 产地代码 | 机器或调整器的DLL | 低级一体化 |
虽然MD和AI使用XML,但它们有自己的元素和执行规则. 检查根元素和目录,而不是仅仅根据扩展判断. Python或C#可能出现在工具和复杂项目中;这并不能使它们成为内置的 MD语言. 一个 XML 补丁只需要其表现和差异.
当扩展加载时发生什么#
下面的原始图概括了责任,而不是承诺一个确切的普遍负载顺序. X4 版本,DLC,依赖性,其他 mods和保存状态都影响了结果. content.xml 确定扩展及其版本/依赖性. ui.xml 列出Lua文件用于UI环境. 显现版本字段具有定义的数值格式;不要替代任意的人类版本字符串,如0.1.0.
extensions/имя_мода/content.xml
→ игра узнаёт расширение и его зависимости
→ получает ресурсы с учётом расширений и патчей
→ загружает подходящие скрипты и UI
→ события и callbacks вызывают обработчики
→ движок меняет состояние мира举例1: XML 存储一个属性#
在下面缩短的宏观插图中,体是一个元素,最大是一个属性,1800是它的值. XML本身并没有运行循环;引擎在资源文本中解释该领域. 另一个变化改变了所选的属性.
读取选项:输入 /macros/macro, 保留指定名称的宏,输入 /properties/hull, 然后选择 /@max. 其他这是一个文件的 XPath,不是一个 MD 状况或一个活船的搜索. 资源变化仍然需要在现存存储的对象上进行测试. 看到 完整的第一块.
<properties>
<hull max="1800" />
</properties><diff>
<replace sel="/macros/macro[@name='ship_arg_s_fighter_02_a_macro']/properties/hull/@max">3600</replace>
</diff>举例2: MD执行行动#
第一个部分将3分配给 $Count, 检测是否超过零,并打印诊断表. 它属于合适的标志. actions; 它们不是一个独立的延伸. XML 外部引用界定属性; 内部确切,数字3与引用字符串不同.
完全的MD脚本包含mdscript,线索,标志条件和操作. 标志是一个状态的逻辑节点:它可以等待,激活和完成. 想象一个事件驱动的处理器,而不是一个完整的文件, instantiate=true namespace=this 让重复事件有其自身变量背景的实例. 阅读 cue, 变量 并且对实际游戏版本的链接的主要文档.
<set_value name="$Count" exact="3" />
<do_if value="$Count gt 0">
<debug_text text="'Есть элементы для обработки'" />
</do_if><set_value name="$Count" exact="3" />
<set_value name="$Label" exact="'Три'" />例子3:用户界面调用Lua#
下面的简单Lua示例不使用游戏API. local 创建一个地方名称, function 定义函数,其参数接收输入, return 产生结果, .. 加入了弦. 标本的原始信息保留原始语言.
按分配的函数被UI后期调用;这是回调. 分配一个函数和立即调用它是不同的操作. 没有发明按API的例子说明了这一区别.
local function makeLabel(name)
if type(name) ~= "string" or name == "" then
return "Без имени"
end
return "Корабль: " .. name
end
local label = makeLabel("Север")local callback = makeLabel -- сохранить саму функцию
local result = makeLabel("Север") -- вызвать и сохранить ответ窗户和世界如何交流#
Lua具有游戏阅读API和一些引擎操作;MD暴露了不同的操作和特性. 根据可用的操作和生命周期选择层. 不是每一个世界变化都必须通过MD.
常见的交换器使用AddUITriggeredEvent到MD,然后raise_lua_event到RegisterEvent回调. 这些是X4环境设施:普通Lua没有提供它们. MD set_value和 raise_lua_event是XML元素,而不是Lua函数. 看到 双对的例子.
Lua: AddUITriggeredEvent(screen, control, payload)
→ MD: event_ui_triggered
→ данные запроса: event.param3
→ действия и чтение результата
→ MD: raise_lua_event
→ Lua: RegisterEvent(name, callback)为什么编辑文件可能会留下旧结果#
补丁可能是针对另一个宏或被兼容性冲突覆盖的. Lua 没有 ui.xml. 预测可能已经完成了保存. 载荷后可能会出现过时的对象参考. 保存恢复世界和MD状态,而不是简单地重新启动每个源文件. 有些变化需要初始化或迁移.
单独问:文件是否加载,预期处理器是否运行,实际对象是否改变并保留了改变? 处理器的日志标记不能证明最终效果. 单独检查新的游戏和相关的现有储存.