自底向上分层,依赖方向单向向下:

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):

  1. Main::setup(main.cpp:963)— 解析命令行 + 初始化 core(两阶段,setup2 于 main.cpp:3006:注册场景类型/服务器、创建 MainLoop)
  2. Main::start(main.cpp:3974)— 二次解析 CLI;-e/--editor 时 memnew(EditorNode) 挂到根窗口(main.cpp:4569)并 Engine::set_editor_hint(true);否则加载主场景
  3. os.run() — OS 事件循环反复调用 Main::iteration
  4. Main::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_PUSH L117、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_。

关键设计决策

  1. RID 句柄制:场景层不直接持有渲染/物理资源,只持 RID(整数句柄);服务器线程可自由管理/重建这些资源。
  2. 编辑器即场景:编辑器是挂在根窗口下的普通 EditorNode : Node,见 editor-architecture。
  3. 通知机制替代虚函数:生命周期事件走 NOTIFICATION_* 整数通知分发(C++→GDExtension→script),见 object-model。
  4. 模块四级初始化:模块注册分 CORE/SERVERS/SCENE/EDITOR 四级,与 GDExtension 对齐,见 build-system。

相关