merge(master): S9 类型闸修复批与两条工程条目出账 并入 iter37(收口前最后一次并源)
三处冲突全部按「取我方结构+确认对方注解已落新址」处置,零丢弃对方改动: - main.gd:四解析函数体已由卡② r1-2 搬入 board_resolvers.gd,master 给 _identity_lookup 补的 -> Variant 在新件 identity_lookup:28 同形在位;build_adventure_params 的 SaveManagerCore/MetaProgressionCore 注解经自动合并落住(main.gd:367) - views/battle_stage_view.gd:卡① d12 已改 (target_id: String, display_name: String) -> Variant,master 对旧一参形态的注解属同址更新,取我方 - views/board_view.gd:查表族/明度归一族已由卡③ r2-1 搬入 tile_palette.gd,master 的 lumas_out: Variant 注解在 tile_palette.gd:134 同形在位 待办清单.md:我方 P0 条目与 master 删两条已完成工程条目自动合并(64 条,S9/S13 条目出账) 合并后复核:13 个触及脚本 --check-only 零 Parse Error;master 修好的 S9 类型闸 PASS(其 26 处补注解零丢失、本批九新件零命中);gdstyle 216/216 基线内、新违规 0、恶化 0
This commit is contained in:
commit
2dd3ec5640
18 files changed
+53
-99
No files matched your search
@@ -2,8 +2,8 @@
|
||||
|
||||
## 文档状态
|
||||
|
||||
- 版本:1.9
|
||||
- 最近更新:2026-10-21(迭代 32 卡②反哺点写入——effect_engine 行与战斗域装配节改无状态化 ctx 形态、架构原则新增「系统无状态」条;2026-10-21 用户裁)
|
||||
- 版本:1.10
|
||||
- 最近更新:2026-10-25(架构与规范对齐批部分落文——模块归属表 API 对齐实现实况+B1 域文件集成文+明细行协议两层化指针+层合同计数 18;2026-10-25 用户令)
|
||||
- 引擎:Godot 4.7.2-stable(GDScript 单语言;2026-09-07 锁定)
|
||||
- 评审模式:solo(`review-mode.txt`,2026-09-12 用户拍板——TD/LP 门禁按 solo 跳过,用户授权架构产出自主推进、迭代期回调)
|
||||
- 覆盖 GDD:现行全集——`design/gdd/` 顶层 00–08 共 9 件 + `systems/` 五域 25 件(排雷循环 4 / 战斗循环 5 / 冒险循环 5 / 跨局循环 5 / 表现与支撑 6)+ `ux/` 8 件;原英文命名 12 份系统 GDD 已全部迁入中文域目录,原「未设计」预留(A5 扫雷秘宝 / C1–C4 / B5 / D3–D6)均已立项成文
|
||||
@@ -92,7 +92,7 @@
|
||||
|---|---|---|---|---|
|
||||
| **ConfigDB**(autoload,D2) | 全部玩法数值表(`data/tables/*.tres` + `data/schemas/*.gd`);SCHEMA_VERSION;加载/校验/override/诊断状态机 | 类型化属性读取;`load_tables(root, collect_only)`;`resolve()`(R1 floor);debug override;`set_reload_gate()`;诊断收集器 | 无(基础层顶点) | Resource/.tres 加载、autoload 生命周期——LOW |
|
||||
| **RngService**(autoload,D2) | master_seed、各流 scope 计数器(封闭流:board_gen / reward_roll;增流走 P1 评审) | `set_master_seed()`(唯一调用方 C2);`open_stream(stream)` 有状态门面;`derive_at(stream, scope)` 纯函数;只读计数器 | ConfigDB(无) | 无——纯逻辑 |
|
||||
| **action_economy**(A3) | AP/RAP 账本、last_round_end、轮次相位机 {Idle, Active, Waiting}、结束仲裁 | 8 API 全布尔面:notify_round_start / request_dig / request_flag_place / request_flag_pull / request_stop / request_refresh / notify_settlement_done / notify_combat_end;ap/rap/phase 只读 | ConfigDB(ActionEconomyTable);B1 回发 next_round_mode/battle_over | 无 |
|
||||
| **action_economy**(A3) | AP/RAP 账本、last_round_end、轮次相位机 {Idle, Active, Waiting}、结束仲裁 | 意图与通知布尔面:notify_round_start / request_dig / request_stop / request_refresh / notify_settlement_done / notify_combat_end;预授权通道:grant_reserve_ap / finish_round_stop;ap/rap/phase 只读 | ConfigDB(ActionEconomyTable);B1 回发 next_round_mode/battle_over | 无 |
|
||||
| **variation 定义**(A4) | VariationTable schema(现行 6 行:六 region——贫矿脉 global 行 2026-10-16 用户令屏蔽删行,global 型机制代码保留)与 F1 候选池门控谓词 | `variant_pool(level_index, board_type, node_type="")`(门控三维:unlock+board_types+节点身份——global 行仅 boss/elite 入池,缺省跳过零扰动);`global_variant_row(level_index, board_type, node_type)`(全局型单行决议访问器) | ConfigDB(VariationTable) | 无 |
|
||||
| **status_container**(B3) | 状态实例容器(战斗域生命周期、跨轮跨图延续) | 5 API:notify_battle_start / apply_effect / query_active / decay_round / notify_battle_end | ConfigDB(StatusEffectTable) | 无(RefCounted) |
|
||||
| **save_system**(D3,Alpha;iter27 已升格 autoload「SaveManager」) | 存档格式与版本比较 | (契约规范源:`../../gdd/systems/表现与支撑/存档序列化.md`——契约锚:SCHEMA_VERSION + master_seed + 各流 scope 计数器快照,须在无正在执行中的 open_stream 实例时切出) | ConfigDB、RngService 只读计数器 | FileAccess——LOW |
|
||||
@@ -103,18 +103,20 @@
|
||||
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|
||||
|---|---|---|---|---|
|
||||
| **board_generator**(A1) | 生成算法(五阶段管线)、BoardGenTable 回填、生成期指标集、合法性谓词(clearable / R₀≠S / min_safe)、可推理率度量(metric_version);生成姿态 = MVP 同步生成 + 加载幕(切片实证 10×10/12×12 同步可接受,WorkerThread 留扩展) | `generate(L, D, rng) -> Board`;度量独立入口×3(推理器 / F3 度量 / 合法性谓词——独立纯函数、同一实现) | ConfigDB(BoardGenTable/VariationTable);board_gen 流(一次 open_stream = 一张图);dig_ap_cost 只读 | 无 |
|
||||
| **minesweeper_rules**(A2) | 棋盘状态(已开集 O / 封印集 G / 小人位)、三事件面、批次仲裁、install 四不变式 | `install_board(board)`;`settle_batch(intents)`(唯一提交入口);try_dig / try_flag_place / try_flag_pull / try_move(便捷形);`compute_move_path(cell)` 只读;`retire_board()`;三源拒绝(board_face / resource_face / phase)+ sub_reason 封闭枚举 | A1 产物(Board class_name 数据契约);A3 try_spend / last_round_end / 相位 | 无(零表读取、零 UI——切片实证) |
|
||||
| **unit_container**(B2) | hero/enemy 单位实例(hp/atk/实例池:池快照+冷却+摇定动作+保底计数)、行值快照 | spawn / query_alive / rollable_skills / special_skills / set_pending_action / pending_action / basic_streak / commit_action / tick_cooldowns / apply_damage / heal / default_target / ambush_grant_plan / despawn_all(2026-09-16 敌人技能池批:query_beat/query_attack/advance 随行为环退役) | ConfigDB(EnemyTable/SkillTable/HeroTable) | 无 |
|
||||
| **reward_economy**(B4) | 格面资源身份映射(install 期预分配、Ready 只读、换图映射消亡)、极性路由字典面((类型, 极性)→ 字典行查询;路由执行归 B1 授予段)、F6 当量供给投影 | 封闭 API:roll_board / query_identity / query_full_snapshot / grant / grant_clear / retire_mapping / polarity_row / equivalence_supply / phase / weighted_pick;另有 is_mapped 静默布尔投影(批量工具用) | ConfigDB(RewardTable);reward_roll 流(scope = 每次 install 批) | 无 |
|
||||
| **minesweeper_rules**(A2) | 棋盘状态(已开集 O / 封印集 G / 小人位)、三事件面、批次仲裁、install 四不变式 | `install_board(board)`;`settle_batch(intents)`(唯一提交入口);查询只读面(current_board / hero_pos / is_revealed / has_seal 等);`compute_move_path(cell)` 只读;`retire_board()`;三源拒绝(board_face / resource_face / phase)+ sub_reason 封闭枚举 | A1 产物(Board class_name 数据契约);A3 try_spend / last_round_end / 相位 | 无(零表读取、零 UI——切片实证) |
|
||||
| **unit_container**(B2) | hero/enemy 单位实例(hp/atk/实例池:池快照+冷却+摇定动作+保底计数)、行值快照 | spawn / query_alive / rollable_skills / special_skills / set_pending_action / pending_action / basic_streak / commit_action / tick_cooldowns / apply_damage / heal / default_target / check_skill_unlocks / despawn_all(2026-09-16 敌人技能池批:query_beat/query_attack/advance 随行为环退役) | ConfigDB(EnemyTable/SkillTable/HeroTable) | 无 |
|
||||
| **reward_economy**(B4) | 格面资源身份映射(install 期预分配、Ready 只读、换图映射消亡)、极性路由字典面((类型, 极性)→ 字典行查询;路由执行归 B1 授予段)、F6 当量供给投影 | 封闭 API:roll_board / query_identity / query_full_snapshot / grant / grant_clear / retire_mapping / polarity_row / phase / weighted_pick;另有 is_mapped 静默布尔投影(批量工具用) | ConfigDB(RewardTable);reward_roll 流(scope = 每次 install 批) | 无 |
|
||||
| **helper_items**(A5,切片已实装秘宝域) | HelperItemTable、探测显影语义 | (契约规范源:`../../gdd/systems/跨局循环/秘宝.md`——桥接位:A2 查询接口 + A4 counter_item_ids) | A2 / A4 / B4 | 无 |
|
||||
|
||||
### 功能层
|
||||
|
||||
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|
||||
|---|---|---|---|---|
|
||||
| **battle_orchestrator**(B1) | 段序骨架(七段结构冻结)、轮 facts 缓冲、可回放步骤流、[明细行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(15 类行 + 字段分层)、条款③⑤闭合对账、**战斗域全部跨系统调用权**、效果引擎宿主(每战 rebuild;round/battle 桶为编排器自有字典、经 EffectContext 引用挂载)+ 树规则挂点施加面(posture 窗/sense 限次/守侧 seal_missed 发射/聚乘算入账前) | `begin_battle(encounter)`;窗口/刷新意图提交面(扮演 D1);`level_clear()`;步骤流(输出契约) | B2/B3/B4 全调用面(**唯一调用方**);A3 request_refresh 代理 + 回发;A2 install/retire + 三事件订阅;A1 generate(attempt 非 scope 事件);D2 SettlementTable + set_reload_gate | 无(零随机、禁 await——切片 88 冒烟实证可回放) |
|
||||
| **battle_orchestrator**(B1) | 段序骨架(七段结构冻结)、轮 facts 缓冲、可回放步骤流、[明细行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(基础行型+扩展行两层 + 字段分层,词表以 owner「明细流水」节为准)、条款③⑤闭合对账、**战斗域全部跨系统调用权**、效果引擎宿主(每战 rebuild;round/battle 桶为编排器自有字典、经 EffectContext 引用挂载)+ 树规则挂点施加面(posture 窗/sense 限次/守侧 seal_missed 发射/聚乘算入账前) | `begin_battle(encounter)`;窗口/刷新意图提交面(扮演 D1);`level_clear()`;步骤流(输出契约) | B2/B3/B4 全调用面(**唯一调用方=B1 域文件集:battle_orchestrator.gd + settlement/ 五段段类 + damage_controller**);A3 request_refresh 代理 + 回发;A2 install/retire + 三事件订阅;A1 generate(attempt 非 scope 事件);D2 SettlementTable + set_reload_gate | 无(零随机、禁 await——切片 88 冒烟实证可回放) |
|
||||
| **damage_controller**(B1 域·伤害单据管线) | 伤害单据唯一兑现管线(单据九栏目声明→分量掷点/克制修正/伤害下限归一→明细行发射;双方同规) | 兑付入口(编排侧开单)+ fx 揭示回调注入位 | B2 单位实例(单据目标传入);B1 注入(EffectContext 引用束与编排回调) | 无 |
|
||||
| **settlement/ 五段段类**(B1 域·结算段件) | B1 每轮结算序列的五段逻辑件(授予/增益减益/战斗/衰减/判定——细则见下「战斗域装配现状」节) | 段处理入口(B1 接线调用);可直接 `new()` 单测 | B2/B3/B4 兑付面与 B1 轮 facts 缓冲(各段按职责) | 无 |
|
||||
| **effect_engine**(核心层——内容数据驱动扩展批 iter17 建域) | 零运行时可变状态的系统(见「架构原则」条 8):事件/事实/效果类型/算子四词表封闭(迭代 21 T3 扩签:EVENTS 18→19 +seal_missed 标错判定、FACTS +battle_index 关卡域战斗序)+ 树规则合成订阅六键(posture 每关首轮窗/sense 两组限次 counter 闸·adv_ 前缀走冒险桶跨战斗持久) | rebuild(每战重建订阅表)/`dispatch(ctx, event, payload, facts)`/`validate_trigger_row` + 静态计数口 `counter`·`counter_add`·`counter_spend`·`bucket_of`·`counter_id_legal`(计数器读写只经 EffectContext 引用束,无导出/灌入接口) | ConfigDB(feats/treasure 行集)、EffectContext(四桶引用由宿主持有:round/battle 桶归编排器、level 桶归关卡域、adventure 桶归 RunLedger) | 无(零随机全确定) |
|
||||
| **level_runner**(C1-lite,切片已建) | 关卡域生命周期(节点链推进、共享 B4 + HP 携带、关卡末 level_clear) | 节点推进接口;LevelTable(`level.tres`——节点 enum {battle,reward,rest,boss}、末节点必须 Boss、ConfigDB 跨表校验⑧) | B1 begin_battle、B4 grant_node_active、ConfigDB LevelTable | 无 |
|
||||
| **level_runner**(C1-lite,切片已建) | 关卡域生命周期(节点链推进、共享 B4 + HP 携带、关卡末 level_clear) | 节点推进接口;LevelTable(`level.tres`——节点 enum {battle,reward,rest,boss}、末节点必须 Boss、ConfigDB 跨表校验⑧) | B1(直构 BattleOrchestrator 接线战斗)、ConfigDB LevelTable | 无 |
|
||||
| **run_structure**(C2) | 冒险/关卡序列、失败重开、**master_seed 唯一接线方** | (契约规范源:`../../gdd/systems/冒险循环/冒险结构.md`) | RngService.set_master_seed、C3/D2 | 无 |
|
||||
| **difficulty**(C3) | DifficultyTable 回填、全部曲线数值调参所有权、战斗期望表(切片 monte_carlo 为工具原型) | 调参输出(经 D2 R1 解析/编排器传递,禁反向调用生成) | ConfigDB、B1 对账输出(调参约束清单)、A1 报告 C | 无 |
|
||||
| **meta_progression**(C4,Alpha) | MetaTable、钥石账本、天赋树域(MetaTreeTable 12 节点 v0.8——Fork 一节点双态/row 字段退役/RULE_KEYS 六键/彩蛋特化觉醒,迭代 21 T1 换代)+ 同调位槽位判定(树点亮数单源——T4 槽位收编) | tree_can_buy/tree_buy/tree_buy_fork/tree_toggle_fork(写口唯一)、hero_override 注入(树淬炼 flat+锻造路线加值位预留 0)、tree_rule_keys | D3、C2、ConfigDB | 无 |
|
||||
@@ -146,9 +148,9 @@
|
||||
|
||||
### 视觉层装配合同
|
||||
|
||||
- **树序 = 登记序 = z 序**,同源派生;层序唯一事实源 = `main.gd` 的 `LAYER_CONTRACT` 常量表(现行 17 项,kind 五类:shell=屏壳〔成员随壳不占独立树位〕/modal=模态层〔入登记册,tags 随登记〕/state=全屏态/node=非视觉节点/float=不注册 ModalStack 的最顶浮层〔任何 UI 打开都不遮挡它〕)。
|
||||
- **树序 = 登记序 = z 序**,同源派生;层序唯一事实源 = `main.gd` 的 `LAYER_CONTRACT` 常量表(现行 18 项,kind 五类:shell=屏壳〔成员随壳不占独立树位〕/modal=模态层〔入登记册,tags 随登记〕/state=全屏态/node=非视觉节点/float=不注册 ModalStack 的最顶浮层〔任何 UI 打开都不遮挡它〕)。
|
||||
- 全仓唯一落位口 = `_apply_layer_contract()`(装配尾统一排序+登记);散落 `move_child` 由冒烟 V1d 源码断言判红;**改层序只改合同表**。
|
||||
- 具体层清单不复制进本文(双写失同步禁令)——查现行 17 项直接读 `main.gd`。
|
||||
- 具体层清单不复制进本文(双写失同步禁令)——查现行 18 项直接读 `main.gd`。
|
||||
|
||||
### 会话生命周期(RunScope)
|
||||
|
||||
@@ -338,7 +340,7 @@ CJK 字体随包发行并设为 theme 默认字体——运行时默认字体无
|
||||
| A1 → A2 | Board 产物 class_name 数据契约 | install 四不变式校验(violation = 拒绝 + 五类诊断枚举) | 生成期合法性闸(R₀≠S / clearable / min_safe) |
|
||||
| A1 ↔ B1 | attempt 边界非 scope 事件;actuals p10 为对账输入(非 target 参数) | 编排不把重试当取号 | 生成期指标集输出(实测可推理率 / 实际雷数与安全格数 / 重试次数 / 降级与非法产物标记) |
|
||||
| B4 → B3 | buff 类经 B1 调 apply_effect(B4 零跨系统读、零直接接口) | 满层拒绝 = 零兑付 + 明细行(无折算) | 授予时数值快照(抗热重载) |
|
||||
| B1 → D1 | [步骤流行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(15 类封闭枚举 + 公共字段 type/source_class/origin_cell/round_index/display_name/value/highlight? + 特有字段 target/effect_id/pool_value) | 无来源行 = 断言失败;呈现侧禁按行序重演 B2 状态机 | 可回放步骤流(同种子逐行相同) |
|
||||
| B1 → D1 | [步骤流行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(基础行型+扩展行两层封闭 + 公共字段 type/source_class/origin_cell/round_index/display_name/value/highlight? + 特有字段 target/effect_id/pool_value) | 无来源行 = 断言失败;呈现侧禁按行序重演 B2 状态机 | 可回放步骤流(同种子逐行相同) |
|
||||
|
||||
**引擎类型核验注记**:接口使用的引擎类型 = Resource / .tres(D2 全表)、RefCounted(容器类)、Signal/Callable(事件载体)、Control/CanvasLayer/Drawing(D1)、SceneTree headless 协议(测试)——均属 4.x 基线稳定面;4.7 Control 域增量(offset_transform_* 等)已在 breaking-changes.md 登记,D1 采纳前对照核实。
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
设计稿与实现同尺度:功能 = 类(状态 + 行为 + 信号),类是封装的最小交付单位。工具性纯函数只允许挂在明确的宿主类下(静态装配器/工厂),不允许无主散落。
|
||||
|
||||
### 1.3 依赖单向,核心写调用完成
|
||||
依赖方向唯一:`views →(信号)→ 组合根 →(写调用)→ core`。视图零核心写调用(纯 setter / 信号外发优先);"读核心状态 → 拼展示文案"集中于装配器(presenter);核心写接口(settle_batch / submit_window_selection / runner 推进)只允许在组合根出现。
|
||||
依赖方向唯一:`views →(信号)→ 组合根 →(写调用)→ core`。视图零核心写调用(纯 setter / 信号外发优先);"读核心状态 → 拼展示文案"集中于装配器(presenter);核心写接口(settle_batch / player_request_refresh / runner 推进)只允许在组合根出现。
|
||||
|
||||
### 1.4 命名 = 领域命名,禁止系统 ID 前缀
|
||||
文件名与类名禁止 `a1_`/`b1_`/`c1_` 等系统 ID 前缀(`a1_board_generator.gd` → `board_generator.gd`)。设计追溯不靠前缀:代码↔设计的追溯由 GDD 文档承担,系统 ID 只作为文档的追溯锚;文件头注不承担追溯职责,不写任何文档链接(§1.4.1)。豁免:D2 schema 类与 autoload;文档/夹具登记名(如 b4_golden)属文档层。
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
### 明细流水:每一行都能指回你刚才的哪一步棋
|
||||
|
||||
结算过程中每一件事都写一行明细,每行标注来源——哪个安全格、哪处封印、哪颗雷、清图奖励。这份流水是结算明细屏(玩家逐行查看决策兑现结果的界面)的数据源,也是回放对账与数据导出共读的唯一契约。行型封闭为 9 类(2026-09-20 伏击上限删除批下线溢出未生效行),不允许私自增加;新增或下线行型属于行协议变更,必须走本文修订,并同步呈现层的行格式化。
|
||||
结算过程中每一件事都写一行明细,每行标注来源——哪个安全格、哪处封印、哪颗雷、清图奖励。这份流水是结算明细屏(玩家逐行查看决策兑现结果的界面)的数据源,也是回放对账与数据导出共读的唯一契约。行型分两层:**基础行型**封闭 9 类(下表),**扩展行** 1 类(专长经效果引擎插入的结算效果,见下节)。行型词表不允许私自增加;新增或下线行型属于行协议变更,必须走本文修订,并同步呈现层的行格式化。
|
||||
|
||||
| 行型 | 什么时候写 |
|
||||
|---|---|
|
||||
@@ -90,12 +90,20 @@
|
||||
|
||||
第一层按行型豁免两类:衰减行(到期移除本就是段级动作,不属于任何一格)、判定行(它是胜负出口的结论,不是棋盘事实)。这两类连来源类别都不必填。
|
||||
|
||||
第二层按来源类别豁免三类:主角攻击行的来源是主角单位本身,敌方行动行的来源是当时动手的那个敌人单位,清图奖励行的来源是"这张板被清掉"这一整板事实——它们都不指向某个棋盘格,来源格校验因此跳过。
|
||||
第二层按来源类别豁免,封闭清单五类:主角攻击行(来源是主角单位本身)、敌方行动行(来源是当时动手的那个敌人单位)、清图奖励行(来源是"这张板被清掉"这一整板事实)、专长揭示掷格行(落空行没有真实棋盘格可指)、专长 GP 入账行(来源是钱包面而非棋盘面)——它们都不指向某个棋盘格,来源格校验因此跳过。
|
||||
|
||||
豁免不等于免检:按行型豁免的行仍要带齐公共字段、守住各自的语义约束(如衰减行的数值必须是本次移除的读数),按来源类别豁免的行仍必须写明来源类别,其余行必须指回一个真实存在的棋盘格。豁免只是免掉"来源格必须有效"这一条校验,不是免掉整份行协议。
|
||||
|
||||
举证:本节为行协议约定,无计算。
|
||||
|
||||
### 扩展行:专长插入的结算效果
|
||||
|
||||
基础 9 类写的是裸机制的账:玩家没有任何专长时,结算流水的每一行都出得了这九类。有了专长之后,效果引擎会在段内挂点插入额外的结算效果,这类效果写**扩展行**。扩展行是**一个**行型,不是每种专长效果各占一个行型——具体插的是哪种效果,由行携带的效果身份(effect_id 载荷)说明,呈现层按身份取各自的行文案。专长会不断增加、效果种类不可穷举,行型词表因此对扩展类封口:新增专长效果只新增载荷身份,不再新增行型。
|
||||
|
||||
扩展行与基础行共用同一套行协议:公共字段、来源归因、两层豁免、无来源即炸,全部照常生效。发射时点由段序骨架的挂点决定(时序与挂点施加面归架构文档「模块归属·战斗域装配现状」节),本节只管这行是什么、带什么字段。现行实现的扩展行型值以专长实名串承载,效果身份清单与发射点以实现侧 `battle_orchestrator.gd` 文件头注为准;收敛为单一扩展行型+效果载荷的条目在 [待办清单](../../../../待办清单.md) 在册。
|
||||
|
||||
举证:本节为行协议约定,无计算。
|
||||
|
||||
### 收益对照表:所有收益共用同一把尺子
|
||||
|
||||
开安全格给正向、封印标中给正向、踩雷与标错给负向、清图给清图奖励对象——来源不同、形态不同,但玩家必须能回答"挖这一格值不值",所以全部收益用一张效果档位对照表归一换算。折算单位是当量:1 当量等于 1 点主角生命的期望净变化。这张表是[行动经济](../排雷循环/行动经济.md)五条经济契约第一条"单一当量"的载体;本系统是全部五条契约的唯一对账责任方(契约本体见该文档,对账现状登记 [待办清单](../../../../待办清单.md))。
|
||||
@@ -350,7 +358,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
|
||||
- 关卡收束:关卡结束清空秘宝背包(关卡域库存——现行恒空的机械惰性承载,见「轮次生命周期」节注)恰一次并返回清空前计数;战斗结束不清背包。
|
||||
- 可回放(封闭随机流口径):同种子同输入两遍步骤流逐位复现;随机消费仅限七处封闭随机流——开战掷骰(初始化随机)、技能摇号 `behavior_roll`(回合内、开轮时点、步骤流之外)、护甲等级掷点 `armor_roll`(回合内、步骤流之内)、奖励格摇号 `reward_roll`(初始化、装板期)、变异布置 `variant_place`(初始化、装板与资源预分配之后)、换板棋盘生成 `board_gen`(初始化、清图轮换板时点)、战斗结束掉落掷定 `gp_drop`(出口随机、战斗结束分支),无未登记随机源、零界面等待;单敌出招轨迹可独立复放、互不穿插。
|
||||
- 无来源即炸:每行明细都能指回一个来源事实(棋盘格、单位、清图或段级结论);找不到来源即断言失败,行型与来源类别两层豁免清单见明细流水一节,豁免行仍受其它契约约束。
|
||||
- 行型封闭:流水只出现本文登记的 9 类行型;新增或下线行型必须走本文修订并同步呈现层行格式化,未登记行型禁止落行。
|
||||
- 行型封闭:流水行型只出现本文登记的基础 9 类与扩展行;行型词表改动必须走本文修订并同步呈现层行格式化,未登记行型禁止落行。
|
||||
- 伤害单据管线(2026-09-24):全部伤害(主角先手、敌方伤害技、棋盘克制直伤、群伤、反噬、地形变异)经伤害控制器单据管线兑现,兑付配方封闭五种;目标在结账时刻照规则解析;死亡事件由单位自行宣布——怪死其未结单据作废(零行、不进冷却不进保底计数)、主角死兑付终止;段界结账为现行口径、开单即结为回切结构位,两模式各自同种子同输入逐位复现。
|
||||
- 条款3 对账(2026-10-05 判式换代批 T3——与行动经济 F1 条款3 重立同步):①聚合健康式 (1−ρ̂)·E_dig(u) − ρ̂·V_mine(u) ≥ 0 与 β 比值带 [1.2, 2.5] 判读逐 u 检算(常设重跑入口 `tools/clear_dominance_audit.py`,读数快照归 registry clause3 重立条);②封印溢价兑付正确:封印标中正向兑付 = 同型正向 ×(1+δ)(δ 读 `settlement.tres` flag_hit_premium,100=无溢价直通零扰动),三类形态全覆盖(flat power / percent 幅度 / gp 缓冲)、标空与挖格兑付不乘溢价、危险格与安全格同池结构零触碰。
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ extends RefCounted
|
||||
# 同调位实时求值(营地进冒险前求值一次 + 装配覆盖层实时呈现共用同一口径):
|
||||
# 槽位数量 = att_socket1..3 树点亮数(tree_level>=1),未点亮=0。
|
||||
# db 参数保留(调用面两处签名不变——当前判定源零表依赖,参数弃置)。
|
||||
static func slots(db, save) -> int:
|
||||
static func slots(db: ConfigDb, save: Variant) -> int:
|
||||
if save == null:
|
||||
return 0
|
||||
var n := 0
|
||||
|
||||
@@ -163,7 +163,7 @@ func _flush_pending_reveals(ri: int) -> void:
|
||||
|
||||
|
||||
# 补充事实面(fact 取值第二优先源——payload 未携带的运行态读数)
|
||||
func _fx_fact(fact: String):
|
||||
func _fx_fact(fact: String) -> Variant:
|
||||
match fact:
|
||||
"charge_layers":
|
||||
return action_economy.charge_layers
|
||||
@@ -1225,7 +1225,7 @@ func is_battle_live() -> bool:
|
||||
|
||||
|
||||
# 奖励身份解析(组合根注入 BoardView 徽章回调的只读代理——Ready 相位守卫归 地图战斗资源)
|
||||
func query_reward_identity(cell: Vector2i):
|
||||
func query_reward_identity(cell: Vector2i) -> Variant:
|
||||
return _reward_economy.query_identity(cell)
|
||||
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ func _fx_hits(event: String, payload: Dictionary) -> Array:
|
||||
# 补充事实面(fact 取值第二优先源——payload 未携带的运行态读数:charge_layers 编排器每轮注入。
|
||||
# hp_ratio 补入〔背水 when 面,敌技 damage_taken 载荷不带血比例时回落〕;
|
||||
# fx_reveal_request=揭示效果回调〔斩首学者 kill 订阅面——编排器注入,入队授予段末兑付〕)
|
||||
func _fx_fact(fact: String):
|
||||
func _fx_fact(fact: String) -> Variant:
|
||||
match fact:
|
||||
"charge_layers":
|
||||
return charge_layers
|
||||
@@ -612,7 +612,7 @@ func _attack_label(base: String, crit: bool, discount: int) -> String:
|
||||
# ---- 内部 ----
|
||||
|
||||
# 目标解析(结账时刻照规则看现场;句柄即 Dictionary 引用)
|
||||
func _target_for(rule: String):
|
||||
func _target_for(rule: String) -> Variant:
|
||||
match rule:
|
||||
TARGET_FRONT_ALIVE:
|
||||
return units.default_target()
|
||||
|
||||
@@ -309,7 +309,7 @@ func _cond_ok(ctx: EffectContext, c: Dictionary, payload: Dictionary, facts: Cal
|
||||
return false
|
||||
|
||||
|
||||
func _fact_value(ctx: EffectContext, fact: String, c: Dictionary, payload: Dictionary, facts: Callable):
|
||||
func _fact_value(ctx: EffectContext, fact: String, c: Dictionary, payload: Dictionary, facts: Callable) -> Variant:
|
||||
match fact:
|
||||
"counter":
|
||||
return counter(ctx, String(c.get("id", "")))
|
||||
|
||||
@@ -630,7 +630,7 @@ func pick_next_node(node_id: int) -> bool:
|
||||
|
||||
# ---- 只读出口(E1/E3 封装收口:呈现层/工具经此读当前战斗,禁直读协作对象)----
|
||||
|
||||
func current_battle():
|
||||
func current_battle() -> Variant:
|
||||
return _settlement
|
||||
|
||||
# aux 解锁门控集注入(AdventureRunner 自 params 传递)
|
||||
|
||||
@@ -101,7 +101,7 @@ func is_mapped(cell: Vector2i) -> bool:
|
||||
return _phase == "ready" and _mapping.has(cell)
|
||||
|
||||
|
||||
func query_identity(cell: Vector2i):
|
||||
func query_identity(cell: Vector2i) -> Variant:
|
||||
if _phase != "ready":
|
||||
_diag("query_identity 非 Ready 相位")
|
||||
return null
|
||||
@@ -116,7 +116,7 @@ func query_identity(cell: Vector2i):
|
||||
# 身份完整快照(轮内刷新批次隔离用——facts 缓冲期捕获,授予期 mapping 可能已换批):
|
||||
# 返回与 grant 相同结构的快照(cell_type/display_name/power/effect_id/stacks 齐备),
|
||||
# 供 战斗结算 冻结授予直通
|
||||
func query_full_snapshot(cell: Vector2i):
|
||||
func query_full_snapshot(cell: Vector2i) -> Variant:
|
||||
if _phase != "ready":
|
||||
_diag("query_full_snapshot 非 Ready 相位")
|
||||
return null
|
||||
@@ -128,7 +128,7 @@ func query_full_snapshot(cell: Vector2i):
|
||||
|
||||
# ---- 受理面(战斗结算 编排期调用;E6 收口:失败统一返回 null)----
|
||||
|
||||
func grant(cell: Vector2i):
|
||||
func grant(cell: Vector2i) -> Variant:
|
||||
if _phase != "ready":
|
||||
_diag("grant 非 Ready 相位(E4/E7)")
|
||||
return null
|
||||
@@ -143,7 +143,7 @@ func grant(cell: Vector2i):
|
||||
return snap
|
||||
|
||||
|
||||
func grant_clear():
|
||||
func grant_clear() -> Variant:
|
||||
if _phase != "ready":
|
||||
_diag("grant_clear 非 Ready 相位")
|
||||
return null
|
||||
|
||||
@@ -272,7 +272,7 @@ func heal(u: Dictionary, n: int) -> int:
|
||||
|
||||
|
||||
# 固定顺位:行主序生成序最前存活敌;死亡后顺延;空 → null
|
||||
func default_target():
|
||||
func default_target() -> Variant:
|
||||
for u in _enemies:
|
||||
if u.alive:
|
||||
return u
|
||||
|
||||
@@ -5,7 +5,7 @@ extends RefCounted
|
||||
|
||||
|
||||
# 节点进入横幅(棋盘日志——battle/boss 用;节点编号 = 行进器编号空间读面;行色 = UiKit.HEX_* 语义档单点)
|
||||
static func node_banner(runner, node: Dictionary, t: String) -> String:
|
||||
static func node_banner(runner: LevelRunner, node: Dictionary, t: String) -> String:
|
||||
return "[color=#%s]── 节点 %d/%d · %s(编号 %d)──[/color]" % [UiKit.HEX_LOG_GAIN,
|
||||
runner.node_index + 1, runner.nodes().size(),
|
||||
"Boss 房" if t == "boss" else "战斗", runner.node_id_of(node)]
|
||||
@@ -25,7 +25,7 @@ static func shop_line(gp: int) -> String:
|
||||
|
||||
|
||||
# 选路口行(零自动推进停点——战斗胜利/兑付确认后出现)
|
||||
static func route_line(candidates: Array, runner) -> String:
|
||||
static func route_line(candidates: Array, runner: LevelRunner) -> String:
|
||||
var names: Array[String] = []
|
||||
for cand in candidates:
|
||||
names.append("节点 %d" % runner.node_id_of(cand))
|
||||
@@ -69,7 +69,7 @@ static func phase_text(round_index: int, battle_result: String, waiting: bool, b
|
||||
# 行集多行时取**首行** display_name(行序即契约的呈现面后果,
|
||||
# Boss 行集混编护卫时 Boss 名显示可能为护卫名,知情代价登记 敌人系统 v0.15 / 出口报告;
|
||||
# 每坐标恰一行时无此歧义)
|
||||
static func boss_name(runner, db) -> String:
|
||||
static func boss_name(runner: Variant, db: ConfigDb) -> String:
|
||||
if runner != null:
|
||||
var node: Dictionary[Variant, Variant] = runner.current_node()
|
||||
if String(node.get("type", "")) == "boss":
|
||||
|
||||
@@ -78,7 +78,7 @@ static func _refresh_hero(stage: BattleStageView, info: HeroInfoPanelView, s: Di
|
||||
|
||||
# ---- 行动经济(AP 点阵 / RAP / 弃图刷新按钮态——RAP 读数在本条) ----
|
||||
|
||||
static func _refresh_economy(ap_bar: ApBarView, s: Dictionary, db, refresh_remaining: int) -> void:
|
||||
static func _refresh_economy(ap_bar: ApBarView, s: Dictionary, db: ConfigDb, refresh_remaining: int) -> void:
|
||||
ap_bar.set_ap(int(s.ap), int(db.action_economy.ap_per_round))
|
||||
ap_bar.set_rap(int(s.rap))
|
||||
var digging := String(s.phase) == ActionEconomy.PHASE_ACTIVE
|
||||
@@ -90,7 +90,7 @@ static func _refresh_economy(ap_bar: ApBarView, s: Dictionary, db, refresh_remai
|
||||
# 特性持有文案(战斗 C 区与关卡选择页两处共用;空持有=空数组。
|
||||
# 行形态=逐件「件名 ×N」(非逐流派聚合)——表行
|
||||
# 无 archetype 字段,聚合形态会空键兜底实显「流派 ×N · 档一」僵尸文案;流派档位非现行机制)
|
||||
static func feat_holdings_lines(db, held: Array) -> Array[String]:
|
||||
static func feat_holdings_lines(db: ConfigDb, held: Array) -> Array[String]:
|
||||
var rlines: Array[String] = []
|
||||
if db == null or db.feats == null or (db.feats.rows as Array).is_empty() or held.is_empty():
|
||||
return rlines
|
||||
@@ -107,7 +107,7 @@ static func feat_holdings_lines(db, held: Array) -> Array[String]:
|
||||
# 地形变异常驻角标文案(整图变异 id → 文案行;
|
||||
# 空集 = 空数组=空态隐藏。三行制:变异名+两行效果说明(C 区 240px 宽防裁切)。
|
||||
# 文案用常规表述,不用俚语
|
||||
static func board_variant_lines(db, ids: Array) -> Array[String]:
|
||||
static func board_variant_lines(db: ConfigDb, ids: Array) -> Array[String]:
|
||||
var lines: Array[String] = []
|
||||
if db == null or db.variation == null:
|
||||
return lines
|
||||
|
||||
@@ -213,7 +213,6 @@ func _fatal_screen(msg: String) -> void:
|
||||
MainUiBuild.fatal_screen(self, msg)
|
||||
|
||||
|
||||
|
||||
# ==================== 模态 overlay 层级管理(pattern 6 / 缺陷⑤——状态机归 modal_stack.gd) ====================
|
||||
|
||||
func _register_modal(m: Control, tags: Array = []) -> void:
|
||||
@@ -364,7 +363,7 @@ func _wire_adventure() -> void:
|
||||
# 取值=meta.hero_attack_type/hero_armor_type=存档选中路线类型轴,未解锁/异常选中态回退锻造配置默认值)。
|
||||
# 注:runner 侧 resume_adventure 受理面收 attunement/attune_refresh_y/tree_rules 三键
|
||||
# (传参/受理两侧对齐)。
|
||||
static func build_adventure_params(save_manager_ref, meta_ref, extra: Dictionary = {}) -> Dictionary:
|
||||
static func build_adventure_params(save_manager_ref: SaveManagerCore, meta_ref: MetaProgressionCore, extra: Dictionary = {}) -> Dictionary:
|
||||
var params: Dictionary[Variant, Variant] = {
|
||||
"hero_override": meta_ref.hero_override() if meta_ref != null else {},
|
||||
"attack_type": meta_ref.hero_attack_type() if meta_ref != null else "",
|
||||
@@ -402,8 +401,6 @@ func _on_adventure_level_started(level_index: int, display_name: String)-> void:
|
||||
MainAdventureFlow._on_adventure_level_started(self, level_index, display_name)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_runner_node(node: Dictionary, info: Dictionary)-> void:
|
||||
MainAdventureFlow._on_runner_node(self, node, info)
|
||||
|
||||
@@ -412,32 +409,22 @@ func _on_adventure_finished(summary: Dictionary)-> void:
|
||||
MainAdventureFlow._on_adventure_finished(self, summary)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_battle_end_continue() -> void:
|
||||
MainAdventureFlow._on_battle_end_continue(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _start_debug_levels() -> void:
|
||||
MainDebugFlow._start_debug_levels(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_debug_battle_created(settlement_ref: BattleOrchestrator, _level: int, _carry: int)-> void:
|
||||
MainDebugFlow._on_debug_battle_created(self, settlement_ref, _level, _carry)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_debug_battle_ready(settlement_ref: BattleOrchestrator, _level: int, _carry: int)-> void:
|
||||
MainDebugFlow._on_debug_battle_ready(self, settlement_ref, _level, _carry)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_inter_next_pressed() -> void:
|
||||
MainAdventureFlow._on_inter_next_pressed(self)
|
||||
|
||||
@@ -612,14 +599,10 @@ func _on_node_continue() -> void:
|
||||
MainAdventureFlow._on_node_continue(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_choices_presented(candidates: Array)-> void:
|
||||
MainAdventureFlow._on_choices_presented(self, candidates)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_route_chosen(node_id: int)-> void:
|
||||
MainAdventureFlow._on_route_chosen(self, node_id)
|
||||
|
||||
@@ -632,14 +615,10 @@ func _enter_level_screen() -> void:
|
||||
MainAdventureFlow._enter_level_screen(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _exit_level_screen() -> void:
|
||||
MainAdventureFlow._exit_level_screen(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_abandon_requested() -> void:
|
||||
MainAdventureFlow._on_abandon_requested(self)
|
||||
|
||||
@@ -650,8 +629,6 @@ func _open_settings() -> void:
|
||||
MainOverlayFlow._open_settings(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_settings_closed() -> void:
|
||||
MainOverlayFlow._on_settings_closed(self)
|
||||
|
||||
@@ -660,14 +637,10 @@ func _status_data() -> Dictionary:
|
||||
return MainOverlayFlow._status_data(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _open_status_panel() -> void:
|
||||
MainOverlayFlow._open_status_panel(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_status_closed() -> void:
|
||||
MainOverlayFlow._on_status_closed(self)
|
||||
|
||||
@@ -679,8 +652,6 @@ func _open_career() -> void:
|
||||
MainOverlayFlow._open_career(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_career_closed() -> void:
|
||||
MainOverlayFlow._on_career_closed(self)
|
||||
|
||||
@@ -689,8 +660,6 @@ func _open_save_select() -> void:
|
||||
MainOverlayFlow._open_save_select(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_save_select_closed() -> void:
|
||||
MainOverlayFlow._on_save_select_closed(self)
|
||||
|
||||
@@ -721,14 +690,10 @@ func _on_camp_closed() -> void:
|
||||
MainOverlayFlow._on_camp_closed(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _camp_data() -> Dictionary:
|
||||
return MainOverlayFlow._camp_data(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_wallet_changed(event: String, gp: int, extra: Dictionary)-> void:
|
||||
MainOverlayFlow._on_wallet_changed(self, event, gp, extra)
|
||||
|
||||
@@ -917,14 +882,10 @@ func _close_debug_overlay() -> void:
|
||||
MainDebugFlow._close_debug_overlay(self)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_tune_apply(atk_pct: int, hp_pct: int)-> void:
|
||||
MainDebugFlow._on_tune_apply(self, atk_pct, hp_pct)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_tune_simulate(n: int)-> void:
|
||||
MainDebugFlow._on_tune_simulate(self, n)
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ func _init(db_ref, panel_ref, base_hp: int, driver = null) -> void:
|
||||
|
||||
|
||||
# 驱动解析:注入优先;缺省回退运行时 load(旧行为——编译期反向依赖已解除,运行时口径与拆分前逐位一致)
|
||||
func _autoplay():
|
||||
func _autoplay() -> Variant:
|
||||
if _driver != null:
|
||||
return _driver
|
||||
return load("res://sim/level_autoplay.gd") # 与 headless 扫描同口径的自动策略(P3 兜底路径)
|
||||
|
||||
@@ -11,7 +11,7 @@ extends RefCounted
|
||||
# + 结算演出覆盖层(A–D 之上、模态之下——跨区弹道/光带载体)。
|
||||
# 返回句柄字典:{stage, log_view, info_panel, board_zone, board_view, ap_bar, settlement_fx}
|
||||
# (返回句柄不含 gp_label/keystone_label——GP/钥石不在战斗屏呈现)
|
||||
static func build_battle_ui(root: Control, db) -> Dictionary:
|
||||
static func build_battle_ui(root: Control, db: ConfigDb) -> Dictionary:
|
||||
# set_anchors_and_offsets_preset(非 set_anchors_preset):后者会把控件重置回最小内容尺寸
|
||||
# (实测 927×613——缩顶、棋盘 45px 格 ×10 行超出 D 区 333px 高被裁)
|
||||
root.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
@@ -64,7 +64,7 @@ static func build_battle_ui(root: Control, db) -> Dictionary:
|
||||
# (本组不含调试浮窗——由组合根直构挂树序最末,见 main._build_ui;
|
||||
# 本组不含明细回看 overlay——冒险中回看归「生涯」页;
|
||||
# 本组不含营地覆盖层——在 camp_screen 屏壳构建)
|
||||
static func build_overlays(host: Control, db) -> Dictionary:
|
||||
static func build_overlays(host: Control, db: ConfigDb) -> Dictionary:
|
||||
var legend_overlay := LegendOverlay.new(int(db.action_economy.rap_refresh_cost)) # RAP 行表值注入
|
||||
host.add_child(legend_overlay)
|
||||
|
||||
@@ -94,7 +94,7 @@ static func build_overlays(host: Control, db) -> Dictionary:
|
||||
#(教学内容归 Beta 帮助手册〔教学引导定稿 P4 丙〕)**;本层无玩法速览牌;
|
||||
# tooltip 主题归全局主题单点(禁在 root 挂程序化 tooltip 主题)。
|
||||
# 返回键集如首行所列,接线归组合根)
|
||||
static func build_start_overlay(host: Control, db = null) -> Dictionary:
|
||||
static func build_start_overlay(host: Control, db: ConfigDb = null) -> Dictionary:
|
||||
var overlay := overlay_bg(host, UiKit.BG_BRIGHT)
|
||||
# 石纹弱质感+斜光带+暗角(demo .tilebg 0.14/.beams/.vignette 三层;
|
||||
# 石纹层用半透明贴图,非满铺不透。缺位不挂即回退平色)
|
||||
|
||||
@@ -873,7 +873,6 @@ func _floor_tile_for(c: Vector2i) -> Texture2D:
|
||||
return _palette.floor_tile_for(c)
|
||||
|
||||
|
||||
|
||||
# ---- 自绘光标纹理(镐/封印——引擎内置光标无此语义;程序化占位,headless 跳过) ----
|
||||
|
||||
func _apply_custom_cursors() -> void:
|
||||
|
||||
@@ -22,7 +22,7 @@ SCAN_DIRS = ["game/core", "game/data", "game/presentation"]
|
||||
R1A_UNPARAM = re.compile(r"\bvar\s+\w+\s*:\s*(Dictionary|Array)\b(?!\[)")
|
||||
R1B_LITERAL = re.compile(r"^\s*var\s+\w+\s*(:?=)\s*[\{\[]")
|
||||
R1B_TYPED = re.compile(r"^\s*var\s+\w+\s*:\s*[\w\[\]]+")
|
||||
FUNC_DECL = re.compile(r"^(\s*)func\s+(_?\w+)\s*\((.*)\)\s*(->\s*.+)?\s*(#.*)?$")
|
||||
FUNC_DECL = re.compile(r"^(\s*)(?:static\s+)?func\s+(_?\w+)\s*\((.*)\)\s*(?:->\s*([^:#]+?))?\s*:\s*(#.*)?$")
|
||||
PARAM_SPLIT = re.compile(r",(?![^(\[]*[)\]])")
|
||||
RETURN_VALUE = re.compile(r"^\s*return\s+\S")
|
||||
|
||||
|
||||
@@ -43,27 +43,9 @@
|
||||
|
||||
**状态**:待写卡+已写卡+已编迭代 37
|
||||
|
||||
#### S9 类型闸正则失灵修复——R2 恒零命中+static 函数漏网(2026-10-24 登记,来源=审计发现)
|
||||
|
||||
**实况**:工程债证据=reports/审计-game代码结构审查-2026-10-24.md §二 C1(已独立复现):tools/audit_type_hints.py:29 的 FUNC_DECL 正则两洞——①无返回类型声明按 GDScript 语法必然以 `:` 结尾,正则要求 `)` 后只跟 `->`/注释/行尾,R2 目标形态 100% 失配(R2 从上线起恒零命中恒绿);②`^(\s*)func` 不认 `static ` 前缀,static 函数对 R2/R3 整体漏网。实证存量(闸当前退出码 0):core/level_runner.gd:632、core/attunement.gd:10、presentation/main.gd:565、presentation/views/hud_presenter.gd:10-11、core/reward_economy.gd:104/119/131/146、core/unit_container.gd:275(写卡会话路径订正:hud_presenter 实址 game/presentation/hud_presenter.gd,非 views/)。属架构文档测试域自警的「规则扫描面为空=恒绿」静默失效模式(零命中自检因 R1/R3 仍有命中能力未拦住)。2026-10-25 规则修订(改动四类):本件属工程改动(闸件修复,直改类)。执行口径=修 `tools/audit_type_hints.py:29` FUNC_DECL 正则两洞(①无返回类型声明的声明形态恒失配;②`^(\s*)func` 不认 `static ` 前缀),存量以开工时盘面清点(实证九址为已知下限),验收走撤销证明。原需求卡片按违形退役:结论已回写本条目,卡片删除,全稿查 git 历史(提交 546e5113)。
|
||||
|
||||
**改动面**:工具代码
|
||||
|
||||
**状态**:待执行
|
||||
|
||||
#### S13 gdstyle 免名单把数字当身份——存量债改小也报「基线外新违规」(2026-10-25 登记,来源=批次移交)
|
||||
|
||||
**实况**:工程债证据=迭代 35 卡② 合回前后实测(master 合回笔 `5499eb9c`)。闸件 `tools/gdstyle_gate.py:82` 把每条违规登记成三元组「文件|规则|消息全文」,而 gdstyle 的消息文本里带具体数字(如 `function 'resume_adventure' is 104 lines long (max 50)`),基线 `tools/gdstyle_baseline.txt`(241 行)按整句逐字比对——**只要某函数的行数/分支数/变量数发生变化,老违规就匹配不上,被判「基线外新违规」并判红,改小也算新增**。卡② 一批即因此冒出 12 项假新增,逐条对基线旧值核实全是存量债的计数漂移:`config_db_cross_validator.cross_validate` 159→107 行/31→21 分支/39→24 局部/嵌套 6→5(本批按卡片删除跨表校验④整段所致,债变小)、`level_runner` 类变量 40→38 且其「文件 1013 行超长」违规已消失(债被还掉)、`start_level_external` 参数 8→7、`main.gd` 1509→1507、`adventure_runner` 类变量 43→42/文件 1050→1051/`resume_adventure` 104→108 行(本批加断点代差标记键拒绝检查多 4 行)。本批真正新写的超标仅 1 处(新函数 `validate_graph` 72 行/20 分支),已当场拆成四段修掉。**盘面后果**:卡② 按用户令零复跑合回,master 尖 5499eb9c 从未整套跑绿过代码域闸;下一次任何批跑代码域闸都会看到 S13 红这 12 项(不处理则每批重复一次「要么重生成基线、要么被红挡在合回前」)。卡片裁决留档(卡片已违形退役,git 历史可考):四待裁点已拍板——稳定身份键/恶化判据超登记值即红/本批治本+批内刷新基线/refresh 加对账自检与骤降守卫;验收按 2026-10-24 撤销证明口径执行。2026-10-25 规则修订(改动四类):本件属工程改动(闸件修复,直改类)——原卡片按违形退役,结论已回写本条目,卡片删除,全稿查 git 历史(提交 36b444eb);执行口径=治本档(四待裁点已拍板项照录上文),用户发令直改。
|
||||
|
||||
两档方案(第一条只治标):① 治标=人工跑一次 `python tools/gdstyle_gate.py --refresh` 重生成基线+一笔提交,约 5 分钟,但键形态未改,下一批再动这些文件还会重演;② 治本=改 `tools/gdstyle_gate.py` 的键构造段(:77-90,约 10–20 行)为「文件|规则|函数名」——函数名从消息里正则提取 `function 'x'`,无函数名的条目(类变量数/文件长度)退化为「文件|规则」,并**另加一条恶化判据**防新键吞掉真问题(同一函数当前指标较基线登记值恶化超阈值即判红,纯规范化数字会把 104→300 行的恶化也放过去,不可只靠数字抹平);随动=重生成 `tools/gdstyle_baseline.txt`(241 行按新键重排)、`tools/run_all_gates.sh` 头注与 `game/tests/README.md` 工具速查表的 S13 描述各一行、撤销证明四项(新增一处真超标必红/同函数改小改大的数字漂移禁止再冒新/恶化超阈值必红/禁闸内自动重生成清基线换绿的自检仍绿——各配撤销该判据见红+还原复绿)。合计约 **0.5 个工作日**,工程改动(tools/ 闸机面)直改类。
|
||||
|
||||
**改动面**:文档+工具代码
|
||||
|
||||
**状态**:待执行
|
||||
|
||||
#### S6/S7/S8 静态规则落地——编排唯一性/禁 await/信号纪律三闸(2026-10-24 登记,来源=审计发现)
|
||||
|
||||
**实况**:工程债证据=reports/审计-game代码结构审查-2026-10-24.md §二 C2:三规则 static_scan.sh TODO 在案(架构文档静态扫描表自认未落地)——S6 core↔core 信号禁 lambda 捕获 self、S7 B2/B3/B4 API 符号命中文件 ⊆ B1 文件集、S8 结算路径 await 零命中。2026-10-24 审查人工 grep 结论干净(core 零 await、A2/B3/B4 零相互直调),但防线缺位=回归无闸。S7 前置:须先在架构文档成文 B1 文件集边界(含 core/settlement/ 五段类与 damage_controller——现归属表零条目,见「架构与规范对齐批」条目①)。**2026-10-24 用户裁:条目整条冻结待④(「架构与规范对齐批」)裁决后再写卡**——写卡会话核对结论:S6(core 信号禁 lambda)与 S8(结算路径禁 await,文件集可按现行结算文件直接枚举)与④零依赖、技术上可先行,但按「先裁④再动③」整条冻结不先行。
|
||||
**实况**:工程债证据=reports/审计-game代码结构审查-2026-10-24.md §二 C2:三规则 static_scan.sh TODO 在案(架构文档静态扫描表自认未落地)——S6 core↔core 信号禁 lambda 捕获 self、S7 B2/B3/B4 API 符号命中文件 ⊆ B1 文件集、S8 结算路径 await 零命中。2026-10-24 审查人工 grep 结论干净(core 零 await、A2/B3/B4 零相互直调),但防线缺位=回归无闸。S7 前置:须先在架构文档成文 B1 文件集边界(含 core/settlement/ 五段类与 damage_controller——现归属表零条目,见「架构与规范对齐批」条目①;2026-10-25 该前置已落文备齐,冻结状态不变)。**2026-10-24 用户裁:条目整条冻结待④(「架构与规范对齐批」)裁决后再写卡**——写卡会话核对结论:S6(core 信号禁 lambda)与 S8(结算路径禁 await,文件集可按现行结算文件直接枚举)与④零依赖、技术上可先行,但按「先裁④再动③」整条冻结不先行。
|
||||
|
||||
**改动面**:工具代码
|
||||
|
||||
@@ -73,7 +55,9 @@
|
||||
|
||||
**实况**:审计报告=reports/审计-game代码结构审查-2026-10-24.md(§二 C3/C4/C5+§三 漂移清单)。漂移与待裁件七件:①架构文档「模块归属」多行 API 清单与实现不符(A2 try_* 便捷形/B2 ambush_grant_plan/B4 equivalence_supply 不存在;实有 grant_reserve_ap/finish_round_stop/check_skill_unlocks 未登记;damage_controller 与 settlement/ 五段类零条目——S7 落地的前置);②code-conventions §1.3 核心写调用位置——三拆件控制器(presentation/curio_interact_controller.gd、camp_shop_presenter.gd、treasure_interact_controller.gd)持写调用 vs 规范「只允许在组合根出现」的 spec-AC 冲突,须裁「改规范成文组合根家族」vs「调用收回 main」;③A3→EffectEngine 反向依赖(core/action_economy.gd:43-49)——真违约或事实源失真二选一(effect_engine 降层登记基础层 vs B1 代发 vs 仅补登记);④架构文档 :149/151 层合同计数写死 17 项 vs LAYER_CONTRACT 实 18 项;⑤明细行协议三处三个数(头注 9/实发 13/架构文档 15);⑥§1.3 例举 submit_window_selection 符号已退役;⑦core/effect_engine.gd:360 校验文案「9 项」实为 18 项。
|
||||
|
||||
**缺口**:一次 doc-design 会话逐点裁决(②③有方案取舍须用户拍板,①④⑤⑥⑦为机械对齐);裁决后走文档设计改动直改写入 design/engineering/。
|
||||
**2026-10-25 部分落文(用户令执行已裁件)**:⑤明细行协议两层化(基础 9 类+扩展行 1 类;文档只写概念与指引,效果身份清单指向实现侧 battle_orchestrator.gd 头注,专长实名串永不入文档词表)落战斗结算.md 明细流水节+验收标准+来源类别豁免封闭清单五类对齐;①归属表 API 对齐实现实况(A2 撤 try_* 便捷形换查询只读面、A3 补 grant_reserve_ap/finish_round_stop、B2 换 check_skill_unlocks、B4 撤 equivalence_supply、level_runner 撤幻影 grant_node_active)+damage_controller 与 settlement/ 五段段类两行入表+B1 域文件集成文(S7 判据来源已备);④层合同计数 17→18(实数核对);⑥§1.3 例举换代 player_request_refresh。凭据=architecture.md v1.10+战斗结算.md/code-conventions.md(本批 git 提交)。
|
||||
|
||||
**缺口**:②核心写调用位置(案甲改规范成文「组合根家族=main+三拆件控制器」vs 案乙调用经回调收口回 main——乙涉游戏代码须转需求通道)与③A3→EffectEngine 反向依赖(案 a effect_engine 降登记基础层 vs 案 b B1 代发改码 vs 案 c 仅补登记消费依赖)两裁决点待用户拍板,裁后落文闭合条目;⑦校验文案改数属游戏代码字符串修订,归需求改动通道随卡顺带。
|
||||
|
||||
**改动面**:文档
|
||||
|
||||
|
||||
Reference in new issue
Block a user