docs: 订正 wand_fast 饱和点 0.05→0.0667;roadmap 关闭已决定项并澄清移速表述

【订正】wand_fast(0.25s) 的饱和点按公式 (1/60)/0.25 = 0.0667,不是 0.05。
numerical_design:21 的标注与它自己上一句的公式直接矛盾,spec/plan 另有三处同源
错误标注——均派生自一句口头转述,实测表里记的 0.0667 一直是对的。

结论也随之改对,不只是改数字:hard=0.05 使 wand_basic(饱和 0.0333) 与
circuit_fork(0.0278) 无无效区间,但 wand_fast 仍剩 [0.05, 0.0667) 这段买不到东西
(较原 hard:0.01 的 6.7 倍缩至 1.33 倍)。仍取 0.05 的理由:饱和点 = (1/60)/法杖
基准间隔,随杖而异,不存在对所有杖都最优的单一 hard——取 0.0667 让 wand_fast 干净
会使另两把杖够不到自己的饱和点,反而制造新的不可达区间。hard 数值不变。

顺带说明实测表里 wand_fast@0.0667 读到 2 帧的原因:采样点比真实边界 1/15 高 3.3e-5
(T 上高 8.3e-6 s),再叠加整帧倍数多花一帧的浮点余量效应,故实际 1 帧上界略低于
0.0667。数据没错,是标签错了。

【roadmap】E3-① 下的 cast_delay_mod 条目仍记为「待人定」并指向两个选项,而该决定
已在 ba7c885 关闭——roadmap 是查「E3 还剩什么」的索引,留着会把已关闭的决定重新打开。
改为已处理,并注明彻底消除需让 hard 逐杖化(挪进 cores.json),属独立立项。

【roadmap】「实测 200→300 px/s」读起来像发版移速由 200 改成 300,与同批改动里
numerical_design 的订正(发版是 200,300 是从未被读过的纸面值)直接冲突。改写为
「发版基准仍是 200;实测手段是临时挂 +50% 加成使生效值变 300」。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 13:36:53 +08:00
co-authored by Claude Opus 5
parent ba7c885291
commit 84c10725e2
4 changed files with 52 additions and 16 deletions
@@ -89,13 +89,13 @@ E6-a 玩家无敌帧(i-frames) ← 先行小项:Boss 弹幕公平性前置,
**依赖**:货架 C 依赖「属性词条系统」先落地;核心抽取复用已有 `cores.json`/`make_core_by_id`
**切分(建议 4 个子计划,属性词条优先)**
1. ~~**属性词条系统**~~**完成**2026-07-31`feat/player-attributes`spec/plan `docs_dev/{specs,plans}/2026-07-31-player-attributes*`):`AttributeFormula` 纯静态公式模块(`hybrid` 连乘 / `inverse` 反向下限 / `add_int``pct` + `pct` 越界钳 0);`PlayerStats``_attr_def` + `_modifiers` 并把公式结果写回静态类型裸字段(读取端零开销);`add_modifier` / `remove_modifiers_from(source)` 按来源增撤;`data/attributes.json` + 设计器「属性」页。**接线三条死数据**:`spell_evaluator` MAX_OPS 改读生效 `cpu_limit`(法杖份额以 `source="core"` 加成接入,运行时实测 3→120 / 5→200 / 8→320 步)、`player_manager``const MOVE_SPEED` 改读 `PlayerStats.move_speed`实测 200300 px/s)、`_handle_auto_cast` 开火时乘 `cast_delay_mod`。删孤儿字段 `armor`/`resistance``hp_max`/`cpu_limit` 移出存档(改为派生值)。
1. ~~**属性词条系统**~~**完成**2026-07-31`feat/player-attributes`spec/plan `docs_dev/{specs,plans}/2026-07-31-player-attributes*`):`AttributeFormula` 纯静态公式模块(`hybrid` 连乘 / `inverse` 反向下限 / `add_int``pct` + `pct` 越界钳 0);`PlayerStats``_attr_def` + `_modifiers` 并把公式结果写回静态类型裸字段(读取端零开销);`add_modifier` / `remove_modifiers_from(source)` 按来源增撤;`data/attributes.json` + 设计器「属性」页。**接线三条死数据**:`spell_evaluator` MAX_OPS 改读生效 `cpu_limit`(法杖份额以 `source="core"` 加成接入,运行时实测 3→120 / 5→200 / 8→320 步)、`player_manager``const MOVE_SPEED` 改读 `PlayerStats.move_speed`**发版基准仍是 200**;实测手段是临时挂一条 `+50%` 加成使生效值变 300,测得玩家实际位移速度同步由 200300 px/s,证明读取端是活的)、`_handle_auto_cast` 开火时乘 `cast_delay_mod`。删孤儿字段 `armor`/`resistance``hp_max`/`cpu_limit` 移出存档(改为派生值)。
- ⚠️ **实际范围小于原描述**:原写「定义 4/5 缺失 player stats(如暴击/急速/范围/吸血/减伤)」—— 那些属性名是拟稿推测,不存在于任何权威文档(见上方「现状」订正)。本期只做**框架 + 三条死数据**,明确延后三项,各有理由:
- `attunement_fire/ice/lightning/poison`(4 个元素精通)—— 属**新增玩法维度**而非断线,需接入元素伤害管线,独立立项。
- `luck` —— 权威表定义它「影响暴击率」,而**暴击链目前是死的**(`bullet_manager.gd:81``is_crit` 硬编码为 `false``CastStats.crit_chance` 从未被掷判);打通暴击链是其前置。
- `recharge_speed_mod` —— 代码中**不存在充能系统**(全项目 grep `recharge` 零命中),属新增机制而非断线。
- 另:`mana_max` 的「与法杖取 Min」语义(权威 §1.1)未迁入框架,现状是核心值直接覆盖玩家值;那是独立设计判断,记为已知遗留。
- ⚠️ **`cast_delay_mod` 存在饱和区`hard: 0.01` 承诺了循环交付不了的东西**(运行时实测,待人定)`_handle_auto_cast``if` 而非 `while`,每物理帧至多一次施法 → 60 次/秒硬顶,实际速率按**整帧量化**。小木法杖(0.5s) `mod ≤ 0.0333` 即饱和,`wand_fast`(0.25s) `mod ≤ 0.0667` 即饱和;从饱和点到 `hard`(0.01) 之间买不到任何东西。数字与两个处理选项`docs_dev/plans/2026-07-31-player-attributes.md` Task 5 Step 7b②
- **`cast_delay_mod` 饱和区问题已处理(`hard: 0.01 → 0.05`,提交 `ba7c885`,决定已关闭)**`_handle_auto_cast``if` 而非 `while`,每物理帧至多一次施法 → 60 次/秒硬顶,实际速率按**整帧量化**,故饱和点 = `(1/60) / 法杖基准间隔``circuit_fork` 0.0278 / `wand_basic` 0.0333 / `wand_fast` 0.0667)。原 `hard: 0.01` 远在所有杖的饱和点之下,从饱和点0.01 射速纹丝不动。因饱和点随杖而异、不存在对所有杖都最优的单一 `hard`,取 0.05 为折中:`wand_basic` / `circuit_fork` 无无效区间,`wand_fast` 仍剩 `[0.05, 0.0667)`(较原来的 6.7 倍缩至 1.33 倍)。完整实测数据集`docs_dev/specs/2026-07-31-player-attributes-design.md` §2.2b。若日后要把 `wand_fast` 那段也消掉,正确做法是让 `hard` **逐杖化**(挪进 `cores.json`)而非继续挪这个全局数 —— 属独立立项,**不是本期遗留待办**
2. **货架 C(属性购买)**:商店可购属性词条(消耗金币/以太),叠加到 PlayerStats。S~M。
3. **货架 B(核心抽取)**:商店提供 Core 抽取/更换(复用 `_CORE_ROSTER`),与现有换杖打通。S~M。
4. **出售退款 G5**:背包内法术/核心可出售,按 `numerical` 退款比例返还货币。S。
@@ -1015,8 +1015,8 @@ Run: godot-mcp-pro `stop_scene`,然后 `execute_editor_script` 扫四个文件
| `wand_fast`(基准 0.25 s | 1.0 | 0.25 s | 16 帧 | 3.75 /s |
| | **0.1soft** | 0.025 s | 2 帧 | **30 /s** |
| | 0.07 | 0.0175 s | 2 帧 | 30 /s |
| | 0.0667 | 0.016675 s | 2 帧 | 30 /s |
| | **0.05** | 0.0125 s | 1 帧 | **60 /s ← 饱和点** |
| | 0.0667 | 0.016675 s | 2 帧 | 30 /s ← 采样点比真实边界 1/15 高 3.3e-5,故落在 2 帧侧 |
| | **0.05** | 0.0125 s | 1 帧 | **60 /s ← 已在饱和区内(饱和点是 0.0667,非 0.05** |
| | **0.01hard** | 0.0025 s | 1 帧 | 60 /s |
结论(供决策):
@@ -1028,13 +1028,17 @@ Run: godot-mcp-pro `stop_scene`,然后 `execute_editor_script` 扫四个文件
**两个选项曾提交人定**(a) 保持 `hard: 0.01` 并在文档写明饱和区;(b) 把 `hard` 提到 ~0.05。
**✅ 用户 2026-07-31 决定:采用 (b)`hard: 0.01 → 0.05`。** 依据正是上表 —— `wand_fast` 恰在 0.05 饱和、`wand_basic` 在 0.0333 饱和,取 0.05 使两把主力杖都不再有「买了没用」的无效区间。落地三处:`data/attributes.json``numerical_design.md` §1.1、spec 新增 §2.2b(收录完整实测数据集)。
**✅ 用户 2026-07-31 决定:采用 (b)`hard: 0.01 → 0.05`。** 落地三处:`data/attributes.json``numerical_design.md` §1.1、spec 新增 §2.2b(收录完整实测数据集)。
依据:饱和点 = `(1/60) / 法杖基准间隔` = `circuit_fork` 0.0278 / `wand_basic` **0.0333** / `wand_fast` **0.0667**。**该值随杖而异,故不存在对所有杖都最优的单一 `hard`**:取 0.05 使 `wand_basic``circuit_fork` 无无效区间,`wand_fast` 仍剩 `[0.05, 0.0667)` 一小段(从原来的 6.7 倍缩到 1.33 倍);若改取 0.0667 让 `wand_fast` 干净,则 `wand_basic`/`circuit_fork` 反而够不到自己的饱和点,制造新的不可达区间。
> **📌 订正(2026-07-31**:本步初稿曾写「`wand_fast` 恰好在 0.05 饱和 / 两把主力杖都不再有无效区间」,**算错了** —— `(1/60)/0.25 = 0.0667` 而非 0.05。上方实测表里的 0.0667 一直是对的,错的是从口头转述派生的标注。`hard` 数值不受影响(0.05 仍是选定值,只是理由要说准)。
**边界复测**(改动后用同一套扫描重跑,这是本次改动唯一的行为差异,值得实测而非推导):
| 法杖 | 请求 `mod` | 生效 `mod` | T | 实测帧距 | 速率 |
| :-- | --: | --: | --: | --: | --: |
| `wand_fast` | 0.05 | 0.05 | 0.0125 s | **1 帧×179** | 60 /s恰好饱和,不浪费|
| `wand_fast` | 0.05 | 0.05 | 0.0125 s | **1 帧×179** | 60 /s已入饱和区;饱和点是 0.0667,故 `[0.05, 0.0667)` 仍是无效区间|
| `wand_fast` | 0.01 | **0.05** | 0.0125 s | 1 帧×179 | 60 /s`maxf(hard,…)` 钳制生效)|
| `wand_basic` | 0.05 | 0.05 | 0.025 s | **2 帧×89** | 30 /s |
| `wand_basic` | 0.01 | **0.05** | 0.025 s | 2 帧×89 | 30 /s(钳制生效)|