docs(roadmap): E1-③ 子弹归航完成,勾除现状项 + 记录快照删除这一有意偏离

「现状」归航行与切分列表第 3 项改为完成态,格式对齐已完成的 ①②。
显式记录与本文档原方案的偏离:未消费 _enemy_pos_snapshot 而是删除之 ——
锁定式目标需 entity_id,而快照按槽位存位置、不含 id,结构上支撑不了该语义。
另记退避 + 抖动这一同期落地的性能措施(详见 spec §5)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 16:54:13 +08:00
co-authored by Claude Opus 5
parent df81e9eafa
commit d498097005
@@ -42,7 +42,9 @@ E6-a 玩家无敌帧(i-frames) ← 先行小项:Boss 弹幕公平性前置,
**现状(代码复核 2026-07-23**
- ~~元素抗性~~ ✅ **完成**2026-07-24`feat/element-resistance`):`apply_damage_from_context``ctx.damage_type``_RESIST` 表传入 `calc_damage(0, res)``enemies.json` 每型可选 `resistances{元素名:-0.9~0.9}`(支持负=弱点加伤);设计器敌人页加 6×5 抗性网格。MCP 实测:抗火0.5→半伤、弱冰-0.5→1.5×、抗性+护甲叠加45。⚠️ **已知限制**DOT 伤害(`status_manager.gd:116` 直调 `apply_damage`)暂不享元素抗性(架构上 DOT 不走 context,见 E2)。(`player_stats.gd:23 resistance` 玩家侧抗性仍占位。)
- ~~连锁/弹跳~~ ✅ **完成**2026-07-24`feat/bullet-bounce`):镜像 pierce 管线——`CastStats.bounce_add``_apply_modifier` 折叠 → `_push_projectile` 写冷数据 → `_check_collision` 命中转向最近未访问敌(`_find_nearest_unvisited`)、`damage_mult×decay` 递减、`visited_targets` 防回跳、命中循环跳过已访问防密集群重复命中。bounce 优先于 pierce(耗尽后落 pierce)。`modifier_bounce` 词条上架。MCP 实测:bounce=2→3 敌 100/90/81、速度重定向证明优先级、折叠 bounce_add=2。
- 归航:`bullet_manager.gd:21` 每帧建 `_enemy_pos_snapshot`(预分配满足 P6-N25)但 `_gd_integrate` 无 homing 转向计算,**快照无人消费**
- ~~归航~~ ✅ **完成**2026-07-30`feat/bullet-homing`):镜像 bounce 管线——`CastStats.homing_add`(float) → `_apply_modifier` 折叠 → `_push_projectile` 写冷数据 `homing_strength/homing_range/homing_target_id``_gd_integrate` 在位置积分**之前**调 `_apply_homing`,用 `wrapf` 取最短转向、`clampf``strength*delta` 限角速度、`rotated()` 保速率。目标为**发射后锁定**:仅首帧与目标死亡时经 `_find_nearest_unvisited` 重选;bounce 命中重定向时改写 `homing_target_id`bounce 选目标、homing 追上去)。`modifier_homing` 词条上架。MCP 实测见下方「⚠️ 有意偏离」与 spec §5
- ⚠️ **有意偏离本文档原方案**:本行原写「`_gd_integrate` 消费 `_enemy_pos_snapshot`」,实现**没有**消费它,而是**删除**了 `_enemy_pos_snapshot` 及其唯一生产者 `EnemyManager.fill_pos_snapshot`。理由:最终设计采用**按 entity_id 锁定目标**(轨迹可读、目标死亡有明确判据 `get_pos_by_id` 哨兵),而该快照**按槽位存位置、不含 entity_id**,结构上支撑不了锁定语义;接上它反而要每帧 O(敌人数) 重扫最近点。净效果是**减少**一份每帧 O(敌人数) 开销。
- ⚠️ **性能**:重选**失败**路径会每帧重跑 `query_circle(r=400)`,实测 300 弹即越过 2.0 ms 线,故同期落地**退避 + 抖动**(`homing_retry_at``HOMING_RETRY_MS=200`)。抖动必需——朴素固定退避会把同帧失败的子弹锁进同相,尖峰每 12 帧永久复发。详见 spec §5。
- 轨迹修正(加速/曲线):`_data +11 acceleration` 已积分,但无"转向/曲线"类修饰器写入。
**设计来源**`docs/mechanics/combat_mechanics_depth.md §4`(抗性公式)、子弹冷数据字段。
@@ -52,7 +54,7 @@ E6-a 玩家无敌帧(i-frames) ← 先行小项:Boss 弹幕公平性前置,
**切分(建议 4 个子计划)**
1. ~~**元素抗性 (1-Res)**~~**完成**2026-07-24`feat/element-resistance`spec/plan `docs_dev/{specs,plans}/2026-07-24-element-resistance*`):enemies.json `resistances{元素名:-0.9~0.9}`EnemyManager `_RESIST` 查表传入 `calc_damage(0,res)`;设计器 6×5 抗性网格。
2. ~~**连锁/弹跳 chain/bounce**~~**完成**2026-07-24`feat/bullet-bounce`spec/plan `docs_dev/{specs,plans}/2026-07-24-bullet-bounce*`):冷数据 `bounce_remaining/visited_targets/decay/range`,命中转向最近未访问敌+×0.9 递减,bounce 优先于 pierce`modifier_bounce` 词条。
3. **归航 homing**:子弹冷数据 `homing_strength``_gd_integrate` 消费 `_enemy_pos_snapshot` 求最近敌人,按 strength 插值转向速度向量。修饰器 `modifier_homing`。S
3. ~~**归航 homing**~~**完成**2026-07-30`feat/bullet-homing`spec/plan `docs_dev/{specs,plans}/2026-07-30-bullet-homing*`):冷数据 `homing_strength/homing_range/homing_target_id`,每帧以 `strength*delta` 为上限朝**锁定目标**转向(`wrapf` 最短转向 + `rotated()` 保速率),目标死亡才重选;失败退避 + 抖动(`homing_retry_at`);bounce 协同改写目标;`modifier_homing` 词条。**偏离**:未消费 `_enemy_pos_snapshot` 而是删除之(快照按槽位存位置、不含 entity_id,支撑不了锁定语义),见上方「现状」
4. **轨迹修正**:曲线/环绕类(angular velocity 字段)+ 对应修饰器。S(可选,最低价值,YAGNI 可延后)。
**验收标准**:抗性 50% 的敌人受火伤减半(数值实测);bounce=2 子弹依次命中 3 个不同敌人且伤害递减;homing 子弹命中偏移目标;各修饰器可在商店买到并影响弹道;纯数据驱动、MCP 运行时实测。