Files
gplan-2/docs/architecture/adr-0006-board-node2d-rendering.md
T

142 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-0006: 战斗棋盘 Node2D 渲染迁移(Board Node2D Rendering Migration)
## Status
Accepted(2026-09-23 用户拍板方向;本 ADR 落文。Phase A 棋盘实施另批执行;B 区舞台迁移为后续批,本 ADR 只定分工不排期)
部分取代 ADR-0003 Decision 3(形态条款定向 Node2D,「禁盲目迁移」解除;autoload 清单 / 类形态 / CJK 字体前置等其余条款不变)
## Date
2026-09-23
## Engine Compatibility
| Field | Value |
|-------|-------|
| **Engine** | Godot 4.7.2-stable |
| **Domain** | UI / 棋盘渲染 |
| **Knowledge Risk** | MEDIUM(SubViewport 内 theme 传播与像素缩放纹路两项待实施批实证;其余为已验证引擎面) |
| **References Consulted** | `docs/engine-reference/godot/`;ADR-0003 Decision 3 形态对比留档;art-bible §8.2 画布暂定档 |
| **Post-Cutoff APIs Used** | None |
| **Verification Required** | SubViewport 内 CJK 字体显式注入核对(实施批);分辨率两档装板校验(实施批) |
## ADR Dependencies
| Field | Value |
|-------|-------|
| **Depends On** | ADR-0001(组合根接线纪律)、ADR-0002(渲染器与窗口键)、ADR-0003(场景结构与渲染形态——本 ADR 修订其 Decision 3) |
| **Enables** | 表现层升级(B 区站桩 / 意图三档动画 / P3 演出需要 Node2D 载体);美术终稿资产 1:1 换入的槽位体系 |
| **Blocks** | 无(B 区舞台迁移为本 ADR 分工内的后续批,不阻塞他批) |
| **Amends** | ADR-0003 Decision 3(逐格控件形态维持条款)与 Alternative 2(逐格 Node2D 否决——否决理由「无必要」因表现层升级需求不再成立,节点开销论据维持有效) |
## Context
### Problem Statement
ADR-0003 Decision 3 将棋盘渲染冻结为「GridContainer + 逐格常驻控件」,并登记 _draw/自绘迁移为 D1 正式化候选、迁移前禁盲目动手(探针耦合是登记成本)。2026-09-23 用户拍板:表现层走 Node2D 重构,**只迁战斗棋盘**,开始菜单(ui_assembler build_start_overlay)与各覆盖层保持 Control——分工不是替换。原「禁盲目迁移」条款与现行裁决冲突,需要新 ADR 定向解禁并落分工边界。
### Constraints
- 战斗屏四区布局与分区尺寸是 HUD框架 结构冻结项——本迁移只换渲染技术,四区结构、双舞台常驻、尺寸表零改动(战斗屏进度条退场与四区→三区重排由停点前移批按文档修订流程另行落地,与本批解耦)
- 组合根纪律(ADR-0001):核心写调用唯一落点不变;BoardView 信号外发 + 只读注入模式不变
- 性能预算(HUD框架 引用值):同屏 draw calls < 200;进入战斗屏 500ms 内首格可点
- 美术终稿资产全部缺位(样张批未跑)——迁移必须以程序化占位服役为前提,不新增素材前置
- core/ 零 UI 依赖(D2 Rule 7)——本迁移全部发生在 presentation/,逻辑层零接触
### Requirements
- B 区战斗画面(站桩立绘、意图三档动画、受击/死亡演出)的后续迁移不被本批堵死——骨架同构可复制
- 分辨率两档(1280×800 / 1920×1080,2026-09-22 定案)与「格边长按分辨率档位计算」口径(2026-09-18 拍板,推翻两档定值冻结)继续成立
- 三探针(ui_probe / ui_click_probe / ui_layout_probe)与冒烟全量基线不破
## Decision
**1. D 区棋盘本体迁 Node2D 渲染,BoardView 类名与公共面契约保持不变。**
BoardView(`presentation/views/board_view.gd`,现 extends Control + 内部 GridContainer)重构为:Control 壳参与屏幕栅格布局不变,壳内经 **SubViewportContainer + SubViewport + Node2D 世界**(BoardWorld)渲染棋盘。对外契约逐项保持:
| 契约面 | 消费方 | 保持方式 |
|---|---|---|
| 类名 `BoardView` / extends Control | ui_assembler 组装、屏幕栅格布局 | 不变 |
| 信号 `action_requested` / `hover_forbidden` / `chord_attempted` | 组合根动作通道 | 不变 |
| `click_cell(cell, button)` 公共入口 | ui_click_probe 直调路径(ui_click_probe.gd:257–277) | 不变 |
| `_cells` 字典(Vector2i → 格单元) | ui_probe `_cells.is_empty()/.size()` 断言(ui_probe.gd:73/187)、ui_click_probe.gd:97 | 键面不变,值 Button → 格单元 Node2D |
| `board()` / `set_desaturated()` / `set_identity_resolver()` / `set_variant_mask_resolver()` / `set_cell_area()` / `rebuild()` / `refresh()` | 组合根与探针 | 不变 |
| `cell_size` 只读属性 | ui_layout_probe `get("cell_size")`(现返回 null——`_cell` 为私有名) | 增补只读属性,顺手修正 |
**2. 渲染技术分工表(本 ADR 核心裁决——「三块模型」)。**
战斗屏渲染技术按内容形态切分,与屏幕布局正交。**战斗屏目标形态 = B/C/D 三区**(2026-09-23 用户裁定:战斗画面不再保留关卡进度条——战斗结束后返回关卡画面,节点链进度只留关卡画面):
| 内容 | 渲染技术 | 批次 |
|---|---|---|
| D 区棋盘本体(格面/数字/旗/徽章/变异纹带/高亮/微光) | **Node2D**(本 ADR) | Phase A(本批立项) |
| B 区战斗舞台(主角/敌人站桩、意图三档动画、受击/死亡演出、FX) | **Node2D** | Phase B(后续批,本 ADR 只定分工) |
| A 区关卡进度条 | Control | **战斗屏退场且代码退役**(裁定见下;退场落地随停点前移批——流程未倒置前 A 区仍是战斗中唯一节点链可视面,先删致盲,本批不动其现状) |
| C 区角色信息(数据框/状态槽/立绘) | Control | 不动 |
| D 区 AP 条、按钮组、toast 槽 | Control | 不动 |
| B 区结算明细带、回合阶段指示、战斗日志 | Control(文本件) | 不动(Phase B 时留 B 区 Control 半区) |
| 全部弹层(选路/节点/结算/图例/营地/开始菜单) | Control | 不动(2026-09-23 用户拍板) |
**A 区退场形态(2026-09-23 追问裁定)**:LevelStripView **退役,不迁移**;关卡画面**不重新实现**——由 RouteOverlay(整幅节点图选路层,节点态色板语义与压缩条同族、候选按钮与放弃入口在役)升级为常驻页面承接。压缩条唯一存在理由(战斗屏无整图时的常显替代面)随零进度裁定消亡,无独有资产流失;唯一继承面 = 逻辑层节点数据面(runner 只读出口零改动)。退役删除面清单见迁移方案 §1。
**3. 命中测试 = 板级公式换算单点,非逐格 Area2D。**
鼠标输入经 BoardView 壳层 `_gui_input` 接收(Control 已有的矩形命中),格坐标 = `floor(local_pos / 格边长)` 单点公式换算——悬停/点选/双击 chord/长按全部复用现有逻辑入口。不为 144 格建 Area2D(节点开销无必要,Alternative 2 论据沿用);ADR-0003 登记的「自建命中测试」成本由此收敛为一个公式函数。无障碍面缺失为接受后果(沿 ADR-0003 Decision 3 已登记口径,键盘寻格体系延后)。
**4. 素材槽位按圣经 §8.2 暂定档预留,程序化占位继续服役。**
格单元内部为固定叠层序的精灵槽位(砖面 < 变异纹带 < 数字/徽章 < 旗 < 焦点高亮),本批全部槽位由程序化绘制填充(现行占位等价平移);终稿纹理(格面 32×32 暂定档)到位后 1:1 换入,零结构返工。**美术缺口不阻塞本迁移**——样张批终值(格边长×格源占比摩擦,v1.9 待决注记①路线)只换 `set_cell_area` 单点数值,不动架构。
**5. SubViewport 模式为两舞台统一骨架,Phase B 复制不返工。**
Phase B 届时将 BattleStageView 同构改造(PanelContainer → Control 壳 + SubViewport 舞台 + 结算明细带 Control 半区)。本批在 ui_assembler 组装侧不引入「单舞台」写死假设,SubViewport 内 theme/字体注入做成可复用挂点(两舞台共用)。
## Alternatives Considered
### Alternative 1: 维持逐格控件形态(ADR-0003 现行)
- **Cons**: 表现层升级(站桩动画/演出/FX)在 Control 树内无载体,最终仍需二次迁移;两次改造总成本高于一次定向。
- **Rejection Reason**: 2026-09-23 用户已定向 Node2D;本 ADR 职责是把方向落为工程边界。
### Alternative 2: 直挂 Node2D(Control 壳内手挂 Node2D,无 SubViewport)
- **Cons**: 屏幕坐标↔棋盘坐标换算、缩放纪律、两档分辨率适配全部自建;布局联动手工维护。
- **Rejection Reason**: SubViewportContainer 是 Control——容器栅格布局引擎原生参与,鼠标坐标引擎换算,内部分辨率固定使像素缩放纪律有单点可管。
### Alternative 3: 逐格 Area2D 承载命中
- **Cons**: 144 个 Area2D 节点开销与信号接线量;命中语义(相邻约束/chord/长按)仍要自建。
- **Rejection Reason**: 板级公式换算单点已覆盖全部交互语义,物理命中是纯开销。
### Alternative 4: TileMapLayer 承载棋盘
- **Rejection Reason**: ADR-0003 已否(瓦片语义与变体标记/数字/旗多层叠加不匹配),维持。
### Alternative 5: B 区与棋盘同批迁移
- **Cons**: B 区站桩形态绑美术样张批(剪影/动画方案未冻结),混批互卡。
- **Rejection Reason**: 2026-09-23 用户拍板分批——先只迁棋盘,战斗画面 Node 后续完成。
## Consequences
### Positive
- 表现层升级获得渲染载体;棋盘先行验证 SubViewport 骨架,B 区复制模式即可
- BoardView 公共面契约保持——三探针与组合根零改造(实证耦合面仅 `_cells` 键面/`click_cell`/`cell_size`,全部保留)
- 素材终稿 1:1 换入,样张批与渲染批解耦,互不阻塞
- 逻辑层(core/)零接触——MC/模拟试玩/verifier 读数面零影响
### Negative
- Node2D 世界内 theme 不自动继承主场景 Control 主题——CJK 字体与 ui_kit 样式需显式注入(实施批义务,ADR-0003 Decision 4 关联)
- 键盘寻格/无障碍面缺失口径延续(已登记接受)
- 非整数缩放的像素纹路风险(45/36px 锚点 × 32px 格源非整倍)——沿 §8.2 路线归样张批定终值,架构只保证 `set_cell_area` 单点可调
### Risks
- SubViewport 渲染目标在低端机的显存/带宽开销 → 缓解:棋盘区逻辑分辨率小(≤ 12×12×36px 量级),实施批实测帧预算
- 输入路径改 `_gui_input` 后现探针全走 `click_cell` 直调,公式换算无自动化覆盖 → 缓解:实施批增补 push_input 端到端输入探针(ADR-0003 已登记项,本批转义务)
## Migration Plan
Phase A(棋盘,实施另批):BoardView 内部重构 + 探针增补 + 冒烟全量回归 + 文档随批(HUD框架渲染注记/battle.md 实现注记/architecture.md 模块归属行)。Phase B(B 区舞台,后续批):同构复制 + 站桩精灵迁移 + 意图动画承载;开工前置 = 样张批冻结剪影与动画方案。战斗屏进度条退场的 GDD 修订面(HUD框架 四区表、关卡节点地图 节点链常显条款、battle.md 像素布局表与 28px 纵向空间再分配)随停点前移批(关卡画面成为常驻枢纽)落地,不随本批。工程细节见同目录 `board-node2d-migration-plan.md`。
## Validation Criteria
- 冒烟全量绿(现行基线不破);三探针(ui / ui_click / ui_layout)绿
- 新增 push_input 端到端输入探针绿(悬停/左键/右键/chord 各一case)
- 功能等价清单:数字/旗/徽章/危险红/变异纹带/呼吸微光/悬停/路径预览/灰化(set_desaturated)/出生展开区 R₀ 豁免,逐项可点可验
- 性能预算:同屏 draw calls < 200;进入战斗屏 500ms 内首格可点
- 分辨率两档(1280×800 / 1920×1080)装板校验通过(12×12 与 10×10 板各验)
## Related Decisions
- ADR-0003(本 ADR 部分取代其 Decision 3;Alternative 2 否决理由更新)
- ADR-0001(组合根纪律——BoardView 信号外发模式沿袭)
- art-bible §8.2(画布暂定档与缩放纪律)、HUD框架(四区结构冻结与性能预算引用值)、battle.md(格尺寸公式锚点)