mcpField
D
defold-scripts-editing

defold-scripts-editing

github.com/indiesoftby开发10452 次安装27 周前更新
代码仓库

关于 defold-scripts-editing

defold-scripts-editing 面向 Defold 开发者和编码 Agent,指导编辑 Lua 脚本与模块,涵盖文件类型、运行上下文、生命周期回调、模块状态及编辑规范。

主要功能

  1. 01四种脚本类型及其上下文
  2. 02可复用 Lua 模块结构
  3. 03生命周期回调指引
  4. 04运行时限制与 API 可用性
  5. 05原生扩展 API 元数据格式
  6. 06Lua 预处理器用法

适用场景

  1. 01创建供多个脚本复用的模块
  2. 02为 Defold 脚本添加回调
  3. 03编辑脚本时保留属性和签名
  4. 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.md
gui_script.md
render_script.md
script.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_scriptGUI 组件LuaJIT否gui、msg、vmath、sys
.render_script渲染管线(每个项目一个)LuaJIT否render、graphics、camera、msg、vmath、sys
.editor_scriptDefold 编辑器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,可像表一样用于存储实例状态。

脚本结构
  1. 模块引入(可选)——local M = require("module")
  2. 局部辅助函数(可选)——必须位于模块作用域,不能放在其他函数内部
  3. 声明(仅限 .script:在顶层调用 go.property())
  4. 生命周期回调
生命周期回调可用性
回调.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)
  1. 当逻辑需要在多个脚本或界面间复用时使用。
  2. 创建一个局部表,添加函数并返回该表。
  3. 尽可能让模块保持无状态;如果包含状态,请说明该状态会被共享。
  4. 使用点号表示法调用 require:require("main.utils")、require("screens.game.helpers")。
创建新脚本
  1. 确定脚本类型对应的正确扩展名。
  2. 阅读 references/ 中对应类型的参考文档,了解约束和模板。
  3. 遵循结构模式:依赖导入 → 辅助函数 → 声明 → 回调。
  4. 仅添加实际需要的生命周期回调。
编辑现有脚本
  1. 阅读当前文件。
  2. 保留现有声明(例如 go.property() 名称)和回调签名。
  3. 根据需要添加或修改回调。
  4. 更改 go.property() 的名称或类型可能会破坏 .go 和 .collection 文件中的覆盖项。

评论

支持 Markdown