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:
@@ -132,7 +132,7 @@ if _cast_timer <= 0.0:
|
||||
| | **0.1(soft)** | 0.025 s | 2 帧 | **30 /s** |
|
||||
| | 0.07 | 0.0175 s | 2 帧 | 30 /s |
|
||||
| | 0.0667 | 0.016675 s | 2 帧 | 30 /s |
|
||||
| | **0.05(现 hard)** | 0.0125 s | 1 帧 | **60 /s ← 恰好饱和** |
|
||||
| | **0.05(现 hard)** | 0.0125 s | 1 帧 | **60 /s ← 已在饱和区内(饱和点是 0.0667,见下)** |
|
||||
| | 0.01(原 hard) | 0.0025 s | 1 帧 | 60 /s |
|
||||
|
||||
#### 四条结论
|
||||
@@ -141,8 +141,13 @@ if _cast_timer <= 0.0:
|
||||
| 法杖 | 基准间隔 | 饱和点 | 来源 |
|
||||
| :-- | --: | --: | :-- |
|
||||
| `wand_basic` | 0.5 s | ≈ **0.0333** | 实测(0.034 仍 2 帧、0.033 已 1 帧)|
|
||||
| `wand_fast` | 0.25 s | ≈ **0.0667** | 实测(0.0667 仍 2 帧、0.05 已 1 帧)|
|
||||
| `wand_fast` | 0.25 s | ≈ **0.0667**(= 1/15)| 实测夹在 (0.05, 0.0667] 内:0.0667 仍 2 帧、0.05 已 1 帧 |
|
||||
| `circuit_fork` | 0.6 s | ≈ 0.0278 | **公式推导,未实测** |
|
||||
|
||||
> **关于 `wand_fast @ 0.0667` 读到 2 帧**:数据没错,是采样点的问题。真实边界是 `1/15 = 0.06666…`,
|
||||
> 我取的 `0.0667` 比它高 `3.3e-5`(T 上高 `8.3e-6 s`),故落在 2 帧那侧。再叠加结论 3 的浮点余量效应
|
||||
> —— T 恰为整帧倍数时反而多花一帧 —— **实际的 1 帧上界略低于 0.0667**。故 `wand_fast` 的饱和点
|
||||
> 应读作「0.0667 稍下方」,本文一律以公式值 0.0667 记,误差方向是保守的(真实无效区间只会**更大**一点)。
|
||||
2. **soft→hard 之间的可达档位是台阶而非曲线**:`wand_basic` 只有 20 / 30 / 60 次每秒三档,
|
||||
`wand_fast` 只有 30 / 60 两档。中间值买不到。
|
||||
3. **周期恒为 `ceil(T × 60)` 帧,且 T 恰为整帧倍数时会多花一帧**(`T = 0.5` 得 **31** 帧而非 30,
|
||||
@@ -154,8 +159,31 @@ if _cast_timer <= 0.0:
|
||||
|
||||
#### 决定(用户 2026-07-31)
|
||||
|
||||
`hard: 0.01 → 0.05`。取 0.05 的依据正是上表:`wand_fast` 恰在 0.05 饱和,`wand_basic` 在 0.0333 饱和,
|
||||
故 0.05 使**两把主力杖都不再有「买了没用」的无效区间**,让 JSON 承诺的是真能交付的东西。
|
||||
`hard: 0.01 → 0.05`。
|
||||
|
||||
**关键前提:饱和点 = `(1/60) / 法杖基准间隔`,随杖而异,因此不存在对所有杖都最优的单一 `hard`。**
|
||||
`hard` 是**全局**的一个数,而每把杖的饱和点各不相同(0.0278 / 0.0333 / 0.0667),任何取值都只能覆盖一部分:
|
||||
|
||||
| `hard` 取值 | `circuit_fork`(0.0278) | `wand_basic`(0.0333) | `wand_fast`(0.0667) |
|
||||
| :-- | :-- | :-- | :-- |
|
||||
| 0.01(原值) | 无效区间 0.0278→0.01 | 无效区间 0.0333→0.01 | 无效区间 0.0667→0.01(6.7 倍)|
|
||||
| **0.05(已采用)** | ✅ 无无效区间 | ✅ 无无效区间 | ⚠️ 仍剩 `[0.05, 0.0667)` |
|
||||
| 0.0667 | ✅ | ✅ | ✅ 无无效区间 |
|
||||
|
||||
—— 但 `0.0667` 会让 `wand_basic`(饱和 0.0333)与 `circuit_fork`(0.0278)**够不到自己的饱和点**,
|
||||
即它们的最高射速被硬上限提前截断,**制造出新的"不可达区间"**(想更快但买不到)。
|
||||
|
||||
**故 0.05 是折中**:让**多数杖**(`wand_basic` / `circuit_fork`,以及所有基准间隔 ≥ 0.333 s 的杖)
|
||||
无无效区间,只在最快的 `wand_fast` 上留 `[0.05, 0.0667)` 这一小段。相对原 `0.01`
|
||||
(两把主力杖都深陷饱和区)是大幅改进,但**不是"两把主力杖都不再有无效区间"** ——
|
||||
`wand_fast` 那段仍在,只是从 6.7 倍缩到 1.33 倍。
|
||||
|
||||
> **📌 订正记录(2026-07-31)**:本节初稿曾写「`wand_fast` 恰好在 0.05 饱和 / 两把主力杖都无无效区间」,
|
||||
> **算错了** —— 按同一节自己给出的公式 `(1/60)/0.25 = 0.0667`,不是 0.05。实测数据表(§2.2b 上方)
|
||||
> 记的 0.0667 一直是对的,错的只是从那句口头转述派生出来的几处标注。已连同
|
||||
> `numerical_design.md` §1.1、roadmap E3-①、plan Step 7b② 一并订正。
|
||||
> **教训与本期其余三条同源**:结论若与自己上一句的公式矛盾,是最容易被略过的一类错 ——
|
||||
> 因为读者会假定作者算过。
|
||||
|
||||
**明确不做**:不在代码里加下限钳制。下限已由 `attributes.json` + `AttributeFormula` 的
|
||||
`maxf(hard, ...)` 强制;在 `player_manager` 再加一个会形成**重复权威**,设计师调 `hard` 时立刻脱同步,
|
||||
@@ -165,7 +193,7 @@ if _cast_timer <= 0.0:
|
||||
|
||||
| 法杖 | 请求 `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 | ⚠️ 已达 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 | ✅ 钳制生效 |
|
||||
@@ -173,10 +201,14 @@ if _cast_timer <= 0.0:
|
||||
| `circuit_fork` | 0.05 | 0.05 | 0.03 s | **2 帧×89** | 30 /s | ✅ 见下方遗留 |
|
||||
|
||||
> **遗留(实测)**:`circuit_fork`(0.6 s)在新 `hard` 0.05 处实测为 **2 帧/次(30 /s)** ——
|
||||
> 它的饱和点 0.0278(公式推导)低于 0.05,故**没有**无效区间,但也吃不满 60 /s。这是
|
||||
> 「用最快的杖定 `hard`」的必然结果,属可接受的取舍:**无效区间清零优先于人人吃满硬顶**
|
||||
> (无效区间是"花了钱没效果",吃不满硬顶只是"上限没那么高")。若日后引入基准间隔更长的
|
||||
> 法杖,此结论不变。
|
||||
> 它的饱和点 0.0278(公式推导)低于 0.05,故**没有**无效区间,但也吃不满 60 /s;`wand_basic`
|
||||
> 同理(0.0333 < 0.05,30 /s)。反过来 `wand_fast`(0.0667 > 0.05)能吃满 60 /s,代价是
|
||||
> `[0.05, 0.0667)` 那段无效区间。
|
||||
>
|
||||
> **这正是"单一全局 `hard` 撞上逐杖饱和点"的必然取舍**:`hard` 偏小则慢杖有无效区间,偏大则
|
||||
> 快杖被截断。0.05 选择了**让无效区间只留在一把杖上**,因为无效区间是"花了钱没效果"(欺骗),
|
||||
> 而吃不满硬顶只是"上限没那么高"(诚实)。若日后要彻底消除,正确做法是让 `hard` 逐杖化
|
||||
> (即把它变成 `cores.json` 的一个字段),而不是继续挪这个全局数 —— 那属于新的设计立项。
|
||||
|
||||
### 2.3 公式模块 —— `AttributeFormula`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user