diff --git a/game/README.md b/game/README.md index a997e1e4..53ae9193 100644 --- a/game/README.md +++ b/game/README.md @@ -2,9 +2,9 @@ > // VERTICAL SLICE - NOT FOR PRODUCTION > // Validation Question(v2,2026-09-11):线性第一关(战×2→道具→战×2→恢复→Boss)能否承载 -> // "数值提升→通关期望改善"的 Roguelike 元进度验证——基线属性应该难到打不过、天赋数值提升把 -> // 通关期望拉回可玩带,且这条曲线能用数值调整板 + 批量模拟**测量出来** -> // (通关攻击期望 / 败北血量数学期望);v1 的单战斗循环问题(逐行归因 P2 / Core headless 可跑) +> // "数值提升→冒险成功期望改善"的 Roguelike 元进度验证——基线属性应该难到打不过、天赋数值提升把 +> // 冒险成功期望拉回可玩带,且这条曲线能用数值调整板 + 批量模拟**测量出来** +> // (冒险成功攻击期望 / 败北血量数学期望);v1 的单战斗循环问题(逐行归因 P2 / Core headless 可跑) > // 已于 2026-09-10 验证并保持回归(初版断言面 46 项,后并迁系统测试宿主,沿革查 git log)。 > // Date: 2026-09-10(v1)· 2026-09-11(v2 关卡扩展)· 引擎 Godot 4.7.2 · 本目录仅作设计验证参考,禁止 import 进生产代码 @@ -12,10 +12,10 @@ 1. 用 Godot 4.7.2 打开本目录(含 `project.godot` 的文件夹) 2. 按 F5 运行(主场景 `presentation/main.tscn`) -3. **主入口:`▶ 开始冒险(三关连探:地精洞窟 → 幽暗地域 → 灰矮人矿城)`**——一条命走完三关(冒险结构实现批 2026-09-21:生命/GP/加算区跨关同账、非末关通关发大奖励〔上限提升+血回满+钥石〕、任意战斗倒下冒险终、结算屏出冒险摘要五件事;选路停点可「放弃冒险」(同失败结算,2026-09-21 用户拍板补入口));首关节点链:战→战→赏→战→战→疗→王。唯一试玩入口 = 完整冒险——单关测试直入口(L2/L3)已退役(2026-09-23 用户拍板) -4. `调试` 角标浮窗(恒开——2026-10-16 用户令 DS_DEBUG 写死,原环境变量门控退役;2026-10-04 迭代 14.5 调试整合批:原数值调整板/随机种子框/两层调试三散件收一):攻击/生命百分比加成(模拟天赋树解锁)+ 批量模拟(输出通关率/承伤期望/败北节点分布)+ 两层调试入口 +3. **主入口:`▶ 开始冒险(三关连探:地精洞窟 → 幽暗地域 → 灰矮人矿城)`**——一条命走完三关(冒险结构实现批 2026-09-21:生命/GP/加算区跨关同账、非末关的关卡完成发大奖励〔上限提升+血回满+钥石〕、任意战斗倒下冒险终、结算屏出冒险摘要五件事;选路停点可「放弃冒险」(同失败结算,2026-09-21 用户拍板补入口));首关节点链:战→战→赏→战→战→疗→王。唯一试玩入口 = 完整冒险——单关测试直入口(L2/L3)已退役(2026-09-23 用户拍板) +4. `调试` 角标浮窗(恒开——2026-10-16 用户令 DS_DEBUG 写死,原环境变量门控退役;2026-10-04 迭代 14.5 调试整合批:原数值调整板/随机种子框/两层调试三散件收一):攻击/生命百分比加成(模拟天赋树解锁)+ 批量模拟(输出关卡完成率/承伤期望/败北节点分布)+ 两层调试入口 -headless 冒烟(752 项断言〔计数随批增长,现值以最新批末闸读数为准〕,含关卡线性推进/满配通关/裸装败北/回放确定性;2026-10-02 性能报告实测 60.55 秒,报告在 `性能实测报告(已退役,git 历史可查)`): +headless 冒烟(752 项断言〔计数随批增长,现值以最新批末闸读数为准〕,含关卡线性推进/满配冒险成功/裸装败北/回放确定性;2026-10-02 性能报告实测 60.55 秒,报告在 `性能实测报告(已退役,git 历史可查)`): ``` Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://probe/smoke_all.gd @@ -35,7 +35,7 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . res://probe/ui_tune_pr 其余八场景探针(ui_click_probe 行为链 / ui_input_probe 输入合成 / ui_struct_probe 全屏结构 / ui_contrast_probe 对比度 / ui_probe·ui_tune_probe 调参面板 / t17_defer_probe 结算演播延迟链回归 / shot_probe·fx_probe·fx_shot_probe·board_shot_probe 画面与特效采样;全部由 `tools/probe_gate.sh` 与 `tools/render_gate.sh` 调度,闸清单见 `tools/run_all_gates.sh`)+ 板图校准工具 `sim/calibrate_boards.gd`(board_calibration.csv 重跑入口,--script 运行): -全冒险期望扫描(零加成三关连探批量——通关率/止步分布/败退节点;调参期难度读数一律走全冒险口径): +全冒险期望扫描(零加成三关连探批量——关卡完成率/止步分布/败退节点;调参期难度读数一律走全冒险口径): ``` Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://sim/adventure_monte_carlo.gd -- [N] [seed0] diff --git a/game/core/adventure_runner.gd b/game/core/adventure_runner.gd index a91d904e..b7c8f14f 100644 --- a/game/core/adventure_runner.gd +++ b/game/core/adventure_runner.gd @@ -7,9 +7,9 @@ class_name AdventureRunner extends RefCounted signal level_started(level_index: int, display_name: String) ## 每关开始(含冒险首关)——呈现层重取 runner()、刷新图条与层名行 -signal curio_choice_presented(payload: Dictionary) ## 专长三选一停点(非末关通关恰一次;通道白名单后候选恒专长+回血在载荷)——{level_index, candidates, heal_gained, hp_before, hp_after, keystone_gained, keystone_total, gp, aux_cleared} +signal curio_choice_presented(payload: Dictionary) ## 专长三选一停点(非末关的关卡完成恰一次;通道白名单后候选恒专长+回血在载荷)——{level_index, candidates, heal_gained, hp_before, hp_after, keystone_gained, keystone_total, gp, aux_cleared} signal curio_resolved(result: Dictionary) ## 三选一兑付完成(pick_curio/替换受理后恰一次)——{picked, value, hp_before, hp_after, level_index} -signal adventure_finished(summary: Dictionary) ## 冒险结算(completed/failed/abandoned)——summary 五件事:打穿没有/通关几关/止步第几关/钥石合计/主种子(+additive keystone_drops) +signal adventure_finished(summary: Dictionary) ## 冒险结算(completed/failed/abandoned)——summary 五件事:打穿没有/完成几关/止步第几关/钥石合计/主种子(+additive keystone_drops) # ---- 转发族(签名与 LevelRunner 同款——呈现层对接透明;S6 经 _forward_* 方法)---- signal node_entered(node: Dictionary, info: Dictionary) signal choices_presented(candidates: Array) @@ -266,7 +266,7 @@ func _resume_pending(bp_pending: Dictionary) -> void: var migrated: Array[Variant] = [] for c in (bp_pending.get("candidates", []) as Array): if c is Dictionary: - # T4——feat_id 随迁移(通关渠道候选=纯专长令牌,身份键 relic|tier|feat_id 三段全要) + # T4——feat_id 随迁移(关卡完成渠道候选=纯专长令牌,身份键 relic|tier|feat_id 三段全要) var mig := {"kind": String((c as Dictionary).get("kind", "")), "tier": String((c as Dictionary).get("tier", ""))} if String(mig["kind"]) == "relic": mig["feat_id"] = String((c as Dictionary).get("feat_id", "")) @@ -339,7 +339,7 @@ func continue_to_next_level() -> bool: # 停点空候选消化(池空=三选一环节整体跳过:候选 0 件时停点视同已处理, # 呈现层跳开选择面直接走后续推进。仅空候选合法;非空停点拒绝——零自动推进契约不破,正常 -# 消化仍只走 pick_curio/apply_node_curio 兑付。触发源=渠道白名单过滤后池空(关卡 Boss 通关 +# 消化仍只走 pick_curio/apply_node_curio 兑付。触发源=渠道白名单过滤后池空(关卡 Boss 击破=关卡完成 # 渠道只出专长,专长零配置/旧档 deck 无 relic 余库即空集)。) func skip_empty_curio() -> bool: if _curio_pending.is_empty(): @@ -390,7 +390,7 @@ func _feat_payload_keys(feat_id: String) -> Dictionary: # 三选一件兑付共享体(TP0——令牌消费、摘牌单点,含 relic 分支): # 属性件写加算区 + 件获取计数、AP 件写第四轴、GP 件走钱包、恢复件当即回血(封顶生效上限—— -# 与账本置满/通关回血同式 effective_max_hp)、relic 件入持有集(散件单体保底——效果接线面 +# 与账本置满/关卡完成回血同式 effective_max_hp)、relic 件入持有集(散件单体保底——效果接线面 # 按挂点消费,档位质变由 FeatsEngine 求值)。兑付即从 _curio_deck 摘除该令牌(选中踢池; # 未选候选从未摘牌=自动回池)。道具件不入此体——未知件返回 false 由调用方按渠道名报错。 func _apply_curio_pick(kind: String, tier: String, value: int, feat_id: String = "") -> bool: @@ -483,7 +483,7 @@ func _finish_curio_pick(picked: String, value: int, hp_before: int, tier: String _snapshot_breakpoint() -# ---- 奖励节点三选一(与通关三选一共享同池同权重同次数上限)---- +# ---- 奖励节点三选一(与关卡完成三选一共享同池同权重同次数上限)---- # 候选呈现(节点到达时调用——恰一 reward_pick scope 洗牌 + 道具件掷定 scope;本停点断点不载, # 续玩重建到选路停点后重走重抽,恢复的全局计数器保证同候选逐位复现)。 @@ -498,7 +498,7 @@ func present_node_curio(candidates: Array) -> void: _node_curio_pending = {"candidates": candidates.duplicate(true)} -# 点选兑付(节点域——无部分回血无钥石;令牌消费与牌库摘牌与通关三选一同库;relic 同权入持有集) +# 点选兑付(节点域——无部分回血无钥石;令牌消费与牌库摘牌与关卡完成三选一同库;relic 同权入持有集) func apply_node_curio(kind: String, tier: String = "", feat_id: String = "") -> bool: if kind == "feat_ticket": return _redeem_feat_ticket() # T5 拿到即开——节点停点候选替换为专长三选一(呈现层本地重绘) @@ -562,7 +562,7 @@ func node_curio_pending_state() -> Dictionary: } -# 三选一刷新(免费位 X/Y——组合根唯一调用口;无停点/无余量 false 零副作用)。通关停点重抽后重发 +# 三选一刷新(免费位 X/Y——组合根唯一调用口;无停点/无余量 false 零副作用)。关卡完成停点重抽后重发 # curio_choice_presented(呈现层重建卡片+刷新余量);节点停点由组合根读 node_curio_pending_state 重 present。 func refresh_curio() -> bool: return _refresh_curio_common(false) @@ -651,7 +651,7 @@ func _feat_ticket_consider(rg: RandomNumberGenerator) -> bool: func _redeem_feat_ticket() -> bool: _feat_ticket_sold += 1 _feat_ticket_pity = 0 - var cands: Array[Variant] = _draw_curio_candidates("level_clear") # 专长池(与通关渠道同白名单) + var cands: Array[Variant] = _draw_curio_candidates("level_clear") # 专长池(与关卡完成渠道同白名单) if cands.is_empty(): push_error("[冒险结构] 专长凭证兑付失败——专长池空集") _feat_ticket_sold -= 1 @@ -668,7 +668,7 @@ func _redeem_feat_ticket() -> bool: # Boss 钥石逐杀掉落(掉落渠道 = Boss/精英击杀;首杀/复杀两档读 meta.tres boss_keystone; # 首杀判据 = 存档 boss_first_kill 标记位〔断点未注入 = 恒首杀——模拟/冒烟零扰动;标记仍在收束 -# apply_adventure_summary 逐通关关次置位〕;末关 Boss 照常入账;明细随摘要 additive 键供结算面归因) +# apply_adventure_summary 逐关卡完成关次置位〕;末关 Boss 照常入账;明细随摘要 additive 键供结算面归因) func _boss_keystone_drop(li: int) -> void: var first := true if _save_manager != null: @@ -779,7 +779,7 @@ func _on_level_finished(payload: Dictionary) -> void: # Boss 钥石逐杀掉落(击杀掉落渠道,末关照常入账;首杀/复杀读 meta.tres boss_keystone) _boss_keystone_drop(level_index) if level_index < levels_total: - # 通关兑付(非末关恰一次;三层奖励框架):部分回血先行 → 加权洗牌掷 3 → 三选一停点 + # 关卡完成兑付(非末关恰一次;三层奖励框架):部分回血先行 → 加权洗牌掷 3 → 三选一停点 #(顺序即契约——回血按当刻账本与上限结算,选择停点零自动推进) var hp_before := int(ledger.get("hero_hp", 0)) var max_eff := effective_max_hp() # 回血封顶口径含调试浮窗 pct(同战斗内上限) @@ -791,7 +791,7 @@ func _on_level_finished(payload: Dictionary) -> void: _curio_paid_refreshes = 0 # 付费刷计数随停点清零(对齐商店进店清零) var pick_payload: Dictionary[Variant, Variant] = { "level_index": level_index, - "candidates": _draw_curio_candidates("level_clear"), # T4 渠道白名单——关底 Boss 击败=通关渠道只出专长 + "candidates": _draw_curio_candidates("level_clear"), # T4 渠道白名单——关底 Boss 击败=关卡完成渠道只出专长 "heal_gained": heal, "hp_before": hp_before, "hp_after": int(ledger.get("hero_hp", 0)), @@ -805,12 +805,12 @@ func _on_level_finished(payload: Dictionary) -> void: curio_choice_presented.emit(pick_payload) _snapshot_breakpoint() # 选择停点可中断(契约 5——续玩不重抽不静默丢失) return - # 末关通关:不发三选一与部分回血(没有下一战可受益)、Boss 钥石照常入账——冒险完成结算 + # 末关的关卡完成:不发三选一与部分回血(没有下一战可受益)、Boss 钥石照常入账——冒险完成结算 _settle("completed") func _settle(result: String) -> void: - # 冒险摘要五件事:打穿没有 / 通关几关 / 止步第几关 / 钥石入账合计 / 本局主种子 + # 冒险摘要五件事:打穿没有 / 完成几关 / 止步第几关 / 钥石入账合计 / 本局主种子 summary = { "result": result, "cleared": result == "completed", diff --git a/game/core/config_db.gd b/game/core/config_db.gd index ea4362e0..e6370402 100644 --- a/game/core/config_db.gd +++ b/game/core/config_db.gd @@ -254,7 +254,7 @@ func level_gen_params_row(level_index: int) -> Dictionary: return level_gen_params.row_by_level_index(level_index) if level_gen_params != null else {} -# 序列总关数(AdventureRunner levels_total / MetaProgression 通关累加域的取数口径) +# 序列总关数(AdventureRunner levels_total / MetaProgression 关卡完成累加域的取数口径) func level_count() -> int: return level.rows.size() if level != null else 0 diff --git a/game/core/config_db_cross_validator.gd b/game/core/config_db_cross_validator.gd index 4e7d8912..eab43084 100644 --- a/game/core/config_db_cross_validator.gd +++ b/game/core/config_db_cross_validator.gd @@ -40,7 +40,7 @@ func cross_validate(loaded: Dictionary, push_diag: Callable) -> void: if not treasure_live.has(treasure_eff): push_diag.call("error", "reward_dangling_treasure", "RewardTable %s aux 行引用无效道具 %s(retired/deferred/不存在): %s" % [row.get("reward_id"), treasure_eff, "双表校验"]) # ①c F2 投放维度覆盖校验不启用:挖格不掉道具,秘宝 - # 唯一来路=三选一共享池〔节点/通关〕;共享池为「抽到道具位再动态掷定具体道具」,维度覆盖不可 + # 唯一来路=三选一共享池〔节点/关卡完成〕;共享池为「抽到道具位再动态掷定具体道具」,维度覆盖不可 # 静态校验。 # ② SettlementTable.effect_pool_map 悬空 for eff in st_tab.effect_pool_map.keys(): diff --git a/game/core/level_runner.gd b/game/core/level_runner.gd index 8d88a30c..aec898ba 100644 --- a/game/core/level_runner.gd +++ b/game/core/level_runner.gd @@ -561,7 +561,7 @@ func _on_battle_finished(payload: Dictionary) -> void: hero_hp = maxi(1, int(payload.get("hero_hp", 0))) # despawn 前捕获值(载荷自包含) _gain_wallet(int(payload.get("gp_dropped", 0))) # 战斗完成入账(clamp ≥0——破财可把 escrow 打负,钱包入账时钳制) if String(node.get("type", "")) == "boss" or result == "defeat": - # Boss 胜利 = 关卡通关;任意战斗败北 = 关卡失败(漂移⑦清偿——每战结果上报冒险结构, + # Boss 胜利 = 关卡完成;任意战斗败北 = 关卡失败(漂移⑦清偿——每战结果上报冒险结构, # 失败结算归 AdventureRunner;本类只发 level_finished) level_result = "victory" if result == "victory" else "defeat" var hp_left := hero_hp if result == "victory" else 0 @@ -742,7 +742,7 @@ func _gain_wallet(amount: int) -> void: wallet_changed.emit("gain", gp, {"amount": amount}) -# 冒险收束清零(通关/倒下/放弃——局内货币生命周期终点,不入存档不入摘要;public——冒险模式由 +# 冒险收束清零(冒险成功/倒下/放弃——局内货币生命周期终点,不入存档不入摘要;public——冒险模式由 # AdventureRunner._settle 在冒险收束时调用,单关模式 = 关卡收束即冒险收束) func close_wallet() -> void: gp = 0 @@ -772,7 +772,7 @@ func _emit_wallet_event(event: String, gp_now: int, extra: Dictionary) -> void: wallet_changed.emit(event, gp_now, extra) -# 购血(商店 max_hp 商品——当前生命 +Δ 并封顶新上限,与账本置满/通关回血同式) +# 购血(商店 max_hp 商品——当前生命 +Δ 并封顶新上限,与账本置满/关卡完成回血同式) func _gain_max_hp_flat(flat: int) -> void: hero_hp = mini(hero_hp + flat, effective_max_hp()) diff --git a/game/core/meta_progression.gd b/game/core/meta_progression.gd index 46c4b6b5..25749848 100644 --- a/game/core/meta_progression.gd +++ b/game/core/meta_progression.gd @@ -271,7 +271,7 @@ func forge_shop_status() -> Array: # (keystone_drops 副本随摘要入 recent_summaries)。 # 钥石为 Boss 逐杀掉落——掉落金额已在冒险内逐杀入账(summary.keystone_total # 含全部掉落;首杀/复杀判定在 AdventureRunner._boss_keystone_drop,首杀标记在下方 -# apply_adventure_summary 逐通关关次置位)。本函数只做标记+入账+归档。 +# apply_adventure_summary 逐关卡完成关次置位)。本函数只做标记+入账+归档。 func settle_adventure(summary: Dictionary) -> Dictionary: # 首次冒险布尔位置位(关卡节点图生成 v0.4——完成/失败/放弃三结局同经本收束挂点,写入只在收束) save.mark_first_adventure_done() diff --git a/game/core/save_manager.gd b/game/core/save_manager.gd index e5475a88..ed4a56fa 100644 --- a/game/core/save_manager.gd +++ b/game/core/save_manager.gd @@ -7,7 +7,7 @@ class_name SaveManagerCore extends Node -const SAVE_FORMAT_VERSION := 7 # registry schema_version:v7=锻造工坊域(meta 新域 forge_routes〔六路线等级 levels+直购解锁清单 unlocked+当前武器/甲选中标记 weapon/armor;无特效域〕,旧档缺键由 _normalize 按默认补齐=初始持有态〔sword/light 在档余四锁、选中=初始路线〕,v6→v7 空迁移=缺键补齐模式);v6=生涯终身计数域(meta 两新域 adventure_total〔冒险总局数,开局即计含放弃与失败〕/adventure_cleared〔通关局数,三关全通才计 1——判定字段 summary.cleared〕,旧档缺键由 _normalize 按默认补零,收束自增唯一入账=apply_adventure_summary);v5=天赋树域(meta 三新域 tree_nodes〔node_id→已购等级〕/fork_sides〔fork_group→a|b〕/migration_note〔三体系迁移补偿注记〕);v4=同调位域(meta 三新域 boss_kill_count/attunement_equipped/attune_refresh_level——旧档缺键 = 合法空态);v3=断点附随件扩列+摘要 keystone_drops;v2=断点域出生;v1=首版;高版本拒读 owner=存档序列化 +const SAVE_FORMAT_VERSION := 7 # registry schema_version:v7=锻造工坊域(meta 新域 forge_routes〔六路线等级 levels+直购解锁清单 unlocked+当前武器/甲选中标记 weapon/armor;无特效域〕,旧档缺键由 _normalize 按默认补齐=初始持有态〔sword/light 在档余四锁、选中=初始路线〕,v6→v7 空迁移=缺键补齐模式);v6=生涯终身计数域(meta 两新域 adventure_total〔冒险总局数,开局即计含放弃与失败〕/adventure_cleared〔冒险成功局数,三关全通才计 1——判定字段 summary.cleared〕,旧档缺键由 _normalize 按默认补零,收束自增唯一入账=apply_adventure_summary);v5=天赋树域(meta 三新域 tree_nodes〔node_id→已购等级〕/fork_sides〔fork_group→a|b〕/migration_note〔三体系迁移补偿注记〕);v4=同调位域(meta 三新域 boss_kill_count/attunement_equipped/attune_refresh_level——旧档缺键 = 合法空态);v3=断点附随件扩列+摘要 keystone_drops;v2=断点域出生;v1=首版;高版本拒读 owner=存档序列化 const SUMMARY_CAP := 10 # 最近冒险摘要保留条数(最新在前) const TREE_STRUCT_VERSION := 2 # 树结构版本标记(12 节点 v0.8 结构;加载检测缺失 @@ -154,7 +154,7 @@ func delete_slot(slot: int) -> bool: return true -# 摘要三项按槽窥视读器(sv7/sv8,契约 5/9):钥石余额/通关局数/冒险总局数。 +# 摘要三项按槽窥视读器(sv7/sv8,契约 5/9):钥石余额/冒险成功局数/冒险总局数。 # 只读零副作用:不激活、不写盘、不触发 _corrupt_fallback 改名(.corrupt.bak 只在正式进档路径产生)。 # 返回 {"readable", "has_file", "keystone", "cleared", "total"}——readable=true=可读槽(空槽=零值合法态, # .tmp 残留按空槽——主文件不在即空);readable=false=不可读槽(损坏/高版本/缺版本字段/打开失败, @@ -285,7 +285,7 @@ func _default_data() -> Dictionary[String, Variant]: "recent_summaries": [], "first_adventure_done": false, "adventure_total": 0, # 生涯终身计数·冒险总局数(开局即计含放弃与失败,收束唯一入账) - "adventure_cleared": 0, # 生涯终身计数·通关局数(三关全通才计 1——判定字段 summary.cleared) + "adventure_cleared": 0, # 生涯终身计数·冒险成功局数(三关全通才计 1——判定字段 summary.cleared) "vision_used": 0, # 生涯终身计数·真视类工具累计使用次数(信标网络解锁行为条件; # 受理成功唯一计数点=battle 层经冒险层聚合、收束入账;缺键补零不升版本) "forge_routes": { # 锻造工坊域(六路线等级+直购解锁清单+当前选中标记;无特效域) @@ -417,7 +417,7 @@ func boss_first_kill_marked(level_index: int) -> bool: # ---- 同调位账本域(里程碑谓词表计数源 + 装配关系 + Y 升级态)---- -# Boss 击杀总数(含重复——底稿裁决 4 计数源;收束入账 = apply_adventure_summary 逐通关关次 +1, +# Boss 击杀总数(含重复——底稿裁决 4 计数源;收束入账 = apply_adventure_summary 逐关卡完成关次 +1, # Boss 恒唯一终点故 levels_cleared 即本次冒险 Boss 击杀数) func boss_kill_count() -> int: return int(_data["meta"].get("boss_kill_count", 0)) @@ -431,8 +431,8 @@ func adventure_total() -> int: return int(_data["meta"].get("adventure_total", 0)) -# 通关局数(口径=三关全通才计 1——判定字段 summary.cleared,adventure_runner「completed」 -# 唯一出口=末关通关) +# 冒险成功局数(口径=三关全通才计 1——判定字段 summary.cleared,adventure_runner「completed」 +# 唯一出口=末关的关卡完成) func adventure_cleared() -> int: return int(_data["meta"].get("adventure_cleared", 0)) @@ -558,7 +558,7 @@ func set_attune_refresh_level(n: int) -> void: _data["meta"]["attune_refresh_level"] = maxi(0, n) -# 同调位计数源组装(Attunement 服务取数口——clear_count = 逐关通关次数合计〔含重复关,底稿 §2.1 口径〕; +# 同调位计数源组装(Attunement 服务取数口——clear_count = 逐关完成次数合计〔含重复关,底稿 §2.1 口径〕; # clear_count(level_index) 逐关访问器零改动复用) func recent_summaries() -> Array: return _data["meta"]["recent_summaries"].duplicate(true) # 值拷贝出户(本类契约「禁碰内部结构」——消费方直改不得渗入存档内存态) @@ -566,10 +566,10 @@ func recent_summaries() -> Array: # 域更新原语(正式冒险收束唯一入账口——组合根经本函数入账,禁直改内部结构): # 钥石入账(summary.keystone_total——逐杀掉落已在冒险内计入,boss_drops 参数为 -# 摘要归档副本不重复入账)+ 逐通关关次 clear_count +1 与 Boss 首杀标记 + Boss 击杀总数累计 +# 摘要归档副本不重复入账)+ 逐关卡完成关次 clear_count +1 与 Boss 首杀标记 + Boss 击杀总数累计 # (同调位里程碑计数源)+ 摘要头部插入(cap 10,最新在前,元素附 # keystone_drops 副本——复盘可归因)+ 生涯终身计数自增(总局数开局即计: -# 三结局同经本口恰计一次;通关局数按 summary.cleared 判定三关全通才计 1。终身计数写入 +# 三结局同经本口恰计一次;冒险成功局数按 summary.cleared 判定三关全通才计 1。终身计数写入 # 单口=本函数,禁第二写入点)。 func apply_adventure_summary(summary: Dictionary, boss_drops: Array = []) -> void: _data["meta"]["adventure_total"] = adventure_total() + 1 diff --git a/game/data/schemas/adventure_table.gd b/game/data/schemas/adventure_table.gd index a1f635a5..ef87d79b 100644 --- a/game/data/schemas/adventure_table.gd +++ b/game/data/schemas/adventure_table.gd @@ -1,7 +1,7 @@ ## VERTICAL SLICE - NOT FOR PRODUCTION ## 冒险大奖励表(奇物三选一令牌池)schema:档位配额/件值/已拿上限的类型化读取(单行全局;垂直切片验证:三关连探一条命走完)。 ## kind/tier 词表封闭——断点附随件与牌库剔除态依赖,扩件走本表+registry 修订,禁调用侧私扩。 -## 档位配额总量是结构锚(validate 硬断言):改投放总量=重裁非调参;全部 knob provisional,上调须重扫通关率带。 +## 档位配额总量是结构锚(validate 硬断言):改投放总量=重裁非调参;全部 knob provisional,上调须重扫关卡完成率带。 class_name AdventureTable extends Resource @@ -36,7 +36,7 @@ const TIER_LEGENDARY := "legendary" ## validate() 硬断言;此后改总量=重裁非调参)。 const TIER_QUOTAS := {"common": 70, "excellent": 25, "rare": 7, "legendary": 0} -# —— 通关部分回血(固定型,非末关通关兑付)—— +# —— 关卡完成部分回血(固定型,非末关兑付)—— @export var clear_heal_pct: int = 20 # [0,100] knob——回复生效上限的百分比,封顶上限不回满 # —— 三选一候选数—— diff --git a/game/data/schemas/treasure_item_table.gd b/game/data/schemas/treasure_item_table.gd index 7dd35bd3..20acd403 100644 --- a/game/data/schemas/treasure_item_table.gd +++ b/game/data/schemas/treasure_item_table.gd @@ -9,8 +9,8 @@ extends Resource @export var rows: Array[Variant] = [] # Array[Dictionary] 键 item_id # 计数键封闭枚举(就地内联于本表,无独立谓词表; -# 通关口径=C6(通关=打通整局冒险),键名 adventure_cleared -# (生涯通关局数,save_manager 生涯计数域在役);扩 vision_used(真视类工具 +# 解锁口径=C6(冒险成功=打通整局冒险),键名 adventure_cleared +# (生涯冒险成功局数,save_manager 生涯计数域在役);扩 vision_used(真视类工具 # 累计使用——信标网络行为条件计数;use_treasure 受理成功处累计、冒险收束导出入档); # 键域以本枚举为准) const UNLOCK_COUNTER_KEYS := ["adventure_cleared", "boss_kill_count", "vision_used"] diff --git a/game/data/tables/adventure.tres b/game/data/tables/adventure.tres index 59dc7beb..17a5c641 100644 --- a/game/data/tables/adventure.tres +++ b/game/data/tables/adventure.tres @@ -48,6 +48,6 @@ feat_ticket_pity_step = 5 ; 洗牌改令牌 Fisher-Yates(不放回抽 3,消费 reward_pick 封闭流)。 ; 迭代 11 第②批 商店共享池注记:货架 = 令牌级抽签(同 kind 去重每 kind 至多一卡、价格公式 tier-blind ; ceil(基价×b^(关序−1)×A^visit) 维持批②裁定、购买消费在架令牌本体)。 -; 末关通关不发三选一与回血(奖励只朝下一战生效)。 +; 末关的关卡完成不发三选一与回血(奖励只朝下一战生效)。 ; 全部 provisional-pending-曲线调参批(值锚与上调约束归 难度曲线与Boss;档位配额结构锚 70/25/7/0—— ; schema TIER_QUOTAS,validate 硬断言,改总量须重裁)。 diff --git a/game/data/tables/enemy.tres b/game/data/tables/enemy.tres index e8c5c1de..5279f5ff 100644 --- a/game/data/tables/enemy.tres +++ b/game/data/tables/enemy.tres @@ -765,7 +765,7 @@ rows = [{ ; 敌方攻击区间批(2026-09-14 用户拍板②第二步——"上限掺运气"敌方侧:atk 上阶/下阶,中点恒等行值; ; roll 时机 = 遭遇骰同流〔encounter〕spawn 期整战持久,每拍抖动否决〔数字可读性锚〕;B2 零随机纪律保持 -; ——收 override 即确定值。宽度 ±3 provisional 归 C3 测量迭代;验收 = 完美策略档 0 加成通关 ≤40%。 +; ——收 override 即确定值。宽度 ±3 provisional 归 C3 测量迭代;验收 = 完美策略档 0 加成关卡完成 ≤40%。 ; 护甲等级掷点批(2026-09-16 用户拍板):armor_class 字段入列(缺省 0 向后兼容)——防守方掷点判定阈值基数, ; 与 armor_type(克制属性轴)两概念严格分离、不做映射。首关六行暂定 0(正式行值归怪物/敌人系统设定批—— @@ -868,7 +868,7 @@ rows = [{ ; d6 巢群/d7 小队/d9 石君王】。清单:L2 d0 45→50 · d1 18→22 · d4 20→24 · d5 68→88+atk3 · d6 18→22 · ; d7 18→22 · d9 80→112+atk3;L3 d0 50→62+atk3 · d1 25→30+atk3 · d4 20→26+atk3 · d5 76→98+atk3 · ; d6 20→26+atk3 · d7 20→26+atk3 · d9 92→140+atk3。 -; 目标对齿(熟练玩家):S0 零成长 L2 达 boss ~20%/通 ~0%、L3 ~0;S1(≈5 次 L1 通关锻造后,hero 快照 +; 目标对齿(熟练玩家):S0 零成长 L2 达 boss ~20%/通 ~0%、L3 ~0;S1(≈5 次 L1 关卡完成锻造后,hero 快照 ; 攻4/血26/甲11)L2 达 ~70%/通 ~50%;S2(攻6/血32/甲12)L3 通 ~55%。验证 = hero.tres 阶段快照 MC ; (设计文档 §6,快照后恢复基线)。验证出带微调旋钮序:L2 d1/d6/d7 血 22→20 → d4 24→22 → d9 112→108。 ; provisional 未提交。 diff --git a/game/data/tables/meta.tres b/game/data/tables/meta.tres index dda26b7d..33d05bf1 100644 --- a/game/data/tables/meta.tres +++ b/game/data/tables/meta.tres @@ -52,7 +52,7 @@ attune_refresh_upgrade = [{ ; ; 数值设计批·关卡成长×永久成长对齿(2026-09-22——设计权威 qa-data/数值设计_关卡成长×永久成长_v1.md, ; game-balancer 工作流,用户三拍板 1A/2A/3A):forge base_price 10→20(三行同,ratio 150% 不变, -; 效果档 血+3/攻+1/甲+1 不变)——S1 一档(攻+2/血+6/甲+1 ≈ 120 GP)对齐「≈5 次 L1 通关开门」节奏 +; 效果档 血+3/攻+1/甲+1 不变)——S1 一档(攻+2/血+6/甲+1 ≈ 120 GP)对齐「≈5 次 L1 关卡完成开门」节奏 ; (实测 L1 通关局收入 ≈29-35 GP)。换算率表维持全 0(墙/钥匙闭环不依赖该轴,留扩展)。 ; 配套怪表改动见 enemy.tres 同日批注。provisional 未提交。 ; diff --git a/game/data/tables/treasure_items.tres b/game/data/tables/treasure_items.tres index 057813d0..78122b08 100644 --- a/game/data/tables/treasure_items.tres +++ b/game/data/tables/treasure_items.tres @@ -8,7 +8,7 @@ script = ExtResource("1") ; 旧 12 行删除——venom_edge/seal_burst 已随迭代 20 专长批迁出删除,本批实删 12 行)。三档=普通 7/优秀 3/稀有 2 ; (传说留空=空集合法,迭代 20 追认③先例)。解锁混合制(契约 8 逐件分配锁定表,2026-10-11 用户裁 C1): ; 钥石购买件 unlock_keystone_cost(provisional 占位);条件件 unlock_requires 谓词行——计数键 -; adventure_cleared=生涯通关局数(C6 裁:通关=打通整局冒险)/boss_kill_count=生涯 Boss 击杀/vision_used= +; adventure_cleared=生涯冒险成功局数(C6 裁:打通整局冒险)/boss_kill_count=生涯 Boss 击杀/vision_used= ; 真视类工具累计使用(本批新增计数域)。全部数值 provisional 归调参批(契约 7)。 ; 常时参数面件(无订阅行——效果=开局/装板参数注入,非事件订阅):阔视野带/储备罐/远程镐/信标网络/刷新练习/ ; 刷新执照六件 effect_kinds 挂参数 kind,由注入面按装配集 kind 分发读取(_attune_refresh_x_total 先例)。 diff --git a/game/presentation/curio_interact_controller.gd b/game/presentation/curio_interact_controller.gd index 5fa0e55a..7a15dd3a 100644 --- a/game/presentation/curio_interact_controller.gd +++ b/game/presentation/curio_interact_controller.gd @@ -25,7 +25,7 @@ var _fatal_screen: Callable var _gp_summary: Callable # () → 战斗总结 GP 行文案(组合根 lambda——_last_gain_amount 取数面在根) var _pending_curio := {} # 三选一停点载荷暂存(战斗总结结算确认后开三选一面;续玩停点复用) -var _curio_context := "level_clear" # 三选一面上下文(level_clear=通关停点→推进下一关 / reward_node=奖励节点→回图选路) +var _curio_context := "level_clear" # 三选一面上下文(level_clear=关卡完成停点→推进下一关 / reward_node=奖励节点→回图选路) func _init(ctx: CurioFlowContext) -> void: @@ -82,7 +82,7 @@ func _skip_empty_stop() -> bool: return true -# 三选一停点(非末关通关恰一次):Boss 胜利先经战斗总结结算面(settlement-summary v1.1——钥石 +# 三选一停点(非末关的关卡完成恰一次):Boss 胜利先经战斗总结结算面(settlement-summary v1.1——钥石 # 增量行在其上),确认后进三选一面(level-clear.md v2);续玩停点恢复同入口(零自动推进契约) func on_presented(payload: Dictionary) -> void: if String(payload.get("context", "")) == "feat_ticket": @@ -111,7 +111,7 @@ func on_presented(payload: Dictionary) -> void: _refresh_presentations.call() -# 奖励节点三选一(与通关三选一共享同池同权重同上限;CurioPickOverlay 共用面)。 +# 奖励节点三选一(与关卡完成三选一共享同池同权重同上限;CurioPickOverlay 共用面)。 # 无替换子交互(同调装配不可变,见类头)。 func present_node_curio() -> void: var adventure = _adventure_get.call() @@ -177,7 +177,7 @@ func _curio_card_texts(candidates: Array) -> Array: # 新件写行即有名有姓) # 三选一刷新(X/Y 双源 + 对齐商店 MC-1——免费位用尽转 GP 付费档: -# 同 shop_refresh_cost_base/curve 旋钮、同冒险钱包 runner.gp;通关停点经重发 curio_choice_presented 直落 +# 同 shop_refresh_cost_base/curve 旋钮、同冒险钱包 runner.gp;关卡完成停点经重发 curio_choice_presented 直落 # 选择面,节点停点在此读在途态重 present——零自动推进契约不破,停点仍在途) func on_refresh() -> void: var adventure = _adventure_get.call() @@ -228,7 +228,7 @@ func on_resolved(result: Dictionary) -> void: _refresh_presentations.call() -# 继续钮:收三选一面 → 上下文分派(通关停点=推进下一关 / 奖励节点=兑付确认回图选路——零自动推进) +# 继续钮:收三选一面 → 上下文分派(关卡完成停点=推进下一关 / 奖励节点=兑付确认回图选路——零自动推进) func on_continue() -> void: _close_modal.call(curio_overlay) curio_overlay.close_pick() diff --git a/game/presentation/main_adventure_flow.gd b/game/presentation/main_adventure_flow.gd index e6aa68b9..70dffc74 100644 --- a/game/presentation/main_adventure_flow.gd +++ b/game/presentation/main_adventure_flow.gd @@ -51,7 +51,7 @@ static func _on_runner_node(root: Variant, node: Dictionary, info: Dictionary) - root._show_board_fx_for_node(t) root.log_view.append_bb(root.Narrator.node_banner(root.run_scope.runner, node, t)) elif t == "reward": - # 奖励节点三选一(与通关三选一共享同池同权重同上限;CurioPickOverlay 共用面)。 + # 奖励节点三选一(与关卡完成三选一共享同池同权重同上限;CurioPickOverlay 共用面)。 # 呈现编排归 curio_interact_controller.present_node_curio。 root._bonus.present_node_curio() root.log_view.append_bb(root.Narrator.reward_line()) diff --git a/game/presentation/tune_sim_controller.gd b/game/presentation/tune_sim_controller.gd index 051a1f53..4f681dab 100644 --- a/game/presentation/tune_sim_controller.gd +++ b/game/presentation/tune_sim_controller.gd @@ -35,7 +35,7 @@ func is_running() -> bool: func run(n: int) -> void: _running = true - # 共享日志会话(模拟运行与真人试玩同日志合规——操作/轮次/战斗/通关全量 JSONL; + # 共享日志会话(模拟运行与真人试玩同日志合规——操作/轮次/战斗/关卡完成全量 JSONL; # 一文件多局,run 行携带种子切分局次) var logger = PlaytestLogger.new() logger.ap_per_round = int(db.action_economy.ap_per_round) diff --git a/game/presentation/views/curio_pick_overlay.gd b/game/presentation/views/curio_pick_overlay.gd index 13dd1c91..46e2eb67 100644 --- a/game/presentation/views/curio_pick_overlay.gd +++ b/game/presentation/views/curio_pick_overlay.gd @@ -1,5 +1,5 @@ ## VERTICAL SLICE - NOT FOR PRODUCTION -## 提升三选一覆盖层(模态):通关停点的三卡点选→确认→兑付反馈两态呈现。 +## 提升三选一覆盖层(模态):关卡完成停点的三卡点选→确认→兑付反馈两态呈现。 ## 文案拼装归 Narrator 经组合根喂入——本类零文案装配。 class_name CurioPickOverlay extends Control diff --git a/game/sim/adventure_monte_carlo.gd b/game/sim/adventure_monte_carlo.gd index 5c02fb9d..718a2e9c 100644 --- a/game/sim/adventure_monte_carlo.gd +++ b/game/sim/adventure_monte_carlo.gd @@ -6,7 +6,7 @@ # 刷新/行进序列/逐战上限序列——后续统计分析的取数面); # ② 全量操作日志 = playtest_logger 共享会话 JSONL(与真人试玩同合规口径,每策略一批一文件, # run 行携带种子/策略切分局次,落 user://logs/)。 -# 本工具只采集与落盘数据,不做统计判读(通关率/败因分布归分析会话)。 +# 本工具只采集与落盘数据,不做统计判读(关卡完成率/败因分布归分析会话)。 # 运行:Godot_console.exe --headless --path . --script res://sim/adventure_monte_carlo.gd -- [N] [seed0] [normal|perfect|both] [route min|max] extends SceneTree diff --git a/game/sim/auto_player.gd b/game/sim/auto_player.gd index 37f092a0..a2d3b5b6 100644 --- a/game/sim/auto_player.gd +++ b/game/sim/auto_player.gd @@ -33,7 +33,7 @@ static func choose_dig(minesweeper) -> Dictionary: # 进阶级 = 联动定式(1-1 / 1-2 / 1-2-1 / 1-2-2-1 / 子集缩减)与概率分析——本切片归完美档 subset 推理承载, # 不入普通画像(新手不可靠掌握)。本档语义 = 只做新手级推理 + 无处可推时按既有口径盲挖边界格(新手冲动)+ # 不主动刷新(新手无刷新策略意识)。测量定位:教会基础规则后的真实玩家下限近似 -# (乱点/最近格口径测的是无认知玩家下限,对通关率带判读失真,不作普通画像)。 +# (乱点/最近格口径测的是无认知玩家下限,对关卡完成率带判读失真,不作普通画像)。 # 普通画像单步决策入口(每动作一查——挖掘揭示新数字后重推理):move/dig/seal/stop 四值(无 refresh)。 static func novice_action(minesweeper) -> Dictionary: diff --git a/game/sim/level_autoplay.gd b/game/sim/level_autoplay.gd index a719f0d1..ff3e8cf6 100644 --- a/game/sim/level_autoplay.gd +++ b/game/sim/level_autoplay.gd @@ -1,16 +1,16 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# 日志合规:任何模拟运行与真人试玩同日志——操作记录 / 轮次状态 / 战斗结束 / 通关结束 全量 JSONL。 +# 日志合规:任何模拟运行与真人试玩同日志——操作记录 / 轮次状态 / 战斗结束 / 关卡完成 全量 JSONL。 # logger=null 时自建会话(每局一文件),批量调用方传共享 logger(log_run 局次标记切分)。 -# 关卡自动通关策略(理性玩家近似)——呈现层数值调整板的批量模拟与 headless 扫描 +# 关卡自动完成策略(理性玩家近似)——呈现层数值调整板的批量模拟与 headless 扫描 # 共用同一实现,保证"面板模拟读数"与"扫描表读数"同口径。策略与 smoke_all 战斗自动玩家同族: # 挖最近可挖格 / 无可挖停手 / 奖励恢复点立即确认。 # run_level = 机制夹具/单战锚点专用(smoke_all 机制断言、rhythm/defense/damage 单战扫描)—— -# 通关率/难度类测量禁用本入口(满血零上下文进关,与真实冒险条件通关率脱节),一律走 run_adventure。 +# 关卡完成率/难度类测量禁用本入口(满血零上下文进关,与真实冒险条件关卡完成率脱节),一律走 run_adventure。 # 策略档 policy:"normal"(默认)/ "perfect"(零盲挖/全封印/卡死刷新——上界测量仪,求解器与 # 动作语义见 auto_player.gd 完美策略档节)。 # 选路驱动(零自动推进):兑付确认/战斗胜利后 runner 进选路态,驱动循环按 route 策略显式 # pick_next_node;route = "min"/"max"(候选节点句柄最小/最大——确定性路径轴,零随机流自开;默认 "min")。 -# run_adventure 三关连探驱动(AdventureRunner——主种子恰一次、通关兑付停点确认、adventure_finished +# run_adventure 三关连探驱动(AdventureRunner——主种子恰一次、关卡完成兑付停点确认、adventure_finished # 置 result/summary;外层每关重取 runner 实例经 _drive_level 复用单关驱动)。 # 大奖励停点 = 三选一驱动(候选取首件/替换放弃新件)。 # 普通档 v3 = 完美策略 + 受控失误注入(失误流走独立策略 RNG——种子派生自局种子,逐局确定性/ @@ -303,7 +303,7 @@ static func _pick_token(candidates: Array, feat_mode: String = "off") -> Diction return best -# 三选一兑付完成 → 上下文分派(通关停点=推进下一关 / 奖励节点=回图选路) +# 三选一兑付完成 → 上下文分派(关卡完成停点=推进下一关 / 奖励节点=回图选路) static func _on_adventure_curio_resolved(result: Dictionary, st: Dictionary, adr) -> void: st.reward_events.append({"curio_resolved": result.duplicate(true)}) if String(result.get("context", "")) == "reward_node": diff --git a/game/sim/verifier_batch.gd b/game/sim/verifier_batch.gd index 0fb1cf35..39165bd3 100644 --- a/game/sim/verifier_batch.gd +++ b/game/sim/verifier_batch.gd @@ -2,16 +2,16 @@ # 判定端 tools/balance_verifier.py 的数据源,本文件零判定逻辑 # 两段一次采集,stdout 以「VJSON 」前缀行出机器读 JSON(其余行为人读进度/摘要): # adventure 段 全冒险连探基线(run_adventure 零永久强化)× 双画像 × na——止步分布、败退节点 -# (摘要 defeat 明细 + 末场战斗敌方名)与逐关条件通关率派生源;inject 档行带 +# (摘要 defeat 明细 + 末场战斗敌方名)与逐关条件关卡完成率派生源;inject 档行带 # inject_tag/override(flat 三键) # campaign 段 营地循环战役 × 双画像 × k 局——SaveManager 隔离档 + MetaProgression 真实账本: # 逐局 hero_override() 注入 → 冒险 → settle_adventure 入账 → 花费策略买锻造, -# 回答「累计几次通关冒险后下一关可过」(元进度换算率标定的模拟读数源) +# 回答「累计几次冒险成功后下一关可过」(元进度换算率标定的模拟读数源) # 运行:Godot_console.exe --headless --path . --script res://sim/verifier_batch.gd -- [k=v ...] # na=40(基线冒险局数) k=40(战役局数) seed0=8000 # only=adventure,campaign(缺省全段) spend=hp_first|atk_first|armor_first(锻造花费优先序) # inject=max_hp:3,atk:1(冒险段 flat 注入档——三键 {max_hp, atk, armor_class},缺省全零白板; -# 换算率标定用:每档与白板同种子流配对,逐关条件通关率差 = 该档的带平移量实测) +# 换算率标定用:每档与白板同种子流配对,逐关条件关卡完成率差 = 该档的带平移量实测) # 种子纪律:unique 逐局独立(掷点测量修复批 A 案——seed0 + 全局游标,每掷点恰消费一次)。 # 同 seed0 跨档复用 = 配对读数(同序种子流——分析侧按种子配对消方差)。 # 日志合规:全段共享 playtest_logger 会话(与真人试玩同日志),分析工具可直接消费。 @@ -108,7 +108,7 @@ func _emit(row: Dictionary) -> void: print("VJSON " + JSON.stringify(row)) -# ---- adventure 段:全冒险连探基线(零永久强化——止步分布/败退节点归因/逐关条件通关率派生源); +# ---- adventure 段:全冒险连探基线(零永久强化——止步分布/败退节点归因/逐关条件关卡完成率派生源); # inject 档 = 同种子流配对的 OFAT 边际读数(行带 inject_tag/override flat 三键) ---- func _seg_adventure(db, autoplay, logger, opt: Dictionary, counts: Dictionary) -> void: diff --git a/game/tests/README.md b/game/tests/README.md index 10c6e4b7..11d14a72 100644 --- a/game/tests/README.md +++ b/game/tests/README.md @@ -150,7 +150,7 @@ timeout 120s godot --headless --script tests/run_all.gd `tests/static_scan.sh` 头注**——迭代 32 两卡是代码实现批,按流水线红线禁写 `design/`,故这两段未进架构文档。 新违规案例必须**先补扫描规则再修码**。 -S11 代码注释禁用词:扫描 game/ 全域 .gd/.tres/.md/.json/.sh 的注释面;禁词全部由 `design/gdd/术语表.md`「退役词对照」第一列解析供给(脚本内不内联任何词面——单一事实源);解析结果再按「巢穴」「旗」「flag_*」三条整行排除,另设同形异义豁免「去重闸」(封印重判去重的机制判别器,与某闸档退役词后二字同形——行内含「去重闸」整行跳过);三层豁免(闸门自指/显式留档 4 处/非注释面天然不取);两道自检(扫描面文件数非空+词表解析非空)。 +S11 代码注释禁用词:扫描 game/ 全域 .gd/.tres/.md/.json/.sh 的注释面;禁词全部由 `design/gdd/术语表.md`「退役词对照」第一列解析供给(脚本内不内联任何词面——单一事实源);解析结果再按「巢穴」「旗」「flag_*」三条整行排除,另设同形异义豁免「去重闸」(封印重判去重的机制判别器,与某闸档退役词后二字同形——行内含「去重闸」整行跳过);三层豁免(闸门自指/显式留档 20 处〔契约原名引述与带日期历史读数注释,清单见 `tests/static_scan.sh` 头注〕/非注释面天然不取);两道自检(扫描面文件数非空+词表解析非空)。 S12 效果引擎无状态化旧件零残留:扫描 game/ 全域 `.gd` 与 `game/data/tables/*.tres`,禁已删符号(`counters_export`/`counters_seed`/`_reset_tree_limited_counters` 等)与带引号的旧计数器 id 字面(引号锚定,不误伤 `adv_`/`round_` 前缀新名);扫描面文件数为零即判红。 diff --git a/game/tests/static_scan.sh b/game/tests/static_scan.sh index 609c6ab7..76c5ce99 100644 --- a/game/tests/static_scan.sh +++ b/game/tests/static_scan.sh @@ -127,9 +127,13 @@ fi # 在册断言标签成片误红;代价=该行同时出现的真闸档用词也不报,靠文档域 08 闸兜住) # 扫描面:game/ 全域 .gd/.tres/.md/.json/.sh(.txt 不收=第三方许可证非本仓库文本) # 注释文本提取:.gd/.sh 取 # 后文本;.tres 取 ; 后文本;.md 取整行;.json 无注释语法(保留扩展名但不产生注释段) -# 三层豁免依序:①闸门自指(行内含检查/禁令形态即跳过)②显式留档豁免单 7 处 ③非注释面天然不取 +# 三层豁免依序:①闸门自指(行内含检查/禁令形态即跳过)②显式留档豁免单 20 处 ③非注释面天然不取 # 豁免单新增三处(2026-10-26 令牌配额口径清扫批 B4b 用户裁定保留):adventure_table.gd:26 档名映射对照注 # +adventure_table.gd:93 与 curio_deck.gd:130 四口径契约④原名引述——合法载体非残留,改写即断链 +# 豁免单再增 13 处(2026-10-26 口径换代批用户裁「带日期历史读数注释保留原文」): +# hero.tres:21/:36、enemy.tres:751/:891、action_economy.tres:15/:16/:26/:27、status_effects.tres:91、 +# meta.tres:48/:56/:62(.tres 十二处历史读数/带日期批记录)+level_autoplay.gd:560(完美档 41% 历史实证)—— +# 历史读数原文锚定当时实测口径,改写即失真;现行口径描述不豁免(已随批换代) if [ -d game/core ]; then S11_TABLE="design/gdd/术语表.md" @@ -184,6 +188,7 @@ else if(FILENAME~"adventure_table"&&FNR==26)next if(FILENAME~"adventure_table"&&FNR==93)next if(FILENAME~"curio_deck"&&FNR==130)next + if(FILENAME~"level_autoplay"&&FNR==560)next print FILENAME":"FNR":"words[i] next } @@ -201,6 +206,18 @@ else if($0~/contains\(|find\(|grep|has_char\(|禁「|禁『|零「|零『/)next if(index(cmt,"去重闸")>0)next if(FILENAME~"enemy.tres"&&FNR==653)next + if(FILENAME~"hero.tres"&&FNR==21)next + if(FILENAME~"hero.tres"&&FNR==36)next + if(FILENAME~"enemy.tres"&&FNR==751)next + if(FILENAME~"enemy.tres"&&FNR==891)next + if(FILENAME~"action_economy.tres"&&FNR==15)next + if(FILENAME~"action_economy.tres"&&FNR==16)next + if(FILENAME~"action_economy.tres"&&FNR==26)next + if(FILENAME~"action_economy.tres"&&FNR==27)next + if(FILENAME~"status_effects.tres"&&FNR==91)next + if(FILENAME~"meta.tres"&&FNR==48)next + if(FILENAME~"meta.tres"&&FNR==56)next + if(FILENAME~"meta.tres"&&FNR==62)next print FILENAME":"FNR":"words[i] next } diff --git a/体验验证清单.md b/体验验证清单.md index 9d86e54b..1604291d 100644 --- a/体验验证清单.md +++ b/体验验证清单.md @@ -104,7 +104,7 @@ **2026-10-01 数值修复批后试玩注记**(master 4b4a011 起的正式标定局):本批已落 hero 血池 20→26 / 直伤雷三行 4/5/5→6/8/8 / L1 系敌 atk 2→1(轨迹与读数见 numfix 报告(已退役,git 历史可查))。试玩时对号新增两点: 1. **踩雷疼痛感**(本批主刀):「踩很多雷还是轻松活」应是过去式——单雷 6-8 直伤、两三连雷应明显肉疼;若仍无痛感=回调信号,记一句话即可; -2. **整体难度印象**:用户 2026-10-01 已阶段性验收「令人稍微满意」——本批试玩读数作正式标定(真人通关率+k 系数),若体感偏难/偏易也照实记,不因单局顺逆回调。 +2. **整体难度印象**:用户 2026-10-01 已阶段性验收「令人稍微满意」——本批试玩读数作正式标定(真人关卡完成率+k 系数),若体感偏难/偏易也照实记,不因单局顺逆回调。 模拟侧对照读数(普通档画像 L1 13%/战役 0%;完美档 78.5%)见同报告 §四。 ### ⑩ 迭代 10 奖励重构体验项(2026-10-01 顺带登记——实机目检一轮已过 1/3/4/5/6/9/14,余项人工参与) @@ -190,12 +190,12 @@ ### ⑲ 生涯页目检(迭代 18 卡④生涯界面实装批·期一顺带登记——主菜单新增一级只读页+存档 v6) - **入口与开合**:〔入口已换代——迭代 33 卡② 撤主菜单生涯钮后无玩家可见入口,待迭代 34 卡④ 营地笔记本接入;接入前本项验到页内容即可〕点开全屏页、点「返回」回上层(开始层钮可见性随开合正确恢复)。 -- **页呈现两类六项**:组一·冒险战绩(冒险总局数 / 通关局数〔括注「三关全通」〕 / 各关通关次数〔一行三关,关名带层号〕 / Boss 首杀〔X/3 关〕 / Boss 总击杀);组二·资源(钥石余额徽)——数值与存档实况一致(对照:玩几局后总局数含放弃与失败、三关全通才计通关)。〔原「属性锻造已购合计」「天赋树已购概览」两观测项随生涯页三投影删除摘除——2026-10-12 用户裁⑧,天赋树实装批顺带〕 +- **页呈现两类六项**:组一·冒险战绩(冒险总局数 / 冒险成功局数〔括注「三关全通」〕 / 各关完成次数〔一行三关,关名带层号〕 / Boss 首杀〔X/3 关〕 / Boss 总击杀);组二·资源(钥石余额徽)——数值与存档实况一致(对照:玩几局后总局数含放弃与失败、三关全通才计冒险成功)。〔原「属性锻造已购合计」「天赋树已购概览」两观测项随生涯页三投影删除摘除——2026-10-12 用户裁⑧,天赋树实装批顺带〕 - **旧档载入**:v5 现役档(升级前存档)载入后生涯页正常显示,总局数/冒险成功局数从 0 起计(终身计数域 v6 新增,缺省补零),钥石等既有进度原样。 - **零跳转与局内零入口**:页内除「返回」外无任何前往他处的按钮;冒险进行中(战斗屏/关卡地图屏/状态面板)无生涯入口。 - **对比度与零动效**:页文字亮墨族在深棕底上可读(机检 3 对已入 ui_contrast 闸);开页/关页无过渡动画。 - **红灯信号**:计数与实玩局数对不上(收束入账重复或漏计);旧档载入返回错误或计数域显示异常;页内出现购买/跳转入口;入口在局内可点。 -- **结论回流**:呈现问题归生涯批后续修正(本批需求卡片 v1.2 在案);「通关局数」口径如与体感冲突=P1 甲裁决复核(三关全通才计 1,用户已裁);期二内容(历史回看/图鉴)缺位属分期计划非缺陷。 +- **结论回流**:呈现问题归生涯批后续修正(本批需求卡片 v1.2 在案);「冒险成功局数」口径如与体感冲突=P1 甲裁决复核(三关全通才计 1,用户已裁);期二内容(历史回看/图鉴)缺位属分期计划非缺陷。 ### ⑳ 营地统一四柜台目检(迭代 21 天赋树实装批顺带登记——V22 人闸;2026-10-12)