本文定义整个 1.x major 发布线中受支持的模块表面和跨模块不变量。精确参数名与返回值已经用 LuaCATS 标注在源码中;本文重点说明消费者可以依赖哪些入口,以及仅看函数签名无法表达的生命周期和所有权语义。
| 层级 | 含义 | 示例 |
|---|---|---|
| 公共 API | 在整个 1.x major 内向后兼容;不兼容变更必须进入 2.0.0 或更高 major |
gamekit.game、State、Save、Scene、Narrative facade、Sequence、Audio、Camera、Screen、Interaction、FX |
| 扩展 SPI | 支持 adapter/command 扩展,但实现者必须遵循完整协议 | service descriptor、Narrative command handler、Scene transition adapter、GUI/Camera/FX bridge |
| 工具 API | Editor/CI 契约与运行时分别版本化 | gamekit.editor.*、HTTP bridge_version、Python validator |
| 内部/参考 | 如果没有公共调用路径依赖,可以不要求应用迁移而改变 | 测试模块、demo benchmark driver、Render Target handle 布局、生成 Story Database 的文本格式 |
/main/、/game/、/input/ 和 /assets/ 下的路径属于宿主/参考内容,不属于 GameKit API。
机器可读的 API_BASELINE.json 为整个 1.x 锁定 33 个公共/SPI 模块和 259 个导出符号。python tools/validate_public_api.py 与 release packager 会拒绝发布线不匹配、模块缺失或符号缺失,防止意外重命名/删除被静默发布。允许以向后兼容方式增加导出。更新或删除 baseline 条目必须遵循 LIBRARY.md、MIGRATING.md 和 CHANGELOG.md 的 major 版本与弃用流程;只修改 snapshot 不构成合法的兼容性流程。
MAJOR、MINOR、PATCH、STRING——不可变的 package 版本字段。API_LEVEL——同一 package 发布线内单调递增的工具/协议能力标记。is_compatible(required_major, minimum_minor?)——检查 package 发布线;非数字参数会被拒绝。
它不代表 Save schema、Story 数据 revision 或特定游戏内容一定兼容。
围绕一个显式创建 App 的 shared-state facade:
init(options?) -> app创建唯一活动 App,并拒绝二次初始化。start()解析并启动所有已注册服务。update(dt)按解析后的顺序更新服务。shutdown()按反向顺序停止服务并释放活动 App。on(event_name, callback) -> token、off(token) -> boolean、emit(event_name, payload?) -> delivered暴露 App event bus。service(name) -> api返回已启动服务的 API。is_initialized() -> boolean支持宿主安全清理。
宿主负责每帧只调用一次 update(),并在应用最终关闭时只调用一次 shutdown()。
Service descriptor 是普通 table:
{
name = "inventory",
dependencies = { "state" },
init = function(context) end,
start = function(context) end,
update = function(context, dt) end,
shutdown = function(context) end,
api = {},
}服务名必须唯一。生命周期开始前,缺失依赖和依赖环都会报错。初始化/启动遵循拓扑排序后的注册顺序;关闭使用反向顺序。不要用 Game Object 的 init() 顺序替代此契约。
实例事件总线:new、on、off、emit、clear、listener_count。事件同步分发。分发期间移除 listener 是安全的。Listener 报错会停止当前分发,并携带事件上下文继续抛出。Token 只属于创建它的 event bus。
单通道实例 wrapper:new、connect、disconnect、emit、clear。当具名多事件总线不会增加信息时使用 Signal。
最小的逐帧任务系统:new、start、cancel、update、clear、count、wait。Update callback 返回任务是否完成;取消操作只会调用一次 cleanup callback。它不是 coroutine scheduler,也不是持久化层。
- Config 是显式的实例 key/value 存储。
- Log 创建有 scope 的日志等级,并使用 Defold/Lua
print输出。 - Debug 负责各模块共用的参数和不变量检查。
- App 组合 config、log、event bus、task runner 和 service registry。大多数游戏通过
gamekit.game使用它。
使用 new(options?) 创建实例状态。通过 push_context(state, context, owner) -> token 压入逻辑上下文;普通代码必须使用 pop_context(state, token, owner) 弹出精确的栈顶 token。子系统清理可以调用 release_owner(state, owner)。
on_input(state, action_id, action) 会规范化已配置设备 trigger、跟踪按下状态,并只发出栈顶上下文允许的动作。已经识别但被阻止的动作仍会被消费,避免输入泄漏到更底层 Gameplay。内置上下文为 gameplay、dialogue、menu、cutscene、debug。
Defold input binding 由宿主拥有。重新绑定只改变 trigger 到逻辑动作的映射,不改变后续上下文语义。
State 包含三个 domain:
global——跨场景持久存在的进度和设置。scene——按世界保存的持久状态。runtime——临时 UI/cache/control 状态,始终排除在持久 snapshot 之外。
公共操作为 new、get、has、set、remove、reset_domain、snapshot_persistent、restore_persistent、set_paused、service。点路径访问嵌套 table。set(..., nil) 会被拒绝,删除必须显式调用 remove。变更通知包含 domain/path/old/new。游玩时间更新由 service adapter 管理,不提供独立公共模块函数。
new(options) 要求 application/schema 配置,并可接受 capture、restore、validation 和逐版 migration。重要操作:
write(state, slot, payload) -> saved, metadata_or_errorload(state, slot) -> payload_or_nil, metadata_or_errormetadata(state, slot) -> metadata_or_nil- Service API:
save_slot、load_slot、quick_save、quick_load、metadata
每个 slot 在 generation a 与 b 之间交替。写入会选择非当前 generation,完成写入、重新读取和验证后,才允许它成为最新数据。加载先尝试最新健康数据,再回退旧 generation。未来 schema 会被拒绝;每个旧版本必须恰好提供一步 migration。Game version metadata 只供参考。
new(registry, options?) 把稳定 ID 映射到 Collection Proxy URL。公共行为包括 go_to、current、set_paused、Proxy message 转发和 service adapter;service API 还提供 phase、is_paused 查询。
受支持的名称是 go_to,不是 goto,因为 goto 是 Lua 关键字。状态机拥有完整流程:fade out → disable/final/unload → load/init/enable → fade in。重复请求采用 last-request-wins 排队;transaction token 用于忽略过期 callback。宿主必须连同原始 sender 转发 Proxy message。
Transition adapter 协议提供异步 fade_out(callback) 和 fade_in(callback),completion 必须且只能发生一次。gamekit.presentation.transition 基于持久 GUI 实现此协议。
new(options) 接收 language ID 和数据路径。公共操作为 text、format、has、language、set_language、service。内容层只接触此 facade;Defold Lang 专用 table/loader 不泄漏到 Story 或 UI。
Story 是只包含数据的 table,拥有稳定 id、稳定 entry 和 nodes map。命令名会规范为小写。文本值是本地化 key,不是最终文案。内置 core command 类型:
say、choice、set、if、jump、call、wait、signal、end。
表现/场景扩展增加:
scene、audio、camera、sequence、interaction、fx。
Story loader 会规范化并复制数据。Validator 检查 ID、entry、node command array、参数、target、重复 command ID、可达性、通往 End 的路径,并通过注入的 has_localization 函数检查本地化。注册 Story 前应执行一次验证,Editor/CI 工具中还应再次执行。
注册带 validate/execute 行为的唯一命令类型。执行返回一种控制结果:continue、jump、call、wait 或 end。扩展不能修改 Runner dispatch,也不能直接调用表现 Library;应注入依赖或发出语义化表现请求。
在纯 Runner 与游戏状态/表现 callback 之间提供桥接:读取/写入变量、signal、显示/清除 dialogue 和外部 wait。Context 属于宿主/组合状态,不是 GUI 状态。
拥有 Story cursor、call stack、已提交 Choice、变量、phase 和 wait descriptor。支持 start、update、advance、choose、skip、pause/resume、cancel、snapshot、restore。即时命令数量上限会把意外无限循环转成明确错误。Choice 会在执行副作用前推进 cursor,因此恢复后不能重复提交。
负责 command 注册、Story registry、播放、用户意图、更新、取消、snapshot 和恢复的 facade/service。scene_command 和 presentation_commands 是可选 SPI installer。
GUI dialogue script 始终是数据驱动 view:通过消息接收扁平 model,只返回 intent message。
状态操作:new、play、update、cancel、skip、cancel_owner、is_active、set_paused、service。
Spec 构造器:
wait(duration)call(callback, options?)serial(children, options?)parallel(children, options?)tween(from, to, duration, on_value, options?)- 通过已记录 node protocol 定义的自定义 spec
时间由宿主提供的 dt 驱动;GameKit 拥有 pause、skip 和 cleanup。每个活动 sequence 都有适合场景/UI 清理的 owner。Defold Tweener 只提供 easing 数学。
公共能力:new、register_clip、play、stop、crossfade、master/category volume 和 mute setter、category pause、owner stop、update、设置 snapshot/restore、service。
Clip definition 把语义 ID 绑定到宿主 Sound component URL 和 category。模块拥有策略与活动播放数据,不拥有媒体资源。Fade/crossfade 逐帧驱动,并支持按 owner 清理。
提供 new、adapter 注册、活动 camera 选择、状态 push/pop、move、zoom、follow、shake、update、坐标转换、pause 和 service adapter。逻辑 camera 状态始终是权威数据。Proxy world 的位置修改通过 collection-local camera_bridge.script 完成;不支持跨 world 直接调用 go.set_position()。
状态栈 token 和 owner 可防止 Dialogue close-up 或 Cutscene 恢复错误的旧 camera 状态。
new(options) 接收 Input Context push/pop callback。把语义 screen ID 注册到 view URL/context/modal 规则,然后显示、隐藏、更新 model 或查询当前 stack。LIFO modal 所有权是显式的。隐藏或 owner cleanup 会弹出匹配的 Input token。
只用于 GUI view 的 adapter。Druid button callback 发送 intent message;绝不 require State、Save、Narrative 或其他游戏逻辑模块。Druid focus 不会取代 GameKit Input Context 所有权。
注册 kind behavior 和实例数据:id、kind、position、radius、priority、enabled、owner。可以为 actor 查询/激活最佳候选;场景清理时注销每个实例,service shutdown 会清空 registry。范围内高 priority 获胜,相同优先级使用确定性规则。Component bridge 只发布注册消息;中央游戏逻辑拥有 behavior。
统一语义 facade:
- 组件 target:register/unregister、
set、clear、play、model; - 屏幕闪光:
flash_screen; - 后处理:
post_set、post_play、post_clear、post_model; - 光照:light register/set/unregister,以及 environment/play/clear/model;
- 生命周期:
cancel_owner、quality、pause、update、shutdown、service。
组件参数覆盖 tint/fade、grayscale、RGB-level quantization、outline、dissolve、flash。后处理参数覆盖 vignette、blur、glitch、chromatic aberration、pixelation。光照明确限定为无阴影 2D ambient 加按优先级选择的 radial light。
内容层绝不接触 shader uniform 名或 Render Target handle。Owner cancellation 会恢复之前的语义 model,并移除所属 light/sequence。
它们是面向自定义组合的公共低层状态模块,负责范围校验、quality tier、动画、pause 和 owner cleanup。除非宿主有意替换 render transport,否则优先使用 fx facade。
gamekit.render.*、effect.script、camera_bridge.script 和 Interaction component script 构成 SPI/resource 层。已记录宿主配置中使用的资源路径和 message payload 受到支持;内部 Render Target 格式、handle cache 和 shader uniform packing 不属于应用 API。
- 编程错误(无效类型、ID、范围、重复注册、不可能的生命周期)会立即携带上下文抛出。
- 预期的运行时缺失/失败通常返回
false/nil, reason;调用者必须处理。 - 幂等 cleanup 在有意义时返回 boolean/count,绝不静默转移所有权。
- Token/handle 只属于创建它的状态实例。
owner是稳定的 subsystem/scene/screen ID,不是显示文案。- Scene unload 和 App shutdown 必须取消所属 Sequence、Audio、Interaction、FX 和 Input Context。
- 公共可变状态不保存在 metatable/class 实例中,而使用显式数据 table。
当前所有 GameKit runtime API 都在 Defold Lua/game thread 中执行。除非某 API 明确返回 wait/transition handle,否则 event dispatch 和 command execution 都是同步的。Editor script 运行在 Editor 独立的 Lua 5.2 环境,runtime code 不能 require 它们。