joywayer
|
06f0049221
|
fix(shop): can_buy_attribute 同样校验属性已接线;订正路线图残留表述
购买路径是独立守门人:货架 B / 出售退款等后来者会直接调 can_buy_attribute
而不必先过 get_sellable_attrs,只在展示侧拦截不足以保住不变量。未接线属性
生效值恒为 0,_at_soft_cap 因此永不封顶,可被无限买成空气。
同时把路线图第 99 行残留的「加属性零代码」括注收敛到下一条 ⚠️ 订正,避免
同一条目里两句话互相矛盾。
|
2026-08-03 13:02:20 +08:00 |
|
joywayer
|
ce4ce2b392
|
docs(shop): 记录属性子面板行容量上限,供后续扩容前置说明
商店「属性」子面板行坐标 y = 220 + i*34,关闭按钮占 y=[420,460];按当前坐标常量
算出 250+34i <= 420 ⟺ i <= 5,即最多 6 行(i=0..5)不与关闭按钮重叠,第 7 行
(i=6)落在 y=424 正压在按钮上。路线图 E3-① 延后的 7 个属性一旦全部上架会超出
此容量。本轮不实现滚动/布局改造(超出本次合并范围),仅加注释记录数字,供后续
实现者在动那批属性之前先规划布局。
|
2026-08-03 12:51:30 +08:00 |
|
joywayer
|
8680e8c0ef
|
fix(designer): 属性页仅为已有 shop 段的属性写回该段
_collect() 此前无条件为 ATTR_ORDER 里每个属性写出 entry["shop"](因为 _shop_rows
在 _ready() 里对全部 4 个属性都无条件建了控件行,哪怕原属性没有 shop 段也会以 0 值
占位)。若某属性本来没有 shop 段,保存会写出 price_base=0 的空段,PriceFormula 会把
0 价地板钳到 1G,等于把一个零效果属性变成 1G 无限购买,直接反转货架 C「无 shop 段
即不可售」的核心不变量。
加一道 had_shop 判定:只有 _data 里原本就带 shop 段的属性才写回该段;已有段的属性
继续沿用原有的 duplicate(true) 合并式防丢键行为不变。当前 4 个 ATTR_ORDER 属性都带
shop 段,故此路径今天不可达,需设计器保存才会触发;已用手工构造的 _data/_rows/_shop_rows
调用 _collect() 验证:摘掉 shop 段的属性不再被写回该段,其余属性不受影响。
|
2026-08-03 12:51:23 +08:00 |
|
joywayer
|
5889b3c1e5
|
fix(shop): 可售属性排除未接线项,修正路线图「零代码」表述
get_sellable_attrs() 此前只看 attributes.json 是否有 shop 段,不看 PlayerStats
是否真的实现了该属性。运行时实测:给一个合成属性加 shop 段(不改任何代码)会被列出、
可买、扣钱、购买计数增加,但 get_attr_value 永远读到 0.00——玩家买到的是空气,
且 _at_soft_cap 因为 0.0 < soft 永远不封顶,变相无限花钱买无效果。
PlayerStats 新增 has_attr(attr_id) 谓词(查 _attr_effective,只有 _recompute_attrs
真正算过的属性才算数,不是查 _attr_def 有没有这一节);get_sellable_attrs 用它做
第二道过滤。诊断特意拆进独立函数 _report_unwired_shop_attrs 才调用 push_error+assert——
实测 assert(false) 在本项目运行环境下会让「当前函数」提前返回声明类型的默认值:若诊断写
在收集循环里,一旦命中就会让 get_sellable_attrs 本身连同已收集好的合法属性一起返回空数组,
比原来的「静默卖空气」更糟(整个货架消失);拆成独立函数调用后,中断只发生在诊断函数
自己的调用帧内,调用方(get_sellable_attrs)仍会正常继续并返回过滤后的正确列表。
已注入未接线属性验证:4 个合法属性照常出现,注入项被排除,无一致性问题。
顺带订正路线图 docs_dev/plans/2026-07-23-missing-features-roadmap.md 里「加 shop 段
即可上架、零代码」的表述——该结论只在属性已先接入 PlayerStats 框架(player_stats.gd
的裸字段 + _recompute_attrs 分支 + _attr_effective 条目,以及 attribute_tab.gd 的
ATTR_ORDER)之后才成立,E3-① 延后的 7 个属性都还没有这一步;同时记录商店属性子面板
当前坐标最多容纳 6 行的限制,供后续实现者提前规划。
|
2026-08-03 12:51:13 +08:00 |
|
joywayer
|
56d7eefdc8
|
fix(shop): 新局启动接线 ShopManager.reset(),修复购买记录跨局残留
ShopManager.reset() 此前从未被任何地方调用(grep 零命中):PlayerStats.reset_for_run()
只清 _modifiers,_attr_purchases 不清,两份状态跨局错开——新局价格从已购价起算、
UI 显示「已购 N 次」却生效值是基准值,且买任意一件属性会把整份旧 _attr_purchases
重新套用回 PlayerStats(复现:hp_max 购买 2 次后重开局,加成消失但计数还在;
再买一次 hp_max 后旧的两次加成随之复活)。在 start_game() 内 PlayerStats.reset_for_run()
之后调用 ShopManager.reset()——顺序不能反,reset() 会撤销 shop_c 加成,须晚于
reset_for_run() 清空 _modifiers 之后才不会把两处清理搅乱。
|
2026-08-03 12:50:56 +08:00 |
|
 joywayerandClaude Opus 5
|
7c8c1ec564
|
docs(plan): 订正 Task 6 两处评审指出的归因表述(不改代码/数值)
Step 6 归因写反:脚本手工内联复现两种顺序,从未调用 ProfileManager.apply_run(),
故对调 apply_run() 内部顺序不影响其结果;真正的 apply_run() 顺序回归哨兵是 Step 5b
(评审对调 profile_manager.gd:68-69 顺序后,Step 5b 未改一字即 FAILS=1)。
「22」出处指代错误:task-6-brief.md 全文无此数字,实际出自
docs_dev/specs/2026-07-31-shelf-c-attribute-shop-design.md:133 设计表,数值本身无误。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 12:30:58 +08:00 |
|
 joywayerandClaude Opus 5
|
0b631a475f
|
docs(shop): 货架 C Task 6 运行时验收 + 权威文档补录 + 计划回填
17 条验收标准 + Task 3 遗留的回读顺序风险全部运行时实测通过(FAILS=0),
无代码改动。发现简报三处脚本不可用并替换/补充:Step 1 阳性对照改用
add_modifier 未知属性守卫;新增 Step 5b 补前序评审「磁盘往返未独立复核」;
Step 6/7 原脚本经排查为空断言,改用真实红/绿对照场景。
numerical_design.md §1.1/§1.2 补录属性购买消耗与 cast_delay_mod 的 soft
约束说明;路线图 E3 第 2 项勾除完成。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 12:19:09 +08:00 |
|
 joywayerandClaude Opus 5
|
d69389e09d
|
feat(shop): 设计器「属性」页扩展 shop 段五字段
mode/curve 下拉存 key 不存双语显示串;UI.spin 的 min 取 0 以免 Range 的
抵消误差把浮点噪声写进权威数据文件(E3-① 实测);price_base 存 float
而非 int——JSON.parse_string 对所有 JSON 数字一律解析为 float,存 int
会使往返逐位比较恒假失败,且与 price_formula.gd 的 float() 读取一致。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 11:56:55 +08:00 |
|
 joywayerandClaude Opus 5
|
ad98f916e9
|
feat(shop): 商店「属性」区独立子面板 UI + 4 语言 i18n 键
主商店面板已无空间容纳四行属性(面板 y=200~540,既有控件已占到 y≈522,仅剩约 18px),
经确认后改为独立子面板方案(参照 _setup_settings_ui 既有模式),不改动主面板任何既有控件坐标。
按 get_sellable_attrs() 动态生成行,加可售属性无需改 UI 代码。
禁用态显示具体原因(金币不足/已达上限)而非只灰掉按钮。
can_buy_attribute 注释补 i18n 债务说明(禁用原因暂未 tr(),见路线图 E7-③)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 11:46:05 +08:00 |
|
 joywayerandClaude Opus 5
|
cc57980e63
|
docs(plan): Task4 坐标实测订正——商店面板放不下,改用独立子面板
计划里 y=450 起的坐标基于「现有控件止于 y=440」的假设,实测为错:
面板覆盖 y=200–540,现有控件已排到 y≈479,_shop_warn 在 y=502,
panel 内仅余约 18px,而标题+4 行需约 161px。
改用方案 B(独立子面板,照既有 _setup_settings_ui 结构):与项目
「主面板 + 按钮开子面板」的既有模式一致,且零坐标风险。方案 A 撑高面板
后离视口底仅 28px,后续新增控件会再次撞墙。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 11:38:46 +08:00 |
|
 joywayerandClaude Opus 5
|
f9486083e3
|
docs(plan): 订正 Task3 吞血成因——补正提交 900eaea 说明中的失实描述
900eaea 的提交信息照抄了简报里「hp_max 买到 180 后即可复现」的说法,而
Task 3 实测 + 评审独立复现证明该路径不触发:_modifiers 为空时
remove_modifiers_from 提前返回,单次合并的 add_modifier 一步算出最终值,
中间没有可观察的陈旧 hp_max。
真实风险窗口是同进程内二次 apply_run(_modifiers 已有 shop_c 加成时)。
计划里补了三行复现数据与「写回归测试必须用场景 B 前提」的告诫——
按失实说法写的断言恒绿。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 11:34:07 +08:00 |
|
 joywayerandClaude Opus 5
|
900eaea697
|
feat(shop): 货架 C 购买次数进局内存档(schema 2→3)
只存次数不存加成——加成是派生物,回读时经 _apply_attr_purchases 重建。
这也躲开了 E3-① 记录的坑:_modifiers 是 Array[Dictionary],而 JSON 回读的
无类型 Array 直接 = 赋值是运行时类型错误,必须 .assign();存派生源头则不涉及。
回读顺序:attr_purchases 必须早于 load_save_data。后者设 hp,而重建加成会经
_recompute_attrs 触发 hp = minf(hp, hp_max);顺序颠倒会拿未加成的 hp_max 去钳,
静默吞血(hp_max 可买到 180 后即可复现)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 11:27:23 +08:00 |
|
 joywayerandClaude Opus 5
|
f8e02b0a0b
|
fix(shop): pct 合并公式按 combine 分支取值,修正 inverse 属性算错
_apply_attr_purchases() 原公式 merged=(1+step)^n−1 只对 AttributeFormula 的
hybrid 分支(f=1+v)成立;inverse 分支用 f=1−v,四个可售属性里 cast_delay_mod
恰是 inverse+pct,实际把 f 算成 2−1.1^n 而非设计意图的 0.9^n——n=7 时应得
0.478,实得 ≈0.0513,可购买次数从设计的约 22 次被砍到约 7 次即撞 soft,且
全程 f≥0 走不到越界钳制分支,零诊断。
这是 Task 2 简报 spec 本身推导错误(简报只在 hybrid 下验证过等价性),非
实现偏差;评审已订正 spec 与计划(68e3edb)。现按订正后的公式补上按
combine 分支取值:hybrid 用 merged=(1+step)^n−1,inverse 用
merged=1−(1−step)^n,flat 与 combine 无关不变。
补测显式覆盖此前遗漏的 inverse+pct 组合(此前运行时验证只买过
move_speed/hp_max/cpu_limit,唯独没买过 cast_delay_mod——测试盲区精确盖住
了 bug 所在处):n=1..3/7 逐点数值比对(容差 1e-6),并确认 soft 封顶购买
次数从 ~7 恢复到 ~22;hybrid/flat 对照组数值不变。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 11:19:23 +08:00 |
|
 joywayerandClaude Opus 5
|
68e3edbc7d
|
docs: 订正 pct 合并公式——必须按 combine 分支,inverse 用 1−(1−step)^n
spec §2.4 与计划 Task2 写的 merged = (1+step)^n − 1 只对 hybrid 成立
(AttributeFormula 对 hybrid 用 f=1+v)。inverse 用的是 f=1−v,于是
cast_delay_mod 实际算成 f = 2−1.1^n 而非意图中的 0.9^n:
n=2 应 0.81 实得 0.79;n=7 应 0.478 实得 0.0513
后果是该属性在第 7 次购买就撞 soft 封顶(设计意图约 22 次),
可购买次数砍到 1/3、边际收益曲线整体错误,且零诊断。
评审真机连续购买 7 次坐实。此为 spec 源头错误,非实现偏差。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 11:17:35 +08:00 |
|
joywayer
|
25bdc83c93
|
docs(plan): Task2 Step6 的 git add 补上 player_stats.gd
预检时新增的 Step 0(PlayerStats 通用访问器)改了该文件,但当时没同步更新
Step 6 的提交命令。实现者发现并正确地把它纳入提交。
|
2026-08-03 11:12:17 +08:00 |
|
 joywayerandClaude Opus 5
|
622da4a18e
|
feat(shop): 货架 C 状态与购买——shop 段驱动可售集合,唯一写入点重建加成
可售集合纯数据驱动:attributes.json 的 shop 段缺失即不可售,将来解除 7 个
被阻塞属性的前置后只需加一段 JSON,零代码。
PlayerStats 新增通用生效值访问器 get_attr_value(attr_id),消除商店/UI 侧
本应出现的三处硬编码 match attr_id;_attr_effective 与裸字段在同一处
(_recompute_attrs)更新,避免两者不同步导致显示值与生效值脱节。
_attr_purchases 只存次数;每属性至多一条 _modifiers、value 为合并值
(pct 下 n 次 +step 等价于单条 (1+step)^n − 1)。这样出售退款只需次数减一后
重算,不必给 PlayerStats 新增按条撤销的 API。
所有改动次数的路径都收在 _apply_attr_purchases()——两份状态不同步会产生
「显示买了 3 次但加成只有 2 次」且无任何诊断,收敛写入点是唯一防线。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 11:11:08 +08:00 |
|
 joywayerandClaude Opus 5
|
6aeadb84b8
|
fix(shop): PriceFormula 大购买次数溢出静默塌陷为 1;同步计划文档残留类型名
geometric 曲线在 purchased 较大时(如 n=300,base=60 growth=1.15)raw
虽仍是合法有限 double(约 9.7e19),但已超出 int64 安全范围,roundi()
对此行为未定义/环绕,经 maxi(...,1) 静默塌陷成 1——方向与「买得越多越
贵」相反,且零诊断。仅判断 is_finite(raw) 测不出这种情况(double 本身
溢出为 INF 要到 n≈5077 才发生,晚于 int64 溢出很多),故改为
`not is_finite(raw) or raw > 9.0e15` 双重判据,触发时 push_error 并钳
到统一上限,不再依赖具体常数断言(新增用例只断言单调性与「不再塌陷回
归」)。
同时补齐 docs_dev/plans/2026-07-31-shelf-c-attribute-shop.md:64 遗漏的
`PriceFormula.Curve` → `PriceFormula.PriceCurve` 同步(enum 部分先前已
改,返回类型标注漏改),并全仓复核确认无其它残留。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 11:05:51 +08:00 |
|
 joywayerandClaude Opus 5
|
359da9f24f
|
docs: 订正 enum Curve → PriceCurve(与 Godot 内置 Curve 资源类冲突)
Task 1 实现时发现:enum Curve 在 4.7.1 解析期即报
"member Curve shadows a native class"——与引擎内置的 Curve 资源类同名。
实现者做了独立最小复现,确认与 class_name 无关。
spec §2.1 与计划 Task 1 的代码块都写着 enum Curve,若不订正,Task 2 的简报
会从计划里抄到错误的类型名。下游一律用 PriceFormula.PriceCurve。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 10:56:57 +08:00 |
|
 joywayerandClaude Opus 5
|
c6e89a0787
|
feat(shop): PriceFormula 定价模块——geometric / linear / flat 三曲线
定价集中于单一纯静态模块,无状态零依赖,故可脱离游戏进程单元断言
(与 AttributeFormula 同构)。模块不认识「属性/武器/装备」,只认识
{price_base, price_growth, curve},划分点在数据里——故货架 B 与出售退款
可直接复用,不必各写一套。
返回值下限 1:免费购买无意义,且 0 价会让「买不起」的判定失效。
偏离简报字面代码一处:枚举由 `Curve` 改名 `PriceCurve`。Godot 4.7.1
拒绝声明与引擎全局类同名的嵌套枚举("member Curve shadows a native
class",与 class_name 是否注册无关),简报/设计文档中的 `enum Curve`
在本引擎版本下无法编译,属简报代码本身的缺陷而非誊抄误差。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 10:55:35 +08:00 |
|
 joywayerandClaude Opus 5
|
24948c77f8
|
docs(plan): 预检订正——消除三处硬编码属性名,兑现「加属性零代码」
开工前扫描发现计划初稿违反了它自己的 Global Constraint:ShopManager
_effective_value() 与 combat_s2 的两个辅助各写了一个 match 硬编码四个属性名,
外加 4 个 ATTR_* 的 i18n 键。第 5 个属性加 shop 段后会「UI 生成了行、
但生效值读出 0 且名字是裸 id」——本特性的立身之本直接破功。
改为:PlayerStats 维护 _attr_effective 冷路径视图 + get_attr_value(id)
(热路径仍走裸字段,零开销不受影响);UI 的显示名读 attributes.json 已有的
display_name;ShopManager 暴露 get_attr_def()。三处 match 与 4 个 i18n 键全部删除。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-03 10:52:10 +08:00 |
|
joywayer
|
e41a32b751
|
chore: .gitignore 忽略 .superpowers/(子代理工作流的临时工作区)
该目录存放 SDD 流程的账本、任务简报与评审包,属过程性临时产物,
不进版本控制;否则会长期挂在 git status 里成为噪声。
|
2026-08-03 10:39:12 +08:00 |
|
 joywayerandClaude Opus 5
|
e069b76ee1
|
docs(plan): E3-② 货架 C 逐任务实现计划(7 任务 · 含回读顺序吞血风险)
Task0 建分支 / Task1 PriceFormula(TDD,含报错通道断言)/ Task2 shop 段 +
ShopManager 购买与唯一写入点 / Task3 存档 schema 2→3 / Task4 商店 UI +
4 语言 i18n / Task5 设计器 shop 段 / Task6 运行时验收 + 权威文档补录 + 回填。
Task3 写死一条顺序要求:apply_run 目前第一步就 load_save_data 设 hp,而属性
加成若在其后恢复,回读的 hp 会被尚未加成的 hp_max 钳掉——hp_max 可买到 133
之后即可复现静默吞血。Task6 Step6 专门验证该顺序。
自审订正 spec §3 影响文件表:原列 combat_manager「存档读写接入」是想当然,
profile_manager._collect_run_data 本就直接调 ShopManager.get_shop_seed(),
同样可直接调 get_attr_purchases_save(),不必绕一层。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 16:51:25 +08:00 |
|
 joywayerandClaude Opus 5
|
06d66dbd1a
|
docs(spec): E3-② 货架 C(属性购买)设计——PriceFormula 模块 + shop 段数据驱动
按用户指定的架构方向,定价由专门模块 PriceFormula 负责(与 AttributeFormula
同构:纯静态零依赖,故可脱离游戏进程单元断言)。模块不认识「属性/武器/装备」,
只认识 {price_base, price_growth, curve}——划分点在数据里,故货架 B 与出售退款
可直接复用。
可售集合纯数据驱动:attributes.json 的 shop 段缺失即不可售,自动覆盖 7 个
「已定义但被阻塞」的属性,将来解除前置只需加一段 JSON,零代码。
附完整角色属性盘点(6 类):框架内 4 个可售、权威表已定义未进框架 7 个、
PlayerStats 里权威表漏记的事实属性 2 个(mana_regen/mana_leech,权威给货架 C
举的「回蓝速度」正是前者)、资源与进度、法杖侧、全局配置。
查明 numerical_design §1.2 消耗清单缺属性购买一项,故定价属设计而非查表,
定稿后补录列为本设计的组成部分。
自审订正一处方向性错误:初稿称 cast_delay_mod 的饱和点高于 soft、需逐杖动态
判定——反了。inverse 属性数值更低=更快,三个饱和点全部低于 soft(0.1),正常
购买够不到,UI 只需 soft 一道闸。差点规定一个永远触发不了的功能。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 16:35:18 +08:00 |
|
 joywayerandClaude Opus 5
|
d7420a284f
|
docs(roadmap): 新增 E7-⑥ 计算模块化重构(用户 2026-07-31 指定的架构方向)
原则:凡涉及计算的都由专门功能模块负责,便于测试与配置。
AttributeFormula 是已验证的模板(纯静态零依赖,故不启动游戏就能单元断言)。
盘点出计算散落 8 处、仅 1 处已模块化。最严重的是伤害被劈成两半分居两个文件,
且两处都在扣护甲——目前不重复扣仅因调用点特意传 armor=0,而该约定只存在于
调用点,两个函数各自看都是完整公式。连击 +2%/层 也硬编码在管理器里。
记录立项时必须先决定的设计问题与热路径风险,避免实现期顺手定。
顺序:货架 C(含 PriceFormula)先做,本项独立立项。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 16:04:04 +08:00 |
|
 joywayerandClaude Opus 5
|
9a5f2c1271
|
chore: 补提交 addons/godot_mcp 的 35 个 .gd.uid,与全项目约定对齐
此前 godot_mcp 是全项目唯一不跟踪 .uid 的目录:
scripts/ 51 .gd / 51 .uid
addons/game_designer/ 13 .gd / 13 .uid
addons/godot_mcp/ 35 .gd / 0 .uid ← 唯一例外
且 .gitignore 无任何 .uid 规则,CLAUDE.md 亦要求新增 .gd 连同 .gd.uid 一并提交。
.uid 是稳定资源标识符,不跟踪则其它机器扫描时会重新生成不同 UID,
可能打断 uid:// 引用;Godot 官方亦建议提交。一并消除长期挂在
git status 里的 35 行噪声。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 15:00:25 +08:00 |
|
 joywayerandClaude Opus 5
|
9361bf8767
|
refactor(attr): "core" 来源提为常量;_compute_attr 补 assert;注明 execute_sub 预算独立
MOD_SOURCE_CORE 常量取代四处裸字面量(combat_manager:275,276、combat_test:20,21)。
combat_manager:273 的注释自己就警告「漏掉 remove 会累积,且 hard:50 会把它封成一个
看起来合理的数字」——而 remove 那一侧的字面量若打错一个字符,产生的正是这个零诊断
故障:旧份额撤不掉、逐次累积、被硬上限封顶成常数。常量把它变成编译期错误。
_compute_attr 缺定义时返回 0.0 是消费侧的不对称:Task 4 已硬化生产侧(attribute_tab
的 _loaded 拒绝写出零载荷),但手删 JSON 里的 cast_delay_mod 仍会让生效间隔变 0
(每物理帧施法一次)、删 move_speed 则玩家不能动。它有 push_error,但运行时 push_error
到不了任何日志通道(本期已实测),故表现为一块莫名其妙的砖。按 _recompute_attrs 空定义
分支的同款模式补 assert:release 编译掉、开发期立刻中断。
spell_evaluator:332 的新注释说「生效 cpu_limit 已含法杖份额」,读者可能推断整个 VM 都按
cpu_limit 走,但 execute_sub 的子荷载预算仍是独立的 MAX_OPS_PER_CPU * 2(=80)。补一句
注明其独立且属既有行为(改前同样脱节),不改 execute_sub 的行为。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 13:37:15 +08:00 |
|
 joywayerandClaude Opus 5
|
84c10725e2
|
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>
|
2026-07-31 13:36:53 +08:00 |
|
 joywayerandClaude Opus 5
|
ba7c885291
|
fix(attr): cast_delay_mod 硬上限 0.01 → 0.05,消掉两把主力杖的射速无效区间
_handle_auto_cast 用 if 而非 while,每物理帧至多施法一次,故本属性存在饱和点
= (1/60) / 法杖基准间隔:wand_basic(0.5s) ≈ 0.033、wand_fast(0.25s) ≈ 0.05。
原 hard: 0.01 在两把主力杖上都深深落在饱和区内——玩家把 cast_delay_mod 从
0.033 一路买到 0.01,射速一点没变,属"承诺了循环交付不了的东西"。
取 0.05 使 wand_fast 恰在硬上限处饱和、wand_basic 全程无无效区间。
边界实测(同一套 _physics_process 帧距扫描):wand_fast@0.05 = 1 帧/次(60/s)、
wand_basic@0.05 = 2 帧/次(30/s)、请求 0.01 被 maxf(hard,…) 钳回 0.05 后帧距不变、
soft(0.1) 对照仍 3 帧/次(20/s)、circuit_fork@0.05 = 2 帧/次。
未加任何代码钳制:下限已由 attributes.json + AttributeFormula 的 maxf(hard,…)
强制,代码里再加一个会形成重复权威,设计师调 hard 时立刻脱同步。
spec 新增 §2.2b 收录完整实测数据集(饱和点公式与三把杖的值、soft→hard 是台阶
而非曲线、周期恒为 ceil(T×60) 且整帧倍数多花一帧故实际射速恒 ≤ 名义值)——
结论易得而数据难得,故一并留档。circuit_fork 的饱和点 0.0278 标注为公式推导。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 13:18:46 +08:00 |
|
 joywayerandClaude Opus 5
|
d259205db2
|
docs(plan): 补跑守卫的另外三条进入路径,六条全部由运行时而非眼读覆盖
resume_game / _apply_padded(买卡) / apply_wand_save_data 三条原本只经静态核对,
现已在运行时跑到:均 0 条 cpu_limit=0 报错,且 deck/属性状态正确。
连同已跑的 start_game / switch_core / combat_test,六条齐全。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 13:10:24 +08:00 |
|
 joywayerandClaude Opus 5
|
f3d07c04f8
|
docs(plan): 订正 Step 7b 报错归因措辞——MCP 注入脚本的解析告警不是探针
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 13:06:49 +08:00 |
|
 joywayerandClaude Opus 5
|
04ca402f3c
|
docs(plan): 回填属性系统计划为实际执行版,勾除除合并决策外全部步骤
按 Task 5 Step 8:每个因评审而变的代码块与断言脚本都替换为真正跑通的版本,
逐处附「原写法为何不可用」——这才是回填的持久价值,否则下次复跑喂出的是
过时代码和可能已失效的断言(归航那期踩过)。
主要回填:AttributeFormula 的 pct 越界守卫与静态类型;PlayerStats 的 add_modifier
校验 / hp 钳制 / reset_for_run 清空 / 空定义分支用 assert;守卫从施法处移到 equip_wand;
cast_delay_mod 改开火时生效(原计划的装备时折叠会让局中加成到下次换杖才生效,
正好废掉货架 C);补 combat_test 注入这个原计划遗漏的消费方;属性页 SpinBox 下限、
_loaded 拒写回、autowrap、两条 push_warning。
订正计划自己的一句假话:原写「四个属性的值全部落在 0.01 格点上,故往返无量化损失」。
实测 min=-99999 时 0.1→0.100000000005821、0.01→0.00999999999476131,二者恰恰都在
0.01 格点上——成因是 Range 吸附式在 min 与 step 相差七个数量级时的抵消误差,与格点
无关;而 0.0001 容差比该漂移大七个数量级,原断言在有 bug 的版本上也是绿的。改为对
落盘文本逐字节比较。
Task 5 另记两条工具坑:运行中游戏的 push_error/push_warning 不进 MCP 的两个日志通道
(只有 print 进),故「跑一局看日志无报错」本身是空断言,必须读编辑器 Debugger 错误页
并先用故意错误做正对照;execute_game_script 不支持 await、三引号会被外层包装破坏。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 13:05:40 +08:00 |
|
 joywayerandClaude Opus 5
|
9f71108719
|
docs(attr): 守卫注释改引函数名而非会腐烂的行号;调试场景补注入顺序理由
Task 3 复审转来的两条 Minor。player_manager 守卫注释里的
「player_stats.gd:173/191」是行号引用,改动一次就失效,改为
_load_attr_definitions / add_modifier 两个函数名。
combat_test 的注入原先只有不变式没有理由,补上 remove→add→equip_wand
三者的先后依据(累积防护 + 守卫读的是注入结果)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 12:55:08 +08:00 |
|
 joywayerandClaude Opus 5
|
1aeae19187
|
docs: 订正 move_speed 300→200 与 cpu_limit「从不读」告警;路线图 E3-① 勾除并订正现状
move_speed 300 从未被任何代码读取,是纸面孤值;200 自 S0 沿用并已围绕它调校
20 波内容与 Boss 弹幕密度,以既成事实为准。cpu_limit 行的「代码硬编码 40×5、
从不读 cpu_limit」告警随本次接线失效,改记生效值构成(玩家基准 0 + 法杖 3–8)
与 hard(50) 作用于加总后的总值;基准值一并由 5 改为 0,否则重蹈 move_speed 的
「纸面值与实现长期脱节」。
路线图 E3 现状原写「player_stats.gd 有 resistance 等占位属性(4/5 stats 未接线)」
与事实不符——权威属性表是 11 个,armor/resistance 根本不在表内,是实现先于设计的
孤儿字段。E3-① 勾除并标注实际范围(只做框架 + 三条死数据),attunement_×4 /
luck / recharge_speed_mod 三项延后各附理由;顺带记 cast_delay_mod 的饱和区待人定。
E1 现状里「玩家侧抗性仍占位」一句同因失效,一并订正。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 12:54:22 +08:00 |
|
 joywayerandClaude Opus 5
|
7884e43147
|
fix(attr): 补齐属性页最后两条静默改写数据的诊断,并订正两处注释
1. 条目缺失时无任何诊断(上一轮 `and not d.is_empty()` 引入的回归)。
attributes.json 格式良好但少了 hp_max 时,_loaded 仍为 true、保存照常,
_collect 写出 {"base":0,"soft":0,"hard":0,"combine":"hybrid"}。更糟的是这个键
从此「存在」,player_stats.gd 的「缺少属性」报错也不再触发,hp_max=0 完全静默
进游戏;而 hard=0 在 hybrid 下意味着不钳制,连兜底都没有,玩家瞬死。
改为 if d.is_empty() 单独 push_warning,与 combine 那条对称。
2. min=0.0 引入的负值静默钳制同样无诊断("move_speed":{"base":-50} → 写回 0)。
运行时本就把生效值钳到 ≥0,但静默改写权威数据正是 combine 警告要防的事,
并入同一警告块保持处理对称。
3. _clean 的注释末句由描述改为禁令。原文「当前 12 个值并不依赖本函数」是事实,
但读起来像绿灯,而删掉它一直无害——直到有人放宽 min,也就是它存在的唯一场景。
4. _collect 的注释夸大了:未知键只有是对象时才存活,顶层标量键会让 _load 整体
拒绝加载。改为「保留未知属性条目」。
实测:缺 hp_max 与 base=-1234.5 两条警告均如实发出;未改动的 attributes.json
连建三次零警告零报错(误报比不报更糟,已专门验证)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 12:35:12 +08:00 |
|
 joywayerandClaude Opus 5
|
36c4f79f10
|
fix(attr): 属性页提示自动换行、加载失败拒绝写回、收紧 SpinBox 下限
三处评审必修:
1. 提示 Label 未换行,在 dock 里被裁掉。该 Label 最小宽度 786px,autowrap 为
AUTOWRAP_OFF,而 designer_panel 的 ScrollContainer 禁用横向滚动、同侪分页实际
宽度 337–887px —— 被裁的正是「inverse 的 hard 是下限」这半句,即这条提示存在的
全部理由。加 AUTOWRAP_WORD_SMART,最小宽度降到 17px,337px 下 4 行全可见。
同时补两处内容缺漏:add_int 下 hard=0 同样表示不钳制(cpu_limit 就是 add_int,
还是第一行);soft 本期无消费方,注明「留给货架 C」。
2. 加载失败后保存会写出打砖游戏的文件。_data 为空时 _collect 产出四条全 0、无
display_name 的合法 JSON,PlayerStats 照单全收 → move_speed.base=0、hp_max.base=0
直接进游戏,玩家不能移动/瞬间死亡且零诊断。加 _loaded 标志:加载失败 push_error,
_save 开头守卫拒绝写回。并按 player_stats.gd 的既有做法加逐条 is Dictionary 守卫
(畸形条目如 "hp_max": 5 原会硬崩、dock 停在半构建状态)。
3. SpinBox 下限收紧到 0.0,并订正上一版注释里的误诊。噪声不是「按 step 吸附」的
普遍现象,而是 Range 的 round((v-min)/step)*step+min 在 |min| 远大于 |v| 时的抵消
误差(min=-99999 与 step=0.01 相差七个数量级)。实测:min=-99999 且不用 _clean 时
漂移 2 处,min=0 且不用 _clean 时漂移 0 —— 收紧 min 才是真解法,_clean 并非必需。
四个属性按定义均非负,故 min=0 也更贴语义。_clean 保留作宽区间属性的廉价保险。
另:无法识别的 combine 改为 push_warning 后回落 hybrid(打字错误不该硬拒)。
按评审裁决不给 COMBINE_KEYS[selected] 加 clampi(UI.opt 已 clamp,不可达),改留注释记依赖。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 12:26:09 +08:00 |
|
 joywayerandClaude Opus 5
|
a0e205a031
|
feat(attr): 游戏设计器新增「属性」页,字段化编辑 attributes.json
按 CLAUDE.md 编辑器插件规范:控件经 designer_ui 工厂创建、标签中英双语中文在前、
combine 下拉存 key 不存显示串、_save 合并式写回防丢键、UI 在 _ready 而非 _init 构建。
另修:SpinBox 按 step 吸附会引入双精度噪声(0.01 → 0.00999999999476),
直接写回会把噪声固化进 JSON;_collect 用 snappedf(v, 1e-6) 抹平,
使「不改任何值就保存」得到逐位一致的 attributes.json。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 12:05:50 +08:00 |
|
 joywayerandClaude Opus 5
|
a6c6fdbf1e
|
docs(plan): Task5 补 Step7b——守卫零误报实测 + cast_delay_mod 饱和点上报
Task 3 复审转来两项:
① 守卫搬到 equip_wand 后需跑一局确认零误报——六条进入路径靠眼读弱于跑一局,
且误报的症状与它要报的故障一模一样,是自伤式回归。
② hard: 0.01 承诺了循环交付不了的东西:_handle_auto_cast 用 if 非 while,
每帧至多一次施法,wand_basic 在 cast_delay_mod≈0.033 即饱和,且速率按整帧
量化成 60/30/20/15 的台阶。需人定:写明饱和区,或把 hard 提到 ~0.05。
明确不在代码里加下限钳制——会与 attributes.json 形成重复权威。
另收两条 Minor:注释里会腐烂的行号引用改函数名、combat_test 注入补理由交叉引用。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 11:58:21 +08:00 |
|
 joywayerandClaude Opus 5
|
729c74932f
|
refactor(attr): cpu_limit 守卫移至换杖处;cast_delay_mod 改在开火时生效
守卫从 execute_compiled 搬到 equip_wand:诊断应放在能导致故障的状态转换处,
而非 2 次/秒的使用点——施法端刷屏会埋掉根因,换杖处每局只跑几次且拿得到杖名。
maxi(..., 1) 保留:错误已在换杖处大声报出,退化不再静默,而去掉它会让法术硬瘫。
订正原注释的事实错误:它声称兜住「attributes.json 缺失」与「attr_id 打错」,
但这两种 player_stats.gd:173/191 早已各自报错,守卫零覆盖。真正无人管的是
「新调用点忘了注入」(正是 combat_test 修前的样子)与「cores.json 某杖配成 0」。
cast_delay_mod 由 equip_wand 快照改为开火时相乘:_cast_timer 语义两种写法一致
(总是从上次写入值倒数),代价仅每次施法一次浮点乘法,但「下一个周期」由下次
换杖变为下次施法——玩家买急速道具期待的是后者。随之删去解释延迟生效的注释。
另在 _rebuild_wand 注入处记下 remove-before-add 为何 load-bearing:漏了会让
cpu_limit 随 install_spell 累积,而 hard: 50 会把它封成一个看起来合理的数字。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 11:53:16 +08:00 |
|
 joywayerandClaude Opus 5
|
6f11f4c402
|
fix(attr): 修复调试场景因 cpu_limit 基准改为 0 而退化;记录 cast_delay_mod 快照时序
combat_test 绕过 CombatManager 直接 equip_wand,拿不到 _rebuild_wand 注入的
"core" 份额,导致 cpu_limit=0 触发守卫报错、MAX_OPS 由 200 退化为 40。
镜像 _rebuild_wand 的做法在该场景自行注入(先 remove 再 add),仅修本次弄坏
的部分;该场景整体绕过 CombatManager(如从不设 mana_leech)属既有分歧,不在
本次范围内。
_cast_interval 仅在 equip_wand 时快照,install_spell 只调 _rebuild_wand 不调
equip_wand,实际再同步点是每波开战的 _transition_to_battle。行为不改,加注释
记下时序,免得后续属性商店的实现者误以为购买即时生效。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 11:38:08 +08:00 |
|
 joywayerandClaude Opus 5
|
a3bb778715
|
feat(attr): 接线 MAX_OPS/移速/施法间隔;法杖 cpu_limit 以加成来源接入
MAX_OPS 由硬编码 40×5 改为读生效 cpu_limit——cores.json 里逐法杖配置的
3/5/6/8 自此生效,法杖间恢复运算力区分度。玩家基准取 0,故小木法杖仍为
5 → 200 步,现有平衡零改动。
法杖份额走 add_modifier 而非调用点相加:否则 hard(50) 只钳制玩家那一份,
法杖份额加在钳制之后可使总值越界。换杖时先 remove_modifiers_from("core")
再 add,防止累积。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 11:35:24 +08:00 |
|
 joywayerandClaude Opus 5
|
69ddcddba6
|
docs(attr): 补记货架 C 的回读顺序陷阱;畸形条目报错说明整文件已拒绝
纯注释改动,无行为变更。
1. get_save_data 的货架 C 文档块补回读顺序:_modifiers 必须先 assign +
_recompute_attrs(),再赋 hp。反过来会让新加的 hp = minf(hp, hp_max) 拿
未加成的 hp_max 去钳,静默吞血(评审复现:回读 hp=180/100 → 换杖重算后
100/100,丢 80 HP)。今天不可达(hp_max 恒 100),但持久化 _modifiers 一
落地即活,而这个文档块正是那位实现者会读的地方。
2. 畸形条目的 push_error 补「整个文件已拒绝加载」——守卫是 return,一个坏
条目会让四个属性全部退回声明默认值,原文案读起来像只影响那一个键。
3. ATTRIBUTES_JSON 补「数据源」分区横幅,与文件自身风格一致。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 11:32:10 +08:00 |
|
 joywayerandClaude Opus 5
|
61445caad7
|
docs(plan): Task4 补两条约束——不做热重载 + inverse 的 hard 语义相反需在 UI 体现
remove_modifiers_from 在无命中时提前返回,不是强制重新同步原语,故热重载不能
指望它;本页与其它设计器页一致,保存后提示重启生效即可。
inverse 下 hard 是下限、0 表示钳到 0,与 hybrid/add_int 的「0 = 不钳制」相反,
设计师填 0 期待「不限制」会得到相反结果,提示文案需体现。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 11:32:01 +08:00 |
|
 joywayerandClaude Opus 5
|
af9c94db25
|
fix(attr): add_modifier 补校验、hp 随 hp_max 调和、reset_for_run 清加成
评审 Changes needed 的三个 Important + 五条 Minor:
1. add_modifier 补 attr_id / mode 校验。AttributeFormula 的注释明文把校验委托
给本函数("仅由 PlayerStats.add_modifier 构造…此处不做防御性校验"),而它
原先不守任何门:打错的 attr_id 会永远堆在 _modifiers 里、永不被读到、零诊断。
Task 3 的 add_modifier("cpu_limit",…) 若打成 "cpu_limits" 即 MAX_OPS=0,
所有法术静默执行零步。
2. _recompute_attrs 补 hp = minf(hp, hp_max)。hp_max 改动前事实上不可变,现在
是可动派生值而 hp 从不调和:买 +100 hp_max、血 180/200、卖掉 → 显示 180/100、
get_hp_percent 返回 1.8、heal 静默失效。
3. reset_for_run 清 _modifiers 并重算,且必须早于 hp = hp_max,否则 hp 用陈旧
的 hp_max 播种。今天 "core" 靠 _rebuild_wand 自愈,但货架 C 的购买会跨局白嫖。
Minor:_ATTR_PATH → ATTRIBUTES_JSON 并上移(_PATH 后缀在本项目专指 user:// 路径,
同类 autoload 一律 XXX_JSON);_mods_for 返回 Array[Dictionary];加载器逐条守卫
畸形值("move_speed": 200 会让 Dictionary 赋值硬崩);remove_modifiers_from 无
命中时提前返回不空发 stats_changed;货架 C 提示并入 get_save_data 并补记回读须
用 .assign()(无类型 Array 赋给 Array[Dictionary] 是运行时错误)。
_recompute_attrs 的空定义分支用 assert 而非 push_error:Task 3 接线后每次换杖/
换牌/购买都触发重算,无条件报错一局刷上百行、反而埋掉根因;assert 在 release
被编译掉且开发期首次调用即中断。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 11:24:30 +08:00 |
|
 joywayerandClaude Opus 5
|
8c95cdcbe3
|
docs(plan): Task3 的 MAX_OPS 接线加 cpu_limit=0 守卫
Task 2 代码质量评审建议:cpu_limit=0 的后果是所有法术静默零步,症状离根因极远。
spell_evaluator 的读取点是该故障唯一可观测处,能同时兜住 attributes.json 缺失
与 add_modifier 的 attr_id 打错两种上游失败——根因处的报错够不到这两种。
maxi(...,1) 使故障下游戏仍可玩而非完全瘫痪。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 11:22:23 +08:00 |
|
 joywayerandClaude Opus 5
|
a4a4f613f4
|
feat(attr): attributes.json + PlayerStats 属性框架;删孤儿字段 armor/resistance
PlayerStats 只负责加载定义、持有加成列表、把公式结果写进静态类型裸字段,
不含任何公式(公式在 AttributeFormula)。读取端零开销以满足热路径纪律
(move_speed 每物理帧被 player_manager 读)。
armor/resistance 零消费方且不在 numerical_design §1.1 权威属性表内,属实现
先于设计的残留,删除;真要做玩家侧减伤时按货架 C 属性词条立项(见 spec §2.6)。
hp_max/cpu_limit 现为派生值,从存档字段移除——回读会覆盖公式结果。
旧存档相应键忽略即可,无需提升 schema 版本(hp_max 全项目从无写入方、
cpu_limit 从未被读取)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 11:07:59 +08:00 |
|
 joywayerandClaude Opus 5
|
f86d6cd20e
|
docs(plan): 记录 CACHE_MODE_IGNORE 为验证 class_name 脚本的首选手段 + 加回填步骤
Task 1 实测发现:改完源码后经全局类名直调会拿到**过时结果**(返回修复前的
数值),是假通过陷阱——编辑器持有的已编译类是旧的。正确手段是
ResourceLoader.load(path, "GDScript", CACHE_MODE_IGNORE),它保留 class_name
原样且走引擎自己的编译器,故顺带证明静态类型标注真能被引擎编译。
另记 var x := <Variant 方法调用> 在 4.7.1 是无行号的编译错误而非警告。
新增 Task5 Step8:回填计划为实际执行版并勾复选框——归航那期踩过
「计划里留着过时代码和失效断言」的坑。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 11:04:44 +08:00 |
|
 joywayerandClaude Opus 5
|
9e3cbf8e5a
|
fix(attr): pct 越界因子变负会静默给出错数,钳到 0 并 push_error
因子 (1±v) 可为负;单条负因子被末尾 maxf(0.0,…) 掩盖,两条负因子相乘
则变回正数 —— 得到一个无报错、看起来合理、实则错误的值。实测 hybrid
base 200 两条 pct=-1.5 得 50.0(应 0.0);inverse 两条 pct=2.0 得 1.0,
延迟纹丝不动(应钳到 hard)。这条路径不需要畸形 JSON,货架 C 传个越界
value 即可触发,而本文件是所有未来平衡的必经之地。
顺带:hard 的语义因 combine 而异(inverse 是下限、0.0 不表示不钳制),
从行尾注释提升进 compute() 文档块并在 inverse 分支点明与 hybrid 相反;
补 mods 的构造契约说明;两处下界 0 加注释;ri→floored、
_COMBINE_NAMES→_COMBINE_BY_NAME;查表与循环变量补静态类型。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 11:02:44 +08:00 |
|
 joywayerandClaude Opus 5
|
cd3618c066
|
docs(plan): 补 Step3b 断言 push_error + 订正绕缓存法在类注册后失效
Task 1 评审实测发现两处计划缺陷:
① 断言 ④ 的数字部分对「add_int 拒 pct」是空的——删掉整个拒绝块 ④ 仍返回 13.0,
因为 ADD_INT 的 match 分支不读 pct_prod。拒绝行为唯一可观测证据是 push_error,
补 Step 3b 用唯一标记值 + get_editor_errors 单独断言。
② GDScript.new()+source_code+reload() 在该类被注册为全局类之后同样报
hides a global script class——Task 1 首次运行因尚未注册才侥幸通过,
后续任务照抄会失败。改为先剥离 class_name 行,或直接调已注册的全局类。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 10:53:17 +08:00 |
|
 joywayerandClaude Opus 5
|
ecf765d03e
|
feat(attr): AttributeFormula 公式模块——hybrid 连乘 / inverse 反向下限 / add_int 拒 pct
公式集中于单一纯静态模块,无状态零依赖,故可脱离游戏进程单元断言。
乘算用连乘而非线性求和:三条 +20% 得 ×1.728 而非 ×1.6,避免后期线性失控。
add_int 对离散预算拒绝 pct 并 push_error,而非静默取整掩盖配置错误。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 10:46:20 +08:00 |
|
 joywayerandClaude Opus 5
|
9bc51795c4
|
docs(plan): E3-① 玩家属性系统逐任务实现计划(6 任务 · 公式先 TDD 后接线)
Task1 AttributeFormula 纯函数(先跑断言看失败再实现)/ Task2 attributes.json +
PlayerStats 框架 + 删孤儿字段 / Task3 四处接线 / Task4 设计器属性页 /
Task5 运行时验收 + 权威文档订正。
自审修掉两处:
① Task1 的断言原用 lambda 闭包累加 fails —— GDScript 闭包对 int 按值捕获,
fails += 1 传不回外层,FAILS 会恒为 0、断言全空。改为 Array 逐条收集。
② Task4 原只写「要求」不写代码。已核对 designer_ui.gd 的真实签名
(spin/opt/load_json/save_json 等)并写出完整可抄的实现,避免实现者照
猜测签名写。
另补:hp_max/cpu_limit 转为派生值后必须从存档字段移除,否则回读覆盖公式结果;
并在代码注释里留下货架 C 需持久化 _modifiers 而非派生值的提示。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-07-31 10:42:18 +08:00 |
|