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 最硬的两块骨头:寻路和迷雾。