关于 defold-scripts-editing
defold-scripts-editing 面向 Defold 开发者和编码 Agent,指导编辑 Lua 脚本与模块,涵盖文件类型、运行上下文、生命周期回调、模块状态及编辑规范。
主要功能
- 01四种脚本类型及其上下文
- 02可复用 Lua 模块结构
- 03生命周期回调指引
- 04运行时限制与 API 可用性
- 05原生扩展 API 元数据格式
- 06Lua 预处理器用法
适用场景
- 01创建供多个脚本复用的模块
- 02为 Defold 脚本添加回调
- 03编辑脚本时保留属性和签名
- 04检查脚本专属的运行时限制
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ indiesoftby/ defold-agent-config --skill defold-scripts-editing安装后在 Claude Code 中输入/defold-scripts-editing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/editor_script.mdgui_script.mdrender_script.mdscript.md详细介绍
编辑 Defold 脚本文件和 Lua 模块
Defold 有四种 Lua 脚本类型(每种都在不同上下文中运行,并提供不同的 API),以及用于封装可复用逻辑的普通 .lua 模块。
如需了解 API 详情,请使用 defold-api-fetch 技能。如需查阅概念手册,请使用 defold-docs-fetch 技能。本技能涵盖脚本结构、限制和模板。
Lua 模块(.lua)
普通 .lua 文件是用于封装可复用逻辑的 Lua 模块。将常用的通用逻辑提取到 .lua 模块中——避免重复,并让脚本保持精简。模块通过 require("path.to.module") 引入(用点号分隔路径)。
Defold 项目通常使用 Lua 共享状态(game.project 中的 shared_state)。启用后,所有脚本、GUI 脚本和渲染脚本都在同一个 Lua 上下文中运行。从任何脚本引入的 Lua 模块,在同一个 Lua 解释器实例中都具有相同的上下文和状态——模块级局部变量和 package.loaded 在所有使用该模块的地方共享。有状态模块的行为类似单例。
Lua 模块结构(.lua)
将数据和函数封装在一个局部表中,并返回该表:
local M = {}
function M.hello()
print("Hello")
end
return M
避免在模块中使用全局变量。对于有状态模块,所有调用方共享其内部状态(类似单例)。对于无状态逻辑,请显式传递状态,或使用返回新状态表的构造函数。参见 Modules manual。
脚本类型
| 扩展名 | 上下文 | Lua 运行时 | go.property() | 主要命名空间 |
|---|---|---|---|---|
.script | 游戏对象组件 | LuaJIT | 是 | go、msg、vmath、timer、sys、组件命名空间(sprite、label、factory、collectionfactory、collectionproxy、tilemap、model、sound、particlefx、buffer、resource、physics) |
.gui_script | GUI 组件 | LuaJIT | 否 | gui、msg、vmath、sys |
.render_script | 渲染管线(每个项目一个) | LuaJIT | 否 | render、graphics、camera、msg、vmath、sys |
.editor_script | Defold 编辑器 | Lua 5.2 (luaj) | 否 | editor、editor.ui、editor.prefs、editor.tx、http、json、zip、zlib |
文件格式
所有脚本类型和 .lua 模块都是普通 Lua 文件(不是 Protobuf Text Format)。脚本使用特定扩展名(.script、.gui_script 等);模块使用 .lua。
运行时环境说明(.script、.gui_script、.render_script)
平台特定:html5 模块仅在 HTML5 平台上可用。
App Manifest 排除项:某些内置模块(liveupdate、image、types、profiler、sound、physics 等)可以通过 App Manifest 排除,以减小二进制文件大小。如果模块被排除,其 API 将无法在运行时使用。
没有 utf8 模块:处理非 ASCII 字符串时,请使用 defold-utf8 依赖(https://github.com/d954mas/defold-utf8/archive/refs/heads/master.zip)。API 参考:utf8.script_api。
常见运行时脚本模式(.script、.gui_script、.render_script)
所有运行时生命周期回调都将 self 作为第一个参数——它是一个 userdata,可像表一样用于存储实例状态。
脚本结构
- 模块引入(可选)——
local M = require("module") - 局部辅助函数(可选)——必须位于模块作用域,不能放在其他函数内部
- 声明(仅限
.script:在顶层调用go.property()) - 生命周期回调
生命周期回调可用性
| 回调 | .script | .gui_script | .render_script |
|---|---|---|---|
init(self) | ✓ | ✓ | ✓ |
final(self) | ✓ | ✓ | — |
fixed_update(self, dt) | ✓ | — | — |
update(self, dt) / update(self) | ✓ (dt) | ✓ (dt) | ✓(无 dt) |
late_update(self, dt) | ✓ | — | — |
on_message(self, message_id, message, sender) | ✓ | ✓ | ✓(无 sender) |
on_input(self, action_id, action) | ✓ | ✓ | — |
on_reload(self) | ✓ | ✓ | — |
关键规则
- 将每个实例的状态存储在
self中,而不是模块级局部变量中(模块级局部变量由所有实例共享)。 - 省略未使用的回调,尤其是
update()和fixed_update();即使回调为空,每帧也会产生一次调用开销。 - 将局部辅助函数放在模块级作用域中,绝不要放在其他函数内部。
原生扩展
原生扩展(C/C++/ObjC/Java)通过 Lua C API(lua_register、luaL_openlib 等)将 Lua 函数注册到全局作用域。这意味着扩展通常会添加一个新的全局表(例如 myext),其中的函数和常量可在任何 .script 或 .gui_script 中访问。
扩展通过位于其 api/ 目录中的 *.script_api 文件(YAML 格式)描述 API,以便编辑器提供自动补全。格式如下:
- name: extension_name
type: table
desc: Extension description
members:
- name: function_name
type: function
desc: Function description
parameters:
- name: param_name
type: string
desc: Parameter description
returns:
- name: return_name
type: number
desc: Return value description
类型:table、string、boolean、number、function。多个类型:[type1, type2]。
Lua 预处理
Defold 支持通过 Lua 预处理器扩展进行条件编译(适用于所有 Lua 文件,包括 .lua 模块):
--#IF DEBUG
local lives = 999
--#ELSE
local lives = 3
--#ENDIF
关键字:RELEASE、DEBUG、HEADLESS。
特定类型的参考文档
请参阅 references/ 目录,了解每种脚本类型特有的约束、模板和模式:
references/script.md—go.property()参考(类型、约束、覆盖)、模板references/gui_script.md— GUI 脚本约束、模板节点访问、模板references/render_script.md— 渲染管线架构、系统消息、完整可用模板references/editor_script.md— 模块结构、命令、生命周期钩子、执行模式、模板
工作流
创建新的 Lua 模块(.lua)
- 当逻辑需要在多个脚本或界面间复用时使用。
- 创建一个局部表,添加函数并返回该表。
- 尽可能让模块保持无状态;如果包含状态,请说明该状态会被共享。
- 使用点号表示法调用
require:require("main.utils")、require("screens.game.helpers")。
创建新脚本
- 确定脚本类型对应的正确扩展名。
- 阅读
references/中对应类型的参考文档,了解约束和模板。 - 遵循结构模式:依赖导入 → 辅助函数 → 声明 → 回调。
- 仅添加实际需要的生命周期回调。
编辑现有脚本
- 阅读当前文件。
- 保留现有声明(例如
go.property()名称)和回调签名。 - 根据需要添加或修改回调。
- 更改
go.property()的名称或类型可能会破坏.go和.collection文件中的覆盖项。