中EN
概念页

运行时引擎分层架构

Runtime Engine Architecture

Gregory 把游戏视为“软实时、交互式、基于代理的计算机模拟”,把游戏引擎定义为数据驱动、可复用来做多款游戏的软件。运行时引擎按层组织:从目标硬件、驱动、操作系统、第三方 SDK、平台无关层、核心系统、资源管理器,到渲染、物理、动画、音频、网络等子系统,再到游戏性基础层和游戏专属子系统;上层依赖下层,避免循环依赖。

游戏是什么样的软件

大多数二维、三维电子游戏是软实时 (soft real-time)、交互式、基于代理 (agent-based) 的计算机模拟(卷 I 1.1.1):

  • 模拟:对真实或虚构世界的数学近似与简化;近似和简化是游戏开发者最有力的工具之一。
  • 基于代理:世界由许多相互作用的独立实体(角色、载具、火球……)组成,所以游戏大多至少部分采用面向对象范式。
  • 交互式、时间性:世界状态随时间变化,并且要响应不可预测的玩家输入。
  • 实时与截止时间:画面至少每秒约 24 次更新才有运动错觉(多数游戏 30 或 60 FPS);物理可能要每秒 120 次才稳定;AI 感知每秒几次即可;音频库可能至少每 16.7 毫秒要调用一次以免缓冲断流。
  • 软实时:错过截止时间不是灾难(帧率掉了玩家不会死),区别于直升机航电、核电站控制棒这类硬实时系统。

数学模型分解析和数值两种。恒定重力下下落的刚体有闭式解

y(t)=12gt2+v0t+y0y(t) = \tfrac{1}{2} g t^2 + v_0 t + y_0

可以对任意 tt 求值;但玩家输入不可预测,整个游戏不可能解析建模,所以游戏用数值模型 y(t+Δt)=F(y(t),y˙(t),y¨(t),…)y(t+\Delta t) = F\big(y(t), \dot y(t), \ddot y(t), \dots\big),在游戏循环的每次迭代里让 AI、玩法逻辑、物理等系统推进一个离散时间步,再“渲染”出画面、声音和手柄震动(卷 I 1.1.1;循环细节见 游戏循环与更新方法)。

什么算“游戏引擎”

  • “游戏引擎”一词出现在 1990 年代中期,源于 Doom 把核心组件(渲染、碰撞、音频)与美术资产、关卡和玩法规则较清楚地分开;这种分离催生了授权和 mod 社区(卷 I 1.2)。
  • 游戏与引擎的边界常常模糊:有的渲染代码“知道”怎么画兽人,有的则只提供通用材质着色,“兽人性”完全由数据定义。Gregory 认为数据驱动架构才是引擎与“只是一个游戏”的区别:硬编码规则或为特定对象写特例渲染代码,就很难复用来做别的游戏(卷 I 1.2)。
  • 可复用性是一条连续谱:从只能做一款游戏(Pac-Man)、可定制做相似游戏(Hydro Thunder 引擎)、可 mod 出同类型任何游戏(Quake III 引擎),到能做几乎任何游戏(Unity、Unreal Engine 5、Source……),而“能播放任何游戏内容的通用引擎”可能永远做不到(卷 I 图 1.1)。
  • 通用性与最优性的取舍:高效软件总要基于对用途和硬件的假设做取舍。室内引擎可能用 BSP 树或入口 (portal) 系统做精确遮挡,室外引擎则少用精确遮挡、大量依赖细节层次 (LOD)。硬件变强让类型间差异在缩小,但为特定游戏和平台精调总能做得更好(卷 I 1.2–1.3)。

不同类型对引擎的侧重

书中逐一列举了各类型的技术侧重(卷 I 1.3),摘要如下:

类型技术侧重
第一人称射击大世界高效渲染(室内 BSP/入口,室外遮挡剔除或离线分区可见性)、灵敏的瞄准相机、第一人称手臂动画、宽容的角色运动与碰撞、NPC 动画与 AI、小规模联网对战
平台跳跃与第三人称主角能力与移动方式(移动平台、梯子、绳索)、全身高精度动画、跟随相机与相机碰撞
格斗丰富的格斗动画、精确命中判定、能识别复杂按键组合的输入系统;场景小,基本不需要世界分区或遮挡剔除
竞速远景用二维卡片等技巧、赛道切成“扇区”用于可见性、AI 与寻路、隧道中的相机防穿插
策略视角受限便于优化、网格布局、低精度单位以支持大量同屏、高度场地形
大型多人在线服务器群维护权威世界状态、登录、聊天与计费;画面精度通常较低
VR每帧渲染两次(剔除可共享)、90+ FPS 以免眩晕、移动多用瞬移

分层结构

引擎像所有大型软件一样分层构建,上层依赖下层,反之不行;下层依赖上层就形成循环依赖,会导致耦合、难以测试、妨碍复用(卷 I 1.5)。下图按书中图 1.16 的层次自下而上简化:

flowchart BT
  HW["目标硬件"] --> DRV["设备驱动"] --> OS["操作系统"] --> SDK["第三方 SDK 与中间件"]
  SDK --> PIL["平台无关层"] --> CORE["核心系统"] --> RM["资源管理器"]
  RM --> SUB["渲染 / 碰撞与物理 / 动画 / 音频 / HID / 网络 / 性能分析与调试"]
  SUB --> GF["游戏性基础层"]
  GF --> GS["游戏专属子系统"]

越往上越接近具体游戏;书中认为如果游戏与引擎之间能划出一条线,它就在游戏专属子系统与游戏性基础层之间,但实际中总有游戏专属知识渗入下层(卷 I 1.5.16)。

各层要点(卷 I 1.5.1–1.5.16):

  • 操作系统:PC 上是抢占式多任务,游戏不能假设独占硬件;早期主机的“系统”只是编进游戏的薄库,而现代主机系统会打断游戏、在后台录像和下载,主机与 PC 开发的差距在缩小。
  • 第三方 SDK:容器与算法(Boost、Folly、STL)、图形 API(DirectX、OpenGL、Vulkan、Metal、主机底层接口)、物理(Havok、PhysX、ODE)、动画(Granny、Havok Animation、OrbisAnim)、字体(FreeType、HarfBuzz)、平台服务(Steamworks、EOS)。
  • 平台无关层:包装文件系统、网络、高精度计时器、线程、图形与物理等接口。理由有二:各平台 API(甚至 C 标准库的部分函数)差异很大,包装后上层得到一致接口;即使库本身跨平台(如 Havok),包装也能隔离未来更换中间件的影响。通常只有第一方工作室才不跨至少两个平台。
  • 核心系统:断言(发行版中通常剥离)、自定义内存分配(追求高速并抑制碎片)、数学库、自定义容器与算法(常为避免动态分配而手写),以及字符串与哈希 ID、日志、随机数、反射与序列化、对象句柄、本地化、配置等。
  • 资源管理器:为所有类型的资产提供统一访问接口;有的引擎高度集中(Unreal 的 package),有的则让程序直接读磁盘文件或压缩包(Quake 的 PAK)。
  • 渲染引擎常再分层:底层渲染器只管尽快尽好地画出提交的图元(含图形设备接口、材质与着色器、光照、相机、文字、调试绘制),除背面剔除和把三角形裁剪到视锥之外基本不关心可见性;图形设备接口负责枚举与初始化图形设备、建立渲染表面(后台缓冲、模板缓冲等),PC 上还要写“消息泵”在处理 Windows 消息之余反复运行渲染循环;场景图与剔除层用视锥剔除或 BSP、四叉树、八叉树、k-d 树等空间划分快速求出潜在可见集 (PVS),入口或遮挡剔除也可放在这一层。书中提醒空间划分有时被叫作“场景图”,但严格说场景图是一种特定数据结构,并不涵盖空间划分。理想情况下底层渲染器不依赖具体用哪种划分,这样各游戏团队能复用图元提交代码、只为自己的游戏定制 PVS 判定(OGRE 的可插拔场景图是例子);视觉效果(粒子、贴花、光照贴图与环境贴图、动态阴影、全屏后处理如 HDR 色调映射与泛光、全屏抗锯齿、调色)——粒子和贴花通常是独立组件、作为底层渲染器的输入,光照贴图、环境贴图和阴影通常在渲染引擎内部处理,后处理则要么是渲染器的一部分、要么是作用于其输出缓冲的独立组件;前端(HUD、菜单、开发者控制台、全动态视频 FMV、游戏内过场 IGC)——二维元素通常用正交投影画带纹理的四边形,或在 3D 中以始终朝向相机的公告板四边形绘制。
  • 性能分析与调试:除 VTune、PIX、Razor 等通用工具外,引擎通常自带代码插桩计时、屏显统计、内存与泄漏统计、分类调试输出、事件录制回放;PS4/PS5 的崩溃转储还附带崩溃前的截图和录像。
  • 碰撞与物理:二者通常紧密耦合,因为检测到碰撞后几乎总在物理积分与约束求解中处理;如今很少有公司自写,通常集成第三方 SDK。
  • 动画:五种基本类型:精灵/纹理动画、刚体层级动画、骨骼动画、顶点动画、变形目标;骨骼动画最普遍。动画系统为每根骨骼输出姿势,以矩阵调色板交给渲染器做蒙皮;布娃娃 (ragdoll) 则让动画与物理紧密配合。
  • HID:把平台底层手柄细节与高层游戏操作分开:摇杆死区、按键去抖、按下/抬起事件、加速度计平滑、按键映射,以及组合键、按键序列和手势检测。
  • 网络:单屏多人、分屏多人、联网多人、MMOG 四种形态。多人会深刻影响对象模型、渲染、输入、角色控制和动画;给单机引擎补多人很难,最好从第一天就设计;反过来很简单,许多引擎把单人模式当成只有一个玩家的多人游戏(Quake 的客户端叠在服务器上运行)。
  • 游戏性基础层:在引擎底层与玩法代码之间提供游戏世界(静态与动态元素)、游戏对象模型、事件/消息系统、脚本系统、AI 基础(导航网格、寻路、避障)、世界加载与流送。对象模型要回答:是否面向对象、用什么语言、类层级是单一巨型还是松耦合组件、如何引用对象(裸指针、智能指针、句柄)、如何唯一标识(地址、名字、GUID)、如何管理生命周期、如何随时间模拟状态(详见卷 II 第 17 章)。
  • 脚本系统:没有脚本时改逻辑和数据要重新编译链接;有脚本时改脚本并重新加载即可,有的引擎甚至支持运行中热重载。

与 UE 和本知识库其他页的对应

  • UE 的渲染线程、场景代理和 RHI 分层,对应上面“底层渲染器 + 场景与剔除层”的分工,见 UE5 渲染架构。
  • UE 的 Actor/组件、GameMode 等,属于“游戏性基础层”的一种具体实现,见 Gameplay 框架;对象模型中“单一巨型层级还是组件”的问题,在 组件模式 中有模式层面的讨论。
  • 分层与解耦的代价、性能与灵活性的取舍,可与 游戏编程模式选型:解耦与性能 对照阅读。
  • 运行时之外的另一半是工具与资产管线,见 资产管线与工具链。
  1. Game_Engine_Architecture_4Ed_-_Jason_Gregory.pdf
  2. Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 I 第 1 章 1.1–1.5 节

相关页面

游戏开发资产管线与工具链Asset Conditioning Pipeline & Tools游戏引擎的输入数据来自美术使用的数字内容创作 (DCC) 工具,但 DCC 格式几乎从不直接用于游戏,必须经过资产调理管线 (Asset Conditioning Pipeline, ACP) 导出、处理并按平台打包。围绕它还有世界编辑器、记录资产元数据的资源数据库,以及几种工具架构(独立工具、与引擎共享底层、编辑器内嵌于引擎、Web 界面),各有取舍。游戏开发游戏循环与更新方法Game Loop & Update Method游戏循环 (Game Loop) 让游戏时间的推进与玩家输入和处理器速度脱钩:每一轮非阻塞地处理输入、更新状态、渲染,并跟踪真实时间来控制节奏;最常推荐的做法是“固定更新步长、可变渲染”。更新方法 (Update Method) 是它的搭档:世界维护一组对象,每个对象实现一个模拟“一帧”行为的 update(),每帧依次调用。两者和组件模式一起常被视为游戏引擎的核心。游戏开发组件模式Component Pattern组件模式 (Component Pattern) 让一个实体横跨多个领域(输入、物理、图形、AI……),同时不让这些领域彼此耦合:每个领域的代码放进自己的组件类,实体本身退化为组件的容器。它是现代引擎实体模型的基础,代价是对象变成需要正确装配的一组对象,组件之间如何通信也成了要做的设计决策。游戏开发 · UE5UE5 渲染架构UE5 Rendering ArchitectureUE5 的渲染器是独立的 Renderer 模块,在渲染线程 (Rendering Thread) 上以「场景代理」镜像游戏线程的组件状态,每帧按固定顺序执行深度预通道、G-buffer 基础通道、光照、雾、半透明和后处理。现代渲染代码用渲染依赖图 (Render Dependency Graph, RDG) 声明通道与资源,由 RDG 自动排屏障、复用瞬态内存、并行录制;最终命令经 RHI 线程翻译成 D3D12/Vulkan 等图形 API 调用。默认走延迟着色 (Deferred Shading),也可切换前向着色 (Forward Shading)。游戏开发 · UE5Gameplay 框架Gameplay FrameworkGameplay 框架 (Gameplay Framework) 是 UE 提供的一组相互配合的类,用来搭建游戏的基本结构:Actor 与组件 (Component) 构成场景中的一切;GameMode 在服务器上定规则并生成玩家;玩家由“控制器 (Controller) + 棋子 (Pawn)”组成;GameState 与 PlayerState 负责把全局与每个玩家的状态复制给所有客户端;GameInstance 跨关卡存活。综合游戏编程模式选型:解耦与性能Choosing Game Programming Patterns本页把《Game Programming Patterns》里的 19 个模式放到同一张取舍图上:大多数模式要么为了解耦(降低改代码时需要装进脑子里的知识量),要么为了性能(利用对数据和硬件的具体假设),而这两个目标经常互相拉扯。下面先讲全书的定位和 Nystrom 的架构观,再给出按问题选模式的路线和与 UE 的对照。游戏开发构建配置与编译优化Build Configurations & Compiler OptimizationC++ 游戏代码从源文件到可执行文件要经过预处理、编译、链接。游戏项目通常不止 Debug/Release 两种构建配置 (build configuration),而是 Debug、Development、Ship,有时再加混合构建;配置越多测试越难。编译器优化分为局部优化和全局优化(链接时优化 LTO、剖析引导优化 PGO),它们让程序更快,但也让调试器“说谎”。所以要学会调试优化过的构建,并用统计式或插桩式性能分析器 (profiler) 找出最耗时的代码。游戏开发错误处理与断言Error Handling & AssertionsGEA 把错误分为用户错误和程序员错误,两者处理方式相反:用户错误要尽量平稳地告知并继续,程序员错误应立即停机并给出详细的底层信息。“用户”又分玩家和制作游戏的开发者。实现手段有错误返回码、异常和断言。Naughty Dog、EA、Midway、Insomniac 等在运行时代码中通常关闭 C++ 异常,靠断言和静态断言 (staticassert) 捕获 bug,并用 RAII(Naughty Dog 称为 janitor)管理资源。游戏开发子系统启动与关闭Subsystem Start-Up & Shut-Down游戏引擎由许多相互依赖的子系统组成,启动时必须按依赖顺序初始化(B 依赖 A,则先启动 A),关闭时通常反序。C++ 全局/静态对象的构造与析构顺序不可预测,「首次调用时构造」的函数静态单例也无法控制析构顺序且时机不可控。GEA 推荐最朴素的方案:单例管理器的构造/析构函数什么也不做,提供显式的 startUp() / shutDown(),在 main() 里按顺序手动调用。游戏开发引擎输入系统Game Engine HID System多数引擎不直接使用「原始」HID 输入,而是先加工(死区、滤波)使游戏内行为平滑直观,并在 HID 与游戏之间加至少一层间接(如按键映射表把原始按钮翻译成逻辑游戏动作)。GEA 列出引擎输入系统的典型需求并逐一讲解实现:死区、模拟信号滤波、按下/松开事件、组合键与序列手势、多设备多玩家、跨平台抽象、输入重映射、上下文相关控制与输入禁用。(卷 I 9.5–9.6 节)图形学图形栈与渲染引擎架构Graphics Stack & Rendering Engine Architecture渲染引擎要解决的"渲染问题"是:给定由场景元素、虚拟光源和虚拟相机组成的虚拟世界,生成相机看到的二维彩色图像。GEA 把它拆成可见性问题和光照问题,按解法把引擎分为光线追踪、深度缓冲光栅化、辐射度和混合四类;光栅化引擎通常采用立即模式的两层结构:下层是图形管线,上层是负责剔除、提交几何和设置着色器参数的应用层。本页讲这套整体架构,管线内部见 渲染管线。游戏开发游戏中的物理与中间件Physics in Games & Middleware今天游戏引擎所说的"物理",准确说是经典刚体动力学模拟:理想化的、无限坚硬不可形变的物体在力的作用下如何运动和相互作用。它高度依赖碰撞检测系统;反过来,碰撞检测可以独立存在,几乎所有有移动物体的游戏都有某种碰撞检测,但不一定有物理。GEA 先讨论要不要物理、物理是否好玩、它对项目各部门的影响,再列出主流中间件(GEA4 卷 II 第 14 章引言、14.1–14.2)。游戏开发音频引擎架构Audio Engine Architecture音频渲染软件和多数系统一样是分层的"栈":硬件 → 驱动 → 底层 API → 3D 音频引擎,功能集通常模仿录音棚的多通道调音台。每个 2D/3D 声音是一条语音 (voice),沿语音总线经过编解码、增益、预发送滤波、辅助发送分出干湿两路、混响、后发送滤波和声像,然后由主混音器合成多声道信号,再经主输出总线(预放、LFE 生成、EQ、压缩、主音量)送到扬声器。资产上分片段、音效提示 (cue)、声音库和流式声音;混音靠分组、闪避、总线预设与混音快照、实例限制和语音抢占(GEA4 卷 II 15.5)。游戏开发游戏世界与游戏对象Game World & Game Objects游戏由玩法 (gameplay) 而不是技术定义;游戏机制 (game mechanics) 是支配游戏中各实体交互的规则,以及目标、成败标准、玩家能力、非玩家实体和整体流程(GEA 引用的论文称实现玩法的软件系统为游戏的 G 因子)。大多数游戏世界由静态元素和动态元素组成,划分为若干世界块,并由高层游戏流程组织玩家目标;动态元素通常实现为游戏对象 (GO),引擎提供的建模设施称为游戏对象模型,且分为工具侧和运行时两套(GEA4 卷 II 16、16.1–16.2)。综合引擎运行时架构总览Engine Runtime Architecture Overview本页把 wiki 中分散在 GEA 第 1、6、8、17 章及 GPP、UE5 相关页面里的内容串成一条线,回答"一个游戏引擎在运行时是怎样组织起来的":静态结构上是自下而上的分层,上层依赖下层;启动关闭按依赖顺序显式进行;每一帧由主循环驱动各子系统批量更新,游戏对象的逻辑被安排在子系统阶段之间,并按依赖分桶或设先后关系;多核上一帧被拆成成百上千个作业;玩法基础系统(对象模型、事件、脚本、世界加载流送、高层流程)位于引擎与游戏的分界线附近。各结论的细节与出处见所链接的概念页。

被这些页面引用1 篇

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原