自底向上分层,依赖方向单向向下:
platform / main / editor # 平台入口、主程序、编辑器
↓
modules # 可插拔功能(GDScript、物理、格式等)
↓
scene # 场景系统(Node/SceneTree/GUI/2D/3D)
↓
servers + drivers # 多线程服务器抽象 + 底层驱动
↓
core # Object/Variant/容器/数学/OS 抽象
- core:不含任何游戏概念。核心是 Object 模型 与 Variant,见 object-model。
- servers:把渲染/物理/音频等抽象成”服务器”单例,主线程只持有 RID(资源 ID)句柄,实际资源与计算在服务器线程,见 rendering 与下方线程模型。
- drivers:图形 API(Vulkan/D3D12/Metal/GLES3)、音频(ALSA/WASAPI/CoreAudio…)、图像(PNG)、POSIX/Windows 原语,见 platform-drivers。
- scene:Node 树 + SceneTree 主循环 + 2D/3D/GUI 节点,见 scene-tree。
- editor:一个用引擎自身构建的大型场景,
TOOLS_ENABLED宏隔离;发布运行时不带编辑器,见 editor-architecture。 - modules:59 个模块按 4 个初始化级别注册,见 module-catalog。
启动流程
入口在平台文件(如 platform/linuxbsd/godot_linuxbsd.cpp:70-126),全部委托给 Main 纯静态类(main/main.h:39-86):
Main::setup(main.cpp:963)— 解析命令行 + 初始化 core(两阶段,setup2于 main.cpp:3006:注册场景类型/服务器、创建 MainLoop)Main::start(main.cpp:3974)— 二次解析 CLI;-e/--editor时memnew(EditorNode)挂到根窗口(main.cpp:4569)并Engine::set_editor_hint(true);否则加载主场景os.run()— OS 事件循环反复调用Main::iterationMain::cleanup(main.cpp:5175)
单帧时序(Main::iteration,main.cpp:4880)
main_timer_sync.advance 计算本帧的物理步数、时间缩放、插值系数,然后:
循环 physics_steps 次:
main_loop->iteration_prepare()
PhysicsServer3D/2D sync + flush_queries
main_loop->physics_process(physics_step * time_scale) # 场景树物理
NavigationServer 更新
PhysicsServer3D/2D step
main_loop->process(delta) # 场景树帧逻辑
渲染提交(RenderingServer::draw)
SceneTree(scene/main/scene_tree.h:89,继承 MainLoop)的每帧 process()(scene_tree.cpp:688):multiplayer poll → emit process_frame → _process(false) 按组广播 → 场景切换冲刷 → timers/tweens → delete_queue。physics_process()(scene_tree.cpp:639)同理。
线程模型
关键机制是 CommandQueueMT 命令队列(core/templates/command_queue_mt.h:40)+ 宏模板(servers/server_wrap_mt_common.h):
- 服务器运行在自己的线程(渲染、物理等,可由构建选项关闭退回单线程)
- 主线程调用服务器虚方法时,宏展开为:非服务器线程 →
command_queue.push(server, &Server::method, args...)异步投递;服务器线程 → 直接调用 - 宏后缀语义:无后缀 = 纯异步;
R= 带返回值(阻塞等结果);S= push_and_sync - 使用实例:
servers/physics_3d/physics_server_3d_wrap_mt.h、physics_server_2d_wrap_mt.h - 渲染侧自带变体:
servers/rendering/rendering_server_default.h(ASYNC_COND_PUSHL117、RID 创建走 allocate+initialize 拆分以支持异步建资源),rendering_server_default.cpp:277用WorkerThreadPool::add_task(_thread_loop)启动渲染泵
4.8 中
core/object/server_wrap_mt.h已不存在,机制拆为上述两部分。
线程安全约束:Node 用 ERR_THREAD_GUARD 宏族(scene/main/node.h:937);RenderingServer 有 ERR_NOT_ON_RENDER_THREAD 调试宏(rendering_server.h:48);RenderingDevice 全类 _THREAD_SAFE_CLASS_。
关键设计决策
- RID 句柄制:场景层不直接持有渲染/物理资源,只持
RID(整数句柄);服务器线程可自由管理/重建这些资源。 - 编辑器即场景:编辑器是挂在根窗口下的普通
EditorNode : Node,见 editor-architecture。 - 通知机制替代虚函数:生命周期事件走
NOTIFICATION_*整数通知分发(C++→GDExtension→script),见 object-model。 - 模块四级初始化:模块注册分 CORE/SERVERS/SCENE/EDITOR 四级,与 GDExtension 对齐,见 build-system。