308 字
2 分钟
Trait 组合模式:OpenRA 的类 ECS 单位设计
深受震撼的目录
第一次打开 OpenRA.Mods.Common/Traits/,里面躺着几百个 Trait:Armor.cs(护甲)、Armament.cs(武器挂载)、Attack/(攻击逻辑)、Air/(飞行)、AmmoPool.cs(弹药)。一个单位是什么?是一堆 Trait 的组合,不是七层继承下来的子类。
# mods/ra/rules/infantry.yaml 大概长这样E1: Health: HP: 5000 Armor: Type: None Mobile: Speed: 56 AttackFrontal:策划配 YAML,引擎负责把 Trait 拼成活的单位。加新单位常常零代码,配表就行。
为什么是 Trait 而不是继承
RTS 单位的能力是正交的:能移动 × 能攻击 × 能运输 × 能部署,继承树会被组合爆炸撑死。Trait 把每个能力做成独立小类,挂载即拥有:
AffectsShroud:影响战争迷雾AcceptsDeliveredCash:能收钱(矿车卸货)ActorSpawner:能下崽(母巢、兵营出兵都用它)
我的收获
- 组合优于继承:能力正交时,用组件拼装代替类层次
- 数据驱动:YAML 描述 +
FieldLoader反射灌入,策划和程序解耦 Actor.cs+Activities/(行为)+Orders/(指令)三层分工,单位的状态机清清爽爽
写业务代码也一样:if-else 堆到三层,就该想想是不是缺了一套 Trait。下篇聊 RTS 最硬的两块骨头:寻路和迷雾。