Loading...
正在加载...
请稍候

Godot MCP Native 项目全面解读

✨步子哥 (steper) 2026年06月08日 22:44

一、项目概述

项目名称:Godot MCP Native (Model Context Protocol)

核心定位:一个 Godot Engine 编辑器插件,通过 Model Context Protocol (MCP) 将 AI 助手(如 Claude、Cursor 等)与 Godot 编辑器深度集成,让 AI 能够直接理解和操作 Godot 项目。

核心特点

  • 🦀 完全原生实现:纯 GDScript 编写,无需 Node.js 等外部依赖
  • 🔧 154 个 MCP 工具:30 个核心工具 + 124 个补充工具
  • 🌐 双传输模式:支持 HTTP(SSE)和 Stdio(开发中)
  • 🔇 Vibe Coding 模式:免打扰模式,避免 AI 操作干扰用户工作流
  • 🌍 国际化支持:完整的英文/中文双语支持

二、项目结构

c:\GitHub\Godot-MCP-Native\
├── addons\godot_mcp\           # 插件主目录
│   ├── mcp_server_native.gd    # 插件入口 (EditorPlugin)
│   ├── native_mcp\            # 核心 MCP 实现
│   ├── tools\                 # 154 个工具实现
│   ├── runtime\               # 运行时探针
│   ├── ui\                    # 编辑器 UI 面板
│   └── utils\                 # 工具类
├── docs\                      # 完整文档体系
├── test\                      # 测试体系(单元 + 集成)
├── project.godot              # Godot 项目配置
└── README.md / AGENTS.md      # 项目文档

三、架构设计

3.1 三层架构

┌─────────────────────────────────┐
│     AI Client (Claude, etc.)   │  ← JSON-RPC 2.0 请求
└──────────────┬──────────────────┘
               │ HTTP / Stdio
┌──────────────▼──────────────────┐
│      Godot Native MCP Server    │  ← 工具注册、请求路由、认证
└──────────────┬──────────────────┘
               │ Godot Editor API
┌──────────────▼──────────────────┐
│         Godot Editor            │  ← 场景、脚本、节点操作
└─────────────────────────────────┘

3.2 核心模块

模块 文件 职责
插件入口 mcp_server_native.gd EditorPlugin 生命周期管理
服务器核心 mcp_server_core.gd MCP 协议处理、工具注册、消息路由
传输层 mcp_http_server.gd HTTP + SSE 传输实现
认证管理 mcp_auth_manager.gd Token 认证,时序安全比较
工具分类 mcp_tool_classifier.gd core / supplementary 分类
调试器桥接 mcp_debugger_bridge.gd 连接 Godot 调试器
运行时探针 mcp_runtime_probe.gd 注入游戏获取运行时数据

四、MCP 工具体系(154 个)

4.1 工具分类

类别 核心 补充 总计 源文件
Node Tools 9 11 20 node_tools_native.gd
Script Tools 7 7 14 script_tools_native.gd
Scene Tools 4 4 8 scene_tools_native.gd
Editor Tools 4 12 16 editor_tools_native.gd
Debug Tools 3 67 70 debug_tools_native.gd
Project Tools 3 23 26 project_tools_native.gd
合计 30 124 154 -

4.2 工具注册方式

每个工具通过 8 个参数注册:

server_core.register_tool(
    "tool_name",                    # 1. 工具名称
    "Description...",               # 2. 描述
    input_schema,                   # 3. 输入 JSON Schema
    Callable(self, "_tool_..."),   # 4. 回调函数
    output_schema,                 # 5. 输出 JSON Schema
    annotations_dict,              # 6. 注解(readOnlyHint 等)
    "core",                        # 7. 类别
    "Group-Name"                   # 8. 分组
)

4.3 工具执行流程

AI 请求 → 传输层接收 → 参数验证(JSON Schema) 
  → 权限检查 → 调用工具实现 → 执行 Godot API 
  → 返回结果 → 发送给 AI

五、运行时探针(Runtime Probe)

这是项目的特色功能,允许 AI 在游戏运行时获取和操控游戏状态。

架构

MCP Server ←→ EngineDebugger ←→ MCPRuntimeProbe (注入到游戏场景)

实现机制

通过 EngineDebugger.register_message_capture() 注册消息捕获,实现编辑器与运行时的通信:

func _ready() -> void:
    EngineDebugger.register_message_capture(CAPTURE_PREFIX, 
        Callable(self, "_capture_mcp_message"))

func _capture_mcp_message(message: String, data: Array) -> bool:
    match message:
        "get_runtime_info":
            EngineDebugger.send_message("mcp:runtime_info", [_get_runtime_info()])
        "get_scene_tree":
            EngineDebugger.send_message("mcp:scene_tree", [...])
        # ...更多消息处理

支持的运行时操作

  • 获取运行时场景树
  • 检查节点属性和方法
  • 调用节点方法
  • 计算表达式
  • 模拟输入事件
  • 控制动画播放
  • 获取性能快照

六、测试体系

6.1 测试结构

test\
├── unit\                 # 单元测试 (GUT 框架)
│   ├── test_mcp_*.gd    # 核心模块测试
│   └── tools\           # 工具测试
└── integration\         # 集成测试 (Python)
    └── test_*_flow.py   # 端到端流程测试

6.2 测试规模

  • 单元测试:19 个测试脚本,295 个测试用例,521 个断言
  • 测试框架:GUT (Godot Unit Test) 9.6.0
  • 运行命令
    & "Godot.exe" --headless --path "..." -s addons/gut/gut_cmdln.gd `
      -gdir=res://test/unit/ -ginclude_subdirs -gexit
    

6.3 测试规范(强制)

  • 每次修改代码必须更新对应测试用例
  • 必须覆盖:正常路径 + 边界条件 + 错误处理
  • 禁止提交无测试更新的 commit

七、安全设计

认证机制

  • Token-based 认证(仅 HTTP 模式)
  • 时序安全比较防止时序攻击
  • Token 长度要求 ≥ 16 字符

速率限制

  • 每 IP 每 60 秒最多 100 个请求

路径遍历保护

func is_path_safe(path: String) -> bool:
    if not path.begins_with("res://") and not path.begins_with("user://"):
        return false
    if path.contains(".."):
        return false
    return true

八、文档体系

目录 内容
docs/current/ 当前稳定文档(架构、快速开始、工具参考)
docs/architecture/ 架构设计文档
docs/configuration/ 配置示例
docs/debugging/ 调试文档和问题排查
docs/development/ 开发规范(PR 审查流程等)
docs/release-notes/ 版本发布说明

核心文档

  • tools-reference.md(127 KB)— 最详细的工具参考手册
  • architecture.md(17.6 KB)— 架构设计文档
  • testing-guide.md(16.4 KB)— 测试指南

九、技术亮点

  1. 完全原生实现 — 不依赖 Node.js,纯 GDScript
  2. 线程安全 — 使用 call_deferred()Mutex
  3. 调试器深度集成 — 通过 EngineDebugger API
  4. 运行时探针 — 独特的游戏运行时 AI 交互能力
  5. 完善的 i18n — 英文/中文完整支持
  6. 全面的测试覆盖 — 单元 + 集成测试

十、配置项

配置项 默认值 说明
auto_start false 自动启动服务器
transport_mode "http" 传输模式
http_port 9080 HTTP 监听端口
auth_enabled false 启用认证
log_level 2 日志级别 (0-3)
security_level 1 安全级别 (0=宽松, 1=严格)
rate_limit 100 速率限制(每60秒)
vibe_coding_mode true 免打扰模式

总结

Godot MCP Native 是一个架构清晰、模块化、可扩展性强的 Godot 插件。它通过 MCP 协议将 AI 助手深度集成到游戏开发工作流,154 个工具覆盖了从场景编辑、脚本管理到调试和项目配置的各个方面。特别是运行时探针的设计,为 AI 辅助游戏开发提供了独特的能力,是该项目最大的技术亮点。

讨论回复

5 条回复
✨步子哥 (steper) #1
2026-06-08 22:50

Godot MCP Native 架构设计深度分析

一、整体架构评价 ⭐⭐⭐⭐☆

优点

  1. 分层清晰:MCP 协议层 → 服务器核心层 → 工具实现层 → Godot API 层,职责明确
  2. 原生实现:完全 GDScript,无外部依赖,部署简单
  3. 可扩展性强:工具注册机制统一,新增工具只需遵循 8 参数注册规范

不足

  1. 单点故障风险mcp_server_core.gd 承载过多职责(协议处理、工具注册、消息路由、认证)
  2. 传输层耦合:HTTP 和 Stdio 传输实现与核心逻辑耦合度较高

二、模块划分分析

合理的部分

  • native_mcp/ 核心模块 vs tools/ 工具模块分离清晰
  • runtime/ 运行时探针独立,职责单一
  • ui/ 面板代码与业务逻辑分离

建议改进

当前:tools/ 下按功能平铺 6 个文件
建议:tools/core/ + tools/supplementary/ 按分类组织
      或 tools/node/ + tools/script/ 等按领域组织

三、可扩展性与可维护性

扩展性设计 ⭐⭐⭐⭐⭐

  • 工具注册机制优秀:register_tool() 8 参数设计涵盖名称、描述、Schema、回调、分类、分组
  • 工具分类器(mcp_tool_classifier.gd)支持动态分类
  • 工具状态管理器支持运行时启用/禁用

维护性挑战

  1. 154 个工具的文档同步docs/current/tools-reference.md 127KB,手动维护成本高
    • 建议:从工具注册的 Schema 自动生成文档
  2. 测试覆盖追踪:目前依赖手动更新测试计数
    • 建议:自动化测试覆盖率报告

四、性能考虑

当前设计

  • HTTP 服务器使用 TCPServer 轮询,非异步 I/O
  • 工具执行在主线程,大量工具并发时可能阻塞编辑器

潜在风险

# mcp_http_server.gd 中的轮询模式
func _process(delta: float) -> void:
    var connection = _tcp_server.take_connection()  # 阻塞调用
    if connection:
        _handle_request(connection)

建议

  1. 使用 Thread 处理请求解析
  2. 耗时工具(如批量节点操作)应支持异步执行
  3. 添加请求队列和 Worker 线程池

五、安全性设计分析 ⭐⭐⭐⭐☆

已实现的防护

  1. 路径遍历保护is_path_safe() 检查 res://user:// 前缀
  2. 时序安全比较:认证 Token 比较使用安全比较
  3. 速率限制:每 IP 每 60 秒 100 请求
  4. 安全级别security_level 0/1 两档

缺失的防护

  1. 无 CORS 控制:HTTP 模式未配置 CORS,可能存在跨站请求风险
  2. Token 明文存储config_manager.gd 中 Token 未加密
  3. 无请求签名:无法验证请求完整性
  4. 工具的权限细粒度控制:目前只有 security_level 全局开关

六、与 Godot Editor API 的集成

集成方式

EditorPlugin (mcp_server_native.gd)
    ↓ get_editor_interface()
EditorInterface
    ↓ get_edited_scene_root(), get_selection()
场景/节点/脚本操作

创新点

  • execute_editor_script 工具:允许 AI 发送 GDScript 片段在编辑器上下文执行
  • EngineDebugger 集成:运行时探针通过调试器消息机制通信,无需网络端口

潜在风险

# execute_editor_script 工具可以执行任意 GDScript
# 当前仅有 security_level 检查,无沙箱隔离

七、运行时探针(Runtime Probe)设计评价 ⭐⭐⭐⭐⭐

这是项目最具创新性的设计。

设计亮点

  1. 零网络端口:通过 EngineDebugger 消息机制通信
  2. 注入式架构:探针节点自动注入到运行场景
  3. 双向通信:编辑器 ←→ 运行时双向数据交换

架构图

MCP Server (编辑器)
    ↓ EngineDebugger.register_message_capture()
EngineDebugger (Godot 内部)
    ↓ 消息捕获/发送
MCPRuntimeProbe (游戏内节点)
    ↓ get_node(), call(), get()
游戏场景树

改进建议

  1. 性能优化:序列化整个场景树可能很慢,建议支持增量更新
  2. 安全性:运行时探针应有安全开关,防止生产版本泄露信息
  3. 错误隔离:探针脚本错误不应导致游戏崩溃

八、测试体系完备性分析 ⭐⭐⭐⭐☆

优点

  1. 双层测试:单元测试(GUT)+ 集成测试(Python)
  2. 测试规范严格:AGENTS.md 中规定强制测试更新
  3. 295 个测试用例,覆盖广

不足

  1. 集成测试依赖外部 MCP 客户端:需要真实运行 Godot 和 MCP 请求
  2. 无 Mock 框架:GDScript 中难以 Mock Godot Editor API
  3. 测试数据管理.tmp_* 临时目录清理依赖手动规范

九、文档质量评价 ⭐⭐⭐⭐⭐

亮点

  1. docs/current/tools-reference.md(127 KB):154 个工具的详细文档
  2. AGENTS.md:开发规范清晰,新工具工作流明确
  3. docs/debugging/:问题排查文档详细

建议改进

  1. 架构图缺失architecture.md 以文字为主,建议添加架构图
  2. API 文档自动生成:从 Schema 生成,减少手动维护
  3. 视频/动画教程:MCP 工具使用演示

十、改进建议总结

高优先级

  1. 核心模块拆分:将 mcp_server_core.gd 按职责拆分为更小模块
  2. 异步请求处理:避免阻塞编辑器主线程
  3. 工具文档自动生成:从 Schema 和注释生成 tools-reference.md

中优先级

  1. CORS 控制:HTTP 传输添加 CORS 配置
  2. Token 加密存储:使用 Godot 的 Encryption API
  3. 测试覆盖率自动化:添加覆盖率报告生成

低优先级

  1. 架构图绘制:使用 Mermaid 或 PlantUML
  2. 性能基准测试:建立性能回归测试
  3. 多语言文档:除中英外,添加日文/西班牙文

总体评价

Godot MCP Native 是一个设计精良、实现扎实的 Godot 插件项目。其运行时探针设计尤为创新,通过 EngineDebugger 实现编辑器与运行时的零端口通信,是项目的核心竞争力。

主要技术债务集中在:

  1. 核心模块职责过重
  2. 性能优化(异步处理)
  3. 文档维护自动化

如果能在后续版本中解决这些问题,项目将达到生产级成熟度。

✨步子哥 (steper) #2
2026-06-08 23:35

一、如何用 C++ 写 Godot 扩展(GDExtension)

基本流程

  1. 安装 Godot 引擎(确保有 C++ 头文件)
  2. 设置编译环境(SConstruct 或 CMake)
  3. 编写 C++ 类并绑定到 Godot
  4. 编译为动态库.dll / .so / .dylib
  5. 在 Godot 项目中加载 .gdextension 配置文件

核心步骤示例

1. 创建 .gdextension 配置文件

[configuration]
entry_symbol = "example_library_init"
compatibility_minimum = "4.3"

[libraries]
windows.debug.x86_64 = "res://bin/windows/debug/libexample.dll"
windows.release.x86_64 = "res://bin/windows/release/libexample.dll"

2. 编写 C++ 类

#include <godot_cpp/classes/ref.hpp>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/godot.hpp>

using namespace godot;

class MyExtension : public RefCounted {
    GDCLASS(MyExtension, RefCounted);

protected:
    static void _bind_methods() {
        ClassDB::bind_method(D_METHOD("hello"), &MyExtension::hello);
    }

public:
    String hello() {
        return "Hello from C++!";
    }
};

3. 注册扩展

extern "C" GDExtensionBool example_library_init(
    GDExtensionInterfaceGetProcAddress p_get_proc_address,
    GDExtensionClassLibraryPtr p_library,
    GDExtensionInitialization *r_initialization
) {
    // 注册类
    ClassDB::register_class<MyExtension>();
    return true;
}

二、GDScript 插件能否用 C++ 重写?

可以,但需权衡利弊:

方面 GDScript C++ (GDExtension)
性能 较慢 极快
编写速度
调试 容易 较复杂
热重载 支持 需重新编译
分发 直接脚本 需编译各平台二进制

适合用 C++ 重写的场景

  • 性能瓶颈明显的逻辑(物理、寻路、密集计算)
  • 需要访问底层 API(OS、渲染、多线程)
  • 要封装第三方 C/C++ 库

不适合重写的场景

  • 简单工具脚本(Inspector 插件、UI 逻辑)
  • 频繁修改的原型代码
  • 依赖 Godot 编辑器的 EditorPlugin 接口(C++ 也能写,但更复杂)

✨步子哥 (steper) #3
2026-06-09 01:20

Godot MCP Native (模型上下文协议)

English Version

Godot 版本
许可证
版本

一个强大的 Godot 引擎插件,通过模型上下文协议 (MCP) 集成 AI 助手(如 Claude 等)。让 AI 可以直接通过自然语言读取和修改您的 Godot 项目——场景、脚本、节点和资源。

🚀 功能特性

  • 完整项目访问:AI 助手可以读取和修改脚本、场景、节点和资源
  • 原生实现:无需 Node.js 依赖——完全在 Godot 中运行
  • 实时编辑:直接在编辑器中应用 AI 建议
  • 全面的工具集(154 个工具——30 核心 + 124 补充):
    • 节点工具(9 核心 + 11 高级):创建、修改、管理场景节点,复制、移动、重命名,锚点预设,信号连接,组管理,批量操作,场景审计
    • 脚本工具(7 核心 + 8 高级):编辑、分析、创建、附加、验证 GDScript 文件,执行脚本,文件搜索,符号索引,定义和引用查找
    • 场景工具(4 核心 + 4 高级):操作场景结构、保存场景、列出/打开/关闭场景标签页,项目场景列表
    • 编辑器工具(4 核心 + 12 高级):控制编辑器功能、截图、信号检查、文件系统重载,节点/文件选择,导出管理,属性检查器
    • 调试工具(3 核心 + 66 高级):日志、调试会话、断点、栈帧/变量读取、性能分析器、运行时探针,动画/音频/着色器/瓦片地图运行时控制,调试执行控制
    • 项目工具(3 核心 + 23 高级):访问项目设置、列出资源、创建资源,运行测试、管理输入映射、检查自动加载/全局类,资源诊断与健康审计

📦 安装

方法 1:资源库(推荐)

  1. 打开您的 Godot 项目
  2. 进入编辑器中的 AssetLib 标签页
  3. 搜索 "Godot MCP Native"
  4. 点击 下载 然后 安装

方法 2:手动安装

  1. 下载或克隆此仓库
  2. addons/godot_mcp 文件夹复制到项目的 addons/ 目录
  3. 在 Godot 中打开项目
  4. 进入 项目 > 项目设置 > 插件
  5. 启用 "Godot MCP Native" 插件

🔧 使用

启用插件

  1. 打开 项目 > 项目设置 > 插件
  2. 在列表中找到 "Godot MCP Native"
  3. 将状态设置为 启用

配置 MCP 服务器

插件提供两种传输模式:

HTTP 模式(用于远程访问)

  • 适用场景:基于网络的 AI 集成
  • 配置:在插件设置中设置 transport_mode = "http" 并配置 http_port(默认:9080)
  • 可选:启用 auth_enabled 并设置 auth_token 以保障安全

连接 Claude Desktop

首先安装 mcp-remote 包:

npm install mcp-remote

HTTP 模式配置

{
  "mcpServers": {
    "godot-mcp": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "http://localhost:19080/mcp"
      ]
    }
  }
}

连接 Cursor / Trae

HTTP 模式配置

{
  "mcpServers": {
    "godot-mcp": {
      "url": "http://localhost:9080/mcp"
    }
  }
}

带身份验证:

{
  "mcpServers": {
    "godot-mcp": {
      "url": "http://localhost:9080/mcp",
      "headers": {
        "Authorization": "Bearer your-secret-token-here"
      }
    }
  }
}

连接 Cline

HTTP 模式配置

编辑 Cline 配置文件(cline_mcp_settings.json):

{
  "mcpServers": {
    "godot-mcp": {
      "url": "http://localhost:9080/mcp",
      "type": "streamableHttp",
      "disabled": false,
      "autoApprove": []
    }
  }
}

连接 OpenCode

HTTP 模式配置

{
  "mcp": {
    "godot-mcp": {
      "type": "remote",
      "url": "http://localhost:9080/mcp"
    }
  }
}

连接 Codex

HTTP 模式配置

[mcp_servers]

[mcp_servers.godot-mcp]
type = "streamableHttp"
url = "http://localhost:19080/mcp"

💬 示例提示

连接后,您可以通过 Claude 与 Godot 项目交互:

@mcp godot-mcp read godot://script/current

我需要帮助优化我的玩家移动代码。能提出改进建议吗?
@mcp godot-mcp get-scene-tree

在场景中间添加一个立方体,并创建一个相机看向它。
创建一个主菜单,包含开始、选项和退出按钮
实现一个带有动态光照的昼夜循环系统

📚 可用命令

Node-Write (6)

  • create-node - 创建新节点
  • delete-node - 删除节点
  • update-node-property - 更新节点属性
  • duplicate-node - 复制节点及子节点
  • move-node - 移动节点到新父节点
  • rename-node - 重命名节点

Node-Read (3)

  • get-scene-tree - 获取场景树结构
  • get-node-properties - 获取特定节点的属性
  • list-nodes - 列出父节点下的所有节点

Node-Write-Advanced (5)

  • set-anchor-preset - 设置 Control 节点锚点预设
  • connect-signal - 连接节点间的信号
  • disconnect-signal - 断开信号连接
  • set-node-groups - 设置节点的组成员关系
  • add-resource - 向节点添加资源子节点(碰撞形状、网格等)

Node-Advanced (6)

  • get-node-groups - 获取节点所属的组
  • find-nodes-in-group - 查找组中的所有节点
  • batch-update-node-properties - 在单个 UndoRedo 动作中批量更新节点属性
  • batch-scene-node-edits - 在单个 UndoRedo 动作中批量执行场景节点编辑
  • audit-scene-node-persistence - 审计节点 owner 和持久化状态
  • audit-scene-inheritance - 审计场景继承/实例化结构

Script (7)

  • list-project-scripts - 列出所有脚本
  • read-script - 读取特定脚本
  • modify-script - 更新脚本内容
  • create-script - 创建新脚本
  • get-current-script - 获取当前正在编辑的脚本
  • attach-script - 将已有脚本附加到节点
  • execute-script - 执行 GDScript 表达式

Script-Advanced (8)

  • analyze-script - 分析脚本结构
  • validate-script - 验证 GDScript 语法
  • search-in-files - 搜索项目文件
  • list-project-script-symbols - 索引 GDScript 和 C# 文件的脚本符号
  • find-script-symbol-definition - 查找脚本符号的定义位置
  • find-script-symbol-references - 查找脚本符号的文本引用
  • rename-script-symbol - 跨文件重命名脚本符号
  • open-script-at-line - 在编辑器中打开脚本到指定行

Scene (4)

  • create-scene - 创建新场景
  • save-scene - 保存当前场景
  • open-scene - 打开场景
  • get-current-scene - 获取当前场景信息

Scene-Advanced (4)

  • list-project-scenes - 列出所有场景
  • get-scene-structure - 获取场景结构详情
  • list-open-scenes - 列出当前打开的场景标签页
  • close-scene-tab - 关闭场景标签页

Editor (4)

  • get-editor-state - 获取当前编辑器状态
  • run-project - 运行项目
  • stop-project - 停止运行中的项目
  • execute-editor-script - 执行 GDScript 脚本

Editor-Advanced (12)

  • get-selected-nodes - 获取选中的节点
  • set-editor-setting - 修改编辑器设置
  • get-editor-screenshot - 截取编辑器视口截图
  • get-signals - 检查节点信号和连接
  • reload-project - 重新扫描项目文件系统
  • select-node - 在场景中选择节点并聚焦检查器
  • select-file - 在文件系统面板中选择文件
  • get-inspector-properties - 检查节点/资源的属性元数据
  • list-export-presets - 列出导出预设
  • inspect-export-templates - 检查已安装的导出模板
  • validate-export-preset - 验证导出预设
  • run-export - 运行 Godot CLI 导出

Debug (3 核心 + 66 高级)

  • get-editor-logs - 获取编辑器/运行时日志
  • debug-print - 打印调试信息
  • clear-output - 清除 MCP/编辑器输出缓冲
  • get-performance-metrics - 获取性能数据
  • get-debugger-sessions - 列出编辑器调试会话和 active/break 状态
  • set-debugger-breakpoint - 启用或禁用调试断点
  • send-debugger-message - 向运行中的游戏调试器发送自定义消息
  • toggle-debugger-profiler - 在活动会话中切换 EngineProfiler 通道
  • get-debugger-messages - 读取 bridge 捕获的运行时自定义消息
  • add-debugger-capture-prefix - 捕获更多 EngineDebugger 消息前缀
  • get-debug-stack-frames - 读取已暂停会话捕获到的脚本栈帧
  • get-debug-stack-variables - 读取指定栈帧的局部变量、成员变量和全局变量
  • install-runtime-probe - 向当前场景添加 MCP 运行时探针节点
  • remove-runtime-probe - 从当前场景移除 MCP 运行时探针节点
  • request-debug-break - 请求运行时探针进入 Godot 调试暂停循环
  • send-debug-command - 向已暂停会话发送 step/next/out/continue/stack 调试命令
  • get-runtime-info - 通过探针查询运行时指标(FPS、节点数等)
  • get-runtime-scene-tree - 从运行中的游戏读取实时场景树
  • inspect-runtime-node - 检查运行时节点及其可序列化属性
  • update-runtime-node-property - 修改运行时节点上的属性
  • call-runtime-node-method - 调用运行时节点上的方法
  • evaluate-runtime-expression - 在运行中的游戏计算 GDScript 表达式
  • await-runtime-condition - 轮询运行时表达式直到为真或超时
  • assert-runtime-condition - 断言运行时表达式在超时内变为真
  • get-debug-threads - 返回 DAP 样式调试器线程
  • get-debug-state-events - 读取记录的调试器状态转换
  • get-debug-output - 读取分类的运行时调试器输出
  • get-debug-scopes - 将栈变量分组为 DAP 风格的 scope
  • get-debug-variables - 解析 DAP 风格的变量引用
  • expand-debug-variable - 通过 scope 和路径展开调试变量
  • evaluate-debug-expression - 在调试上下文评估表达式
  • debug-step-into / debug-step-over / debug-step-out / debug-continue - 调试执行控制
  • debug-step-into-and-wait / debug-step-over-and-wait / debug-step-out-and-wait / debug-continue-and-wait - 调试执行控制(等待状态)
  • await-debugger-state - 检查调试器会话执行状态
  • get-runtime-performance-snapshot - 捕获运行时性能快照
  • get-runtime-memory-trend - 捕获运行时内存趋势
  • create-runtime-node - 在运行中游戏创建节点
  • delete-runtime-node - 从运行中游戏删除节点
  • simulate-runtime-input-event - 注入结构化 InputEvent
  • simulate-runtime-input-action - 注入 InputEventAction
  • list-runtime-input-actions - 列出运行时 InputMap 动作
  • upsert-runtime-input-action - 创建或更新运行时 InputMap 动作
  • remove-runtime-input-action - 移除运行时 InputMap 动作
  • list-runtime-animations - 列出运行时动画
  • play-runtime-animation - 播放运行时动画
  • stop-runtime-animation - 停止运行时动画
  • get-runtime-animation-state - 获取运行时动画播放状态
  • get-runtime-animation-tree-state - 获取运行时 AnimationTree 状态
  • set-runtime-animation-tree-active - 启用/禁用 AnimationTree
  • travel-runtime-animation-tree - 转移运行时动画状态机
  • get-runtime-material-state - 解析运行时节点材质绑定
  • get-runtime-theme-item - 解析运行时 Control 主题项
  • set-runtime-theme-override - 应用运行时主题覆盖
  • clear-runtime-theme-override - 移除运行时主题覆盖
  • get-runtime-shader-parameters - 列出运行时着色器参数
  • set-runtime-shader-parameter - 更新运行时着色器 uniform
  • list-runtime-tilemap-layers - 列出运行时 TileMap 层
  • get-runtime-tilemap-cell - 获取运行时 TileMap 单元格数据
  • set-runtime-tilemap-cell - 写入/擦除运行时 TileMap 单元格
  • list-runtime-audio-buses - 列出运行时音频总线
  • get-runtime-audio-bus - 获取运行时音频总线状态
  • update-runtime-audio-bus - 更新运行时音频总线
  • get-runtime-screenshot - 捕获运行时视口截图

Project (3 核心 + 23 高级)

  • get-project-info - 获取项目信息
  • get-project-settings - 获取项目设置
  • list-project-resources - 列出项目资源
  • create-resource - 创建新资源
  • get-project-structure - 获取项目目录结构
  • list-project-tests - 发现和列出可运行的项目测试
  • run-project-test - 运行单个项目测试
  • run-project-tests - 运行多个项目测试
  • list-project-input-actions - 列出项目 InputMap 动作
  • upsert-project-input-action - 创建或更新项目 InputMap 动作
  • remove-project-input-action - 移除项目 InputMap 动作
  • list-project-autoloads - 列出项目自动加载条目
  • list-project-global-classes - 列出项目全局脚本类
  • get-class-api-metadata - 获取 ClassDB 或全局类 API 元数据
  • inspect-csharp-project-support - 检查 C# 项目支持文件
  • compare-render-screenshots - 比较两张截图并报告差异
  • inspect-tileset-resource - 检查 TileSet 资源
  • reimport-resources - 通过导入管线重新导入资源
  • get-import-metadata - 获取资源导入元数据
  • get-resource-uid-info - 检查 ResourceUID 映射
  • fix-resource-uid - 确保资源有持久化 UID
  • get-resource-dependencies - 列出资源依赖
  • scan-missing-resource-dependencies - 查找破损的依赖引用
  • scan-cyclic-resource-dependencies - 查找循环依赖链
  • detect-broken-scripts - 扫描脚本语法错误
  • audit-project-health - 运行项目健康审计

🔒 安全建议

  • 生产环境:始终启用身份验证(auth_enabled = true
  • 令牌:使用强令牌(≥16 个字符,包含字母、数字、特殊字符)
  • 存储:不要将令牌提交到版本控制
  • ⚠️ 远程访问:使用 HTTPS(TLS/SSL)进行网络访问

📋 要求

  • Godot Engine 4.x(推荐 4.5 或更高版本)
  • 无额外依赖(原生实现)

📖 文档

详细文档请查看 docs/current/ 文件夹:

🤝 贡献

欢迎贡献!请随时提交 Pull Request。

📄 许可证

本项目采用 MIT 许可证 - 详见 LICENSE 文件。

👤 作者

yurineko73

🙏 致谢

  • Godot 引擎团队带来的出色游戏引擎
  • 模型上下文协议 (MCP) 规范
  • Anthropic 的 Claude AI 启发了此集成

注意:这是一个社区插件,与 Godot Engine 或 Anthropic 无官方关联。

✨步子哥 (steper) #4
2026-06-09 01:24

一、GDExtension 接口 API 架构

1. 核心类型系统

GDExtension 定义了一套完整的 C 接口类型,对应 Godot 内部的 Variant 类型:

// 基础类型枚举(对应 Godot 的 Variant 类型)
typedef enum {
    GDEXTENSION_VARIANT_TYPE_NIL = 0,
    GDEXTENSION_VARIANT_TYPE_BOOL = 1,
    GDEXTENSION_VARIANT_TYPE_INT = 2,
    GDEXTENSION_VARIANT_TYPE_FLOAT = 3,
    GDEXTENSION_VARIANT_TYPE_STRING = 4,
    GDEXTENSION_VARIANT_TYPE_VECTOR2 = 5,
    // ... 直至 GDEXTENSION_VARIANT_TYPE_VARIANT_MAX = 39
} GDExtensionVariantType;

2. 指针类型定义

为安全起见,GDExtension 区分已初始化与未初始化指针:

typedef void *GDExtensionVariantPtr;           // 已初始化的 Variant 指针
typedef void *GDExtensionUninitializedVariantPtr; // 未初始化的 Variant 指针
typedef void *GDExtensionObjectPtr;            // Godot 对象指针
typedef void *GDExtensionClassInstancePtr;     // C++ 扩展实例指针

二、双向通讯机制

GDExtension 之双向通讯,乃其设计之精髓。分为两个方向:

方向一:C++ → Godot(扩展调用引擎)

通过 函数指针表 调用 Godot 引擎 API。

初始化时获取函数指针

// 扩展初始化函数
GDExtensionBool my_extension_init(
    GDExtensionInterfaceGetProcAddress p_get_proc_address,  // 获取函数地址的回调
    GDExtensionClassLibraryPtr p_library,
    GDExtensionInitialization *r_initialization
) {
    // 通过函数名获取 Godot API 函数指针
    GDExtensionInterfaceGetGodotVersion get_godot_version = 
        (GDExtensionInterfaceGetGodotVersion)p_get_proc_address("get_godot_version");
    
    // 调用 Godot API
    GDExtensionGodotVersion version;
    get_godot_version(&version);
}

常用 Godot API 函数指针类型

// 获取 Variant 操作符求值函数
typedef void (*GDExtensionPtrOperatorEvaluator)(
    GDExtensionConstTypePtr p_left, 
    GDExtensionConstTypePtr p_right, 
    GDExtensionTypePtr r_result
);

// 获取内置方法调用函数
typedef void (*GDExtensionPtrBuiltInMethod)(
    GDExtensionTypePtr p_base, 
    const GDExtensionConstTypePtr *p_args, 
    GDExtensionTypePtr r_return, 
    int32_t p_argument_count
);

// 实用函数(如 print、str 等)
typedef void (*GDExtensionPtrUtilityFunction)(
    GDExtensionTypePtr r_return, 
    const GDExtensionConstTypePtr *p_args, 
    int32_t p_argument_count
);

方向二:Godot → C++(引擎调用扩展)

通过 回调函数表 注册 C++ 类的虚函数。

类创建信息结构体(GDExtensionClassCreationInfo6)

此为注册 C++ 类到 Godot 的核心结构体:

typedef struct {
    GDExtensionBool is_virtual;      // 是否为虚类
    GDExtensionBool is_abstract;     // 是否为抽象类
    GDExtensionBool is_exposed;      // 是否暴露给脚本
    GDExtensionBool is_runtime;      // 是否为运行时类
    
    // 属性访问回调
    GDExtensionClassSet set_func;                    // Godot 调用此函数设置属性
    GDExtensionClassGet get_func;                    // Godot 调用此函数获取属性
    GDExtensionClassGetPropertyList get_property_list_func; // 获取属性列表
    GDExtensionClassFreePropertyList2 free_property_list_func;
    
    // 属性重置回调
    GDExtensionClassPropertyCanRevert property_can_revert_func;
    GDExtensionClassPropertyGetRevert property_get_revert_func;
    GDExtensionClassValidateProperty validate_property_func;
    
    // 通知回调
    GDExtensionClassNotification2 notification_func;  // Godot 通知 C++ 对象(如 _ready, _process)
    
    // 引用计数回调(用于 RefCounted 子类)
    GDExtensionClassReference reference_func;
    GDExtensionClassUnreference unreference_func;
    
    // 实例创建/销毁回调
    GDExtensionClassCreateInstance3 create_instance_func; // Godot 创建实例时调用
    GDExtensionClassFreeInstance free_instance_func;     // Godot 销毁实例时调用
    GDExtensionClassRecreateInstance recreate_instance_func;
    
    // 虚函数回调
    GDExtensionClassGetVirtual2 get_virtual_func;       // Godot 查询虚函数重写
    GDExtensionClassGetVirtualCallData2 get_virtual_call_data_func;
    GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
    
    // RID 回调
    GDExtensionClassGetRID get_rid_func;
    
    // 用户数据
    void *class_userdata;
} GDExtensionClassCreationInfo6;

回调函数类型详解

属性访问回调:

// Godot 设置属性时调用
typedef GDExtensionBool (*GDExtensionClassSet)(
    GDExtensionClassInstancePtr p_instance,  // C++ 实例指针
    GDExtensionConstStringNamePtr p_name,   // 属性名
    GDExtensionConstVariantPtr p_value      // 属性值
);

// Godot 获取属性时调用
typedef GDExtensionBool (*GDExtensionClassGet)(
    GDExtensionClassInstancePtr p_instance,
    GDExtensionConstStringNamePtr p_name,
    GDExtensionVariantPtr r_ret              // 返回值
);

虚函数调用回调:

// Godot 调用虚函数时,通过此回调获取函数指针
typedef GDExtensionClassCallVirtual (*GDExtensionClassGetVirtual2)(
    void *p_class_userdata,
    GDExtensionConstStringNamePtr p_name,   // 虚函数名(如 "_ready")
    uint32_t p_hash                          // 函数名哈希
);

// 实际的虚函数签名
typedef void (*GDExtensionClassCallVirtual)(
    GDExtensionClassInstancePtr p_instance,
    const GDExtensionConstTypePtr *p_args,  // 参数数组
    GDExtensionTypePtr r_ret                // 返回值
);

三、方法注册与调用

1. 注册方法到 Godot

使用 GDExtensionClassMethodInfo 结构体:

typedef struct {
    GDExtensionStringNamePtr name;           // 方法名
    void *method_userdata;                   // 用户数据
    GDExtensionClassMethodCall call_func;    // 普通调用(带类型检查)
    GDExtensionClassMethodPtrCall ptrcall_func; // 快速调用(无类型检查)
    
    uint32_t method_flags;                  // 方法标志(NORMAL, CONST, VIRTUAL 等)
    
    GDExtensionBool has_return_value;
    GDExtensionPropertyInfo *return_value_info;
    GDExtensionClassMethodArgumentMetadata return_value_metadata;
    
    uint32_t argument_count;
    GDExtensionPropertyInfo *arguments_info;
    GDExtensionClassMethodArgumentMetadata *arguments_metadata;
    
    uint32_t default_argument_count;
    GDExtensionVariantPtr *default_arguments;
} GDExtensionClassMethodInfo;

2. 方法调用回调

// Godot 调用 C++ 方法时触发
typedef void (*GDExtensionClassMethodCall)(
    void *method_userdata,
    GDExtensionClassInstancePtr p_instance,
    const GDExtensionConstVariantPtr *p_args,  // 参数(Variant 数组)
    GDExtensionInt p_argument_count,
    GDExtensionVariantPtr r_return,           // 返回值
    GDExtensionCallError *r_error             // 错误码
);

// 高性能调用(无类型检查,直接传递类型指针)
typedef void (*GDExtensionClassMethodPtrCall)(
    void *method_userdata,
    GDExtensionClassInstancePtr p_instance,
    const GDExtensionConstTypePtr *p_args,    // 参数(原始类型指针)
    GDExtensionTypePtr r_ret                  // 返回值
);

四、信号机制

C++ 发射信号给 Godot

C++ 扩展可以发射信号,Godot 侧可连接这些信号:

// 在 GDExtension 中发射信号
// 需要通过 Godot API 函数指针调用 Object::emit_signal
typedef void (*GDExtensionObjectEmitSignal)(
    GDExtensionObjectPtr p_object,
    GDExtensionConstStringNamePtr p_signal_name,
    const GDExtensionConstVariantPtr *p_args,
    GDExtensionInt p_argument_count
);

注册信号

在类注册时声明信号:

// 通过 GDExtensionInterface 注册信号
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassSignal)(
    GDExtensionClassLibraryPtr p_library,
    GDExtensionConstStringNamePtr p_class_name,
    GDExtensionConstStringNamePtr p_signal_name,
    int32_t p_argument_count,
    const GDExtensionPropertyInfo *p_arguments
);

五、完整示例:双向通讯

C++ 侧(扩展)

#include <godot_cpp/godot.hpp>
#include <godot_cpp/classes/ref.hpp>
#include <godot_cpp/core/class_db.hpp>

using namespace godot;

class MyExtension : public Node {
    GDCLASS(MyExtension, Node);

    String name;

protected:
    static void _bind_methods() {
        // 暴露方法给 Godot
        ClassDB::bind_method(D_METHOD("say_hello"), &MyExtension::say_hello);
        
        // 注册属性
        ClassDB::bind_method(D_METHOD("set_name", "name"), &MyExtension::set_name);
        ClassDB::bind_method(D_METHOD("get_name"), &MyExtension::get_name);
        ADD_PROPERTY(PropertyInfo(Variant::STRING, "name"), "set_name", "get_name");
        
        // 注册信号
        ADD_SIGNAL(MethodInfo("health_changed", PropertyInfo(Variant::FLOAT, "new_health")));
    }

public:
    String say_hello() {
        // C++ 调用 Godot 的 print 函数
        UtilityFunctions::print("Hello from C++!");
        return "Hello!";
    }
    
    void set_name(const String &p_name) {
        name = p_name;
        // 发射信号给 Godot
        emit_signal("name_changed", name);
    }
    
    String get_name() const {
        return name;
    }
    
    // Godot 调用此虚函数
    void _ready() {
        UtilityFunctions::print("MyExtension ready!");
    }
};

GDScript 侧(调用 C++ 扩展)

extends Node

func _ready():
    var ext = MyExtension.new()
    ext.name = "Test"
    ext.say_hello()
    
    # 连接 C++ 扩展的信号
    ext.connect("name_changed", Callable(self, "_on_name_changed"))
    
    # 调用 C++ 方法
    var result = ext.say_hello()
    print(result)

func _on_name_changed(new_name):
    print("Name changed to: " + new_name)

六、通讯机制总结

通讯方向 机制 说明
C++ → Godot 函数指针表 通过 p_get_proc_address 获取 Godot API 函数指针
Godot → C++ 回调函数表 注册 set_func, get_func, notification_func 等回调
方法调用 GDExtensionClassMethodCall Godot 调用 C++ 方法
虚函数重写 get_virtual_func Godot 查询 C++ 是否重写了虚函数
信号 emit_signal C++ 发射信号,Godot 连接
属性 set_func / get_func Godot 通过回调访问 C++ 属性

七、godot-cpp 封装层

实际开发时,无需直接使用原始 C 接口。godot-cpp 提供了 C++ 封装:

// godot-cpp 自动生成了类型安全的封装
// 无需手动处理 GDExtensionVariantPtr 等原始指针

class MyExtension : public Node {
    GDCLASS(MyExtension, Node);
    
    // 使用宏绑定方法
    static void _bind_methods() {
        ClassDB::bind_method(D_METHOD("my_method", "arg1"), &MyExtension::my_method);
    }
};

✨步子哥 (steper) #5
2026-06-09 02:46

一、核心机制:双轨制生命周期管理

轨一:C++ 侧 RAII(资源获取即初始化)

C++ 扩展对象由 memnew/memdelete 管理,遵循 RAII 原则:

// 创建对象
MyClass *obj = memnew(MyClass);

// 销毁对象
memdelete(obj);
  • memnew:调用 operator new + 构造函数
  • memdelete:调用析构函数 + operator delete
  • 不使用 C++ 标准库的 shared_ptr,而是 Godot 自研的内存管理器

轨二:Godot 侧引用计数(针对 RefCounted 子类)

若 C++ 类继承自 RefCounted,则采用 SafeRefCount 引用计数:

class RefCounted : public Object {
    SafeRefCount refcount;       // 引用计数
    SafeRefCount refcount_init;   // 初始化计数
    SafeNumeric<uint32_t> dereference_count;
};

引用计数规则

  • 引用 +1Ref<T> 对象拷贝构造或赋值时
  • 引用 -1Ref<T> 析构或 unref()
  • 计数为 0:自动调用 memdelete 销毁对象

二、GDExtension 特有的生命周期桥接

关键机制:Instance Binding

GDExtension 通过 InstanceBinding 结构体,桥接 C++ 对象与 Godot 引擎:

// Object 类中的 InstanceBinding 定义
struct InstanceBinding {
    void *binding = nullptr;  // C++ 对象指针
    GDExtensionInstanceBindingFreeCallback free_callback = nullptr;       // 释放回调
    GDExtensionInstanceBindingReferenceCallback reference_callback = nullptr; // 引用回调
};

Instance Binding 回调三剑客

typedef struct {
    GDExtensionInstanceBindingCreateCallback create_callback;       // 创建绑定
    GDExtensionInstanceBindingFreeCallback free_callback;           // 释放绑定
    GDExtensionInstanceBindingReferenceCallback reference_callback;  // 引用计数变化
} GDExtensionInstanceBindingCallbacks;

三、GDExtension 对象生命周期完整流程

阶段一:C++ 对象创建

// 1. C++ 侧创建对象
MyExtension *obj = memnew(MyExtension);

// 2. 将 C++ 对象绑定到 Godot Object
obj->set_instance_binding(
    token,                      // 扩展标识
    obj,                        // C++ 对象指针
    &binding_callbacks           // 回调函数表
);

阶段二:Godot 侧引用

# GDScript 侧持有引用
var ext = MyExtension.new()  # 引用 +1
# ... 使用 ext ...
ext = null  # 引用 -1,若无其他引用,触发销毁

阶段三:销毁流程

// 1. Godot 引用计数降为 0
// 2. 调用 reference_callback (若 C++ 类继承自 RefCounted)
// 3. 调用 free_callback 销毁 C++ 对象
// 4. 调用 memdelete 释放内存

四、RefCounted 在 GDExtension 中的特殊处理

问题:C++ 与 Godot 引用计数如何同步?

答案:通过 reference_funcunreference_func 回调。

回调注册

// 注册 C++ 类时,提供引用计数回调
GDExtensionClassCreationInfo6 class_info = {
    .reference_func = [](GDExtensionClassInstancePtr p_instance) {
        // Godot 增加引用时,调用 C++ 侧 RefCounted::reference()
        reinterpret_cast<RefCounted *>(p_instance)->reference();
    },
    .unreference_func = [](GDExtensionClassInstancePtr p_instance) {
        // Godot 减少引用时,调用 C++ 侧 RefCounted::unreference()
        if (reinterpret_cast<RefCounted *>(p_instance)->unreference()) {
            // 引用计数为 0,销毁对象
            memdelete(reinterpret_cast<RefCounted *>(p_instance));
        }
    },
    // ... 其他回调
};

引用计数同步流程

GDScript: ext = MyExtension.new()
    ↓
Godot: RefCounted::reference()  # 引用 +1
    ↓
C++: reference_func() 回调       # 通知 C++ 侧
    ↓
C++: RefCounted::reference()      # C++ 侧引用计数 +1

GDScript: ext = null
    ↓
Godot: RefCounted::unreference() # 引用 -1
    ↓
C++: unreference_func() 回调     # 通知 C++ 侧
    ↓
C++: RefCounted::unreference()   # C++ 侧引用计数 -1
    ↓
若计数为 0: memdelete(obj)       # 销毁 C++ 对象

五、Node 类(非 RefCounted)的生命周期

若 C++ 类继承自 Node(非 RefCounted),则不依赖引用计数,而是:

管理方式:树形结构 + 手动释放

// C++ 侧
class MyNode : public Node {
    GDCLASS(MyNode, Node);
};

// GDScript 侧
var node = MyNode.new()  # 创建
get_parent().add_child(node)  # 加入场景树(引用 +1)
node.queue_free()  # 标记销毁
# 或
node.free()  # 立即销毁

销毁流程

Node::queue_free()
    ↓
Node::_notification(NOTIFICATION_PREDELETE)
    ↓
调用 GDExtension 的 free_instance_func 回调
    ↓
C++ 侧销毁对象(调用析构函数)
    ↓
memdelete(obj)

六、godot-cpp 的封装简化

实际开发中,godot-cpp 已封装好生命周期管理,开发者无需手动处理:

示例:RefCounted 子类

#include <godot_cpp/classes/ref_counted.hpp>
#include <godot_cpp/core/class_db.hpp>

using namespace godot;

class MyResource : public RefCounted {
    GDCLASS(MyResource, RefCounted);

    String data;

protected:
    static void _bind_methods() {
        ClassDB::bind_method(D_METHOD("set_data", "data"), &MyResource::set_data);
        ClassDB::bind_method(D_METHOD("get_data"), &MyResource::get_data);
        ADD_PROPERTY(PropertyInfo(Variant::STRING, "data"), "set_data", "get_data");
    }

public:
    void set_data(const String &p_data) { data = p_data; }
    String get_data() const { return data; }
    
    // 无需手动管理引用计数!
    // godot-cpp 自动处理 reference/unreference 回调
};

示例:Node 子类

#include <godot_cpp/classes/node.hpp>
#include <godot_cpp/core/class_db.hpp>

using namespace godot;

class MyNode : public Node {
    GDCLASS(MyNode, Node);

protected:
    static void _bind_methods() {
        ClassDB::bind_method(D_METHOD("do_something"), &MyNode::do_something);
    }

public:
    void _ready() {
        UtilityFunctions::print("MyNode ready!");
    }
    
    void do_something() {
        UtilityFunctions::print("Doing something!");
    }
    
    // 无需手动管理内存!
    // Godot 场景树负责 Node 的生命周期
};

七、内存泄漏防范

规则一:RefCounted 对象必须用 Ref<T> 持有

// 正确:使用 Ref<T>
Ref<MyResource> res = memnew(MyResource);
// 自动管理引用计数

// 错误:裸指针
MyResource *res = memnew(MyResource);  // 引用计数为 0
// 可能导致内存泄漏!

规则二:Node 对象必须加入场景树或手动释放

// 正确:加入场景树
Node *node = memnew(MyNode);
get_parent()->add_child(node);  // 场景树持有引用

// 正确:手动释放
Node *node = memnew(MyNode);
node->queue_free();  // 标记销毁

// 错误:孤立的 Node
Node *node = memnew(MyNode);
// 忘记加入场景树或释放 → 内存泄漏!

规则三:避免循环引用

// 错误:循环引用
class NodeA : public RefCounted {
    Ref<NodeB> b;  // 引用 B
};

class NodeB : public RefCounted {
    Ref<NodeA> a;  // 引用 A
};

// 解决:使用 WeakRef 或手动打破循环

八、总结:生命周期管理要点

类别 管理方式 销毁触发条件
RefCounted 子类 Godot 引用计数 + C++ 引用计数(双轨同步) 引用计数为 0
Node 子类 场景树持有 + 手动释放 queue_free()free()
普通 Object 子类 手动管理(memnew/memdelete) 显式调用 memdelete
Instance Binding 回调函数表 Godot 对象销毁时触发 free_callback

九、关键结论

  1. 非单纯依赖 C++ 引用计数,而是 Godot 引用计数与 C++ 引用计数双轨同步
  2. RefCounted 子类:通过 reference_func / unreference_func 回调同步引用计数。
  3. Node 子类:依赖场景树管理生命周期,无需引用计数。
  4. godot-cpp 已封装细节,开发者只需遵循 RAII 原则,避免内存泄漏。
推荐
智谱 GLM-5 已上线

我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。

领取 2000万 Tokens 通过邀请链接注册即可获得大礼包,期待和你一起在 BigModel 上畅享卓越模型能力
登录