6.8 KiB
6.8 KiB
武器系统扩展设计方案 (Weapon System Expansion Design)
本文档旨在描述基于现有的 HMWS (Hackable Modular Weapon System) 和 ECS BulletManager 架构,可以进一步扩展的玩法机制。
当前的系统已经支持了基础的投射物、霰弹、激光,以及修正器(多重施法、弹射、追踪、穿透、连锁、冰冻)。在此基础上,我们可以引入更高级的策略组合和“涌现式”玩法。
1. 轨迹修正 (Trajectory Modifiers)
通过修改子弹在 _physics_process 中的运动逻辑,创造独特的弹道体验。
1.1 正弦/波浪弹道 (Sine/Wave Pattern)
- 机制: 子弹不再直线飞行,而是沿着正弦波轨迹运动。
- 实现:
- 新增
ModifierSine. - 在
BulletManager的 Data Stride 中增加waveFrequency和waveAmplitude(或复用customData)。 - 在
_physics_process积分位置时,叠加垂直于速度方向的偏移量。
- 新增
- 玩法: 直线命中率低,但能绕过正面护盾,或者覆盖更宽的横向区域。
1.2 回旋镖 (Boomerang)
- 机制: 子弹飞出一定距离后,反向加速飞回玩家。
- 实现:
- 新增
ModifierBoomerang. - 在
BulletManager中逻辑:当lifetime经过一半时,给予一个反向的加速度Acceleration指向玩家。
- 新增
- 玩法: 高风险高回报,利用回程的子弹对追击的敌人造成“背刺”双倍伤害。
1.3 轨道环绕 (Orbiting/Shield)
- 机制: 子弹不飞远,而是围绕玩家旋转,形成护盾。
- 实现:
- 轨道参数
is_orbiting: bool、orbit_radius: float、orbit_angle: float、orbit_speed: float均存入_bullet_contexts: Dictionary(冷数据字段,P6-N9 权威定义),BulletManager SoA 热数组不新增字段。 - 双写优化(P6-N15 规范):环绕子弹的位置由圆周公式 100% 决定,不依赖速度积分。因此在
BulletManager._physics_process中,必须先判断 is_orbiting,再决定是否执行常规物理积分:# BulletManager._physics_process 热路径(伪代码) for i in _active_count: var ctx = _bullet_contexts.get(i, null) if ctx and ctx.get(“is_orbiting”, false): # 跳过速度积分,直接覆写位置(避免无意义的双写开销) var angle: float = ctx.orbit_angle + ctx.orbit_speed * delta ctx.orbit_angle = fmod(angle, TAU) var px := _player_x + cos(ctx.orbit_angle) * ctx.orbit_radius var py := _player_y + sin(ctx.orbit_angle) * ctx.orbit_radius _data[i * BULLET_STRIDE + 0] = px _data[i * BULLET_STRIDE + 1] = py # vx/vy 保持 0,lifetime 正常递减 else: # 常规物理积分(速度 + 加速度) _data[i * BULLET_STRIDE + 0] += _data[i * BULLET_STRIDE + 2] * delta _data[i * BULLET_STRIDE + 1] += _data[i * BULLET_STRIDE + 3] * delta - 性能评估:环绕子弹数量通常不超过 20 颗(护盾构建),
is_orbiting冷数据查询 20 次/帧可接受;若未来出现大量环绕子弹需求,再评估是否升居热数组(SoA 增加 1 bit flag)。
- 轨道参数
- 玩法: 仅近战流派,配合”击退”修正器保命。
2. 触发器系统 (Trigger System) - "Noita" 风格的核心
这是 roguelike 构建深度玩法的关键,即“子弹生子弹”。
2.1 击中施法 (Cast On Hit)
- 机制: 当母弹击中敌人时,以击中点为原点,释放另一个法术。
- 案例: "毒箭" + "击中施法" + "爆炸" = 毒箭射中敌人后产生爆炸。
- 架构实现(✅ 已完成):
ProjectileDef.on_hit_payload_id(int,-1=无触发)存储SubPayloadRegistry中预注册的子法术 ID。SpellEvaluator预编译时将 TRIGGER 节点后续法术打包为 SubPayload 并注册到表;BulletManager在_on_bullet_hit()回调中查表、通过SpellEvaluator.execute_sub()执行。 弹体本身仅携带整数 ID,无需存储复杂对象引用,完全兼容 SoA PackedFloat32Array 布局。 详见architecture_design.md §3.2.A(ProjectileDef 完整字段)与implementation_plan.md §2.2(SubPayloadRegistry)。
2.2 死亡/超时施法 (Cast On Death/Timer)
- 机制:
- On Timer: 子弹飞行亦段时间后,变成另一种子弹(或释放子弹)。例如:集束手雷(飞行 -> 分裂成小炸弹)。
- On Death: 子弹消失/撞墙时触发。
- 玩法: 延迟伤害、陷阱布局。
3. 元素交互 (Elemental Synergy)
扩展现有的 Ice (冰冻) 机制,引入状态反应。
3.1 状态定义
- 冰 (Wet/Freeze): 减速。
- 火 (Burn): 持续扣血 (DoT)。
- 毒 (Poison): 持续扣血 + 易伤 (受到的伤害增加)。
- 雷 (Shock): 间歇性打断动作。
3.2 组合反应 (Combo)
- 热休克 (Fire + Ice): 解除冰冻,但在解除瞬间造成一次巨额爆发伤害 (Steam Burst)。
- 导电 (Water/Ice + Lightning): 如果敌人处于冰冻/潮湿状态,被雷电击中时,触发大范围 AoE 连锁伤害。
- 毒爆 (Poison + Fire): 毒气被点燃,移除中毒状态,产生一次性范围爆炸。
4. 或者是召唤物 (Summons)
将 ActionNode 的产物从子弹变为独立的实体单位。
4.1 炮台 (Turret)
- 机制: 在玩家位置放置一个静止单位,它拥有独立的射击逻辑(自动瞄准最近敌人)。
- 实现: 需要新增
TurretManager或在EnemyManager扩展一个 "Friendly" 阵营。 - 玩法: 塔防流,玩家只负责跑位和放置。
4.2 浮游炮 (Funnel/Bit)
- 机制: 跟随玩家移动的无敌单位,复制玩家的射击行为(类似《沙罗曼蛇》的 Option)。
5. 开发路线图建议
- Phase 1 (Easy): 实现 ModifierSize (巨大化) 和 ModifierSplit (击中分裂 - 简易版 Trigger)。这两个只需要修改
BulletManager的数值逻辑,无需重构 ECS。 - Phase 2 (Medium): 实现 状态交互 (Elemental)。完善
EnemyManager的状态槽位(目前只有freezeTimer,可以用位运算扩展状态标记)。 - Phase 3 (Hard): 实现 Trigger System。✅ 架构已在
implementation_plan.md §2.2完成(SubPayloadRegistry + on_hit_payload_id 方案)。本阶段实施重点:编写多层 TRIGGER 嵌套的单元测试,接入 VFXManager 命中回调。
6. 数值与平衡参考
| 扩展类型 | 开发难度 | 趣味增益 | 性能消耗 |
|---|---|---|---|
| 正弦弹道 | 低 | 中 | 极低 |
| 击中分裂 | 中 | 高 | 高 (子弹数指数增长) |
| 元素反应 | 中 | 高 | 低 |
| 召唤炮台 | 高 | 中 | 中 |