游戏拆解与组装(非 ECS)

「游戏拆解与组装」讲的是一套非 ECS 的拆解与组装案例:游戏程序拆成 Engine(支撑子系统)与 Game(业务子系统),再由 GameApplication 组装。Engine 负责「怎么运行」,Game 负责「运行什么」——这是拆解与组织原则在游戏上的完整应用,不依赖 ECS。这一条线就是这个案例本身:游戏怎么拆、怎么组。


一、先把「支撑子系统 / 业务子系统 / 调度组装」分开

一个游戏程序可以抽象成两个子系统:

1
2
3
游戏程序
├── Engine 子系统 ← 支撑
└── Game 子系统 ← 业务
1
2
3
4
5
Engine
├── ECS / Rendering / Physics / Input / Audio / Resource / Scene

Game
├── Player / Enemy / Weapon / Character / Inventory / Quest / GameRule

Engine 是支撑子系统,Game 是业务子系统。 这是游戏拆解的第一刀——把「怎么运行游戏」和「游戏内容是什么」分开。


二、Engine 继续拆(支撑子系统)

1
2
3
4
5
Engine
├── ECS World / Entity / ComponentStorage / Query / Scheduler
├── Rendering Renderer / Mesh / Material / Camera / RenderPass
├── Physics World / RigidBody / Collider / CollisionQuery
├── Input / Audio / Resource / Scene

每个支撑子系统内部再拆成组件——与任何大型软件的系统拆分相同。


三、Game 也完全一样拆(业务子系统)

1
2
3
4
5
Game
├── Character CharacterComponent / MovementSystem / CharacterController / CharacterData
├── Combat HealthComponent / AttackComponent / DamageSystem / AttackSystem / CombatRule
├── Inventory InventoryComponent / ItemComponent / InventorySystem / ItemRule
├── Quest / AI / World

Engine Component 和 Game Component 在「组件化」层面没有区别。 区别只是:Engine Component 支撑游戏,Game Component 实现具体游戏。


四、谁来组装:GameApplication

不是 main 一个个 new 所有东西,而是 GameApplication 负责组装:

1
2
3
4
5
6
7
8
9
10
11
int main() { GameApplication app; app.run(); }

class GameApplication {
void run() {
Engine engine;
Game game;
game.registerComponents(engine);
game.registerSystems(engine);
engine.run();
}
};

Engine 负责「怎么运行」

1
2
3
4
5
6
7
8
9
10
11
class Engine {
void run() {
while (running) {
input.update();
ecs.update();
physics.update();
rendering.render();
audio.update();
}
}
};

Engine 负责生命周期、运行循环、系统调度、基础设施、资源管理;它不知道游戏规则。

Game 负责「运行什么」

1
2
3
4
5
6
7
8
9
10
11
class Game {
void registerComponents(Engine& engine) {
engine.ecs.registerComponent<Transform>();
engine.ecs.registerComponent<Health>();
engine.ecs.registerComponent<Weapon>();
}
void registerSystems(Engine& engine) {
engine.ecs.addSystem<MovementSystem>();
engine.ecs.addSystem<CombatSystem>();
}
};

Game 不自己运行——它把「有哪些组件、有哪些系统」告诉 Engine,由 Engine 运行。


五、完整组装关系

1
2
3
4
5
6
7
8
9
10
11
12
13
               GameApplication

┌──────────────┴──────────────┐
↓ ↓
Engine Game
┌─────┼─────┐ ┌────────┼────────┐
↓ ↓ ↓ ↓ ↓ ↓
ECS Rendering Physics Character Combat Inventory

└── Scheduler


Game Systems(Movement / Combat / Enemy / Inventory)

真正运行时:

1
GameApplication → Engine → Scheduler → Game Systems → ECS World → Game Components

六、不要把 Game System 和 Engine Scheduler 混为一谈

1
2
CombatSystem → 业务(找到攻击者、计算伤害、修改 Health)
Scheduler → 支撑(只知道什么时候运行 CombatSystem)

Scheduler 不知道「伤害是多少」,只知道「什么时候运行 CombatSystem」。


七、游戏业务也可再框架化

如果游戏很复杂,还可以继续:

1
2
3
4
5
Engine

Game Framework(RPG Framework:Character/Inventory/Quest/Combat/Save)

具体 RPG(魔法/武器/敌人/具体任务)

下层框架提供运行和组装能力,上层框架利用下层框架再次进行领域组装。 ECS Engine 是支撑;Game 是业务;Scheduler 是 Engine 提供的运行机制;Game Systems 是业务逻辑;GameApplication 是把 Engine 和 Game 组装起来的应用层。


八、这一条线的位置

1
2
3
4
5
拆解与组织(主题):
01 元原则(拆解+组织)
02 边界(在哪切)
03 游戏拆解与组装(本线:拆解与组织在游戏上的完整案例,非 ECS)
04 ECS 与注册机制(03 的基础上加入运行时可扩展 = 注册机制)

本线是「非 ECS」的游戏拆解组装:Engine/Game 拆开、GameApplication 组装。ECS 只是在这一基础上额外加了一个机制(注册机制,见 04),不是本线的前提。


收束

1
2
3
4
5
6
7
8
9
10
11
12
13
游戏拆解的第一刀:
Engine(支撑子系统)vs Game(业务子系统)

Engine 负责「怎么运行」:生命周期、运行循环、系统调度
Game 负责「运行什么」:注册组件、注册系统

组装者是 GameApplication:
main → app.run() → 创建 Engine/Game → 注册 → engine.run()

不要混:
CombatSystem(业务)vs Scheduler(支撑)

可再框架化:Engine → Game Framework → 具体 RPG

游戏的拆解与组装 = 拆成 Engine 与 Game,由 GameApplication 组装。 这是拆解与组织原则的完整案例——不依赖 ECS。