CD Code Digest Hub /DOOM 3

DOOM 3 BFG 架构总览

7 分钟阅读 5 个章节 1 张图

DOOM 3 BFG 这份快照包含 Windows 主引擎、DOOM 3 游戏层、经典 DOOM/DOOM II 适配层及构建工具;它不是一个自带完整商业资源的可独立运行发行包。本页为需要修改、调试或移植代码的维护者建立系统地图,具体机制由后续子页面展开。

分析固定到提交 1caba1979589971b5ed44e315d9ead30b278d8b4。构建配置以仓库中的 VS2010/Win32 项目为准,不把其他平台 fork 或后续移植的行为混入本快照。

产物与代码边界#

neo/doom3.sln 组合主程序、idLib、静态游戏库、external、doomclassic、timidity 和独立 amplitude 工具。当前 Win32 项目把 Game-d3xp 与 Classic 都静态链接进主程序,因此阅读调用链时不能假设存在游戏 DLL 或 Classic 子进程。neo/doom3.sln:1-24 neo/game-d3xp.vcxproj:32-43 neo/doomexe.vcxproj:520-545

责任主要代码深入阅读
进程、平台与构建neo/sys/win32、neo/framework、neo/*.vcxproj构建平台、启动帧循环
基础设施与资源neo/idlib、neo/framework/FileSystem*、DeclManager*idLib 与作业、文件与声明
DOOM 3 呈现neo/renderer、base/renderprogs渲染架构及三叶子页面
DOOM 3 玩法neo/d3xp、neo/aas、neo/cm游戏运行时及六个叶子页面
会话与多人neo/framework/Session*、neo/sys/sys_*、neo/d3xp/Game_network.cpp网络、快照与会话
UI 与音频neo/ui、neo/swf、neo/d3xp/menus、neo/soundGUI/SWF、音频
Classic 第二运行时doomclassic 与 Common 中的桥接DOOM Classic

表中项目与工具边界见构建页的项目表;源码布局本身只用于定位,不作为运行行为的证据。

系统级控制与数据流#

入口和 Common 初始化见 win_main.cpp:1503-1549 Common.cpp:936-968;游戏和渲染 world 的创建见 Common.cpp:1131-1160;资源、游戏、渲染和声音的具体边分别由文件声明、游戏运行时、渲染架构和音频中的直接调用证据支撑。

idCommonLocal 是组合根,而不是所有逻辑的所在层。文件系统与声明管理器把 pak/声明转为材质、实体定义、声音等运行对象;Session/Game 推进地图与实体状态;RenderWorld 保存场景定义,RenderSystem 消费命令缓冲;声音系统把逻辑 emitter/channel 映射到 XAudio2 voices。Classic 复用宿主的文件、帧和输出服务,但保留自己的游戏与软件渲染状态。neo/framework/Common_load.cpp:446-526 neo/renderer/RenderSystem.h:265-283 neo/sound/snd_system.cpp:296-317 doomclassic/doom/doominterface.cpp:129-188

一次 DOOM 3 外层帧#

正常 DOOM 3 路径可压缩为以下顺序:

  1. 在帧边界执行游戏切换,排空系统事件和控制台命令。neo/framework/common_frame.cpp:367-407
  2. 完成/交换上一轮渲染命令,按真实时间决定本轮执行多少个游戏 tic,并处理 session、网络和 UI 输入。neo/framework/common_frame.cpp:423-440 neo/framework/common_frame.cpp:548-575
  3. idGameThread 对 host/server 或 client 执行相应模拟,再调用 Draw 生成呈现命令;主线程可把后端渲染与下一轮 Game/Draw 重叠。neo/framework/common_frame.cpp:86-178
  4. 主线程提交 render command buffers,等待游戏线程,发送网络数据、更新声音并消费 gameReturn_t 中的会话命令。neo/framework/common_frame.cpp:622-666

这里有两个容易破坏的契约:一次外层帧可以运行零个或多个 tic;RunGameAndDraw 返回的是上一轮锁存结果,而新一轮可在后台执行。详细时序见启动、帧循环与线程交接和游戏运行时。

修改代码时先定位权威边界#

  • 改资源查找或声明语法: 从文件与声明开始,再进入材质、实体或声音消费者。
  • 改画面: 先区分 RenderWorld 场景状态、前端可见性/交互和后端 GPU 命令,不要直接在实体 Present 中发 draw call。
  • 改玩法: 区分每 tic 权威状态与 Draw 呈现状态;实体事件、脚本、物理和动画各有独立生命周期。
  • 改存档或多人: 分别核对对象恢复格式与 snapshot/usercmd 协议,两者不是同一种序列化契约。
  • 改菜单或 Classic: 识别原生 GUI、SWF VM 和 Classic Globals 三条路径,避免把宿主帧循环重入到旧运行时内部。

范围与验证限制#

README 明确说明源码发布不包含游戏数据,也不包含 Steam 集成、Bink 视频和 depth-fail 模板阴影后端功能;这些区域在本 Wiki 中只分析公开调用边界或列为排除项,不虚构缺失实现。README.txt:12-21 README.txt:35-52

本 Wiki 是静态源码分析:未执行 Windows 构建、未启动游戏、未运行自动化测试,也未实测渲染、音频设备或多人联机。完整覆盖矩阵、关键结论台账和对抗审计见审计报告;术语速查见术语表。

下一页:构建、产物与 Win32 平台边界,或返回Wiki 总目录。