01-游戏系统论
游戏系统论——从想法到引擎:一个游戏如何从零演化、建模、设计、组织
游戏开发不是「写一个 Game Loop」。它是一个完整系统:先有分析→设计的演化(想清楚做什么),再有实现的演化(从窗口到引擎一点点做出来);游戏世界是一个「实体+状态+规则+交互+时间演化」的模型;工程的推进遵循一条十二阶段的完整流程;而技术架构回答「对象是什么、谁负责运行、怎么计算、谁提供底层能力」。 四条线串在一起,就是游戏系统的完整图景。
一、两条演化:设计与实现的独立路线
游戏开发不是一条线,而是两条演化同时在走:
1 | 上层:灵感 → 核心玩法 → 玩法循环 → 设计 → 分析 → 技术 → 验证 → 迭代(先做什么) |
它们互相独立:想法不写代码也能演进,引擎没有玩法也能演进。真正的开发是两条线在可玩核心处汇合——围绕一个核心玩法(移动/跳跃/攻击)不断迭代,每加一个系统都反过来调整前面的设计。
一·A、设计演化:从灵感到技术设计的 12 阶段
第 1 阶段:灵感(Idea)
只有一句话,甚至没有功能:
1 | 我想做一个横版动作游戏。 |
第 2 阶段:核心玩法(Core Gameplay)
回答「玩家到底在干什么?」
1 | 超级马力欧:跑 / 跳 / 踩 |
如果一句话说不清玩家一直在做什么,玩法就还没设计好。
第 3 阶段:玩法循环(Gameplay Loop)
回答「玩家一分钟都在干什么?」
1 | 探索 → 遇敌 → 战斗 → 掉装备 → 升级 → 继续探索 |
这一阶段决定游戏耐不耐玩。
第 4 阶段:需求分析
开始拆功能清单(移动/攻击/敌人/地图/物品/任务/NPC/存档)——已经类似软件需求分析。
第 5 阶段:规则设计(Game Rules)
定义数值规则:
1 | 攻击力 = 武器 + 力量 × 2 |
第 6 阶段:数据设计
分析哪些是数据,形成数据模型:
1 | Weapon { id, name, damage, price, icon } |
第 7 阶段:对象分析
思考世界有哪些对象(Player / Enemy / NPC / Item / Door / Bullet)、哪些共同、哪些不同——由此走向 GameObject → Component 或 Entity。
第 8 阶段:系统分析
问这些对象谁负责运行,于是出现输入系统/渲染系统/动画系统/物理系统/碰撞系统/AI 系统——已经接近引擎设计。
第 9 阶段:世界设计
不是代码,而是地图/剧情/关卡/区域/NPC/任务:森林 → 村庄 → 地下城 → Boss。
第 10 阶段:UI 分析
玩家需要看到什么:血条、技能栏、背包、地图、商店、任务——开始画线框图。
第 11 阶段:资源规划
统计需要多少人物/动画/音效/地图/UI——进入项目管理。
第 12 阶段:技术设计
最后才决定引擎与架构:Unity/Unreal/Godot/SDL/OpenGL,以及 ECS/MVVM/脚本/网络。
注意顺序:先玩法,后技术。第 12 阶段才选引擎——大多数项目搞反了。
一、B、实现演化:从窗口到完整引擎的 21 阶段
如果一个人从零写游戏(不用成熟引擎),工程实现本身也是一步步演化,每个阶段解决上一个阶段产生的问题:
| # | 阶段 | 解决的问题 |
|---|---|---|
| 1 | 显示 | 创建窗口 → 初始化图形 API → 游戏循环 → 清屏 → 画方块 → Present |
| 2 | 输入 | 键盘/鼠标,x += speed 让方块动 |
| 3 | 时间 | 不同电脑速度不同 → deltaTime,position += velocity * deltaTime(重要一步) |
| 4 | 资源系统 | 画矩形 → 读取 PNG/JPG/BMP → Sprite |
| 5 | 动画 | 一张图 → Sprite Sheet/Frame Animation → 动画状态(Idle/Walk/Run/Jump/Attack) |
| 6 | 地图 | 背景一张图 → Tile Map(地图可以无限大) |
| 7 | 摄像机 | 人物移动 → 人物不动 Camera 移动 → 世界坐标 |
| 8 | 碰撞 | AABB/Circle/Polygon 检测,碰撞后停止/滑动/弹开 |
| 9 | 渲染排序 | 不排序人物画到树后面 → Layer/Z Order/Y Sort |
| 10 | 游戏对象系统 | 只有一个 Player → 许多对象 → 抽出 GameObject(Update/Draw) |
| 11 | 组件化 | 所有对象都有位置/图片/动画/碰撞 → 拆成 Transform/Sprite/Animation/Collider/RigidBody(走向 ECS) |
| 12 | 物理 | Gravity/Velocity/Acceleration → Force/Mass/Friction → 跳跃/掉落/推箱子 |
| 13 | AI | 巡逻/追踪/攻击/逃跑 → FSM/行为树/GOAP → 敌人会思考 |
| 14 | 游戏规则 | 生命/经验/等级/金币/背包/装备(Gameplay) |
| 15 | UI | 开始菜单/暂停/HUD/血条/技能栏/背包 |
| 16 | 音频 | BGM/SE/Voice、音量管理、淡入淡出 |
| 17 | 存档 | Save/Load:位置/任务/金币/装备/地图状态 |
| 18 | 脚本系统 | 写死 → Lua/Python/C#/Blueprint,不重新编译改 NPC/剧情/技能 |
| 19 | 关卡编辑器 | 程序员写地图 → 美术直接拖(Unity/Unreal 都属于这一阶段的产物) |
| 20 | 网络 | 多了一套 Server/Client:预测/回滚/插值/校验 |
| 21 | 完整引擎 | 演变/封装成一个引擎架构(Window/Renderer/Resource/Input/Audio/Scene/Camera/GameObject/Component/Physics/Collision/AI/UI/Script/Save/Network/Editor/Tools) |
21 阶段的本质:每个阶段不是新功能,而是解决之前阶段产生的新问题——速度不同补出时间、伙伴多了补出组件化、关卡多了补出编辑器。这和其他软件工程的主线(职责混乱→拆分)是同一条规律在游戏里的体现。
二、世界建模:游戏世界 = 实体 + 状态 + 规则 + 交互 + 时间演化
设计游戏的第一步不是写代码,而是回答问题「这个世界是什么样」。一个世界可以被抽象为:
1 | World |
世界演化可以写成公式:
1 | State(t+1) = Function(State(t), Event, Rule) |
用闯关游戏看:
1 | 实体:玩家、敌人、道具、地形 |
二、A、关卡系统的通用抽象模型
在一个关卡里,五问可以实例化为通用的四部分:
1 | GameLevel(关卡) |
关键洞察:「具体事物只是不同表现形式」。 蘑菇、护盾、药水、技能看着不同,本质都是「改变玩家状态」(player.addEffect(Effect));金币、装备、经验都是「玩家行为产生收益」(Reward);隐藏通道、传送门都是「改变关卡路径关系」(Shortcut);通关条件都是「判断游戏状态是否满足结束条件」(CheckWin)。
于是不同类型的游戏只是替换这些组件:
| 类型 | 玩家 | 障碍 | 收获 | 目标 |
|---|---|---|---|---|
| 超级玛丽 | 马里奥 | 怪物、坑 | 金币、蘑菇 | 旗杆 |
| 银河恶魔城 | 角色 | 敌人、机关 | 能力 | 探索区域 |
| 魂类游戏 | 战士 | 敌人、陷阱 | 武器、魂 | 击败Boss |
| 肉鸽游戏 | 角色 | 随机房间 | 随机强化 | 通关层数 |
底层结构高度类似——这也是为什么引擎不是写「蘑菇类/宝箱类/钥匙类」,而是设计 Entity/Component/System:表现不同,结构相同。
世界建模不是游戏特有——看两个例子:
1 | 现实—一个石头: 游戏—一个箱子: |
游戏世界与现实世界的建模结构完全一样,区别只有一处:
现实世界的规则是发现出来的(物理学、化学),游戏世界的规则是设计出来的(游戏设计)。
二、B、世界建模的边界:宇宙模拟的理论极限
如果世界模型是这个五件套,那么理论上可以模拟任何世界——包括宇宙。这正是拉普拉斯妖思想:知道所有实体的初始状态 + 所有规则 + 无限计算能力,就能推算未来。
用游戏模型看宇宙模拟器:
1 | World:粒子/场/能量(实体) |
和游戏循环结构一模一样。但现实有四个困难:
1 | 1. 我们不知道完整规则(量子力学与广义相对论还没统一) |
所以现实中的模拟都不是「完整宇宙」,而是小宇宙:天气模拟、星系模拟、分子模拟、游戏世界模拟——「发现部分规则 + 近似模型 + 限制范围」。游戏的规模恰好落在可以完整模拟的区间,这是游戏能成为一个可靠「小宇宙」的根本原因。
二、C、从关卡到模拟:连锁影响
设计游戏世界时除了五问,还有一个高级问题:状态变化带来什么连锁影响?
1 | 简单:玩家砍树 → 树消失 |
这就是模拟系统(Simulation)和普通关卡游戏的区别——前者让状态变化产生系统性的连锁,导致涌现;后者状态变化只影响当前场景。
二、D、设计系统的三个切面:手感 × 趣味 × 关卡
玩家与游戏世界的交互,最终落在三个可设计的维度上。它们看起来是三件事,其实是一个东西的三个切面——玩家与游戏之间反馈回路的质量、密度与空间:
1 | 手感 = 反馈的即时质量(这一帧反馈对不对、爽不爽) |
手感不是物理引擎:Hit Stop(命中停顿)、Coyote Time(离开平台边缘仍可跳)、Jump Buffer(提前按跳落地自动触发)这些都不是真实物理,而是为了让反馈符合玩家预期。细致展开见 10-拆解手感(手感的五层结构)。
趣味的核心是极短周期认知闭环(疑惑→实验→发现→掌握),闭环完成的瞬间本身就是奖励——展开见 03 趣味设计。
关卡 = 设计玩家在空间中的行为、挑战与选择(2~4 个合理选择+环境引导,表面自由实际有界),见 09-拆解关卡。
三、工程推进:游戏设计十二阶段的工程流程
前两节是「想清楚」和「怎么实现」,这一节是把整个游戏当作一个软件工程来推进的完整流程。一个完整游戏大致拆成:
1 | 游戏设计 → 系统分析 → 行为分析 → 算法分析 → 引擎能力 → 架构设计 |
逐步展开:
1. 游戏设计:做什么游戏
确定类型、玩家目标/操作、胜负条件、资源经济规则、角色、关卡、UI、音频美术需求。最重要的是确定 Core Loop:玩家操作 → 状态变化 → 反馈 → 新决策 → 再操作。
2. 系统分析:游戏世界有什么
先问「世界里有什么」(Player/Enemy/NPC/Weapon/Item/Map),再问「每个对象什么状态」(Player: Transform/Health/Movement/Character/Inventory)。
3. 行为分析:对象会发生什么行为
从行为反推 System:Movement/Combat/AI/Animation/Physics 变成 MovementSystem/CombatSystem/AISystem/RenderingSystem。System 不负责「是什么」,负责「怎么运行」。
4. 算法分析:哪些是通用计算
System 把具体计算下沉到 Algorithm:DamageAlgorithm/PathfindingAlgorithm。算法不跟 Player/Enemy 绑定。
5. 引擎能力分析
System 需要底层技术能力:RenderingSystem → Renderer,InputSystem → Input,AudioSystem → Audio。链路:Game → System → Engine API → 底层库/OS/GPU。
6. 架构设计:目录、模块、依赖
依赖方向:Application → Game → System → Component/Algorithm → Engine。
7-8. 组装:Component → Object → World
两种组装:对象组装(Component 组成 Object)与场景组装(Object/Terrain/Lights 放进 World/Scene)。这一层与桌面软件里「数据结构+算法+接口组成功能函数、功能函数组成模块」是同一条组织规律。
9. 运行流程:每帧发生什么
按数据依赖关系确定,而不是固定顺序:Input → Movement → Physics → AI → Animation → Camera → Rendering → Audio。
10. 内容生产
程序系统和游戏内容是分开的:Enemy 的定义(Health=100/Speed=5/攻击/模型/动画)是数据不是代码。成熟游戏一定做这种分离。
11. 测试
分层测试按组件级 → 算法级 → 系统级 → 集成级 → Playtest(完整游戏)。游戏特别重要的是 Playtest——代码正确 ≠ 游戏好玩。
12. 迭代
游戏开发与普通软件最大的区别在此:
1 | 设计 → 原型 → 试玩 → 反馈 → 调整 ↺(不是需求→设计→编码→完成) |
完整流程图:
1 | 游戏想法 → 游戏设计/玩法 → 游戏分析 |
四、技术架构三种演化:对象 → 组件 → ECS
技术架构要回答四个问题——拆了什么、组装了什么、谁负责运行、谁提供底层能力。游戏的架构演化回答了三个技术路线:
传统 OOP:继承 + 方法
1 | GameObject → Character → Enemy → FlyingEnemy → FlyingBossEnemy |
继承树会膨胀;行为跟着对象(Player.run / Enemy.run),产生 PlayerMovement/EnemyMovement/BossMovement 的重复。
演进架构:组件 + System + Algorithm(非 ECS)
把三个问题彻底拆开:
1 | 对象是什么? → Component / Object |
最终收敛的目录结构:
Application
├── Engine(唯一,技术支撑,完全在游戏外)
└── Game(唯一,游戏业务)
├── Domain 可复用领域描述(Transform/Movement/Health/Character/AIState)
├── Object 业务对象构建(Player/Enemy,仅数据组合)
├── System 横向运行操作(MovementSystem/AISystem/RenderingSystem,不只管单个对象)
├── Algorithm 具体计算(MovementAlgorithm/DamageAlgorithm)
└── World/Scene(世界与场景组织)
1 |
|
ECS:Entity + Component → Query → System
ECS 把三元问题进一步极致化:Entity 只是 ID 身份,组件属于全局,System 按行为查询批量处理:
1 | Entity = 一个 ID(身份) |
关键:System 按行为横向划分(MovementSystem 处理所有会动的东西),而不是按对象划分(PlayerSystem/EnemySystem)。
三种方式的对比
| 传统 OOP | 组件 Object 方式 | ECS | |
|---|---|---|---|
| 核心单位 | Object/Class | Component + Object | Entity + Component |
| 数据拆分 | 跟着对象拆 | 先拆组件 | 先拆组件 |
| 行为 | 对象方法 | System 负责运行 | System 负责运行 |
| 算法 | 类内/独立类 | 独立 Algorithm | System/独立算法 |
| 对象身份 | Class 实例 | 明确对象(Player/Enemy) | Entity ID |
| 运行时组合 | 较弱 | 代码级组合 | 运行时组件组合 |
| 大量同类对象 | 一般 | 一般~较好 | 非常适合 |
最核心的区别:组件方式保留「明确的业务对象」(Player/Enemy 是数据组合),ECS 刻意弱化对象类型——组件组合本身决定它是什么。
性能不是必然差异:中量对象级别,组件 struct + 对象/组件池 + SoA 也能获得良好数据局部性,不必为了性能用 ECS。
运行时增删组件不是 ECS 独占:获得装备、Buff/Debuff、死亡、进载具,这些结构变化通过 std::optional<Flying> 或组件容器也能处理——ECS 只是把它变成核心机制。
何时值得用 ECS:运行时频繁增删组件、数十万级 Entity、大量组件批处理、需要 Query/Scheduler/数据导向存储。否则组件+System+世界的手动组织更简单。
组件方式解决「如何把游戏设计清楚」;ECS 在解决「如何把大量动态对象高效运行起来」。两者不是对错,是抽象程度和运行机制不同。
五、收束:方法论四问与结构全景
遇到任何新框架/引擎/库,不要先问「它属于什么模式」,直接问四个问题:
1 | 1. 它拆了什么? |
把全文压缩:
1 | 两条演化 设计12阶段(想法→核心玩法→规则→系统→世界→技术) |
游戏系统论回答了「一个游戏是如何从零演化出来、世界如何建模、工程如何推进、技术如何组织」——其余游戏各部分(类型演化、趣味设计、引擎/系统组装、八条拆解)都是这条主线的独立延伸,分别见 02/03、04-06、07-14。
与其他线的关系
- 与 03 趣味设计:本线只把「趣味 = 认知闭环密度 / 核心机制 × 反馈密度」浓缩成一句话;完整推导(Bug 即机制、教学曲线、受控自由、AI 涌现)在 03
- 与 04-06 组装线:本线第五节给出架构全图(Domain/Object/System/Algorithm/Engine);各子系统的分类与组装细节分别见 04 引擎组装、05 游戏系统组件、06 组件组装选择
- 与 02-拆解与组织:21阶段演化规律「每个阶段解决前一阶段问题」就是「拆分职责→组织复用」在游戏的逐次应用;ECS 注册机制见 02-拆解与组织/04
- 与 最小闭环/03:本线一、B 的实现 21 阶段是完整版,最小闭环/03 是最小可验证的子集版本
- 与 业务分析/领域对象分析:游戏世界的对象分析(第 7 阶段)就是领域对象分析在游戏上的应用
