四个原则(数据驱动、组件化、组合优于继承、对象池)
07/26
四个原则(数据驱动、组件化、组合优于继承、对象池)确实是系统从"能跑"到"能维护"的分水岭。
先看看你的游戏现状,再说怎么落地。
你的游戏现状分析
你的《自由的校园》不是传统战斗游戏,但已经有大量"对抗性交互":
| 已有机制 | 对应战斗系统概念 |
| 主角投掷物品(粉笔、扫把) | 投射物 / 技能 |
| 行为违规 → 目击 → 怀疑累积 | Debuff 叠加 |
| 冲突事件 → 保安响应 | Boss 技能 / AI 响应链 |
| 恶作剧结算(broom_playground_prank) | 技能效果 |
| 设施损坏 | AOE / 环境破坏 |
| 物品注册表 21 件 | 已有数据驱动雏形 |
你的优势是已经有了部分正确架构:
- 物品注册表.lua — 21 件物品的统一数据源(类别、可投掷、可赠送、违禁等级)
- 功能空间类型注册表.lua — 数据驱动的空间配置
- 系统已经模块化拆分(好奇心服务、任务服务、事件总线等)
但主角的交互逻辑目前集中在 主角交互服务.lua 和 主角任务服务.lua 里,投掷/赠送/使用的效果是硬编码的 if-else 分支。
四个原则在你游戏中的具体映射
一、数据驱动:你已经有 60 分了
你的 物品注册表 已经是"配方表",但目前只定义了物品属性(类别、可投掷),没有定义使用效果。
现在的问题:主角对物品"使用"后发生什么,写在 主角交互服务.lua 的代码里。
改进方向:
lua-- 物品注册表.lua 扩展(配方表补全) { id = "chalk", name = "粉笔", throwable = true, -- 新增:使用/投掷效果配置 effects = { on_throw = { { type = "damage", amount = 5, target = "hit_actor" }, { type = "violation", severity = 10 }, { type = "sound", clip = "chalk_hit" }, }, on_use_self = { { type = "buff", buffId = "chalk_dust", duration = 3 }, }, }, }
代码不再写 if itemId == "chalk" then ... end,而是读配置、执行效果列表。
二、组件化:主角小人的拆分
你的学生 NPC 已经是"数据 + 服务"模式(学生数据在 state.students,行为由 AI 服务驱动),但主角的操控逻辑分散在多个服务里且没有统一的角色组件抽象。
可以这样拆:
主角小人
├── 属性组件 → hp, stamina, 当前手持物品
├── 状态组件 → 身上挂了什么 buff/debuff(怀疑值、伪装、受伤)
├── 技能组件 → 可执行的动作列表(拾取/投掷/赠送/使用)+ 冷却
├── 移动组件 → 已有:小人空间服务(MoveTo/UpdateMove)
└── 交互组件 → 距离检测、目标选择、菜单触发每个组件只管自己的事。改投掷伤害不会碰到移动逻辑,改移动速度不会碰到状态逻辑。
三、组合优于继承:效果积木块
这是你当前架构最需要的一层。现在主角任务服务里,扫把恶作剧的结算逻辑是专门的 if 分支:
lua-- 当前:每个任务硬编码效果 if taskId == "broom_playground_prank" then -- 20 行专属结算逻辑 end
改成积木块组合后:
lua-- 效果积木块(最小单元) EffectBlocks = { damage = function(target, params) ... end, heal = function(target, params) ... end, addBuff = function(target, params) ... end, violation = function(target, params) ... end, -- 触发违规事件 spawnItem = function(target, params) ... end, -- 生成物品 playSound = function(target, params) ... end, curiosity = function(target, params) ... end, -- 触发好奇心脉冲 } -- 任务/技能配置:积木的组合 broom_playground_prank = { on_complete = { { block = "violation", severity = 30, radius = 20 }, { block = "curiosity", pulseStrength = 15 }, { block = "playSound", clip = "prank_laugh" }, { block = "addBuff", buffId = "mischief_fame", duration = 60 }, } }
新增一个效果类型,只需要写一块新积木。所有任务、物品、事件都能用。
四、对象池:你当前不太需要
你的游戏没有子弹、粒子特效等高频创建/销毁的对象。学生 NPC 是固定数量的,地图物件是静态的。
如果未来加入:
- 投掷物的飞行轨迹可视化
- 冲突特效(星星、感叹号)
- 大量临时 UI 提示气泡
那时候再引入对象池。现在不是瓶颈。
落地建议
不要一次性重构。按优先级分步:
| 优先级 | 做什么 | 为什么先做 |
| P0 | 效果积木块系统 | 当前每加一个交互效果就要改多个服务,这是最痛的点 |
| P1 | 物品注册表扩展效果配置 | 数据驱动,配合积木块,策划可直接改配置 |
| P2 | 主角组件化拆分 | 当前主角逻辑分散但还能维护,等效果系统稳定后再拆 |
| P3 | 对象池 | 等有高频创建/销毁需求时再做 |
核心思路:先建"效果执行器"(积木块),再把现有硬编码效果迁移过去,最后扩展物品/任务配置。

