mirror of
https://github.com/motajs/template.git
synced 2026-10-16 18:40:17 +08:00
docs(09): data-migration audit (task 8) + 09-18 per-directive revision
This commit is contained in:
parent
b544360757
commit
b6f4435b84
164
.planning/phases/09-minimum-browser-runnable/09-17-SUMMARY.md
Normal file
164
.planning/phases/09-minimum-browser-runnable/09-17-SUMMARY.md
Normal file
@ -0,0 +1,164 @@
|
||||
---
|
||||
phase: 09-minimum-browser-runnable
|
||||
plan: 17
|
||||
subsystem: data-migration
|
||||
tags: [legacy-migration, read-only-audit, tile, textures, enemy, item, npc, map, texture-list-schema]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 09-minimum-browser-runnable
|
||||
provides: "旧引擎数据(public/project)与新引擎落点(src/content)的只读映射台账"
|
||||
provides:
|
||||
- "09-DATA-MIGRATION-AUDIT.md:任务 8 只读盘点台账(§0..§9,235 tile / 17 texture / 42 split / 81 enemy / 62 item / 24 npc / 5 map)"
|
||||
affects: [data-migration-plan, texture-list-schema]
|
||||
|
||||
# Actuals (#2632) — no commit (per user instruction to leave output in working tree)
|
||||
actuals:
|
||||
tokens: 13680
|
||||
tasks: 2
|
||||
commits: 0
|
||||
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns: ["只读台账 + 执行前基线对比只读守卫 + 命名候选集中报备"]
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- ".planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md"
|
||||
modified: []
|
||||
|
||||
key-decisions:
|
||||
- "全程只读:唯一写入为盘点文档 + SUMMARY(+ 仓库外只读基线),零 .ts/.tsx、零 public/project/**、零 src/content/** 改动,零 PNG 生成"
|
||||
- "命名候选(拆分文件名 / identifier / 参数名 / .list.jsonc 字段名)只入台账并标注「待用户报备批准」,不落地"
|
||||
- "textures 维度显式含 materials/*.png + autotiles/*.png + tilesets/*.png;autotiles/tilesets 不套用 D-72⑤"
|
||||
- "D-72⑤ 读法(单帧 4×4、多帧 帧数列×4 行)与 SPLIT-COUNT=42 记入 §8 U-1 待用户确认"
|
||||
- "无法静态确定者一律入 §8「未确定项 / 待确认观察」,未登记为缺陷"
|
||||
|
||||
patterns-established:
|
||||
- "只读盘点以执行前基线(仓库外)对比作只读守卫,可检出执行期越界写入"
|
||||
|
||||
requirements-completed: []
|
||||
|
||||
coverage:
|
||||
- id: D1
|
||||
description: "只读盘点台账 09-DATA-MIGRATION-AUDIT.md(§0 口径 + §1 tile + §2 textures + §3 enemy + §4 items + §5 NPC + §6 maps + §7 schema 草案 + §8 未确定项 + §9 汇总)"
|
||||
verification:
|
||||
- kind: other
|
||||
ref: "node -e 静态门禁(AUDIT-TILE-TEX / AUDIT-MIG-FINAL:章节 / 计数 / token / 锚点有效性)+ READONLY 守卫"
|
||||
status: pass
|
||||
human_judgment: true
|
||||
rationale: "盘点的映射候选、拆分方案读法与命名候选均需用户逐项报备 / 裁定(D-73);自动化只能校验结构、计数与锚点有效性,不能替代人工确认语义"
|
||||
- id: D2
|
||||
description: "只读保证:零源码 / 零数据 / 零 PNG 改动(执行前基线对比 READONLY 门禁全绿)"
|
||||
verification:
|
||||
- kind: other
|
||||
ref: "node READONLY gate(Task 1 / Task 2)+ git status --porcelain"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
|
||||
duration: 1h
|
||||
completed: 2026-10-13
|
||||
status: complete
|
||||
---
|
||||
|
||||
# Phase 9 Plan 17: 旧引擎数据迁移只读盘点 摘要
|
||||
|
||||
**旧引擎 `public/project` 数据到新引擎接口(`ITileRawData` / `IEnemyRawData` / `IItemRawData` / `IMapRawData` / `TextureManager`)的只读映射台账:235 tile / 17 texture / 42 split / 81 enemy / 62 item / 24 npc / 5 map**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** ~1h
|
||||
- **Completed:** 2026-10-13
|
||||
- **Tasks:** 2(Task 0 为已闭环的 `blocking-human` 汇报关卡,见下)
|
||||
- **Files modified:** 1(新增盘点文档;另新增 1 份 SUMMARY)
|
||||
|
||||
## Task 0 说明(执行前汇报关卡)
|
||||
|
||||
本计划第一个 block 点是 Task 0 `checkpoint:decision@blocking-human`(AGENTS.md 硬要求 / D-03 / D-74)。**该关卡在本次执行前已闭环**:用户已就预执行汇报明确回复「可以执行」四个字(含盘点范围六类、textures 维度含 materials + autotiles + tilesets、七个维度、D-72 五条拆分规则与 tilesets/autotiles 例外、命名候选报备方式、产出路径、只读保证与开放项 OI-1..OI-6)。据此执行 Task 1 / Task 2;未再重复询问。
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- 产出只读盘点台账 `09-DATA-MIGRATION-AUDIT.md`(54718 字节 / 817 行 / 裸 LF),含 §0..§9 完整章节。
|
||||
- §1 登记 `blocksInfo` 全表 **235** 图块(8 个 `cls`)+ `cls → TileType` 与字段映射候选 + id/num 全清单。
|
||||
- §2 登记 **17** 个 PNG(materials 12 + autotiles 4 + tilesets 1)与实际像素尺寸,按 D-72 五规则给出 materials 拆分方案(目标图 **42** 张)+ autotiles/tilesets 例外参数候选。
|
||||
- §3/§4/§5/§6 分别给出 enemy(81) / items(62) / NPC(24) / maps(5) 映射候选。
|
||||
- §7 给出 `texture/.list.jsonc` 字段结构草案(与 §2 逐条一致);§8 集中登记 18 项未确定项(未登记为缺陷);§9 汇总七维度计数。
|
||||
- 全程只读:只读基线对比守卫(Task 1 / Task 2)与 `git status --porcelain` 全绿。
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md`(新增,只读盘点台账 §0..§9)
|
||||
- `.planning/phases/09-minimum-browser-runnable/09-17-SUMMARY.md`(新增,本摘要)
|
||||
|
||||
## 各维度计数
|
||||
|
||||
| 维度 | 计数 | 机器可读行 |
|
||||
| --- | --- | --- |
|
||||
| 图块 tile | 235 | `TILE-COUNT: 235` |
|
||||
| 贴图素材 textures | 17 | `MATERIAL-COUNT: 17` |
|
||||
| 素材拆分目标图 split | 42 | `SPLIT-COUNT: 42` |
|
||||
| 怪物 enemy | 81 | `ENEMY-COUNT: 81` |
|
||||
| 道具 items | 62 | `ITEM-COUNT: 62` |
|
||||
| NPC | 24 | `NPC-COUNT: 24` |
|
||||
| 地图 maps | 5 | `MAP-COUNT: 5` |
|
||||
|
||||
## 命名候选清单(待用户报备批准)
|
||||
|
||||
均**只作候选入台账,本计划不落地使用**(D-73 / AGENTS.md):
|
||||
|
||||
| 类别 | 候选 |
|
||||
| --- | --- |
|
||||
| materials 拆分图(terrains 单帧) | `terrains0.png` / `terrains1.png` / `terrains2.png` |
|
||||
| materials 拆分图(animates 并入 terrains) | `terrainsAnim0.png` … `terrainsAnim7.png` |
|
||||
| materials 拆分图(items) | `items0.png` … `items3.png` |
|
||||
| materials 拆分图(enemy) | `enemy0.png` … `enemy20.png` |
|
||||
| materials 拆分图(npc) | `npc0.png` … `npc5.png` |
|
||||
| `addAutotile` 的 `identifier` 参数 | `20` / `151` / `152` / `153` |
|
||||
| `addAutotile` 的 `type` 参数 | `AutoTileType.Big3x4` |
|
||||
| `addTileset` 的 `identifier.alias` | `magictower` |
|
||||
| `addTileset` 的 `cellWidth` / `cellHeight` | `32` / `32`(待确认) |
|
||||
| `.list.jsonc` 承载字段名 | `grid` / `rowAnimate` / `autotile` / `tileset` |
|
||||
|
||||
## OI-1..OI-6 最终裁定(本计划处置)
|
||||
|
||||
| 开放项 | 处置 |
|
||||
| --- | --- |
|
||||
| OI-1(产出文档命名 / 路径) | 采用 `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md`(Task 0 已获批) |
|
||||
| OI-2(文档章节结构) | 采用 §0..§9 五节序列(如实现) |
|
||||
| OI-3(命名候选呈现方式) | 采用「命名候选(待报备)」集中表,逐条标注「待用户报备批准」(§2.5 / §4 / §7 / §9) |
|
||||
| OI-4(拆分方案粒度,含例外) | 按 D-72 五规则逐组列出目标图 + 来源 + 帧数 + 行列布局;tilesets/autotiles 各给参数候选(§2.2–§2.4) |
|
||||
| OI-5(schema 草案深度) | 仅给 `texture/.list.jsonc` 字段结构草案与到四个方法的对应,不含最终命名落地(§7) |
|
||||
| OI-6(未确定项与只读守卫口径) | 无法确定者一律入 §8(未登记为缺陷);只读守卫采用「执行前基线对比」,基线由 Task 1 步骤 (0) 一次性写入仓库外,`<verify>` 幂等不覆写 |
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None - plan executed exactly as written(Task 0 关卡已预先闭环;无源码 / 数据 / PNG 改动;无命名落地)。
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
无。所有静态门禁(Task 1:基线幂等 + 结构 / 计数 / token / 锚点 + READONLY;Task 2:结构 / 七计数 / token / 锚点 + READONLY + `git status`)全绿。
|
||||
|
||||
## 只读确认
|
||||
|
||||
- 未修改 / 删除 / 新增任何生产 `.ts` / `.tsx` 源码。
|
||||
- 未修改 / 删除 / 新增任何 `public/project/**` 与 `src/content/**` 数据文件。
|
||||
- 未生成任何 `.png`;未改动任何既有注释;未改 `ROADMAP.md` / `STATE.md` / `09-CONTEXT.md`。
|
||||
- 唯一新增文件为盘点文档与本 SUMMARY(另在仓库外临时目录写入只读基线 `%TEMP%/opencode/gsd-09-17-baseline.txt`)。
|
||||
- 未执行 `git add` / `git commit`(按执行指示将产出留在工作树,供用户审阅后自行决定提交);未触碰用户并发改动(`AGENTS.md`)。
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
- 盘点台账已可直接供后续「旧引擎数据迁移」计划消费(字段映射候选 + 拆分方案 + 命名候选)。
|
||||
- §8 的 18 项未确定项与 §2.5 命名候选待用户裁定 / 报备后,方可进入迁移实施计划。
|
||||
|
||||
## Self-Check
|
||||
|
||||
- FOUND: `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md`
|
||||
- FOUND: `.planning/phases/09-minimum-browser-runnable/09-17-SUMMARY.md`
|
||||
- COMMITS: 0(按执行指示未提交,产出留在工作树)
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
---
|
||||
*Phase: 09-minimum-browser-runnable*
|
||||
*Completed: 2026-10-13*
|
||||
350
.planning/phases/09-minimum-browser-runnable/09-18-PLAN.md
Normal file
350
.planning/phases/09-minimum-browser-runnable/09-18-PLAN.md
Normal file
@ -0,0 +1,350 @@
|
||||
---
|
||||
phase: 09-minimum-browser-runnable
|
||||
plan: 18
|
||||
type: execute
|
||||
wave: 15
|
||||
depends_on: [09-17]
|
||||
files_modified:
|
||||
- .planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md
|
||||
- .planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md
|
||||
autonomous: false
|
||||
requirements: []
|
||||
estimate:
|
||||
tokens: 60000
|
||||
raw_tokens: 60000
|
||||
tasks: 3
|
||||
confidence: low
|
||||
must_haves:
|
||||
truths:
|
||||
- "**本计划的第一个 block 点是 Task 0 的 `blocking-human` 汇报关卡(AGENTS.md 硬要求,D-03 / D-74)**:Task 0 必须先汇报「本计划 = 09-18 · 按用户 2026-10-13 四条指示**修订**既有的 `09-DATA-MIGRATION-AUDIT.md`(只读盘点台账,09-17 产出)」的要做什么 / 为什么 / 大致怎么做 / 影响范围,**必须列明:四条指示的逐条落实方式、只读保证、修订方式(派发子代理执行)、产出文件(`09-DATA-MIGRATION-AUDIT.md` 原地修订 + 新增 `09-18-SUMMARY.md`)、静态门禁方式与计数一致性要求**,然后必须**停下等待**用户明确回复「可以执行」四个字;未收到前不得执行本计划任何一步、不得派发执行子代理,且不因触发方式或 `mode: yolo` / `workflow.auto_advance` 自动放行。"
|
||||
- "**指令 1(`animates` 合并至 `terrains`,确认 D-72③):** 在 §0(D-72 规则原文处)**及** §2(§2.1 登记 / §2.4 拆分方案 / §2.5 命名候选)**及** §5 相关处,以及一切出现 `animates` / `terrains` 归属的位置(§1.1 / §1.4 / §9),以一致表述强化「`animates` 并入 `terrains`,不设独立 `animates` 素材组」,消除「`animates` 是否仍为独立素材组」的歧义;同时明确区分「逻辑类型映射(§1.1 `animates` → `TileType.Animate`,保留)」与「素材 / 分图分组(`animates` 素材并入 `terrains` 组,D-72③)」。"
|
||||
- "**指令 2(严格界定「只记录、不移植」):** 「只记录、不移植」**仅**当新接口(`ITileRawData` / `ITilePassData` / `IEnemyRawData` / `IItemRawData` / `IMapRawData`)**不存在对应字段**时适用;据此在 §1 / §3 / §4 / §6 的映射候选表**逐字段显式标注**三类(映射候选可确定 / 有目标字段但映射不确定 → 待定 / 无目标字段 → 只记录、不移植),并在 §8 **重构**为 §8.1「无目标字段 → 只记录、不移植」与 §8.2「有目标字段但映射不确定 → 待定」两分区(保留非字段级观察为 §8.3);**不得**把有明确目标字段的项(如旧 tile `trigger` → `ITileRawData.events` / `eventPass`、旧 map `events` → `IMapRawData.events`)误标为「只记录、不移植」。"
|
||||
- "**指令 3(图块 `num` 可全部重新排序):** §1 须明确「图块 `num` 可全部重新分配,不沿用旧引擎顺序,唯一约束是 `id` ↔ `num` 一致」;给出 **235 条 `id` 全清单**与 **新 `num` 分配策略候选**(≥3 个策略,均标注「待用户报备批准」);旧 `num` 仅作参考对照。"
|
||||
- "**指令 4(`texture/.list.jsonc` schema 须显式类型声明):** §7 草案必须给出**显式的 TypeScript 类型声明**(`interface` 与 `type` 别名形式,可读、可落地参考),至少含四个 entry 接口(grid / rowAnimate / autotile / tileset)、四者联合类型别名、顶层配置接口;而非仅文字描述;所有新增命名仍标注「待用户报备批准」。"
|
||||
- "**只读边界(D-74 / D-75):** 本计划**唯一允许写入**的两份 `.md` 为 `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md`(原地修订)与 `.planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md`(新增);**零** `.ts` / `.tsx` 改动、**零** `public/project/**` 改动、**零** `src/content/**` 改动、**零** `.png` 生成;**不得**改 09-17 计划 / 摘要、`ROADMAP.md`、`STATE.md`、`09-CONTEXT.md`;命名仍只作「命名候选(待报备)」。"
|
||||
- "**计数一致 + 保留既有正确内容:** 修订只做增改;既有正确内容保留;机器可读计数行保持一致(`TILE-COUNT: 235` / `MATERIAL-COUNT: 17` / `SPLIT-COUNT: 42` / `ENEMY-COUNT: 81` / `ITEM-COUNT: 62` / `NPC-COUNT: 24` / `MAP-COUNT: 5`);若因重构导致行数变化,计数行与各节须同步一致。"
|
||||
- "**锚点真实 + 观察纪律:** 台账 `file:line` 锚点必须指向真实存在且行号在范围内的行;无法从阅读 / 静态解析唯一确定者一律入 §8(不猜测编造);疑似问题**不得**登记为缺陷,只作待确认观察。"
|
||||
artifacts:
|
||||
- path: .planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md
|
||||
provides: "按用户四条指示修订后的只读盘点台账:§0(`animates` 并入 `terrains` 强化表述)、§1(`num` 可全部重排说明 + `id` 全清单 + 新 `num` 分配策略候选 + 字段分类标注)、§2(`animates` 并入 `terrains` 强化)、§3 / §4 / §6(字段分类标注)、§5(交叉引用)、§7(显式 TypeScript 类型声明)、§8(重构为 8.1 只记录 / 8.2 待定 / 8.3 其他)、§9(计数与命名说明)。"
|
||||
- path: .planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md
|
||||
provides: "本修订计划的执行摘要:四条指示的落实位置、命名候选清单、各维度计数(不变)、只读确认、遗留待用户裁定项。"
|
||||
key_links:
|
||||
- "`09-DATA-MIGRATION-AUDIT.md` §1.2 / §3.1 / §4.2 / §6.2 的分类标注 ↔ `packages-user/data-common/src/store/types.ts`(`ITilePassData`:38 / `ITileRawData`:47 / `IItemEffect`:138 / `IItemEquipData`:161 / `IItemRawData`:176 / `IMapRawData`:260 / `IEnemyRawData`:319)—— 「是否有对应目标字段」的唯一判定基准"
|
||||
- "`09-DATA-MIGRATION-AUDIT.md` §7 显式 TypeScript 类型声明 ↔ `packages-user/client-base/src/material/types.ts`(`AutotileType`:12 / `IIndexedIdentifier`:50 / `addGrid`:261 / `addRowAnimate`:275 / `addAutotile`:289 / `addTileset`:302)—— schema 类型声明的能力依据"
|
||||
- "`09-DATA-MIGRATION-AUDIT.md` §2.4 / §2.5(`animates` 并入 `terrains`)↔ D-72③ —— 指令 1 的规则依据"
|
||||
- "`src/content/client.jsonc`:9(`textureListDir: texture/.list.jsonc`)/ `src/content/texture/.list.jsonc`:1(现状 `{}`)—— §7 schema 草案落点侧参考(D-70 消费接线由用户后续提供)"
|
||||
assumptions:
|
||||
- "**执行日行号可能漂移**:本计划内引用行号为 2026-10-13 规划日实测;文档锚点与门禁以**执行日实测**为准,门禁按「文件存在 + 行号在范围内」校验,不硬编码任何行号。"
|
||||
- "**被修订对象为工作树未跟踪产物**:`09-DATA-MIGRATION-AUDIT.md` 与 `09-17-SUMMARY.md` 由 09-17 产出、当前在工作树中未提交;本计划**原地修订**该文档,不新建。"
|
||||
- "**用户并发改动(D-56)**:工作树已有用户并发改动(`AGENTS.md` 处于 `M`);本计划只读守卫采用「执行前基线对比」,仅对本计划执行期**新增**的 `.ts` / `.tsx` / `public/project/**` / `src/content/**` 改动判红,不触碰、不暂存、不提交用户既有改动。"
|
||||
- "**用户指示中「§5」的定位**:本文档 §5 为 NPC 节,其正文与 `animates` / `terrains` 无关;故「§0 / §2 / §5 相关处」按「一切出现 `animates` / `terrains` 归属的位置优先,§5 以交叉引用方式落实」执行,避免在 NPC 节强塞无关内容。"
|
||||
- "**Markdown 使用 LF**:仓库既有 phase 文档与盘点产物均为裸 LF;修订随此约定(**不**强制 CRLF)。"
|
||||
prohibitions:
|
||||
- "不得在用户明确回复「可以执行」四个字之前执行本计划的任何任务、或派发任何执行子代理。"
|
||||
- "**只读边界:** 除 `09-DATA-MIGRATION-AUDIT.md`(原地修订)与 `09-18-SUMMARY.md`(新增)两份 `.md` 外,**不得写入任何文件**;**不得**修改 / 删除 / 新增任何生产 `.ts` / `.tsx`;**不得**改 `public/project/**` 与 `src/content/**`;**不得生成任何 `.png`**;**不得**改 09-17 计划 / 摘要、`ROADMAP.md`、`STATE.md`、`09-CONTEXT.md`。"
|
||||
- "**命名边界:** 修订中提出的任何新增 / 修改命名(`num` 分配策略、`texture/.list.jsonc` 字段名与 TypeScript 类型名等)**只能作为「命名候选」写入台账并标注「待用户报备批准」**,**不得落地使用**、**不得写入任何 `src/content/**` 文件**(D-73 / AGENTS.md:公共 / 受保护 / 私有方法、字段命名须先报备获批)。"
|
||||
- "**分类纪律:** 只有目标接口**确实无对应字段**的旧字段才可标注「只记录、不移植」;**不得**把有明确目标字段的项误标为只记录;判定须引用执行日实测的接口定义作为依据。"
|
||||
- "**不得臆造条目:** 文档中每个 `file:line` 锚点必须指向真实存在且范围内的一行;**不得**编造字段名 / 映射关系 / 尺寸。"
|
||||
- "**不得把观察当缺陷:** 发现的任何「疑似问题 / 不一致 / 缺失」**不得登记为缺陷**,只能写入 §8「未确定项 / 待确认观察」。"
|
||||
- "**不得破坏既有正确内容:** 只按四条指示增改;既有正确的章节、表格、计数与锚点须保留;计数行若因重构变化须同步一致(本计划预期七项计数不变)。"
|
||||
- "不得把门禁建立在「全仓 TS 诊断数」「`pnpm check:type`」「`pnpm build`」之上;不得为了「验证」去改动源码或数据。"
|
||||
- "不得触碰、暂存、提交用户的并发改动(D-56):提交前 `git status` 逐条核对暂存面,只暂存本计划 `files_modified` 的条目。"
|
||||
open_items:
|
||||
- "**OI-1(`num` 分配策略候选):** §1 将给出 ≥3 个 `num` 分配策略候选(如「按 `TileType` 分段」「沿用旧 `num`」「按目标贴图分组顺序」「按 `id` 次序」),均标注「待用户报备批准」。**待用户裁定采用何种策略**(本计划只记录候选,不落地)。"
|
||||
- "**OI-2(`texture/.list.jsonc` 类型声明命名):** §7 将给出候选 TypeScript 类型名(entry 接口、联合别名、顶层配置接口)与字段名,均标注「待用户报备批准」。**待用户报备批准命名**(D-73)。"
|
||||
- "**OI-3(用户指示中的「§5」):** 本文档 §5 为 NPC 节,与 `animates` / `terrains` 无关;本计划以「§0 / §2 为主 + §5 交叉引用」方式落实指令 1。**待用户确认该处理方式。**"
|
||||
- "**OI-4(`animates` 逻辑类型与素材分组的区分):** 本计划明确「§1.1 `animates` → `TileType.Animate`(逻辑类型,保留)」与「素材 / 分图分组并入 `terrains`(D-72③)」为两件事。**待用户确认该消歧方式。**"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Phase 9 · 任务 8 后续 · 第 18 个计划 —— **按用户 2026-10-13 四条指示,原地修订 09-17 产出的只读盘点台账 `09-DATA-MIGRATION-AUDIT.md`**(**不实施实际迁移**)。
|
||||
|
||||
**要解决的问题(用户四条指示 + D-70..D-75):** 09-17 产出的盘点台账存在四处需要收敛之处:① `animates` 并入 `terrains`(D-72③)的表述散布在 §0 / §1 / §2 / §9,易于被理解为「`animates` 仍为独立素材组」,需强化到无歧义;② 文档把「无目标字段(只记录、不移植)」与「有目标字段但映射不确定(待定)」混在一起(尤见 §8 与 §1.2 / §3.1 / §4.2 / §6.2),需按「新接口是否存在对应字段」严格二分,并在各映射候选表逐字段显式标注;③ 图块 `num` 被默认为沿用旧引擎顺序,需明确「`num` 可全部重新分配,只要 `id` ↔ `num` 一致」,并给出 `id` 全清单与新 `num` 分配策略候选;④ §7 的 `texture/.list.jsonc` schema 草案仅有文字描述,需补上**显式 TypeScript 类型声明**。**本计划只修订文档,不改任何源码 / 数据、不生成素材、不实施迁移。**
|
||||
|
||||
**大致解决方案(本计划 = 09-18):**
|
||||
- **Task 0(`checkpoint:decision@blocking-human`)= 预执行汇报关卡**:汇报本修订计划要解决的问题(上述四处)、四条指示的逐条落实方式、只读保证、修订方式(**派发子代理执行**)、产出文件、静态门禁与计数一致性要求,并等待用户「可以执行」。
|
||||
- **Task 1 = 指令 1(§0 部分)+ 指令 2(§1 部分)+ 指令 3**:采集只读基线;在 §0 强化 `animates` 并入 `terrains`(D-72③);在 §1 加入「`num` 可全部重新分配」说明与 §1.5「`id` 全清单 + 新 `num` 分配策略候选(待报备)」;在 §1.2 逐字段加分类标注;§1.4 同步强化。
|
||||
- **Task 2 = 指令 1(§2 / §5 / §9)+ 指令 2(§3 / §4 / §6 + §8 重构)+ 指令 4(§7)**:在 §2 / §5 / §9 强化 `animates` 并入 `terrains`;在 §3 / §4 / §6 逐字段加分类标注;重构 §8 为 8.1 / 8.2 / 8.3;在 §7 补显式 TypeScript 类型声明;收口跑最终静态门禁并写 `09-18-SUMMARY.md`。
|
||||
|
||||
**为何分两个工作任务:** 指令 1 与指令 3 都以 §1 为主承载区,合并在 Task 1 一次成形;指令 2(§3 / §4 / §6 + §8)与指令 4(§7)与指令 1 的余下位置(§2 / §5 / §9)合并到 Task 2,避免对同一节反复改写、并让 §8 的二分在 §1 / §3 / §4 / §6 标注全部就位后集中完成。两任务同属一个只读文档的原地修订,无 `files_modified` 外扩。
|
||||
|
||||
**修改方式声明(AGENTS.md):** 本计划的文档修订由**派发子代理(`gsd-executor`)执行**,非内联执行;除 `files_modified` 两份 `.md` 外无任何写入。
|
||||
|
||||
**API coverage:** `detected:false`。**`No external API integration: 本计划仅为只读盘点台账的文档修订,不涉及任何外部 API。`**
|
||||
</objective>
|
||||
<execution_context>
|
||||
@C:/Users/13194/.config/opencode/gsd-core/workflows/execute-plan.md
|
||||
@C:/Users/13194/.config/opencode/gsd-core/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/phases/09-minimum-browser-runnable/09-CONTEXT.md
|
||||
@.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md
|
||||
@.planning/phases/09-minimum-browser-runnable/09-17-SUMMARY.md
|
||||
@AGENTS.md
|
||||
@dev.md
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="checkpoint:decision" gate="blocking-human">
|
||||
<name>Task 0: 预执行汇报关卡 —— 汇报「按用户四条指示修订 09-DATA-MIGRATION-AUDIT.md」的要做什么 / 为什么 / 大致怎么做 / 影响范围,等待用户回复「可以执行」</name>
|
||||
<precondition>`09-DATA-MIGRATION-AUDIT.md`(09-17 产出)已存在;`packages-user/data-common/src/store/types.ts`、`packages-user/client-base/src/material/types.ts`、`src/content/texture/.list.jsonc`、`src/content/tile.jsonc` 均存在;`09-18-SUMMARY.md` **尚不存在**。</precondition>
|
||||
<files>(只读汇报,不修改任何文件)</files>
|
||||
<read_first>
|
||||
- .planning/phases/09-minimum-browser-runnable/09-CONTEXT.md(D-03 / D-04 / D-06 / **D-70 / D-71 / D-72 / D-73 / D-74 / D-75**)
|
||||
- .planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md(被修订对象现状:§0..§9)
|
||||
- .planning/phases/09-minimum-browser-runnable/09-17-SUMMARY.md(上游摘要,只读参考)
|
||||
- .planning/phases/09-minimum-browser-runnable/09-18-PLAN.md(本计划全文,含四条指示的落实方式与 OI-1..OI-4)
|
||||
- AGENTS.md(执行前须获批、命名须先反馈、修改方式须预先声明);dev.md(命名规则、注释规范、Markdown 连字符命名)
|
||||
</read_first>
|
||||
<action>
|
||||
**停下并向用户汇报,等待明确回复「可以执行」后才继续;汇报本身只读。**
|
||||
|
||||
① **要解决的问题:** 09-17 产出的只读盘点台账 `09-DATA-MIGRATION-AUDIT.md` 有四处需按用户 2026-10-13 指示收敛:**①** `animates` 并入 `terrains`(D-72③)表述需强化到无歧义;**②** 「无目标字段 → 只记录、不移植」与「有目标字段但映射不确定 → 待定」需严格二分并逐字段标注;**③** 图块 `num` 需明确可全部重新分配(`id` ↔ `num` 一致即可)并给出 `id` 全清单与新 `num` 分配策略候选;**④** §7 的 `texture/.list.jsonc` schema 需补显式 TypeScript 类型声明。**只修订文档,不迁移。**
|
||||
|
||||
② **范围与产出:** 只修订 `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md`(原地);另新增 `.planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md`。**全程只读**:零 `.ts` / `.tsx` 改动、零 `public/project/**` 与 `src/content/**` 改动、零 `.png` 生成;不改 09-17 计划 / 摘要、`ROADMAP.md`、`STATE.md`、`09-CONTEXT.md`。
|
||||
|
||||
③ **四条指示的逐条落实方式:**
|
||||
- **指令 1(`animates` 合并至 `terrains`,确认 D-72③):** 在 §0(D-72 原文处)与 §2(§2.1 / §2.4 / §2.5)及 §5,以及一切出现 `animates` / `terrains` 的位置(§1.1 / §1.4 / §9)强化固定表述「`animates` 并入 `terrains`,不设独立 `animates` 素材组」;并区分「§1.1 逻辑类型映射 `animates` → `TileType.Animate`(保留)」与「素材 / 分图分组并入 `terrains`(D-72③)」。
|
||||
- **指令 2(严格界定「只记录、不移植」):** 判定基准为 `ITileRawData` / `ITilePassData` / `IEnemyRawData` / `IItemRawData` / `IMapRawData`(`packages-user/data-common/src/store/types.ts`);**仅当接口不存在对应字段**才标「只记录、不移植」;§1 / §3 / §4 / §6 的映射表逐字段标注三类;§8 重构为 §8.1「无目标字段 → 只记录、不移植」与 §8.2「有目标字段但映射不确定 → 待定」(非字段级观察入 §8.3);**不得**把有目标字段项(如旧 tile `trigger` → `ITileRawData.events` / `eventPass`、旧 map `events` → `IMapRawData.events`)误标为只记录。
|
||||
- **指令 3(`num` 可全部重新排序):** §1 明确「`num` 可全部重新分配,不沿用旧引擎顺序,唯一约束是 `id` ↔ `num` 一致」;新增 §1.5「`id` 全清单(235 条)+ 新 `num` 分配策略候选(≥3 个,标「待用户报备批准」)」;旧 `num` 仅作参考。
|
||||
- **指令 4(schema 须显式类型声明):** §7 增补显式 TypeScript 类型声明区块(`interface` 与 `type` 别名),至少含四个 entry 接口(grid / rowAnimate / autotile / tileset)、四者联合类型别名、顶层配置接口;所有新增命名标注「待用户报备批准」。
|
||||
|
||||
④ **只读保证(D-74 / D-75):** 唯一允许写入 = 上述两份 `.md`;禁止任何源码 / 数据写入与 PNG 生成;命名只作候选、不落地。
|
||||
|
||||
⑤ **验证方式:** 静态断言——文档存在、含 §0..§9 与 §8.1 / §8.2 分区、含七项计数(值不变)、含四条指示对应的标记 token、锚点逐一校验「文件存在 + 行号在范围内」;**只读守卫**采用「执行前基线对比」(基线由 Task 1 `<action>` 步骤 (0) 一次性写入仓库外临时目录,`<verify>` 断言幂等不覆写)。**不设全仓类型 / 构建门禁。**
|
||||
|
||||
⑥ **修改方式声明(AGENTS.md):** 本修订由**派发子代理执行**(`gsd-executor`),非内联执行。
|
||||
|
||||
⑦ **开放项:** OI-1(`num` 分配策略候选,待裁定)、OI-2(`texture/.list.jsonc` 类型命名候选,待报备)、OI-3(用户指示中「§5」的定位:本文档 §5 为 NPC 节,以交叉引用落实)、OI-4(`animates` 逻辑类型与素材分组的消歧方式,待确认)。
|
||||
|
||||
⑧ **关卡性质:** **无论触发方式或 `mode: yolo` / `workflow.auto_advance`,执行者 / 子代理必须停下等待用户明确回复「可以执行」四个字**;回复其它内容视为未通过;若用户给出修订意见,退出本计划、修订后重新汇报。
|
||||
</action>
|
||||
<decision>是否按本计划(09-18)执行「按用户四条指示修订 `09-DATA-MIGRATION-AUDIT.md`」(原地修订文档 + 新增 `09-18-SUMMARY.md`;只读,不改任何源码与数据,不生成素材,不实施迁移),并按 OI-1..OI-4 的默认处置产出文档</decision>
|
||||
<context>
|
||||
AGENTS.md / D-03 / D-04 要求执行前与命名先获批;`.planning/config.json` 为 `mode: yolo`,故本关卡显式 `blocking-human` 且 `autonomous: false`。本次核心 = 四条指示的落实方式确认(含 §5 的定位与 `animates` 消歧方式)+ 只读边界确认 + 产出文件确认 + 修订方式(派发子代理)声明。执行期工作树存在用户并发改动(`AGENTS.md`,D-56),故只读守卫采用「执行前基线对比」。行号为规划日实测、可能漂移,文档锚点与门禁以执行日实测为准。
|
||||
</context>
|
||||
<options>
|
||||
<option id="execute-default">
|
||||
<name>可以执行(采纳全部默认处置)</name>
|
||||
<pros>只读、零源码 / 零数据 / 零 PNG 改动;四条指示逐条落实到位;§8 二分清晰;`num` 重排策略与 schema 类型声明可复核;命名候选集中报备</pros>
|
||||
<cons>无</cons>
|
||||
</option>
|
||||
<option id="execute-narrow">
|
||||
<name>可以执行 + 收窄(仅落实指令 2 与指令 4,指令 1 / 3 暂缓)</name>
|
||||
<pros>文档改动更少</pros>
|
||||
<cons>`animates` 歧义与 `num` 沿用旧序的默认理解仍在,与用户四条指示不符</cons>
|
||||
</option>
|
||||
<option id="revise">
|
||||
<name>修订落实方式 / §5 定位 / `num` 策略口径后重新汇报</name>
|
||||
<pros>避免带着错误口径修订文档</pros>
|
||||
<cons>须修订 PLAN.md 后重新汇报</cons>
|
||||
</option>
|
||||
</options>
|
||||
<resume-signal>回复「可以执行」四个字(如需调整 OI-1..OI-4 的处置,请在回复中指明;修订意见请按 action ⑧ 处理)</resume-signal>
|
||||
<verify>
|
||||
<automated>node -e "const fs=require('fs');const bad=[];const doc='.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md';const sum='.planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md';if(!fs.existsSync(doc))bad.push('missing audit doc (09-17 output)');if(fs.existsSync(sum))bad.push('post-state: 09-18-SUMMARY already exists');for(const p of ['packages-user/data-common/src/store/types.ts','packages-user/client-base/src/material/types.ts','src/content/texture/.list.jsonc','src/content/tile.jsonc']){if(!fs.existsSync(p))bad.push('missing ref: '+p)}if(bad.length>0){console.error('PRESTATE FAILED :: '+bad.join(' ; '));process.exit(1)}console.log('OK pre-execution state: audit doc present; 09-18 summary absent; type/target refs present')"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "PRESTATE FAILED"(被修订对象缺失,或产出摘要已存在,或关键类型 / 落点参考文件缺失)</fails_when>
|
||||
<human-check>用户在对话中明确回复「可以执行」四个字(人工核对回复原文;用户若指定非默认的落实方式 / §5 定位 / `num` 策略口径 / 命名处置,须在汇报与后续任务中据其指定执行)</human-check>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- 用户回复中明确包含「可以执行」四个字
|
||||
- 汇报内容涵盖:本修订计划要解决的问题(四处)、四条指示的逐条落实方式、只读保证、修订方式(派发子代理)、产出文件、验证方式(静态断言,无全仓门禁)、OI-1..OI-4
|
||||
- 汇报中已原样告知:**只读(不改任何 `.ts`/`.tsx` 与 `public/project/**` 与 `src/content/**`、不生成任何 `.png`、不实施迁移、命名候选只报备不落地、锚点不得臆造、疑似问题只入 §8 不当缺陷)**
|
||||
- 汇报中已原样告知**关卡性质**(必须停下等待,不因触发方式或 `yolo` / `auto_advance` 自动放行)
|
||||
</acceptance_criteria>
|
||||
<done>用户明确回复「可以执行」;在此之前未执行任何任务、未修改任何文件、未派发任何执行子代理</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1(指令 1 §0 + 指令 2 §1 + 指令 3):强化 §0 的 `animates` 并入 `terrains`;在 §1 加入 `num` 可全部重分配说明、`id` 全清单与新 `num` 分配策略候选,并逐字段加分类标注</name>
|
||||
<precondition>Task 0 已闭环:用户明确回复「可以执行」四个字(若用户就 OI-1..OI-4 另有指定,按指定执行)。</precondition>
|
||||
<files>.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md(原地修订;另向预批准临时目录写只读基线,仓库外)</files>
|
||||
<read_first>
|
||||
- .planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md(现状:§0 口径 / §1 tile 含 §1.1 `cls`→`TileType`、§1.2 字段映射候选、§1.3 `num`/`id` 全清单、§1.4 图块→贴图归属)
|
||||
- .planning/phases/09-minimum-browser-runnable/09-CONTEXT.md(D-72 / D-73 / D-74 / D-75)
|
||||
- packages-user/data-common/src/store/types.ts:27-63(`PassBit` / `ITilePassData` / `ITileRawData`)—— 分类判定的唯一依据
|
||||
- packages-user/data-common/src/store/types.ts:6-25(`TileType`)、:125-136(`ItemCategory`)—— 逻辑类型映射参考
|
||||
- AGENTS.md(命名须先报备;只读边界);dev.md(命名规则、注释规范、Markdown 连字符命名)
|
||||
</read_first>
|
||||
<action>
|
||||
(0) **采集只读基线(先于任何写入):** 运行 `git status --porcelain`,取其改动路径(去重排序)中匹配 `.ts` / `.tsx` 或前缀 `public/project/` / `src/content/` 的条目,写入**预批准临时目录**的基线文件 `process.env.TEMP + '/opencode/gsd-09-18-baseline.txt'`(仓库外;与 09-17 的基线文件相互独立)。基线只记录执行前的既有改动,**不修改任何仓库文件**。**此步骤是本计划中唯一写入基线的动作**;后续 `<verify>` 只读该基线、不覆写(幂等)。
|
||||
|
||||
(1) **指令 1(`animates` 并入 `terrains`,D-72③)——§0 部分:** 在 §0.5「D-72 五条拆分规则原文(含 tilesets / autotiles 例外)」的原文引用之后,追加一段**强化说明**,使用**固定表述**「`animates` 并入 `terrains`,不设独立 `animates` 素材组」,并明确:**①** 这是**素材 / 分图分组**层面的合并(`animates` 的图块贴图与 `terrain` 同归 `terrains` 素材组),但受规则④约束(`animates` 为多帧,与单帧 `terrains` 分开成图);**②** **不得**与「逻辑类型映射」混淆——§1.1 中旧 `cls: animates` → `TileType.Animate` 的映射**保留不变**(`TileType` 枚举里 `Terrain` 与 `Animate` 并存)。
|
||||
|
||||
(2) **指令 3(`num` 可全部重新排序)——§1:**
|
||||
- 在 §1 数据来源段落后,加入**固定表述**:「图块 `num` 可全部重新分配,不沿用旧引擎顺序,唯一约束是 `id` ↔ `num` 一致(`addTile` 的 `num` 与 `id` 均不冲突即可)」;并注明旧 `num` 仅作参考对照。
|
||||
- 新增 **§1.5「`id` 全清单与新 `num` 分配策略候选」**:**①** 给出 **235 条 `id` 全清单**(可复用 / 汇总 §1.3 的 `id` 列,或独立按 `cls` 分组列出;须完整覆盖 235 条,不遗漏);**②** 给出 **≥3 个新 `num` 分配策略候选**,每条含「策略要点 + 优点 / 缺点 + 与旧 `num` 的对照说明」,例如:按 `TileType` 分段(`Terrain` / `Animate` / `Item` / `Enemy` / `Npc` / `Autotile` / `Tileset` 各占一段)、沿用旧 `num`(不重排,最省迁移)、按目标贴图(拆分后图)分组顺序重排、按 `id` 次序分配;**③** 每个策略候选均标注「待用户报备批准」;**④** 明确「本盘点只记录候选,不落地任何 `num` 分配」。
|
||||
|
||||
(3) **§1.4 强化:** 在 §1.4「图块 → 贴图归属候选」中,把 `animates` 行(现为「`terrains` 组(多帧,D-72③ 并入)」)强化为包含固定表述「`animates` 并入 `terrains`,不设独立 `animates` 素材组」,与 §0.5 表述一致。
|
||||
|
||||
(4) **指令 2(严格界定「只记录、不移植」)——§1 部分:** 在 §1.2「字段映射候选 → `ITileRawData`」的表格**新增一列「分类」**,对**每一个**旧字段逐条标注三类之一:**映射候选(可确定)** / **待定(有目标字段但映射不确定)** / **只记录、不移植(目标接口无对应字段)**。判定基准为 `ITileRawData` 与 `ITilePassData`(`packages-user/data-common/src/store/types.ts`,执行日实测)。
|
||||
- 对用户点名示例 **`trigger` / `canBreak` / `script` / `doorInfo`** 必须**逐条判定并写明依据**(引用对应目标接口字段或其缺失):旧 `trigger` 若确有对应目标字段(`ITileRawData.events` / `eventPass`)则标**待定**,**不得**标只记录;旧 `canBreak` / `script` / `doorInfo` 若无对应字段(经实测确认)则标**只记录、不移植**。
|
||||
- 逐条核对既有 §1.2 行(如 `id` / `cls` / `canPass` / `cannotOut` / `cannotIn` / `animate` / `faceIds` / `autotileConnection` / `name`)的分类,凡**有明确目标字段**者**不得**标「只记录、不移植」。
|
||||
|
||||
(5) **收口:** 不改任何源码 / 数据;不改任何既有注释;§0 与 §1(含新增 §1.5)LF;既有正确内容保留;机器可读行 `TILE-COUNT:` 保持 `235`、`MATERIAL-COUNT:` 保持 `17`、`SPLIT-COUNT:` 保持 `42`(本任务**不**改动任何计数数值)。
|
||||
</action>
|
||||
<reversibility rating="reversible">原地修订只读 `.md` 文档(+ 仓库外临时基线);`git checkout` / 手动撤销可整体回退;未触及任何源码或数据文件。</reversibility>
|
||||
<verify>
|
||||
<automated>node -e "const {execSync}=require('child_process');const fs=require('fs');const base=process.env.TEMP+'/opencode/gsd-09-18-baseline.txt';if(fs.existsSync(base)){console.log('OK baseline already captured by action step (0) (idempotent; verify does NOT overwrite) -> '+base)}else{const lines=execSync('git status --porcelain',{encoding:'utf8'}).split(/\r?\n/).filter(Boolean).map(l=>l.slice(3).trim()).filter(p=>/(\.(ts|tsx)$|^public\/project\/|^src\/content\/)/.test(p)).sort();fs.mkdirSync(require('path').dirname(base),{recursive:true});fs.writeFileSync(base,lines.join('\n'));console.log('OK baseline captured ('+lines.length+' pre-existing source/data changes) -> '+base+' | fallback: action step (0) did not persist baseline')}"</automated>
|
||||
<fails_when>non-zero exit(无法读取 / 采集只读基线;后续只读守卫将无对照)</fails_when>
|
||||
<automated>node -e "const fs=require('fs');const p='.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md';const bad=[];if(!fs.existsSync(p)){bad.push('doc missing')}else{const t=fs.readFileSync(p,'utf8').replace(/\r\n/g,'\n');for(const s of ['## 0.','## 1.']){if(t.indexOf(s)<0)bad.push('missing heading: '+s)}const counts=[['TILE-COUNT:',235],['MATERIAL-COUNT:',17],['SPLIT-COUNT:',42]];for(const c of counts){if(!new RegExp(c[0]+'\\s*'+c[1]).test(t))bad.push('missing count '+c[0]+c[1])}for(const m of ['animates','terrains','不设独立','可全部重新分配','id 全清单','num 分配策略候选','只记录、不移植','待用户报备批准','TileType.Animate']){if(t.indexOf(m)<0)bad.push('missing token: '+m)}if(t.indexOf('不设独立')>=0){if(t.indexOf('不设独立')>t.indexOf('## 1.'))bad.push('animates merge note not placed in section 0')}const anchors=[...t.matchAll(/((?:public\/project|packages-user|src\/content)\/[^\s|)\u0060]+\.(?:js|png|ts|tsx|jsonc)):(\d+)/g)];if(anchors.length<1)bad.push('no file:line anchors');for(const m of anchors){const f=m[1];const ln=parseInt(m[2],10);if(!fs.existsSync(f)){bad.push('anchor to missing file: '+f);continue}const lines=fs.readFileSync(f,'utf8').split(/\r?\n/);if(ln<1||ln>lines.length)bad.push('anchor out of range: '+f+':'+ln)}}if(bad.length>0){console.error('REV-AUDIT-A GATE FAILED :: '+bad.join(' ; '));process.exit(1)}console.log('OK revision A (section 0 animates merge + section 1 num realloc + id list + num strategy candidates + per-field classification)')"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "REV-AUDIT-A GATE FAILED"(文档缺失 / 缺 §0 或 §1 / 缺计数 / 缺指令 1 标记(`animates` `terrains` `不设独立`)/ 缺指令 3 标记(`可全部重新分配` `id 全清单` `num 分配策略候选`)/ 缺指令 2 标记(`只记录、不移植`)/ 缺命名报备标记 / `animates` 强化未落在 §0 / 锚点指向不存在的文件或越界行号)</fails_when>
|
||||
<automated>node -e "const {execSync}=require('child_process');const fs=require('fs');const base=process.env.TEMP+'/opencode/gsd-09-18-baseline.txt';const cur=execSync('git status --porcelain',{encoding:'utf8'}).split(/\r?\n/).filter(Boolean).map(l=>l.slice(3).trim()).filter(p=>/(\.(ts|tsx)$|^public\/project\/|^src\/content\/)/.test(p)).sort();const prev=fs.existsSync(base)?fs.readFileSync(base,'utf8').split(/\r?\n/).filter(Boolean).sort():[];const added=cur.filter(x=>!prev.includes(x));if(added.length){console.error('READONLY FAILED :: new source/data changes :: '+added.join(' | '));process.exit(1)}console.log('OK read-only after Task 1: no new .ts/.tsx/public-project/src-content changes vs pre-write baseline')"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "READONLY FAILED"(本计划执行期(含 Task 1 动作阶段)新增了 `.ts`/`.tsx` 或 `public/project/**` 或 `src/content/**` 改动,违反 D-74/D-75 只读)</fails_when>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- §0.5 含固定表述「`animates` 并入 `terrains`,不设独立 `animates` 素材组」,并区分逻辑类型映射(`TileType.Animate`)与素材分组
|
||||
- §1 含「`num` 可全部重新分配,不沿用旧引擎顺序,唯一约束是 `id` ↔ `num` 一致」;含新增 §1.5(235 条 `id` 全清单 + ≥3 个 `num` 分配策略候选,均标「待用户报备批准」,旧 `num` 仅作参考)
|
||||
- §1.2 表格新增「分类」列,逐字段标注三类;**有明确目标字段者未被标为「只记录、不移植」**;对 `trigger` / `canBreak` / `script` / `doorInfo` 逐条给出判定与依据
|
||||
- §1.4 的 `animates` 行含与 §0.5 一致的固定表述
|
||||
- 只读基线由 `<action>` 步骤 (0) 一次性写入(仓库外),`<verify>` 断言幂等不覆写;未改动任何 `.ts`/`.tsx`、`public/project/**`、`src/content/**`;未生成任何 `.png`;未改任何既有注释;计数数值未变
|
||||
</acceptance_criteria>
|
||||
<done>§0 与 §1(含新增 §1.5)修订完成;`animates` 强化落在 §0 / §1.4;`num` 重排说明与 `id` 全清单 + 策略候选就位;§1.2 分类标注完成;只读基线与静态门禁全绿</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2(指令 1 §2 / §5 / §9 + 指令 2 §3 / §4 / §6 + §8 重构 + 指令 4 §7):完成余下强化与分类标注、§8 二分重构、§7 显式类型声明,跑最终门禁并写 SUMMARY</name>
|
||||
<precondition>Task 1 已完成(文档 §0 与 §1 已就位;只读基线文件存在于仓库外,由 Task 1 `<action>` 步骤 (0) 采集且未被覆写)。</precondition>
|
||||
<files>.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md, .planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md</files>
|
||||
<read_first>
|
||||
- .planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md(本文件现状:§0 与 §1 已修订;待改 §2 / §3 / §4 / §5 / §6 / §7 / §8 / §9)
|
||||
- packages-user/data-common/src/store/types.ts:125-213(`ItemCategory` / `IItemEffect` / `IItemEquipData` / `IItemRawData`)、:260-271(`IMapRawData`)、:319-326(`IEnemyRawData`)—— §3 / §4 / §6 分类判定的唯一依据
|
||||
- packages-user/client-base/src/material/types.ts:12-17(`AutotileType`)、:50-55(`IIndexedIdentifier`)、:261-307(`addGrid` / `addRowAnimate` / `addAutotile` / `addTileset`)—— §7 类型声明的依据
|
||||
- src/content/texture/.list.jsonc:1(现状 `{}`)、src/content/client.jsonc:9(`textureListDir`)—— §7 草案落点参考
|
||||
- .planning/phases/09-minimum-browser-runnable/09-CONTEXT.md(D-72 / D-73 / D-74 / D-75)
|
||||
- AGENTS.md(命名须先报备;只读边界);dev.md(命名规则、注释规范)
|
||||
</read_first>
|
||||
<action>
|
||||
(1) **指令 1(§2 / §5 / §9 部分):**
|
||||
- §2.1 / §2.4 / §2.5:强化固定表述「`animates` 并入 `terrains`,不设独立 `animates` 素材组」(D-72③);确认 §2.4 B 组(`animates` 多帧并入 `terrains`)与 §2.5 命名(`terrainsAnim*`)表述一致、无歧义。
|
||||
- §5(NPC):加一行**交叉引用**,明确 D-72③(`animates` 并入 `terrains`)与本节的 NPC 分组(依 D-72① 并入 `npc`)互不冲突;**不**在 NPC 节强塞无关的 `animates` 内容。
|
||||
- §9:在汇总 / 命名说明处同步强化 `animates` 并入 `terrains`(D-72③),与 §0.5 / §2.4 一致。
|
||||
|
||||
(2) **指令 2(§3 / §4 / §6):** 在 §3.1 / §4.2 / §6.2 的映射候选表**各新增一列「分类」**,对**每一个**旧字段逐条标注三类之一:**映射候选(可确定)** / **待定(有目标字段但映射不确定)** / **只记录、不移植(目标接口无对应字段)**。判定基准(执行日实测):§3 用 `IEnemyRawData`;§4 用 `IItemRawData` / `IItemEffect` / `IItemEquipData`;§6 用 `IMapRawData`。
|
||||
- 特别判定并写明依据:旧 map **`events`** → `IMapRawData.events`(**有目标字段** → 标**待定**,**不得**标只记录);旧 map `title` / `name` / `height` / `firstArrive` / `eachArrive` / `parallelDo` / `changeFloor` / `afterBattle` / `afterGetItem` / `afterOpenDoor` / `beforeBattle` / `cannotMove` / `cannotMoveIn` / `autoEvent` / `images` / `bgm` / `weather` / `ratio` / `defaultGround` / `canFlyTo` / `canFlyFrom` / `canUseQuickShop` / `cannotViewMap` / `upFloor` 等(经实测确认无对应字段者)标**只记录、不移植**;`bgmap` / `fgmap` / `bg2map` / `fg2map` 是否落入 `IMapRawData.map` / `layerAlias` 判定为**待定**或**只记录**(以实测为准并写明依据)。
|
||||
- §3:旧 `name` / `hp` / `atk` / `def` / `money` / `exp` / `point` → `attribute`(**有目标字段** → 映射候选);`special` → 数字键映射对象(**待定**);`value` / `range` / `zoneSquare` / `add` / `n` / `bigImage` / `notBomb` / `atkValue` / `defValue` / `faceIds` 逐条判定并写明依据(凡有对应字段者不得标只记录)。
|
||||
- §4:旧 `name` / `text` / `hideInToolbox` → 直接对应字段(映射候选);`itemEffect` / `itemEffectTip` / `useItemEffect` / `useItemEvent` / `canUseItemEffect` → `IItemEffect`(**有目标字段** → 待定 / 映射候选,按实测);`equip` → `IItemEquipData`(映射候选);`hideInReplay`(经实测确认无对应字段)→ **只记录、不移植**。
|
||||
|
||||
(3) **指令 2(§8 重构):** 将 §8 重构为三分区:**§8.1「无目标字段 → 只记录、不移植」**(字段级,逐条注明所查接口与其缺失字段)、**§8.2「有目标字段但映射不确定 → 待定」**(字段级)、**§8.3「其他待确认观察」**(保留既有非字段级观察:D-72⑤ 读法、`ground` / `airwall` / `keyboard` / `icons` / `icons_old` 归类、`autotile1.png` 类型、`magictower.png` 切格尺寸、48px 单元格、`None` / `Tileset` 图块等);确保 §8.1 / §8.2 的归类与 §1.2 / §3.1 / §4.2 / §6.2 的「分类」列**逐条一致**;疑似问题**不得**登记为缺陷。**保留既有 `U-` 编号观察项**(可将其重排入三分区,但内容不得丢失)。
|
||||
|
||||
(4) **指令 4(§7 显式类型声明):** 在 §7 schema 草案中新增「**显式 TypeScript 类型声明**」区块(保留原有字段结构说明,并补充可读、可落地参考的 `interface` 与 `type` 别名)。至少含:
|
||||
- 四个 entry 接口(候选名 `ITextureListGridEntry` / `ITextureListRowAnimateEntry` / `ITextureListAutotileEntry` / `ITextureListTilesetEntry`),字段与 `addGrid` / `addRowAnimate` / `addAutotile` / `addTileset` 的参数形状一致(grid / rowAnimate 含 `source` / `map` / `width` / `height`;autotile 含 `source` / `identifier` / `type`(`AutotileType`);tileset 含 `source` / `identifier`(`IIndexedIdentifier`)/ `cellWidth` / `cellHeight`);
|
||||
- 一个联合类型别名(候选名 `TextureListEntry`)联合上述四者;
|
||||
- 一个顶层配置接口(候选名 `ITextureListConfig`)含 `textures` 数组字段(元素为 `TextureListEntry`)。
|
||||
**所有新增类型名 / 字段名均标注「待用户报备批准」**,与 §2 登记逐条一致,**不落地写入任何文件**(D-73 / OI-2)。
|
||||
|
||||
(5) **§9 一致化:** 计数行与各节一致(`TILE-COUNT:` 235 / `MATERIAL-COUNT:` 17 / `SPLIT-COUNT:` 42 / `ENEMY-COUNT:` 81 / `ITEM-COUNT:` 62 / `NPC-COUNT:` 24 / `MAP-COUNT:` 5);命名说明更新为含 §7 类型声明命名候选。
|
||||
|
||||
(6) **写 `09-18-SUMMARY.md`:** 记录四条指示的落实位置、命名候选清单(含 `num` 策略与 §7 类型名)、各维度计数(不变)、只读确认、遗留待用户裁定项(OI-1..OI-4)。
|
||||
|
||||
(7) **收口:** 不改任何源码 / 数据;不改任何既有注释;不生成任何 PNG;文档 LF;本任务 `<verify>` 运行最终静态门禁(§0..§9 + §8.1 / §8.2 + 七计数 + 四条指示标记 + 锚点有效性 + 只读守卫)。
|
||||
</action>
|
||||
<reversibility rating="reversible">原地修订只读 `.md` 文档 + 新增 SUMMARY;删除 / `git checkout` 可整体回退;未触及任何源码或数据文件。</reversibility>
|
||||
<verify>
|
||||
<automated>node -e "const fs=require('fs');const p='.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md';const s='.planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md';const bad=[];if(!fs.existsSync(p)){bad.push('doc missing')}if(!fs.existsSync(s)){bad.push('summary missing')}if(fs.existsSync(p)){const t=fs.readFileSync(p,'utf8').replace(/\r\n/g,'\n');for(const h of ['## 0.','## 1.','## 2.','## 3.','## 4.','## 5.','## 6.','## 7.','## 8.','## 9.','### 8.1','### 8.2']){if(t.indexOf(h)<0)bad.push('missing heading: '+h)}const counts=[['TILE-COUNT:',235],['MATERIAL-COUNT:',17],['SPLIT-COUNT:',42],['ENEMY-COUNT:',81],['ITEM-COUNT:',62],['NPC-COUNT:',24],['MAP-COUNT:',5]];for(const c of counts){if(!new RegExp(c[0]+'\\s*'+c[1]).test(t))bad.push('missing count '+c[0]+c[1])}for(const m of ['animates','terrains','不设独立','只记录、不移植','待定','interface ','type ','ITextureListConfig','ITextureListGridEntry','AutotileType','IIndexedIdentifier','待用户报备批准']){if(t.indexOf(m)<0)bad.push('missing token: '+m)}if(t.indexOf('不设独立')>=0){if(t.lastIndexOf('不设独立')<t.indexOf('## 2.'))bad.push('animates merge note not reinforced at/after section 2')}const anchors=[...t.matchAll(/((?:public\/project|packages-user|src\/content)\/[^\s|)\u0060]+\.(?:js|png|ts|tsx|jsonc)):(\d+)/g)];if(anchors.length<5)bad.push('too few anchors: '+anchors.length);for(const m of anchors){const f=m[1];const ln=parseInt(m[2],10);if(!fs.existsSync(f)){bad.push('anchor to missing file: '+f);continue}const lines=fs.readFileSync(f,'utf8').split(/\r?\n/);if(ln<1||ln>lines.length)bad.push('anchor out of range: '+f+':'+ln)}}if(bad.length>0){console.error('REV-AUDIT-B GATE FAILED :: '+bad.join(' ; '));process.exit(1)}console.log('OK final revision (sections 0-9 + 8.1/8.2 split + seven counts + four instruction markers + explicit TS types + anchors valid + summary present)')"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "REV-AUDIT-B GATE FAILED"(文档或 SUMMARY 缺失 / 缺 §0..§9 或 §8.1 或 §8.2 / 缺任一维度计数 / 缺指令 1 标记(`animates` `terrains` `不设独立`,且未在 §2 及之后强化)/ 缺指令 2 标记(`只记录、不移植` `待定`)/ 缺指令 4 标记(`interface ` `type ` `ITextureListConfig` `ITextureListGridEntry`)/ 缺命名报备标记 / 锚点指向不存在的文件或越界行号)</fails_when>
|
||||
<automated>node -e "const {execSync}=require('child_process');const fs=require('fs');const base=process.env.TEMP+'/opencode/gsd-09-18-baseline.txt';const cur=execSync('git status --porcelain',{encoding:'utf8'}).split(/\r?\n/).filter(Boolean).map(l=>l.slice(3).trim()).filter(p=>/(\.(ts|tsx)$|^public\/project\/|^src\/content\/)/.test(p)).sort();const prev=fs.existsSync(base)?fs.readFileSync(base,'utf8').split(/\r?\n/).filter(Boolean).sort():[];const added=cur.filter(x=>!prev.includes(x));if(added.length){console.error('READONLY FAILED :: new source/data changes :: '+added.join(' | '));process.exit(1)}console.log('OK read-only final: no new .ts/.tsx/public-project/src-content changes vs pre-write baseline')"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "READONLY FAILED"(本计划执行期新增了 `.ts`/`.tsx` / `public/project/**` / `src/content/**` 改动,违反 D-74/D-75 只读)</fails_when>
|
||||
<automated>git status --porcelain</automated>
|
||||
<fails_when>输出包含本计划 `files_modified`(`09-DATA-MIGRATION-AUDIT.md` + `09-18-SUMMARY.md`)之外、且**基线不存在**的生产文件或数据改动(如 `.ts`/`.tsx`、`public/project/**`、`src/content/**`、`package.json`);用户既有并发改动(D-56)不计</fails_when>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- §2 / §5 / §9 含固定表述「`animates` 并入 `terrains`,不设独立 `animates` 素材组」(D-72③),与 §0.5 / §1.4 一致
|
||||
- §3.1 / §4.2 / §6.2 表格各含「分类」列,逐字段标注三类;**有明确目标字段者(如旧 map `events`)未被标为「只记录、不移植」**
|
||||
- §8 重构为 §8.1(无目标字段 → 只记录、不移植)/ §8.2(有目标字段但映射不确定 → 待定)/ §8.3(其他待确认观察),与 §1.2 / §3.1 / §4.2 / §6.2 的「分类」列一致;疑似问题未登记为缺陷
|
||||
- §7 含显式 TypeScript 类型声明(四个 entry 接口 + 联合别名 + 顶层配置接口,候选名 `ITextureListConfig` / `ITextureListGridEntry` 等),字段与 `addGrid` / `addRowAnimate` / `addAutotile` / `addTileset` 一致,命名标注「待用户报备批准」
|
||||
- §9 七项计数与各节一致(值不变);`09-18-SUMMARY.md` 已写
|
||||
- 全部 `file:line` 锚点有效;未改动任何 `.ts`/`.tsx`、`public/project/**`、`src/content/**`;未生成任何 `.png`;未改任何既有注释
|
||||
</acceptance_criteria>
|
||||
<done>§2..§9 修订完成;§8 二分重构就位并与各映射表一致;§7 显式类型声明就位;七项计数不变;最终静态门禁 + 锚点校验 + 只读守卫全绿;`09-18-SUMMARY.md` 落盘</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| 只读边界 | 修订只读取 `09-DATA-MIGRATION-AUDIT.md` 与类型定义;**禁止任何源码 / 数据写入与 PNG 生成**(D-74 / D-75) |
|
||||
| 范围边界 | 只修订既有盘点台账的四类内容(指令 1..4);不扩范围、不动 09-17 计划 / 摘要 / `ROADMAP.md` / `STATE.md` / `09-CONTEXT.md` |
|
||||
| 判定边界 | 「只记录、不移植」的判定基准严格限定为 `ITileRawData` / `ITilePassData` / `IEnemyRawData` / `IItemRawData` / `IMapRawData` 是否存在对应字段 |
|
||||
| 命名边界 | 任何新增 / 修改命名(`num` 策略、schema 字段名与 TypeScript 类型名)只作候选入台账、标注「待用户报备批准」,不得落地使用(D-73 / AGENTS.md) |
|
||||
| 产出边界 | 仅允许写 `09-DATA-MIGRATION-AUDIT.md`(原地修订)与 `09-18-SUMMARY.md`(新增)(+ 仓库外只读基线) |
|
||||
| 提交边界 | 不得把用户并发改动(D-56,`AGENTS.md`)纳入暂存 / 提交;不改 `ROADMAP.md` / `STATE.md` |
|
||||
|
||||
**威胁级别说明(security_enforcement = ASVS L1,block on high):** 本计划为**纯只读 Markdown 台账修订**,不执行任何生产代码、不引入依赖、不做任何写入面扩展,**不存在 `high` 级威胁**;下列寄存器均为 `medium` 及以下,并逐条给出缓解。
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|----------|-------------|-----------------|
|
||||
| T-09-18-01 | Tampering | 借「修订」之机修改 / 新增生产源码或数据(`.ts`/`.tsx`、`public/project/**`、`src/content/**`) | medium | mitigate | `files_modified` 白名单 + prohibitions + Task 1/2 `READONLY` 门禁(与**执行前**(Task 1 `<action>` 步骤 (0) 写入、`<verify>` 幂等不覆写)的基线对比,检出执行期任何新增改动) |
|
||||
| T-09-18-02 | Elevation of Privilege | 未经批准即执行 / 使用未报备命名(`num` 策略、schema 字段名与 TypeScript 类型名) | medium | mitigate | Task 0 `blocking-human`;命名候选仅入台账并标注「待用户报备批准」;prohibitions 禁未获批命名落地 |
|
||||
| T-09-18-03 | Tampering | 分类误判:把**有明确目标字段**的项误标为「只记录、不移植」(或反之),导致台账误导后续迁移 | medium | mitigate | `<action>` 要求以执行日实测接口为唯一判定依据;Task 1/2 门禁校验标记 token 与 `### 8.1`/`### 8.2` 分区;acceptance_criteria 明列「有目标字段者不得标只记录」 |
|
||||
| T-09-18-04 | Tampering | 臆造条目(编造字段 / 映射 / 锚点,或指向不存在文件 / 越界行号) | medium | mitigate | `<action>` 要求逐项实测;无法确定者入 §8;Task 1/2 门禁逐一校验「文件存在 + 行号在范围内」 |
|
||||
| T-09-18-05 | Tampering | 生成 / 覆写 PNG 素材(违反 D-75) | medium | mitigate | prohibitions 明列不生成素材;只读守卫覆盖 `public/project/**` 与 `src/content/**`(基线对比) |
|
||||
| T-09-18-06 | Tampering | 破坏既有正确内容(错误地删除 / 改写既有章节、计数、锚点,或使 §8 与各映射表不一致) | medium | mitigate | prohibitions「不得破坏既有正确内容」;Task 2 门禁校验七项计数与 §8.1/§8.2 分区;acceptance_criteria 要求 §8 与 §1.2/§3.1/§4.2/§6.2 一致 |
|
||||
| T-09-18-07 | Information Disclosure | 修订范围外泄(处理 animation / images / sounds / bgms / fonts 或改动他处) | low | mitigate | prohibitions 与 `files_modified` 白名单明列边界;只读守卫覆盖 |
|
||||
| T-09-18-08 | Repudiation | 未跑静态门禁即收口 / 未记录只读确认 | low | mitigate | Task 1/2 各有自动化门禁 + `09-18-SUMMARY.md` 只读确认;未通过不得收口 |
|
||||
| T-09-18-SC | Tampering | npm/pip/cargo installs | low | accept | 无第三方包安装、无依赖安装(纯只读台账修订,不改 `package.json`) |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- **Task 0**:预执行状态(`09-DATA-MIGRATION-AUDIT.md` 存在、`09-18-SUMMARY.md` 不存在、类型 / 落点参考文件存在);人工关卡(用户明确回复「可以执行」)。
|
||||
- **Task 1**:只读基线由 `<action>` 步骤 (0) 一次性采集(仓库外),`<verify>` 断言**幂等**(不覆写);文档含 `## 0.` / `## 1.` 与 `TILE/MATERIAL/SPLIT-COUNT`(值不变);含指令 1 标记(`animates` / `terrains` / `不设独立`,落在 §0)、指令 3 标记(`可全部重新分配` / `id 全清单` / `num 分配策略候选`)、指令 2 标记(`只记录、不移植`)与「待用户报备批准」;锚点有效;只读。
|
||||
- **Task 2**:文档含 `## 0.`..`## 9.` 与 `### 8.1` / `### 8.2`;含七项计数(值不变);含指令 1 标记(`animates` / `terrains` / `不设独立`,且在 §2 及之后强化)、指令 2 标记(`只记录、不移植` / `待定`)、指令 4 标记(`interface ` / `type ` / `ITextureListConfig` / `ITextureListGridEntry`)与「待用户报备批准」;`09-18-SUMMARY.md` 存在;全部锚点有效;只读。
|
||||
- **只读守卫**:执行期无**新增** `.ts`/`.tsx`/`public/project/**`/`src/content/**` 改动(与**执行前**基线对比,基线仅由 Task 1 `<action>` 步骤 (0) 写入、`<verify>` 幂等不改写);`files_modified` 外无越界生产文件或数据改动;用户既有并发改动(D-56)不计。
|
||||
- **计数一致性**:`TILE-COUNT` 235 / `MATERIAL-COUNT` 17 / `SPLIT-COUNT` 42 / `ENEMY-COUNT` 81 / `ITEM-COUNT` 62 / `NPC-COUNT` 24 / `MAP-COUNT` 5(修订预期不变)。
|
||||
- **无全仓门禁**:全程不使用 `pnpm check:type` / `pnpm build` / 全仓 TS 诊断数。
|
||||
- **人工复核**:结论写入 `09-18-SUMMARY.md`(含四条指示落实位置、命名候选清单、七项计数、只读确认、OI-1..OI-4)。
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- **指令 1:** `animates` 并入 `terrains`(D-72③)在 §0 / §2 / §5 / §9 及 §1.4 以固定表述强化到无歧义(「不设独立 `animates` 素材组」),并区分逻辑类型映射(`TileType.Animate`)与素材分组。
|
||||
- **指令 2:** 「只记录、不移植」严格限定为「目标接口无对应字段」;§1.2 / §3.1 / §4.2 / §6.2 逐字段显式标注三类;§8 重构为 §8.1 / §8.2 / §8.3 且与各表一致;**无**「有明确目标字段却被标只记录」的误标。
|
||||
- **指令 3:** §1 明确「`num` 可全部重新分配,不沿用旧引擎顺序,唯一约束是 `id` ↔ `num` 一致」;给出 235 条 `id` 全清单与 ≥3 个 `num` 分配策略候选(标「待用户报备批准」);旧 `num` 仅作参考。
|
||||
- **指令 4:** §7 给出显式 TypeScript 类型声明(四个 entry 接口 + 联合别名 + 顶层配置接口),字段与 `addGrid` / `addRowAnimate` / `addAutotile` / `addTileset` 一致,命名标「待用户报备批准」。
|
||||
- **只读与一致性:** 唯一写入为 `09-DATA-MIGRATION-AUDIT.md`(原地修订)与 `09-18-SUMMARY.md`(新增);零 `.ts`/`.tsx`、零 `public/project/**`、零 `src/content/**`、零 PNG;七项计数与既有正确内容保留;锚点全部有效;疑似问题只入 §8、未登记为缺陷。
|
||||
- 产出经 Task 0 获批;静态门禁(文档结构 / 标记 / 锚点 / 只读)全绿。
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md` when done
|
||||
</output>
|
||||
|
||||
## Artifacts this phase produces
|
||||
|
||||
| 符号 / 路径 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md`(原地修订) | 只读盘点台账 | §0(`animates` 并入 `terrains` 强化)+ §1(`num` 可全部重排 + `id` 全清单 + 新 `num` 分配策略候选 + 字段分类)+ §2(`animates` 强化)+ §3/§4/§6(字段分类)+ §5(交叉引用)+ §7(显式 TypeScript 类型声明)+ §8(8.1 只记录 / 8.2 待定 / 8.3 其他)+ §9(计数与命名说明) |
|
||||
| `.planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md`(新增) | 执行摘要 | 四条指示落实位置、命名候选清单(`num` 策略 + §7 类型名)、七项计数(不变)、只读确认、OI-1..OI-4 |
|
||||
|
||||
**命名说明:** 本计划**不引入任何源码 / 数据命名**;修订中提出的所有候选命名(`num` 分配策略、`texture/.list.jsonc` 字段名与 TypeScript 类型名)**只作台账记录并标注「待用户报备批准」,不落地使用**。
|
||||
|
||||
## Source Coverage Audit
|
||||
|
||||
| 来源 | 项 | 处置 |
|
||||
|------|----|------|
|
||||
| GOAL | Phase 9(ROADMAP)「在已完成的数据端之上完成渲染端框架,产出可在浏览器中运行并验证的最小版本」 | COVERED(增量·任务 8 后续子切片:按用户裁定收敛只读迁移台账) |
|
||||
| REQ | Phase 9 ROADMAP「Requirements: TBD」,无需求 ID | N/A(`requirements: []` 如实标注) |
|
||||
| RESEARCH | 无 RESEARCH.md(本阶段为增量派发,无独立研究产物) | N/A |
|
||||
| CONTEXT | D-70(落点 `src/content`;消费接线由用户后续提供,本次不实现) | COVERED(§7 落点侧参考;prohibitions) |
|
||||
| CONTEXT | D-71(六类迁移范围) | COVERED(修订只动六类对应的既有台账章节,不扩范围) |
|
||||
| CONTEXT | D-72(五条合并 / 分图规则)+ D-72③(`animates` 并入 `terrains`) | COVERED(指令 1:§0 / §1.4 / §2 / §5 / §9 强化) |
|
||||
| CONTEXT | D-73(命名须先报备;schema 反向设计) | COVERED(指令 4:§7 显式类型声明,命名标「待用户报备批准」) |
|
||||
| CONTEXT | D-74(本次规划单元 = 只读盘点;产出 `09-DATA-MIGRATION-AUDIT.md`) | COVERED(原地修订该文档;只读守卫) |
|
||||
| CONTEXT | D-75(素材迁移阶段由 AI 脚本生成 PNG;本盘点不生成) | COVERED(prohibitions + 只读守卫覆盖 `public/project`/`src/content`) |
|
||||
| CONTEXT | D-03 / D-04 / D-06(执行前获批 / 命名获批 / 不扩范围) | COVERED(Task 0 + prohibitions) |
|
||||
| 用户指示 | 指令 1(`animates` 合并至 `terrains`,确认 D-72③) | COVERED(§0 / §1.4 / §2 / §5 / §9;门禁 `不设独立`) |
|
||||
| 用户指示 | 指令 2(严格界定「只记录、不移植」;§8 重构;§1/§3/§4/§6 标注) | COVERED(§1.2 / §3.1 / §4.2 / §6.2 分类列 + §8.1 / §8.2 / §8.3;门禁 `只记录、不移植` / `待定` / `### 8.1` / `### 8.2`) |
|
||||
| 用户指示 | 指令 3(`num` 可全部重新排序;`id` 全清单;新 `num` 分配策略候选) | COVERED(§1 + §1.5;门禁 `可全部重新分配` / `id 全清单` / `num 分配策略候选`) |
|
||||
| 用户指示 | 指令 4(§7 `texture/.list.jsonc` schema 显式 TypeScript 类型声明) | COVERED(§7 类型声明区块;门禁 `interface ` / `type ` / `ITextureListConfig` / `ITextureListGridEntry`) |
|
||||
| 缺口 | 无(四条指示已逐条落到 Task 1 / Task 2 与门禁) | CLOSED |
|
||||
|
||||
149
.planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md
Normal file
149
.planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md
Normal file
@ -0,0 +1,149 @@
|
||||
---
|
||||
phase: 09-minimum-browser-runnable
|
||||
plan: 18
|
||||
subsystem: docs
|
||||
tags: [data-migration, audit, read-only, texture-list, schema, tile-num, animates, terrains]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 09-minimum-browser-runnable
|
||||
provides: "09-17 产出的只读盘点台账 09-DATA-MIGRATION-AUDIT.md(本次原地修订对象)"
|
||||
provides:
|
||||
- "按用户 2026-10-13 四条指示修订后的 09-DATA-MIGRATION-AUDIT.md(只读盘点台账,未实施迁移)"
|
||||
- "四条指示的逐条落实位置、命名候选清单(num 分配策略 + texture/.list.jsonc 类型声明)、七项计数(不变)"
|
||||
affects: [09-19 or later 旧引擎数据迁移计划, texture/.list.jsonc schema 落地]
|
||||
|
||||
# Actuals (#2632) — chars/4 over the revised artifact + summary (docs-only plan; no source diff)
|
||||
actuals:
|
||||
tokens: 15000
|
||||
tasks: 2
|
||||
commits: 0
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns: ["只读盘点台账的原地修订(增改不删既有正确内容)", "字段级三分标注:映射候选 / 待定 / 只记录不移植"]
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- .planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md
|
||||
modified:
|
||||
- .planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md
|
||||
|
||||
key-decisions:
|
||||
- "指令 1:animates 并入 terrains(素材分组),与逻辑类型映射 animates → TileType.Animate 显式区分"
|
||||
- "指令 2:只记录、不移植 严格限定为目标接口无对应字段;§8 重构为 8.1/8.2/8.3"
|
||||
- "指令 3:图块 num 可全部重排(唯一约束 id↔num 一致);新增 §1.5(id 全清单 + 4 个 num 分配策略候选)"
|
||||
- "指令 4:§7.1 补显式 TypeScript 类型声明(四个 entry 接口 + 联合别名 + 顶层配置接口)"
|
||||
- "autotile 条目 AutotileType 参数与判别字段 type 同名冲突,暂以候选名 autotileType 消歧(§8.3 U-19)"
|
||||
|
||||
patterns-established:
|
||||
- "字段分类三分法:映射候选(可确定) / 待定(有目标字段但映射不确定) / 只记录、不移植(目标接口无对应字段)"
|
||||
|
||||
requirements-completed: []
|
||||
|
||||
coverage:
|
||||
- id: D1
|
||||
description: "指令 1 —— animates 并入 terrains(强化到无歧义,并区分逻辑类型映射与素材分组)已落到 §0.5.1 / §1.1 / §1.4 / §2.1 / §2.4 / §2.5 / §5 / §9"
|
||||
verification:
|
||||
- kind: other
|
||||
ref: "node gate REV-AUDIT-A / REV-AUDIT-B: token '不设独立' 落在 §0 且在 §2 及之后强化"
|
||||
status: pass
|
||||
human_judgment: true
|
||||
rationale: "文档表述的『无歧义』程度需用户确认(OI-4)"
|
||||
- id: D2
|
||||
description: "指令 2 —— 只记录、不移植 严格二分 + §1.2/§3.1/§4.2/§6.2 分类列 + §8 重构为 8.1/8.2/8.3"
|
||||
verification:
|
||||
- kind: other
|
||||
ref: "node gate: '只记录、不移植' / '待定' / '### 8.1' / '### 8.2' / '### 8.3' 存在"
|
||||
status: pass
|
||||
human_judgment: true
|
||||
rationale: "字段分类的判定依据(是否存在对应字段)需用户复核"
|
||||
- id: D3
|
||||
description: "指令 3 —— §1 明确 num 可全部重排 + §1.5 id 全清单(235 条)+ 4 个 num 分配策略候选(待报备)"
|
||||
verification:
|
||||
- kind: other
|
||||
ref: "node gate: '可全部重新分配' / 'id 全清单' / 'num 分配策略候选' 存在;§1.5.1 合计 235"
|
||||
status: pass
|
||||
human_judgment: true
|
||||
rationale: "num 分配策略采用哪种待用户裁定(OI-1)"
|
||||
- id: D4
|
||||
description: "指令 4 —— §7.1 显式 TypeScript 类型声明(四个 entry 接口 + 联合别名 + 顶层配置接口)"
|
||||
verification:
|
||||
- kind: other
|
||||
ref: "node gate: 'interface ' / 'type ' / 'ITextureListConfig' / 'ITextureListGridEntry' 存在"
|
||||
status: pass
|
||||
human_judgment: true
|
||||
rationale: "所有类型名 / 字段名为命名候选,待用户报备批准(OI-2)"
|
||||
|
||||
# Metrics
|
||||
duration: ~20min
|
||||
completed: 2026-10-13
|
||||
status: complete
|
||||
---
|
||||
|
||||
# Phase 9 Plan 18: 按用户四条指示修订旧引擎数据迁移只读盘点台账 Summary
|
||||
|
||||
**按用户 2026-10-13 四条指示原地修订 `09-DATA-MIGRATION-AUDIT.md`:`animates` 并入 `terrains` 强化到无歧义、字段级三分标注并重构 §8 为 8.1/8.2/8.3、`num` 可全部重排并补 `id` 全清单与策略候选、§7 补显式 TypeScript 类型声明 —— 全程只读,零源码 / 零数据 / 零 PNG 改动。**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** ~20 min
|
||||
- **Started:** 2026-10-13T08:20Z(约)
|
||||
- **Completed:** 2026-10-13T08:37Z
|
||||
- **Tasks:** 2(Task 0 汇报关卡已由用户「可以执行」满足)
|
||||
- **Files modified:** 1(`09-DATA-MIGRATION-AUDIT.md` 原地修订)+ 1 新增(本 SUMMARY)
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- **指令 1(`animates` 并入 `terrains`)**:新增 §0.5.1 固定表述「**`animates` 并入 `terrains`,不设独立 `animates` 素材组**」,并明确区分**素材分组**(并入 `terrains`)与**逻辑类型映射**(§1.1 `animates` → `TileType.Animate` 保留);§1.1 / §1.4 / §2.1 / §2.4 / §2.5 / §5(交叉引用)/ §9 同步强化。
|
||||
- **指令 2(严格界定「只记录、不移植」)**:`ITileRawData` / `ITilePassData` / `IEnemyRawData` / `IItemRawData` / `IMapRawData` 为目标判定基准;§1.2 / §3.1 / §4.2 / §6.2 各表**新增「分类」列**逐字段标注三类;`trigger` / map `events` 等**有目标字段项标「待定」而非「只记录」**;§8 **重构**为 §8.1(无目标字段 → 只记录、不移植)/ §8.2(有目标字段但映射不确定 → 待定)/ §8.3(其他待确认观察),并与各表逐条一致。
|
||||
- **指令 3(`num` 可全部重排)**:§1 加入固定表述「图块 `num` 可全部重新分配,不沿用旧引擎顺序,唯一约束是 `id` ↔ `num` 一致」;新增 §1.5:**235 条 `id` 全清单**(按 `cls` 分组,合计 235)+ **4 个 `num` 分配策略候选**(A 按 `TileType` 分段 / B 沿用旧 `num` / C 按目标贴图分组 / D 按 `id` 次序),均「待用户报备批准」。
|
||||
- **指令 4(§7 显式类型声明)**:新增 §7.1,给出 `ITextureListGridEntry` / `ITextureListRowAnimateEntry` / `ITextureListAutotileEntry` / `ITextureListTilesetEntry` 四个 entry 接口、`TextureListEntry` 联合别名、`ITextureListConfig` 顶层配置接口,字段对齐 `addGrid` / `addRowAnimate` / `addAutotile` / `addTileset`;全部命名标注「待用户报备批准」。
|
||||
- **计数不变**:`TILE-COUNT: 235` / `MATERIAL-COUNT: 17` / `SPLIT-COUNT: 42` / `ENEMY-COUNT: 81` / `ITEM-COUNT: 62` / `NPC-COUNT: 24` / `MAP-COUNT: 5` 七项值均未变。
|
||||
- **只读确认**:仅写 `09-DATA-MIGRATION-AUDIT.md`(原地)与本 SUMMARY;未改任何 `.ts`/`.tsx`、`public/project/**`、`src/content/**`;未生成 `.png`;未改 09-17 计划 / 摘要、`ROADMAP.md`、`STATE.md`、`09-CONTEXT.md`。
|
||||
|
||||
## Task Commits
|
||||
|
||||
本计划**未提交**(经用户指示:产出留在工作树供审阅,不得 `git add` / `git commit`)。
|
||||
|
||||
1. **Task 1(指令 1 §0 + 指令 2 §1 + 指令 3)** - 未提交(工作树内修订)
|
||||
2. **Task 2(指令 1 §2/§5/§9 + 指令 2 §3/§4/§6 + §8 重构 + 指令 4 §7 + SUMMARY)** - 未提交(工作树内修订)
|
||||
|
||||
_Note:仅本 SUMMARY 为新增文件;`09-DATA-MIGRATION-AUDIT.md` 为原地修订(09-17 产出,原为工作树未跟踪文件)。_
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md` - 原地修订:§0.5.1(新增强化)、§1(`num` 重排说明)、§1.1(消歧)、§1.2(分类列)、§1.4(强化)、§1.5(新增)、§2.1/§2.4/§2.5(强化)、§3.1/§4.2/§6.2(分类列)、§5(交叉引用)、§7.1(新增显式 TS 类型声明)、§8(重构为 8.1/8.2/8.3)、§9(命名说明)
|
||||
- `.planning/phases/09-minimum-browser-runnable/09-18-SUMMARY.md` - 本执行摘要(新增)
|
||||
|
||||
## Decisions Made
|
||||
|
||||
- **`animates` 归属**:明确「素材 / 分图分组并入 `terrains`」与「逻辑类型映射 `animates` → `TileType.Animate` 保留」为两件事(消歧,OI-4)。
|
||||
- **分类三分法**:以目标接口是否存在对应字段为唯一判定基准;`trigger`(`ITileRawData.events`/`eventPass`)、map `events`(`IMapRawData.events`)确认为「待定」而非「只记录」。
|
||||
- **`num` 策略**:只记录 4 个候选,不选型、不落地(OI-1)。
|
||||
- **autotile `type` 同名冲突**:§7.1 暂以候选字段名 `autotileType` 消歧,作为 §8.3 U-19 观察(不登记为缺陷),最终命名待用户裁定(OI-2)。
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None - 计划按用户四条指示执行。计划中允许的「仓库外只读基线」按 Task 1 `<action>` 步骤 (0) 写入 `%TEMP%\opencode\gsd-09-18-baseline.txt`(基线为空 = 执行前无生产文件 / 数据改动);`<verify>` 幂等未覆写。
|
||||
|
||||
> 说明(非偏差):用户指示「§5 相关处」中,本文档 §5 为 NPC 节、与 `animates`/`terrains` 无关,故按计划 assumptions 以「交叉引用」方式落实(OI-3)。
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
None。
|
||||
|
||||
## User Setup Required
|
||||
|
||||
None - no external service configuration required.
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
- 修订后的 `09-DATA-MIGRATION-AUDIT.md` 已就位,供用户审阅后派发后续「旧引擎数据迁移计划」。
|
||||
- 待用户裁定 / 报备项:**OI-1**(`num` 分配策略)、**OI-2**(`texture/.list.jsonc` 类型 / 字段命名)、**OI-3**(§5 定位处理方式)、**OI-4**(`animates` 消歧方式);另有 §8.3 U-19(autotile `type` 同名冲突命名)。
|
||||
- 未提交:产出留在工作树,用户确认后再决定后续流程。
|
||||
|
||||
---
|
||||
*Phase: 09-minimum-browser-runnable*
|
||||
*Completed: 2026-10-13*
|
||||
@ -0,0 +1,984 @@
|
||||
# Phase 9 · 任务 8:旧引擎数据迁移只读盘点台账(09-DATA-MIGRATION-AUDIT)
|
||||
|
||||
> 本文件是 Phase 9 任务 8 的**只读盘点产物**(`09-17-PLAN.md`,D-74)。**全程只读**:未修改 / 删除 / 新增任何生产 `.ts` / `.tsx` 源码,未改动任何 `public/project/**` 与 `src/content/**` 数据文件,未生成任何 `.png` 素材(D-75)。本文件唯一用途是为后续「旧引擎数据迁移」计划提供可消费的映射台账。所有 `file:line` 锚点取自执行日实测,指向真实存在且行号在范围内的行;无法确定者一律收入 §8,不猜测编造。文档使用裸 LF 行尾(随仓库既有 phase 文档约定)。
|
||||
|
||||
## 0. 盘点口径与范围
|
||||
|
||||
### 0.1 盘点范围(D-71)
|
||||
|
||||
本次只读盘点覆盖**六类**:
|
||||
|
||||
1. **图块定义 tile** —— `public/project/maps.js` 的 `blocksInfo`(运行时名,见 §0.3)。
|
||||
2. **地图 maps** —— `public/project/floors/*.js`。
|
||||
3. **贴图素材 textures** —— 显式含 `public/project/materials/*.png` **+** `public/project/autotiles/*.png` **+** `public/project/tilesets/*.png`(2026-10-13 用户裁定,D-71 补充)。
|
||||
4. **怪物 enemy** —— `public/project/enemys.js`。
|
||||
5. **道具 items** —— `public/project/items.js`。
|
||||
6. **NPC** —— `maps.js` 的 `npcs` / `npc48` 图块。
|
||||
|
||||
**不在本次范围:** `animation` 素材(暂不处理,不盘点 / 不挪动 `public/project/animates/*.animate`);`images` / `sounds` / `bgms` / `fonts`。
|
||||
|
||||
### 0.2 落点与接线边界(D-70)
|
||||
|
||||
迁移目标落点为 `src/content`(jsonc 数据 + 素材文件)。把配置写入 store、把贴图列表写入 `TextureManager` 的**消费接线由用户后续单独提供,本次不实现**。本盘点对应参考的落点侧文件:`src/content/tile.jsonc:1`、`src/content/enemy.jsonc:1`、`src/content/item.jsonc:1`、`src/content/maps/MT0.jsonc:1`、`src/content/texture/.list.jsonc:1`、`src/content/client.jsonc:9`(`textureListDir: texture/.list.jsonc`)、`src/content/defaults/tile.jsonc:1`、`src/content/defaults/enemy.jsonc:1`、`src/content/defaults/item.jsonc:1`、`src/content/defaults/map.jsonc:1`、`src/content/defaults/texture.jsonc:1`。
|
||||
|
||||
### 0.3 名词说明(`blocksInfo`)
|
||||
|
||||
`blocksInfo` 是**运行时名称**(`core.maps.blocksInfo`),**并非** `public/project/maps.js` 中的字面键名。该文件的字面形态为顶层 `var maps_<hash> = { "1": {…}, … }` 的图块定义对象(`public/project/maps.js:1` 为 `var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =`,`:3` 为第一个图块条目 `"1": {"cls":"animates",…}`)。本文档凡称 `blocksInfo` 一律指代该顶层对象,**检索时请勿按字面串 `blocksInfo` 在文件中匹配**。同理,`enemys.js` 顶层为 `var enemys_<hash>`(`public/project/enemys.js:1`),`items.js` 顶层为 `var items_<hash>`(`public/project/items.js:1`),`floors/*.js` 顶层为 `main.floors.<id> = {…}`(`public/project/floors/MT0.js:1`)。
|
||||
|
||||
### 0.4 扫描方法论
|
||||
|
||||
- 用 `node` 在 `vm` 沙箱中只读求值 `public/project` 的 JS 数据文件,逐项实测枚举其键与字段,不臆造。
|
||||
- **PNG 像素尺寸**用 `node` 读取 PNG `IHDR`(宽 = 偏移 16 起 4 字节大端,高 = 偏移 20 起 4 字节大端)获得,无需任何依赖。
|
||||
- 映射目标接口以 `packages-user/data-common/src/store/types.ts` 与 `packages-user/client-base/src/material/types.ts` 的既有定义为锚点。
|
||||
- 所有计数为执行日实测;行号以执行日实测为准。
|
||||
|
||||
### 0.5 D-72 五条拆分规则原文(含 tilesets / autotiles 例外)
|
||||
|
||||
> **D-72(合并 / 分图规则):** ① `npc` 与 `npc48`、`enemy` 与 `enemy48` 均**合并**(不再有 48 变体);② `terrains` / `items` / `enemy` / `npc` **分别存储**,不得混入同一张图片;③ `animates` **合并入 `terrains`**;④ **不同帧数**的素材不得放入同一张图片;⑤ 单帧素材按 **4×4** 规格拆分,多帧素材按「**帧数列 × 4 行**」拆分。
|
||||
|
||||
**例外(不套用 D-72⑤):**
|
||||
|
||||
- `public/project/tilesets/*.png` → 走 `addTileset`(`source` / `identifier` / `cellWidth` / `cellHeight`,见 `packages-user/client-base/src/material/types.ts:302`),**不**做 4×4 / 帧数列×4 行拆分。
|
||||
- `public/project/autotiles/*.png` → 走 `addAutotile`(`source` / `identifier` / `type: AutotileType`,见 `packages-user/client-base/src/material/types.ts:289`;`AutotileType` 定义于同文件 `:12`,含 2×3 `Small2x3` 与 3×4 `Big3x4`),**不**做 4×4 / 帧数列×4 行拆分。
|
||||
|
||||
#### 0.5.1 指令落地强化(D-72③:`animates` 并入 `terrains`)
|
||||
|
||||
> **固定表述:** **`animates` 并入 `terrains`,不设独立 `animates` 素材组。**
|
||||
|
||||
上句特指**素材 / 分图分组**层面的合并 —— `animates` 各图块的贴图与 `terrain` 归入**同一** `terrains` 素材组(受规则④约束:`animates` 为多帧,与单帧 `terrains` 分开成图,见 §2.4)。
|
||||
|
||||
**不得**与**逻辑类型映射**混淆:§1.1 中旧 `cls: animates` → `TileType.Animate` 的映射**保留不变**(`TileType` 枚举中 `Terrain` 与 `Animate` 并存,见 `packages-user/data-common/src/store/types.ts:6`)。即「逻辑类型仍区分 `Terrain` / `Animate`」与「素材 / 分图分组并入 `terrains`」是**两件独立的事**(消歧见 §1.1 与 OI-4)。
|
||||
|
||||
### 0.6 命名待报备说明(D-73)
|
||||
|
||||
本盘点中提出的任何新增 / 修改命名(拆分后贴图文件名、`addTileset` / `addAutotile` 的 `identifier` 与参数名、`texture/.list.jsonc` 字段名)**只作为「命名候选」写入台账并逐条标注「待用户报备批准」**,**不落地使用**、**不写入任何 `src/content/**` 文件**(AGENTS.md:公共 / 受保护 / 私有方法、字段命名须先报备获批)。
|
||||
|
||||
### 0.7 只读声明(D-74 / D-75)
|
||||
|
||||
本文件是本次任务**唯一产物之一**(另一为 `09-17-SUMMARY.md`)。全程未改动任何 `.ts` / `.tsx`、任何 `public/project/**` 与 `src/content/**` 数据文件、任何既有注释或任何既有规划文件;未生成任何 `.png`。根据 D-75,迁移阶段的 PNG 素材将由后续脚本生成,**本盘点阶段不生成任何素材**。
|
||||
|
||||
## 1. 图块定义 tile
|
||||
|
||||
数据来源:`public/project/maps.js:3` 起的顶层 `var maps_<hash> = { "num": {…} }` 对象(运行时名 `blocksInfo`)。实测共 **235** 个图块定义。
|
||||
|
||||
**`num` 可全部重新分配(指令 3):** **图块 `num` 可全部重新分配,不沿用旧引擎顺序,唯一约束是 `id` ↔ `num` 一致**(即 `addTile` 的 `num` 与 `id` 均不冲突即可,见 `packages-user/data-common/src/store/types.ts:88`)。§1.3 的旧 `num` 列**仅作参考对照**;新 `num` 分配策略候选见 §1.5,均标注「待用户报备批准」。
|
||||
|
||||
### 1.1 `cls` → `TileType` 映射候选
|
||||
|
||||
目标枚举 `TileType`(`packages-user/data-common/src/store/types.ts:6`):`Unknown` / `None` / `Terrain` / `Animate` / `Item` / `Enemy` / `Npc` / `Autotile` / `Tileset`。
|
||||
|
||||
| 旧 `cls` | 实测条数 | 目标 `TileType`(候选) | 依据 |
|
||||
| --- | --- | --- | --- |
|
||||
| `animates` | 29 | `Animate` | 动画类图块(`public/project/maps.js:3` 首项 `cls:"animates"`) |
|
||||
| `terrains` | 35 | `Terrain` | 地形类图块 |
|
||||
| `autotile` | 4 | `Autotile` | 自动元件(`public/project/maps.js:19` `"20": {"cls":"autotile","id":"autotile"}`) |
|
||||
| `items` | 62 | `Item` | 道具类图块(`public/project/maps.js:227` `"331": {"cls":"items","id":"I331"}`) |
|
||||
| `enemys` | 73 | `Enemy` | 怪物类图块(`public/project/maps.js:121` `"201": {"cls":"enemys","id":"greenSlime"}`) |
|
||||
| `enemy48` | 8 | `Enemy`(合并,D-72①) | 高 48px 怪物图块(`public/project/maps.js:181` `"261": {"cls":"enemy48","id":"angel"}`) |
|
||||
| `npcs` | 14 | `Npc` | NPC 图块(`public/project/maps.js:90` `"121": {"cls":"npcs","id":"man"}`) |
|
||||
| `npc48` | 10 | `Npc`(合并,D-72①) | 高 48px NPC 图块(`public/project/maps.js:102` `"133": {"cls":"npc48","id":"npc0",…}`) |
|
||||
|
||||
合计 29 + 35 + 4 + 62 + 73 + 8 + 14 + 10 = **235**。`cls` 实测集合 = `animates, terrains, autotile, items, npcs, npc48, enemys, enemy48`(8 种);无 `None` / `Tileset` 图块定义。
|
||||
|
||||
> **消歧(指令 1 / OI-4):** 本表是**逻辑类型映射**(`cls` → `TileType`)—— `animates` → `TileType.Animate` 与 `terrains` → `TileType.Terrain` **各自保留**。这与 §0.5.1 / §2.4 的**素材 / 分图分组**合并(`animates` 并入 `terrains`,D-72③)**不是同一件事**:前者管「图块逻辑类型」,后者管「贴图分图归属」。
|
||||
|
||||
### 1.2 字段映射候选 → `ITileRawData`
|
||||
|
||||
目标接口 `ITileRawData`(`packages-user/data-common/src/store/types.ts:47`):`num: number` / `id: string` / `events: Record<number, string>` / `type: TileType` / `pass: ITilePassData` / `eventPass: boolean`。通行性子对象 `ITilePassData`(同文件 `:38`):`onlyEvents: boolean` / `outPass: number` / `inPass: number`。
|
||||
|
||||
旧图块字段实测频次:`cls`(235)、`id`(235)、`canBreak`(4)、`animate`(21)、`doorInfo`(17)、`name`(32)、`canPass`(19)、`trigger`(20)、`script`(5)、`faceIds`(4)、`autotileConnection`(2)、`cannotOut`(18)、`cannotIn`(18)。
|
||||
|
||||
**字段分类(指令 2,判定基准 = 目标接口是否存在对应字段):**
|
||||
|
||||
- **映射候选(可确定)**:目标接口有对应字段,且映射关系可直接确定。
|
||||
- **待定(有目标字段但映射不确定)**:目标接口有对应字段,但取值 / 展开关系无法由静态解析唯一确定(汇总见 §8.2)。
|
||||
- **只记录、不移植(目标接口无对应字段)**:`ITileRawData` / `ITilePassData` 中**不存在**对应字段,旧字段只作盘点记录,不进入迁移(汇总见 §8.1)。
|
||||
|
||||
| 旧字段 | 实测条数 | 目标落点(候选) | 分类 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `id` | 235 | `ITileRawData.id` | 映射候选(可确定) | 直接对应图块字符串 id |
|
||||
| `cls` | 235 | `ITileRawData.type` | 映射候选(可确定) | 经 §1.1 映射为 `TileType` |
|
||||
| `trigger` | 20 | `ITileRawData.events`(事件 id)/ `eventPass` | 待定(有目标字段但映射不确定) | 旧触发名(`null` / `openDoor` / `ski` / `pushBox`);**确有对应字段**,仅事件 id 与事件可通行性的具体对应未定(§8.2 U-2) |
|
||||
| `canPass` | 19 | `ITilePassData`(`inPass` / `outPass` 位运算) | 待定(有目标字段但映射不确定) | 旧布尔「可通行」→ 新四方向通行位(`PassBit`,`packages-user/data-common/src/store/types.ts:27`);**确有对应字段**,仅具体方向展开未定(§8.2 U-3) |
|
||||
| `cannotOut` / `cannotIn` | 18 / 18 | `ITilePassData.outPass` / `inPass` | 映射候选(可确定) | 旧方向数组(`up` / `down` / `left` / `right`)→ 方向位掩码(可确定取反:`outPass = 全方向位 & ~cannotOut`) |
|
||||
| `doorInfo` | 17 | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 含 `time` / `openSound` / `closeSound` / `keys`;`ITileRawData` / `ITilePassData` 无字段承载门机制参数(§8.1 U-4) |
|
||||
| `animate` | 21 | 无(仅用于 §2 素材帧数推导) | 只记录、不移植(目标接口无对应字段) | 旧值多为 `1`;`ITileRawData` 无帧数字段,帧数由素材(`addRowAnimate`)承载(§8.1 U-4) |
|
||||
| `canBreak` | 4 | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 出现在 `animates` 墙类(`yellowWall` 等,`public/project/maps.js:3`);无字段承载「可破坏」语义(§8.1 U-4) |
|
||||
| `script` | 5 | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 旧内联脚本(如 `lavaNet` / `light` / 血网等);`events` 仅存事件 id,不承载脚本正文(§8.1 U-4) |
|
||||
| `faceIds` | 4 | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 仅 `npc48` 的 `npc0..npc3`(`public/project/maps.js:102`)与敌人 `bear` 四面;无字段承载多面机制(§8.1 U-5) |
|
||||
| `autotileConnection` | 2 | 无(目标接口无对应字段;对应 `IAutotileProcessor.setConnection`,非 `ITileRawData` 字段) | 只记录、不移植(目标接口无对应字段) | 仅 `autotile1` / `autotile3`(`public/project/maps.js:108`,值 `["yellowDoor"]`)(§8.1 U-5) |
|
||||
| `name` | 32 | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 旧显示名(如 `血网` / `黄门` / `薄墙-上`);`ITileRawData` 无对应字段(§8.1 U-5) |
|
||||
|
||||
### 1.3 `num` / `id` 全清单(235 条)
|
||||
|
||||
| num | id | cls | 关键字段 |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | yellowWall | animates | canBreak, animate, doorInfo |
|
||||
| 2 | whiteWall | animates | canBreak, animate, doorInfo |
|
||||
| 3 | blueWall | animates | canBreak, animate, doorInfo |
|
||||
| 4 | star | animates | name |
|
||||
| 5 | lava | animates | name |
|
||||
| 6 | ice | animates | doorInfo, animate |
|
||||
| 7 | blueShopLeft | terrains | - |
|
||||
| 8 | blueShopRight | terrains | - |
|
||||
| 9 | pinkShopLeft | terrains | - |
|
||||
| 10 | pinkShopRight | terrains | - |
|
||||
| 11 | lavaNet | animates | canPass, trigger, script, name |
|
||||
| 12 | poisonNet | animates | canPass, trigger, script, name |
|
||||
| 13 | weakNet | animates | canPass, trigger, script, name |
|
||||
| 14 | curseNet | animates | canPass, trigger, script, name |
|
||||
| 15 | blueLava | animates | - |
|
||||
| 16 | water | animates | - |
|
||||
| 20 | autotile | autotile | - |
|
||||
| 21 | yellowKey | items | - |
|
||||
| 22 | blueKey | items | - |
|
||||
| 23 | redKey | items | - |
|
||||
| 24 | greenKey | items | - |
|
||||
| 25 | steelKey | items | - |
|
||||
| 26 | bigKey | items | - |
|
||||
| 27 | redGem | items | - |
|
||||
| 28 | blueGem | items | - |
|
||||
| 29 | greenGem | items | - |
|
||||
| 30 | yellowGem | items | - |
|
||||
| 31 | redPotion | items | - |
|
||||
| 32 | bluePotion | items | - |
|
||||
| 33 | greenPotion | items | - |
|
||||
| 34 | yellowPotion | items | - |
|
||||
| 35 | sword1 | items | - |
|
||||
| 36 | shield1 | items | - |
|
||||
| 37 | sword2 | items | - |
|
||||
| 38 | shield2 | items | - |
|
||||
| 39 | sword3 | items | - |
|
||||
| 40 | shield3 | items | - |
|
||||
| 41 | sword4 | items | - |
|
||||
| 42 | shield4 | items | - |
|
||||
| 43 | sword5 | items | - |
|
||||
| 44 | shield5 | items | - |
|
||||
| 45 | book | items | - |
|
||||
| 46 | fly | items | - |
|
||||
| 47 | pickaxe | items | - |
|
||||
| 48 | icePickaxe | items | - |
|
||||
| 49 | bomb | items | - |
|
||||
| 50 | centerFly | items | - |
|
||||
| 51 | upFly | items | - |
|
||||
| 52 | downFly | items | - |
|
||||
| 53 | coin | items | - |
|
||||
| 54 | freezeBadge | items | - |
|
||||
| 55 | cross | items | - |
|
||||
| 56 | superPotion | items | - |
|
||||
| 57 | earthquake | items | - |
|
||||
| 58 | poisonWine | items | - |
|
||||
| 59 | weakWine | items | - |
|
||||
| 60 | curseWine | items | - |
|
||||
| 61 | superWine | items | - |
|
||||
| 62 | dagger | items | - |
|
||||
| 63 | pack | items | - |
|
||||
| 64 | amulet | items | - |
|
||||
| 65 | hammer | items | - |
|
||||
| 68 | lifeWand | items | - |
|
||||
| 69 | jumpShoes | items | - |
|
||||
| 70 | sword0 | items | - |
|
||||
| 71 | shield0 | items | - |
|
||||
| 72 | skill1 | items | - |
|
||||
| 73 | wand | items | - |
|
||||
| 81 | yellowDoor | animates | trigger, animate, doorInfo, name |
|
||||
| 82 | blueDoor | animates | trigger, animate, doorInfo, name |
|
||||
| 83 | redDoor | animates | trigger, animate, doorInfo, name |
|
||||
| 84 | greenDoor | animates | trigger, animate, doorInfo, name |
|
||||
| 85 | specialDoor | animates | trigger, animate, doorInfo, name |
|
||||
| 86 | steelDoor | animates | trigger, animate, doorInfo, name |
|
||||
| 87 | upFloor | terrains | canPass |
|
||||
| 88 | downFloor | terrains | canPass |
|
||||
| 89 | portal | animates | canPass |
|
||||
| 90 | starPortal | animates | canPass |
|
||||
| 91 | upPortal | animates | canPass |
|
||||
| 92 | leftPortal | animates | canPass |
|
||||
| 93 | downPortal | animates | canPass |
|
||||
| 94 | rightPortal | animates | canPass |
|
||||
| 101 | crystalUp | animates | - |
|
||||
| 102 | crystalBottom | animates | - |
|
||||
| 103 | fire | animates | - |
|
||||
| 104 | switch | animates | - |
|
||||
| 109 | magentaWall | animates | canBreak, animate, doorInfo |
|
||||
| 121 | man | npcs | - |
|
||||
| 122 | trader | npcs | - |
|
||||
| 123 | thief | npcs | - |
|
||||
| 124 | fairy | npcs | - |
|
||||
| 125 | wizard | npcs | - |
|
||||
| 126 | recluse | npcs | - |
|
||||
| 127 | king | npcs | - |
|
||||
| 128 | youngMan | npcs | - |
|
||||
| 129 | sign | npcs | - |
|
||||
| 130 | expShop | npcs | - |
|
||||
| 131 | moneyShop | npcs | - |
|
||||
| 132 | princess | npcs | - |
|
||||
| 133 | npc0 | npc48 | faceIds, animate |
|
||||
| 134 | npc1 | npc48 | faceIds, animate |
|
||||
| 135 | npc2 | npc48 | faceIds, animate |
|
||||
| 136 | npc3 | npc48 | faceIds, animate |
|
||||
| 137 | greenMan | npcs | - |
|
||||
| 138 | blueTrader | npcs | - |
|
||||
| 151 | autotile1 | autotile | autotileConnection |
|
||||
| 152 | autotile2 | autotile | - |
|
||||
| 153 | autotile3 | autotile | autotileConnection |
|
||||
| 161 | arrowUp | terrains | canPass, cannotOut, cannotIn |
|
||||
| 162 | arrowDown | terrains | canPass, cannotOut, cannotIn |
|
||||
| 163 | arrowLeft | terrains | canPass, cannotOut, cannotIn |
|
||||
| 164 | arrowRight | terrains | canPass, cannotOut, cannotIn |
|
||||
| 165 | light | terrains | trigger, canPass, script |
|
||||
| 166 | darkLight | terrains | - |
|
||||
| 167 | ski | terrains | trigger, canPass |
|
||||
| 168 | flower | terrains | canPass |
|
||||
| 169 | box | terrains | trigger |
|
||||
| 170 | boxed | terrains | trigger |
|
||||
| 201 | greenSlime | enemys | - |
|
||||
| 202 | redSlime | enemys | - |
|
||||
| 203 | blackSlime | enemys | - |
|
||||
| 204 | slimelord | enemys | - |
|
||||
| 205 | bat | enemys | - |
|
||||
| 206 | bigBat | enemys | - |
|
||||
| 207 | redBat | enemys | - |
|
||||
| 208 | vampire | enemys | - |
|
||||
| 209 | skeleton | enemys | - |
|
||||
| 210 | skeletonWarrior | enemys | - |
|
||||
| 211 | skeletonCaptain | enemys | - |
|
||||
| 212 | ghostSoldier | enemys | - |
|
||||
| 213 | zombie | enemys | - |
|
||||
| 214 | zombieKnight | enemys | - |
|
||||
| 215 | rock | enemys | - |
|
||||
| 216 | slimeman | enemys | - |
|
||||
| 217 | bluePriest | enemys | - |
|
||||
| 218 | redPriest | enemys | - |
|
||||
| 219 | brownWizard | enemys | - |
|
||||
| 220 | redWizard | enemys | - |
|
||||
| 221 | yellowGateKeeper | enemys | - |
|
||||
| 222 | blueGateKeeper | enemys | - |
|
||||
| 223 | redGateKeeper | enemys | - |
|
||||
| 224 | swordsman | enemys | - |
|
||||
| 225 | soldier | enemys | - |
|
||||
| 226 | yellowKnight | enemys | - |
|
||||
| 227 | redKnight | enemys | - |
|
||||
| 228 | darkKnight | enemys | - |
|
||||
| 229 | blackKing | enemys | - |
|
||||
| 230 | yellowKing | enemys | - |
|
||||
| 231 | greenKing | enemys | - |
|
||||
| 232 | blueKnight | enemys | - |
|
||||
| 233 | goldSlime | enemys | - |
|
||||
| 234 | poisonSkeleton | enemys | - |
|
||||
| 235 | poisonBat | enemys | - |
|
||||
| 236 | ironRock | enemys | - |
|
||||
| 237 | skeletonPriest | enemys | - |
|
||||
| 238 | skeletonKing | enemys | - |
|
||||
| 239 | skeletonPresbyter | enemys | - |
|
||||
| 240 | skeletonKnight | enemys | - |
|
||||
| 241 | evilHero | enemys | - |
|
||||
| 242 | devilWarrior | enemys | - |
|
||||
| 243 | demonPriest | enemys | - |
|
||||
| 244 | goldHornSlime | enemys | - |
|
||||
| 245 | redKing | enemys | - |
|
||||
| 246 | blueKing | enemys | - |
|
||||
| 247 | magicMaster | enemys | - |
|
||||
| 248 | silverSlime | enemys | - |
|
||||
| 249 | blademaster | enemys | - |
|
||||
| 250 | whiteHornSlime | enemys | - |
|
||||
| 251 | evilPrincess | enemys | - |
|
||||
| 252 | evilFairy | enemys | - |
|
||||
| 253 | yellowPriest | enemys | - |
|
||||
| 254 | redSwordsman | enemys | - |
|
||||
| 255 | whiteSlimeman | enemys | - |
|
||||
| 256 | poisonZombie | enemys | - |
|
||||
| 257 | dragon | enemys | - |
|
||||
| 258 | octopus | enemys | - |
|
||||
| 259 | fairyEnemy | enemys | - |
|
||||
| 260 | princessEnemy | enemys | - |
|
||||
| 261 | angel | enemy48 | - |
|
||||
| 262 | elemental | enemy48 | - |
|
||||
| 263 | steelGuard | enemy48 | - |
|
||||
| 264 | evilBat | enemy48 | - |
|
||||
| 265 | silverSlimelord | enemys | - |
|
||||
| 266 | goldSlimelord | enemys | - |
|
||||
| 267 | grayRock | enemys | - |
|
||||
| 270 | greenKnight | enemys | - |
|
||||
| 271 | bowman | enemys | - |
|
||||
| 272 | purpleBowman | enemys | - |
|
||||
| 275 | watcherSlime | enemys | - |
|
||||
| 277 | frostBat | enemys | - |
|
||||
| 278 | devilKnight | enemys | - |
|
||||
| 279 | grayPriest | enemys | - |
|
||||
| 280 | greenGateKeeper | enemys | - |
|
||||
| 300 | ground | terrains | - |
|
||||
| 301 | sWallT | terrains | name, cannotOut, cannotIn |
|
||||
| 302 | sWallL | terrains | name, cannotOut, cannotIn |
|
||||
| 303 | sWallR | terrains | name, cannotOut, cannotIn |
|
||||
| 304 | sWallB | terrains | name, cannotOut, cannotIn |
|
||||
| 305 | grass | terrains | - |
|
||||
| 306 | sWallTL | terrains | name, cannotOut, cannotIn |
|
||||
| 307 | sWallBR | terrains | name, cannotOut, cannotIn |
|
||||
| 308 | grass2 | terrains | - |
|
||||
| 309 | sWallTR | terrains | name, cannotOut, cannotIn |
|
||||
| 310 | sWallBL | terrains | name, cannotOut, cannotIn |
|
||||
| 311 | ground2 | terrains | - |
|
||||
| 312 | sWallTB | terrains | name, cannotOut, cannotIn |
|
||||
| 313 | ground3 | terrains | - |
|
||||
| 314 | sWallLR | terrains | name, cannotOut, cannotIn |
|
||||
| 315 | sWallBLR | terrains | name, cannotOut, cannotIn |
|
||||
| 316 | sWallTLR | terrains | name, cannotOut, cannotIn |
|
||||
| 317 | sWallTBR | terrains | name, cannotOut, cannotIn |
|
||||
| 318 | sWallTBL | terrains | name, cannotOut, cannotIn |
|
||||
| 319 | tallYellowDoor | npc48 | trigger, name, animate, doorInfo |
|
||||
| 320 | tallBlueDoor | npc48 | trigger, name, animate, doorInfo |
|
||||
| 321 | tallRedDoor | npc48 | trigger, name, animate, doorInfo |
|
||||
| 322 | tallGreenDoor | npc48 | trigger, name, animate, doorInfo |
|
||||
| 323 | tallSpecialDoor | npc48 | trigger, name, animate, doorInfo |
|
||||
| 324 | tallSteelDoor | npc48 | trigger, name, animate, doorInfo |
|
||||
| 325 | keiskeiFairy | enemys | - |
|
||||
| 326 | tulipFairy | enemys | - |
|
||||
| 327 | bearDown | enemy48 | - |
|
||||
| 328 | bearLeft | enemy48 | - |
|
||||
| 329 | bearRight | enemy48 | - |
|
||||
| 330 | bearUp | enemy48 | - |
|
||||
| 331 | I331 | items | - |
|
||||
| 332 | I332 | items | - |
|
||||
| 333 | I333 | items | - |
|
||||
| 334 | I334 | items | - |
|
||||
| 335 | I335 | items | - |
|
||||
| 336 | I336 | items | - |
|
||||
| 337 | I337 | items | - |
|
||||
| 338 | I338 | items | - |
|
||||
| 339 | I339 | items | - |
|
||||
| 340 | I340 | items | - |
|
||||
| 341 | I341 | items | - |
|
||||
|
||||
**TILE-COUNT: 235**
|
||||
|
||||
### 1.4 图块 → 贴图归属候选
|
||||
|
||||
按 D-72①③与 §2 的目标拆分,图块 id 归属候选如下(贴图文件名均为 §2.5 的命名候选,**待用户报备批准**):
|
||||
|
||||
| `cls` | 图块 num 段 | 目标贴图归属候选 |
|
||||
| --- | --- | --- |
|
||||
| `terrains` | 7–10, 87–88, 161–170, 300–318 | `terrains` 组(单帧) |
|
||||
| `animates` | 1–6, 11–16, 81–86, 89–94, 101–104, 109 | `terrains` 组(多帧)—— **`animates` 并入 `terrains`,不设独立 `animates` 素材组**(D-72③) |
|
||||
| `items` | 21–73, 331–341 | `items` 组 |
|
||||
| `enemys` + `enemy48` | 201–280, 325–330 | `enemy` 组(合并,D-72①) |
|
||||
| `npcs` + `npc48` | 121–138, 133–136, 319–324 | `npc` 组(合并,D-72①) |
|
||||
| `autotile` | 20, 151–153 | 对应 §2.2 的 autotile 素材(例外,非材料拆分) |
|
||||
|
||||
> **固定表述(指令 1):** **`animates` 并入 `terrains`,不设独立 `animates` 素材组**(D-72③,与 §0.5.1 一致)。此为**贴图归属 / 素材分组**层面的合并(受规则④:多帧 `animates` 与单帧 `terrains` 分开成图);**不影响** §1.1 的**逻辑类型映射**(`animates` → `TileType.Animate` 仍保留)。
|
||||
|
||||
### 1.5 id 全清单与新 num 分配策略候选
|
||||
|
||||
本节汇总 **id 全清单**(235 条,复用 §1.3 的 `id` 列,按 `cls` 分组,**完整覆盖、不遗漏**)与 **num 分配策略候选**(≥3 个,均标注「待用户报备批准」)。**本盘点只记录候选,不落地任何 `num` 分配**(D-73 / OI-1)。
|
||||
|
||||
#### 1.5.1 id 全清单(235 条,按 `cls` 分组)
|
||||
|
||||
| `cls` | 条数 | 图块 id 全清单 |
|
||||
| --- | --- | --- |
|
||||
| `animates` | 29 | yellowWall, whiteWall, blueWall, star, lava, ice, lavaNet, poisonNet, weakNet, curseNet, blueLava, water, yellowDoor, blueDoor, redDoor, greenDoor, specialDoor, steelDoor, portal, starPortal, upPortal, leftPortal, downPortal, rightPortal, crystalUp, crystalBottom, fire, switch, magentaWall |
|
||||
| `terrains` | 35 | blueShopLeft, blueShopRight, pinkShopLeft, pinkShopRight, upFloor, downFloor, arrowUp, arrowDown, arrowLeft, arrowRight, light, darkLight, ski, flower, box, boxed, ground, sWallT, sWallL, sWallR, sWallB, grass, sWallTL, sWallBR, grass2, sWallTR, sWallBL, ground2, sWallTB, ground3, sWallLR, sWallBLR, sWallTLR, sWallTBR, sWallTBL |
|
||||
| `autotile` | 4 | autotile, autotile1, autotile2, autotile3 |
|
||||
| `items` | 62 | yellowKey, blueKey, redKey, greenKey, steelKey, bigKey, redGem, blueGem, greenGem, yellowGem, redPotion, bluePotion, greenPotion, yellowPotion, sword1, shield1, sword2, shield2, sword3, shield3, sword4, shield4, sword5, shield5, book, fly, pickaxe, icePickaxe, bomb, centerFly, upFly, downFly, coin, freezeBadge, cross, superPotion, earthquake, poisonWine, weakWine, curseWine, superWine, dagger, pack, amulet, hammer, lifeWand, jumpShoes, sword0, shield0, skill1, wand, I331, I332, I333, I334, I335, I336, I337, I338, I339, I340, I341 |
|
||||
| `enemys` | 73 | greenSlime, redSlime, blackSlime, slimelord, bat, bigBat, redBat, vampire, skeleton, skeletonWarrior, skeletonCaptain, ghostSoldier, zombie, zombieKnight, rock, slimeman, bluePriest, redPriest, brownWizard, redWizard, yellowGateKeeper, blueGateKeeper, redGateKeeper, swordsman, soldier, yellowKnight, redKnight, darkKnight, blackKing, yellowKing, greenKing, blueKnight, goldSlime, poisonSkeleton, poisonBat, ironRock, skeletonPriest, skeletonKing, skeletonPresbyter, skeletonKnight, evilHero, devilWarrior, demonPriest, goldHornSlime, redKing, blueKing, magicMaster, silverSlime, blademaster, whiteHornSlime, evilPrincess, evilFairy, yellowPriest, redSwordsman, whiteSlimeman, poisonZombie, dragon, octopus, fairyEnemy, princessEnemy, silverSlimelord, goldSlimelord, grayRock, greenKnight, bowman, purpleBowman, watcherSlime, frostBat, devilKnight, grayPriest, greenGateKeeper, keiskeiFairy, tulipFairy |
|
||||
| `enemy48` | 8 | angel, elemental, steelGuard, evilBat, bearDown, bearLeft, bearRight, bearUp |
|
||||
| `npcs` | 14 | man, trader, thief, fairy, wizard, recluse, king, youngMan, sign, expShop, moneyShop, princess, greenMan, blueTrader |
|
||||
| `npc48` | 10 | npc0, npc1, npc2, npc3, tallYellowDoor, tallBlueDoor, tallRedDoor, tallGreenDoor, tallSpecialDoor, tallSteelDoor |
|
||||
| **合计** | **235** | —— |
|
||||
|
||||
> 分组条数校验:29 + 35 + 4 + 62 + 73 + 8 + 14 + 10 = **235**(与 §1.1 / §1.3 一致)。以上 id 与 §1.3 的 `id` 列**逐条一致**(§1.3 含旧 `num`,本节只列 `id`,便于重排 `num` 时按 `id` 唯一对应)。
|
||||
|
||||
#### 1.5.2 新 num 分配策略候选(均「待用户报备批准」)
|
||||
|
||||
以下策略**只作候选记录**,用于后续「迁移计划」确定 `num` 分配口径;**本盘点不选型、不落地**(OI-1)。
|
||||
|
||||
| 策略(候选) | 策略要点 | 优点 | 缺点 | 与旧 `num` 的对照 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| **A. 按 `TileType` 分段** | 按逻辑类型分成连续段:`Terrain` / `Animate` / `Item` / `Enemy` / `Npc` / `Autotile` / `Tileset` 各占一段,段内按 `id` 或旧 `num` 排序 | 段位语义清晰,便于按类型批量分配 / 查错 | 需整体重排,旧 `num` 全部失效;跨类共享 `id` 的图(如 door 类)归属需先定 | 完全打乱旧 `num`,仅以 `id` 对应 |
|
||||
| **B. 沿用旧 `num`** | 保持 §1.3 的 `num` 不变,仅校验 `id` ↔ `num` 唯一一致 | 迁移最省,对照成本最低,旧资料回查方便 | 未利用「可全部重排」的灵活性;`enemy48`/`npc48` 合并后旧 `num` 段可能零散、留空洞 | 与旧 `num` 完全一致 |
|
||||
| **C. 按目标贴图(拆分后图)分组顺序重排** | 以 §2.4 / §2.5 的目标图(A..E 组及拆分序)顺序为纲,同图内图块 `num` 连续分配 | 与素材拆分结果对齐,`num` 局部性贴近贴图,利于按图缓存 / 定位 | 依赖 §2.4 拆分方案最终定稿;拆分调整会牵动 `num` | 与旧 `num` 无关,按目标图顺序重排 |
|
||||
| **D. 按 `id` 次序分配** | 对 §1.5.1 的 id 全清单按 `id` 字典序(或分组后组内字典序)依次赋 `num` | 规则最简单、可完全脚本化、无歧义 | `num` 与语义 / 贴图均无关,调试可读性最差 | 与旧 `num` 无关,按 `id` 次序重排 |
|
||||
|
||||
> 以上任一策略均满足唯一硬约束:**`id` ↔ `num` 一致**(`addTile` 的 `num` 与 `id` 均不冲突,见 `packages-user/data-common/src/store/types.ts:88`)。候选取用哪一种**待用户报备批准 / 裁定**(OI-1)。
|
||||
|
||||
## 2. 贴图素材 textures
|
||||
|
||||
本维度显式含三类素材:`materials/*.png`、`autotiles/*.png`(例外)、`tilesets/*.png`(例外)。
|
||||
|
||||
### 2.1 `materials/*.png` 登记
|
||||
|
||||
像素尺寸由 `node` 读取 PNG `IHDR` 实测(锚点指向对应 PNG 文件,`:1` 表示该文件)。
|
||||
|
||||
| 素材 | 像素尺寸 | 承载图块类(候选) |
|
||||
| --- | --- | --- |
|
||||
| `public/project/materials/terrains.png:1` | 32×1120 | `terrains`(35 单帧图块,1 列 × 35 行) |
|
||||
| `public/project/materials/items.png:1` | 32×1984 | `items`(62 单帧图块,1 列 × 62 行) |
|
||||
| `public/project/materials/enemys.png:1` | 64×2336 | `enemys`(73 怪物,2 列 × 73 行,每怪 2 帧) |
|
||||
| `public/project/materials/enemy48.png:1` | 128×384 | `enemy48`(8 怪物,2 列 × 8 行,每怪 2 帧) |
|
||||
| `public/project/materials/npcs.png:1` | 64×448 | `npcs`(14 NPC,2 列 × 14 行,每 NPC 2 帧) |
|
||||
| `public/project/materials/npc48.png:1` | 128×480 | `npc48`(10 NPC,2 列 × 10 行,每 NPC 2 帧) |
|
||||
| `public/project/materials/animates.png:1` | 128×928 | `animates`(29 动画图块,4 帧列 × 29 行)—— **素材分组并入 `terrains`,不设独立 `animates` 素材组**(D-72③,见 §0.5.1) |
|
||||
| `public/project/materials/ground.png:1` | 32×32 | 单帧素材(归类**待确认**,§8) |
|
||||
| `public/project/materials/airwall.png:1` | 32×32 | 单帧素材(归类**待确认**,§8) |
|
||||
| `public/project/materials/keyboard.png:1` | 416×416 | 13×13 单帧网格(用途归类**待确认**,§8) |
|
||||
| `public/project/materials/icons.png:1` | 32×1120 | 1 列 × 35 行(用途归类**待确认**,§8) |
|
||||
| `public/project/materials/icons_old.png:1` | 32×1120 | 1 列 × 35 行(用途归类**待确认**,§8) |
|
||||
|
||||
**MATERIAL-COUNT: 17**(= 12 materials + 4 autotiles + 1 tileset)
|
||||
|
||||
### 2.2 `autotiles/*.png` 登记(例外,不套用 D-72⑤)
|
||||
|
||||
走 `addAutotile(source, identifier, type)`(`packages-user/client-base/src/material/types.ts:289`);`type` 取 `AutotileType`(同文件 `:12`):2×3 = `Small2x3`、3×4 = `Big3x4`。
|
||||
|
||||
| 素材 | 像素尺寸 | `type` 候选 | `identifier` 候选 | 判定依据 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `public/project/autotiles/autotile.png:1` | 96×128 | `Big3x4` | 20 | 96/32 = 3 列、128/32 = 4 行 → 3×4 |
|
||||
| `public/project/autotiles/autotile2.png:1` | 96×128 | `Big3x4` | 152 | 同上 |
|
||||
| `public/project/autotiles/autotile3.png:1` | 96×128 | `Big3x4` | 153 | 同上 |
|
||||
| `public/project/autotiles/autotile1.png:1` | 384×128 | **待确认**(§8) | 151 | 384/32 = 12;无法由尺寸唯一判定 2×3 / 3×4 |
|
||||
|
||||
`identifier` 候选值取自 §1 中 `autotile` 类图块的 num(20 / 151 / 152 / 153,见 `public/project/maps.js:19`、`public/project/maps.js:108`)。**明确:`autotiles/*.png` 不套用 D-72⑤ 的 4×4 / 帧数列×4 行拆分。**
|
||||
|
||||
### 2.3 `tilesets/*.png` 登记(例外,不套用 D-72⑤)
|
||||
|
||||
走 `addTileset(source, identifier, cellWidth, cellHeight)`(`packages-user/client-base/src/material/types.ts:302`);`identifier` 为 `IIndexedIdentifier`(`{ index: number; alias: string }`,同文件 `:50`)。
|
||||
|
||||
| 素材 | 像素尺寸 | `cellWidth` / `cellHeight` 候选 | `identifier` 候选 | 判定依据 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `public/project/tilesets/magictower.png:1` | 256×1216 | 32 / 32(**待确认**,§8) | `{ index: ?, alias: "magictower" }` | 256/32 = 8 列、1216/32 = 38 行;切格尺寸为**待确认**(§8) |
|
||||
|
||||
**明确:`tilesets/*.png` 不套用 D-72⑤ 的 4×4 / 帧数列×4 行拆分。**
|
||||
|
||||
### 2.4 D-72 目标拆分方案(materials)
|
||||
|
||||
按 D-72 五规则逐组推导(本盘点读法:**单帧目标图 = 4×4 网格,即每图 16 个单帧图块,对应 `addGrid`;多帧目标图 = 「帧数列 × 4 行」,即每图 4 个多帧图块,对应 `addRowAnimate`**。该读法如与用户原意不符,请以用户裁定为准,§8 已记录)。
|
||||
|
||||
| 组 | 来源 PNG | 类别 | 帧数 | 图块数 | 目标图(候选)+ 行列布局 | 目标图数 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| A | `terrains.png` | `terrains` 单帧 | 1 | 35 | `4×4`(16 格/图,`addGrid`) | 3 |
|
||||
| B | `animates.png` | 并入 `terrains`(D-72③)多帧 | 4 | 29 | `帧数列(4) × 4 行`(4 块/图,`addRowAnimate`) | 8 |
|
||||
| C | `items.png` | `items` 单帧 | 1 | 62 | `4×4`(16 格/图,`addGrid`) | 4 |
|
||||
| D | `enemys.png` + `enemy48.png` | `enemy` 合并(D-72①)多帧 | 2 | 81 | `帧数列(2) × 4 行`(4 块/图,`addRowAnimate`) | 21 |
|
||||
| E | `npcs.png` + `npc48.png` | `npc` 合并(D-72①)多帧 | 2 | 24 | `帧数列(2) × 4 行`(4 块/图,`addRowAnimate`) | 6 |
|
||||
|
||||
- 落实规则②:`terrains` / `items` / `enemy` / `npc` 各自成图,不混入同一张。
|
||||
- 落实规则③:**`animates` 并入 `terrains`,不设独立 `animates` 素材组**(因帧数不同,按规则④与 A 组分开成图,D-72③)。
|
||||
- 落实规则④:单帧(A/C)与多帧(B/D/E)分图;B 为 4 帧、D/E 为 2 帧,亦分图。
|
||||
- 落实规则⑤:A/C 为单帧 → 4×4;B/D/E 为多帧 → 帧数列 × 4 行。
|
||||
- `materials` 中 `ground` / `airwall` / `keyboard` / `icons` / `icons_old` 的 D-72 归类**待确认**(§8),未计入本表。
|
||||
- 每图「帧数 × 4 行」按 `addRowAnimate`「每一行的帧数一致」的能力(`packages-user/client-base/src/material/types.ts:275`)设计。
|
||||
|
||||
**SPLIT-COUNT: 42**(= A 3 + B 8 + C 4 + D 21 + E 6;即按 D-72 五规则推导的 materials 目标图数量,仅计 `terrains` / `items` / `enemy` / `npc` 四类)
|
||||
|
||||
### 2.5 命名候选(待报备)
|
||||
|
||||
下表所有命名**均为候选、标注「待用户报备批准」,本计划不落地使用**(D-73 / OI-3)。
|
||||
|
||||
| 候选类别 | 命名候选 | 说明 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| materials 拆分图(`terrains` 单帧) | `terrains0.png` / `terrains1.png` / `terrains2.png` | A 组 3 图 | 待用户报备批准 |
|
||||
| materials 拆分图(`animates` 并入 `terrains`) | `terrainsAnim0.png` … `terrainsAnim7.png` | B 组 8 图;**不设独立 `animates` 素材组**(D-72③) | 待用户报备批准 |
|
||||
| materials 拆分图(`items`) | `items0.png` … `items3.png` | C 组 4 图 | 待用户报备批准 |
|
||||
| materials 拆分图(`enemy`) | `enemy0.png` … `enemy20.png` | D 组 21 图 | 待用户报备批准 |
|
||||
| materials 拆分图(`npc`) | `npc0.png` … `npc5.png` | E 组 6 图 | 待用户报备批准 |
|
||||
| autotile `identifier` 参数 | `20` / `151` / `152` / `153` | 对应 §2.2,取自 §1 图块 num | 待用户报备批准 |
|
||||
| autotile `type` 参数 | `AutoTileType.Big3x4` | `autotile.png` / `autotile2.png` / `autotile3.png` | 待用户报备批准 |
|
||||
| tileset `identifier.alias` | `magictower` | 对应 §2.3 | 待用户报备批准 |
|
||||
| tileset `cellWidth` / `cellHeight` | `32` / `32` | 待确认(§8) | 待用户报备批准 |
|
||||
| `.list.jsonc` 承载字段名 | `grid` / `rowAnimate` / `autotile` / `tileset` | 见 §7 草案 | 待用户报备批准 |
|
||||
|
||||
## 3. 怪物 enemy
|
||||
|
||||
数据来源:`public/project/enemys.js:3` 起的顶层 `var enemys_<hash> = { "<id>": {…} }` 对象,实测 **81** 条,与 §1 的 `enemys`(73) + `enemy48`(8) = 81 图块一一对应(均由 id 关联)。
|
||||
|
||||
目标接口 `IEnemyRawData`(`packages-user/data-common/src/store/types.ts:319`):`num: number` / `attribute: Readonly<T>` / `special: Record<number, any>`。落点默认骨架见 `src/content/defaults/enemy.jsonc:1`(`attribute` 含 `name` / `hp` / `atk` / `def` / `money` / `exp` / `point`)。
|
||||
|
||||
### 3.1 字段映射候选
|
||||
|
||||
旧字段实测频次:`name`(81)、`hp`(81)、`atk`(81)、`def`(81)、`money`(81)、`exp`(81)、`point`(81)、`special`(81)、`value`(6)、`n`(1)、`range`(1)、`zoneSquare`(1)、`bigImage`(3)、`atkValue`(1)、`defValue`(1)、`add`(1)、`notBomb`(2)、`faceIds`(4)。
|
||||
|
||||
分类口径同 §1.2(映射候选(可确定) / 待定(有目标字段但映射不确定) / 只记录、不移植(目标接口无对应字段));判定基准 = `IEnemyRawData`(`packages-user/data-common/src/store/types.ts:319`)。
|
||||
|
||||
| 旧字段 | 目标落点(候选) | 分类 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `num`(由 §1 图块数字得来) | `IEnemyRawData.num` | 映射候选(可确定) | 由 `maps.js` 中 `enemys` / `enemy48` 图块 num 关联(如 `greenSlime` ↔ 201,`public/project/maps.js:121`) |
|
||||
| `name` / `hp` / `atk` / `def` / `money` / `exp` / `point` | `IEnemyRawData.attribute.{…}` | 映射候选(可确定) | 与 `src/content/defaults/enemy.jsonc:1` 的 `attribute` 骨架字段一一对应 |
|
||||
| `special`(数字数组,如 `[16,18]`) | `IEnemyRawData.special: Record<number, any>` | 映射候选(可确定) | 旧为「特殊属性数字」数组 → 新为「数字键 → 值」映射;键即数组中的数字 |
|
||||
| `value` / `range` / `zoneSquare` / `add` / `n` | `IEnemyRawData.special[<键>]`(候选) | 待定(有目标字段但映射不确定) | 旧伴随 `special` 的修饰量;**有目标字段**(`special`),其与具体特殊属性数字键的绑定关系未定(§8.2 U-10) |
|
||||
| `bigImage` | `IEnemyRawData.special[<键>]`(候选) | 待定(有目标字段但映射不确定) | 仅 3 条含(`octopus` / `dragon` / `bearDown`,值为 `null`);**有目标字段**(`special`),键位未定(§8.2 U-10) |
|
||||
| `notBomb` | `IEnemyRawData.special[<键>]`(候选) | 待定(有目标字段但映射不确定) | 2 条(`magicMaster` / `blackKing`);**有目标字段**(`special`),键位未定(§8.2 U-10) |
|
||||
| `atkValue` / `defValue` | `attribute` 派生(候选) | 待定(有目标字段但映射不确定) | 1 条(`slimeman`);**有目标字段**(`attribute` / `special`),派生方式未定(§8.2 U-10) |
|
||||
| `faceIds` | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 4 条(`bearDown` / `bearLeft` / `bearRight` / `bearUp`);无字段承载多面机制(`enemy48` 变体合并入 `enemy`,D-72①)(§8.1 U-10b) |
|
||||
|
||||
### 3.2 `id` / `num` / `attribute` / `special` 全清单(81 条)
|
||||
|
||||
| num | id | name | 附加字段 | special |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 201 | greenSlime | 绿头怪 | - | special=[] |
|
||||
| 202 | redSlime | 红头怪 | value | special=[16,18] |
|
||||
| 203 | blackSlime | 青头怪 | - | special=[] |
|
||||
| 204 | slimelord | 怪王 | - | special=[1,9] |
|
||||
| 205 | bat | 小蝙蝠 | - | special=[1,27] |
|
||||
| 206 | bigBat | 大蝙蝠 | - | special=[] |
|
||||
| 207 | redBat | 红蝙蝠 | - | special=[] |
|
||||
| 208 | vampire | 冥灵魔王 | n | special=[6] |
|
||||
| 209 | skeleton | 骷髅人 | - | special=[] |
|
||||
| 210 | skeletonWarrior | 骷髅士兵 | - | special=[] |
|
||||
| 211 | skeletonCaptain | 骷髅队长 | - | special=[] |
|
||||
| 212 | ghostSoldier | 冥队长 | - | special=[8] |
|
||||
| 213 | zombie | 兽人 | - | special=[] |
|
||||
| 214 | zombieKnight | 兽人武士 | - | special=[] |
|
||||
| 215 | rock | 石头人 | - | special=[3] |
|
||||
| 216 | slimeman | 影子战士 | atkValue, defValue | special=[9] |
|
||||
| 217 | bluePriest | 初级法师 | - | special=[9] |
|
||||
| 218 | redPriest | 高级法师 | - | special=[] |
|
||||
| 219 | brownWizard | 初级巫师 | value, range | special=[15] |
|
||||
| 220 | redWizard | 高级巫师 | value, zoneSquare | special=[15] |
|
||||
| 221 | yellowGateKeeper | 初级卫兵 | - | special=[] |
|
||||
| 222 | blueGateKeeper | 中级卫兵 | - | special=[] |
|
||||
| 223 | redGateKeeper | 高级卫兵 | - | special=[] |
|
||||
| 224 | swordsman | 双手剑士 | - | special=[4] |
|
||||
| 225 | soldier | 冥战士 | - | special=[] |
|
||||
| 226 | yellowKnight | 金骑士 | - | special=[] |
|
||||
| 227 | redKnight | 红骑士 | - | special=[7] |
|
||||
| 228 | darkKnight | 黑骑士 | - | special=[] |
|
||||
| 229 | blackKing | 黑衣魔王 | notBomb | special=[] |
|
||||
| 230 | yellowKing | 黄衣魔王 | - | special=[] |
|
||||
| 231 | greenKing | 青衣武士 | - | special=[] |
|
||||
| 232 | blueKnight | 蓝骑士 | - | special=[8] |
|
||||
| 233 | goldSlime | 黄头怪 | - | special=[] |
|
||||
| 234 | poisonSkeleton | 紫骷髅 | - | special=[13] |
|
||||
| 235 | poisonBat | 紫蝙蝠 | - | special=[13] |
|
||||
| 236 | ironRock | 铁面人 | - | special=[] |
|
||||
| 237 | skeletonPriest | 骷髅法师 | value | special=[18] |
|
||||
| 238 | skeletonKing | 骷髅王 | - | special=[] |
|
||||
| 239 | skeletonPresbyter | 骷髅巫师 | - | special=[] |
|
||||
| 240 | skeletonKnight | 骷髅武士 | - | special=[] |
|
||||
| 241 | evilHero | 迷失勇者 | - | special=[] |
|
||||
| 242 | devilWarrior | 魔神武士 | - | special=[] |
|
||||
| 243 | demonPriest | 魔神法师 | - | special=[] |
|
||||
| 244 | goldHornSlime | 金角怪 | - | special=[] |
|
||||
| 245 | redKing | 红衣魔王 | - | special=[] |
|
||||
| 246 | blueKing | 白衣武士 | - | special=[16] |
|
||||
| 247 | magicMaster | 黑暗大法师 | value, add, notBomb | special=[11] |
|
||||
| 248 | silverSlime | 银头怪 | - | special=[14] |
|
||||
| 249 | blademaster | 剑圣 | - | special=[] |
|
||||
| 250 | whiteHornSlime | 尖角怪 | - | special=[] |
|
||||
| 251 | evilPrincess | 痛苦魔女 | - | special=[10] |
|
||||
| 252 | evilFairy | 黑暗仙子 | - | special=[] |
|
||||
| 253 | yellowPriest | 中级法师 | - | special=[] |
|
||||
| 254 | redSwordsman | 剑王 | - | special=[] |
|
||||
| 255 | whiteSlimeman | 水银战士 | - | special=[] |
|
||||
| 256 | poisonZombie | 绿兽人 | - | special=[12] |
|
||||
| 257 | dragon | 魔龙 | bigImage | special=[] |
|
||||
| 258 | octopus | 血影 | bigImage | special=[] |
|
||||
| 259 | fairyEnemy | 仙子 | - | special=[] |
|
||||
| 260 | princessEnemy | 假公主 | - | special=[] |
|
||||
| 261 | angel | 天使 | - | special=[] |
|
||||
| 262 | elemental | 元素生物 | - | special=[] |
|
||||
| 263 | steelGuard | 铁守卫 | value | special=[18] |
|
||||
| 264 | evilBat | 邪恶蝙蝠 | - | special=[] |
|
||||
| 265 | silverSlimelord | 银怪王 | - | special=[] |
|
||||
| 266 | goldSlimelord | 金怪王 | - | special=[] |
|
||||
| 267 | grayRock | 灰色石头人 | - | special=[] |
|
||||
| 270 | greenKnight | 强盾骑士 | - | special=[] |
|
||||
| 271 | bowman | 初级弓兵 | - | special=[] |
|
||||
| 272 | purpleBowman | 高级弓兵 | - | special=[] |
|
||||
| 275 | watcherSlime | 邪眼怪 | - | special=[] |
|
||||
| 277 | frostBat | 寒蝙蝠 | - | special=[] |
|
||||
| 278 | devilKnight | 恶灵骑士 | - | special=[1,5,7,8] |
|
||||
| 279 | grayPriest | 混沌法师 | - | special=[] |
|
||||
| 280 | greenGateKeeper | 卫兵队长 | - | special=[] |
|
||||
| 325 | keiskeiFairy | 铃兰花妖 | - | special=[] |
|
||||
| 326 | tulipFairy | 郁金香花妖 | - | special=[] |
|
||||
| 327 | bearDown | 熊出没 | faceIds, bigImage | special=[] |
|
||||
| 328 | bearLeft | 熊出没 | faceIds | special=[] |
|
||||
| 329 | bearRight | 熊出没 | faceIds | special=[] |
|
||||
| 330 | bearUp | 熊出没 | faceIds | special=[] |
|
||||
|
||||
**ENEMY-COUNT: 81**
|
||||
|
||||
## 4. 道具 items
|
||||
|
||||
数据来源:`public/project/items.js:3` 起的顶层 `var items_<hash> = { "<id>": {…} }` 对象,实测 **62** 条。目标接口 `IItemRawData`(`packages-user/data-common/src/store/types.ts:176`):`num` / `category: ItemCategory` / `name` / `text` / `hideInToolbox` / `effect: IItemEffect` / `equip: IItemEquipData`。
|
||||
|
||||
### 4.1 `cls` → `ItemCategory` 映射候选
|
||||
|
||||
目标枚举 `ItemCategory`(`packages-user/data-common/src/store/types.ts:125`):`Unknown` / `Constant`(永久道具)/ `Consumable`(一次性道具)/ `Pick`(即捡即用)/ `Equipment`(装备)。
|
||||
|
||||
| 旧 `cls` | 实测条数 | `ItemCategory`(候选) | 依据 |
|
||||
| --- | --- | --- | --- |
|
||||
| `tools` | 20 | `Consumable`(候选) | 多为可多次使用的钥匙 / 器械;`canUseItemEffect` 普遍存在 |
|
||||
| `items` | 32 | `Consumable`(候选) | 含宝石 / 血瓶 / 剑盾(带 `equip`);部分语义接近即拾即用(`yellowGem` 带 `useItemEvent`),细分**待确认**(§8) |
|
||||
| `equips` | 2 | `Equipment` | 仅 `sword0` / `shield0`(`public/project/items.js:132`),带 `equip` |
|
||||
| `constants` | 8 | `Constant` | 永久道具(`book` / `fly` / `coin` 等,`public/project/items.js:304`) |
|
||||
|
||||
说明:`cls` 为 `items` 的剑盾(`sword1..5` / `shield1..5`)也带 `equip`,其 `category` 究竟应取 `Consumable` 还是 `Equipment`**待确认**(§8)。
|
||||
|
||||
### 4.2 效果脚本与装备映射候选
|
||||
|
||||
旧字段实测频次:`cls`(62)、`name`(62)、`text`(49)、`hideInToolbox`(5)、`itemEffect`(23)、`itemEffectTip`(23)、`useItemEffect`(25)、`canUseItemEffect`(38)、`useItemEvent`(2)、`equip`(12)、`hideInReplay`(2)。
|
||||
|
||||
分类口径同 §1.2;判定基准 = `IItemRawData` / `IItemEffect` / `IItemEquipData`(`packages-user/data-common/src/store/types.ts:176` / `:138` / `:161`)。
|
||||
|
||||
| 旧字段 | 目标落点(候选) | 分类 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `name` / `text` / `hideInToolbox` | `IItemRawData.{name,text,hideInToolbox}` | 映射候选(可确定) | 直接对应 |
|
||||
| `itemEffect` | `IItemEffect.effect` 派生(候选) | 待定(有目标字段但映射不确定) | 旧为字符串 / 函数(如 `红宝石` 的 `itemEffect`);**有目标字段**(`IItemEffect`),派生方式未定(§8.2 U-12) |
|
||||
| `itemEffectTip` | `IItemEffect.effect` 派生(候选) | 待定(有目标字段但映射不确定) | 效果提示串(含 `${…}` 模板);**有目标字段**(`IItemEffect`),派生方式未定(§8.2 U-12) |
|
||||
| `useItemEffect` | `IItemEffect.useEffect?`(候选) | 待定(有目标字段但映射不确定) | 旧为字符串脚本(部分为函数体,如 `freezeBadge` 852 字符);**有目标字段**(`IItemEffect.useEffect`),映为 `useEffect(item, state)` 方法的改写方式未定(§8.2 U-12) |
|
||||
| `useItemEvent` | `IItemEffect.useEvent?`(候选) | 待定(有目标字段但映射不确定) | 旧为事件数组(`yellowGem` / `lifeWand`);新 `useEvent?: string` 承载事件 id,事件库由落点侧提供(`src/content/item.ts:7` 的 `item200` 为示例)(§8.2 U-12) |
|
||||
| `canUseItemEffect` | `IItemEffect.canUse?`(候选) | 待定(有目标字段但映射不确定) | 旧为布尔或函数串;新为 `canUse(item, state): boolean`(§8.2 U-12) |
|
||||
| `equip` | `IItemEquipData`(`packages-user/data-common/src/store/types.ts:161`) | 映射候选(可确定) | 字段级有对应目标接口;旧 `equip` = `{ type: number; animate?: string; value: Record<string, number> }` → 新 `{ slots: (number\|string)[]; animate: AnimationIds; value; percentage; loadEvent; unloadEvent }`(子字段映射见 §4.3 / §8.2 U-14) |
|
||||
| `hideInReplay` | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 2 条(`fly` / `skill1`);`IItemRawData` 无对应字段(§8.1 U-13) |
|
||||
|
||||
### 4.3 `equip` → `IItemEquipData` 映射候选
|
||||
|
||||
旧 `equip` 实测 12 条,形态为 `{ type: number; animate?: string; value: Record<string, number> }`。
|
||||
|
||||
| 旧 `equip` 字段 | 目标落点(候选) | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `type`(0 / 1) | `IItemEquipData.slots: (number\|string)[]` | 旧为单个装备孔索引(0 = 武器,1 = 盾);新为数组,是否包成 `[type]` **待确认**(§8) |
|
||||
| `animate`(如 `"sword"`) | `IItemEquipData.animate: AnimationIds` | 仅剑类含(`sword0..5`);旧动画 id 字符串 → 新 `AnimationIds` 的取值**待确认**(§8) |
|
||||
| `value`(`{ atk: 10 }` / `{ def: 10 }`) | `IItemEquipData.value: Record<SelectKey<THero, number>, number>` | 旧属性名(`atk` / `def` / `mdef`)→ 新属性键的对应**待确认**(§8) |
|
||||
| —(旧无) | `IItemEquipData.percentage` / `loadEvent` / `unloadEvent` | 旧数据无对应;`defaults/item.jsonc:1` 给出空骨架 |
|
||||
|
||||
### 4.4 `id` / `num` / `cls` 全清单(62 条)
|
||||
|
||||
| num | id | cls | 关键字段 |
|
||||
| --- | --- | --- | --- |
|
||||
| 21 | yellowKey | tools | hideInToolbox |
|
||||
| 22 | blueKey | tools | hideInToolbox |
|
||||
| 23 | redKey | tools | hideInToolbox |
|
||||
| 24 | greenKey | tools | - |
|
||||
| 25 | steelKey | tools | - |
|
||||
| 26 | bigKey | tools | itemEffect, itemEffectTip, useItemEffect, canUseItemEffect |
|
||||
| 27 | redGem | items | itemEffect, itemEffectTip, useItemEffect, canUseItemEffect |
|
||||
| 28 | blueGem | items | itemEffect, itemEffectTip, useItemEffect, canUseItemEffect |
|
||||
| 29 | greenGem | items | itemEffect, itemEffectTip, useItemEffect, canUseItemEffect |
|
||||
| 30 | yellowGem | items | itemEffect, itemEffectTip, useItemEvent, canUseItemEffect |
|
||||
| 31 | redPotion | items | itemEffect, itemEffectTip, useItemEffect, canUseItemEffect |
|
||||
| 32 | bluePotion | items | itemEffect, itemEffectTip, useItemEffect, canUseItemEffect |
|
||||
| 33 | greenPotion | items | itemEffect, itemEffectTip, useItemEffect, canUseItemEffect |
|
||||
| 34 | yellowPotion | items | itemEffect, itemEffectTip, useItemEffect, canUseItemEffect |
|
||||
| 35 | sword1 | items | equip, itemEffect, itemEffectTip |
|
||||
| 36 | shield1 | items | equip, itemEffect, itemEffectTip |
|
||||
| 37 | sword2 | items | equip, itemEffect, itemEffectTip |
|
||||
| 38 | shield2 | items | equip, itemEffect, itemEffectTip |
|
||||
| 39 | sword3 | items | equip, itemEffect, itemEffectTip |
|
||||
| 40 | shield3 | items | equip, itemEffect, itemEffectTip |
|
||||
| 41 | sword4 | items | equip, itemEffect, itemEffectTip |
|
||||
| 42 | shield4 | items | equip, itemEffect, itemEffectTip |
|
||||
| 43 | sword5 | items | equip, itemEffect, itemEffectTip |
|
||||
| 44 | shield5 | items | equip, itemEffect, itemEffectTip |
|
||||
| 45 | book | constants | hideInToolbox, useItemEffect, canUseItemEffect |
|
||||
| 46 | fly | constants | hideInReplay, hideInToolbox, useItemEffect, canUseItemEffect |
|
||||
| 47 | pickaxe | tools | useItemEffect, canUseItemEffect |
|
||||
| 48 | icePickaxe | tools | useItemEffect, canUseItemEffect |
|
||||
| 49 | bomb | tools | useItemEffect, canUseItemEffect |
|
||||
| 50 | centerFly | tools | useItemEffect, canUseItemEffect |
|
||||
| 51 | upFly | tools | useItemEffect, canUseItemEffect |
|
||||
| 52 | downFly | tools | useItemEffect, canUseItemEffect |
|
||||
| 53 | coin | constants | - |
|
||||
| 54 | freezeBadge | constants | useItemEffect, canUseItemEffect |
|
||||
| 55 | cross | constants | - |
|
||||
| 56 | superPotion | items | itemEffect, itemEffectTip, useItemEffect, canUseItemEffect |
|
||||
| 57 | earthquake | tools | useItemEffect, canUseItemEffect |
|
||||
| 58 | poisonWine | tools | useItemEffect, canUseItemEffect |
|
||||
| 59 | weakWine | tools | useItemEffect, canUseItemEffect |
|
||||
| 60 | curseWine | tools | useItemEffect, canUseItemEffect |
|
||||
| 61 | superWine | tools | useItemEffect, canUseItemEffect |
|
||||
| 62 | dagger | constants | - |
|
||||
| 63 | pack | items | itemEffect, itemEffectTip |
|
||||
| 64 | amulet | constants | - |
|
||||
| 65 | hammer | tools | - |
|
||||
| 68 | lifeWand | tools | useItemEvent, canUseItemEffect |
|
||||
| 69 | jumpShoes | tools | useItemEffect, canUseItemEffect |
|
||||
| 70 | sword0 | equips | equip, itemEffect, itemEffectTip |
|
||||
| 71 | shield0 | equips | equip, itemEffect, itemEffectTip |
|
||||
| 72 | skill1 | constants | hideInReplay, useItemEffect, canUseItemEffect |
|
||||
| 73 | wand | items | - |
|
||||
| 331 | I331 | items | canUseItemEffect |
|
||||
| 332 | I332 | items | canUseItemEffect |
|
||||
| 333 | I333 | items | canUseItemEffect |
|
||||
| 334 | I334 | items | canUseItemEffect |
|
||||
| 335 | I335 | items | canUseItemEffect |
|
||||
| 336 | I336 | items | canUseItemEffect |
|
||||
| 337 | I337 | items | canUseItemEffect |
|
||||
| 338 | I338 | items | canUseItemEffect |
|
||||
| 339 | I339 | items | canUseItemEffect |
|
||||
| 340 | I340 | items | canUseItemEffect |
|
||||
| 341 | I341 | items | canUseItemEffect |
|
||||
|
||||
**ITEM-COUNT: 62**
|
||||
|
||||
## 5. NPC
|
||||
|
||||
依 D-72①,`npcs`(14) 与 `npc48`(10) **合并**为 `npc`(不再有 48 变体)。数据来源为 §1 的图块集合(`public/project/maps.js:90` 起)。
|
||||
|
||||
> **交叉引用(D-72③,指令 1):** D-72③ 的 **`animates` 并入 `terrains`,不设独立 `animates` 素材组** 作用于**图块素材分组**层面,与本节的 NPC 分组(依 D-72① 并入 `npc`)**互不冲突、互不影响**:NPC 图块仍归 `npc` 组,`animates` 图块归 `terrains` 组。本节不涉及 `animates` 内容。
|
||||
|
||||
### 5.1 图块映射候选(合并为 `npc`)
|
||||
|
||||
| 旧 `cls` | 旧 num | 旧 id | 目标 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `npcs` | 121 | `man` | `npc` | 普通 NPC(32px) |
|
||||
| `npcs` | 122 | `trader` | `npc` | |
|
||||
| `npcs` | 123 | `thief` | `npc` | |
|
||||
| `npcs` | 124 | `fairy` | `npc` | |
|
||||
| `npcs` | 125 | `wizard` | `npc` | |
|
||||
| `npcs` | 126 | `recluse` | `npc` | |
|
||||
| `npcs` | 127 | `king` | `npc` | |
|
||||
| `npcs` | 128 | `youngMan` | `npc` | |
|
||||
| `npcs` | 129 | `sign` | `npc` | |
|
||||
| `npcs` | 130 | `expShop` | `npc` | |
|
||||
| `npcs` | 131 | `moneyShop` | `npc` | |
|
||||
| `npcs` | 132 | `princess` | `npc` | |
|
||||
| `npcs` | 137 | `greenMan` | `npc` | |
|
||||
| `npcs` | 138 | `blueTrader` | `npc` | |
|
||||
| `npc48` | 133 | `npc0` | `npc` | 高 48px;含 `faceIds`(四面) |
|
||||
| `npc48` | 134 | `npc1` | `npc` | 高 48px;含 `faceIds` |
|
||||
| `npc48` | 135 | `npc2` | `npc` | 高 48px;含 `faceIds` |
|
||||
| `npc48` | 136 | `npc3` | `npc` | 高 48px;含 `faceIds` |
|
||||
| `npc48` | 319 | `tallYellowDoor` | `npc` | 高门(`trigger: openDoor` + `doorInfo`) |
|
||||
| `npc48` | 320 | `tallBlueDoor` | `npc` | 高门 |
|
||||
| `npc48` | 321 | `tallRedDoor` | `npc` | 高门 |
|
||||
| `npc48` | 322 | `tallGreenDoor` | `npc` | 高门 |
|
||||
| `npc48` | 323 | `tallSpecialDoor` | `npc` | 高门 |
|
||||
| `npc48` | 324 | `tallSteelDoor` | `npc` | 高门 |
|
||||
|
||||
### 5.2 贴图归属候选
|
||||
|
||||
`public/project/materials/npcs.png:1`(64×448,14 NPC × 2 帧)与 `public/project/materials/npc48.png:1`(128×480,10 NPC × 2 帧)按 D-72① **合并**为一张 `npc`(多帧,2 帧),归属 §2.4 的 E 组(目标图 6 张,`npc0.png` … `npc5.png`)。**注意:** `npc48` 中的 6 个高门(319–324)虽归 `npc` 图块类,但其 48px 高度与 32px NPC 的帧尺寸不同——是否与 32px NPC 混入同一目标图,受 D-72④「不同帧数不得同图」约束需进一步确认(§8)。
|
||||
|
||||
**NPC-COUNT: 24**(= `npcs` 14 + `npc48` 10)
|
||||
|
||||
## 6. 地图 maps
|
||||
|
||||
数据来源:`public/project/floors/*.js`(`main.floors.<id> = {…}`,`public/project/floors/MT0.js:1`)。实测 **5** 个楼层文件。目标接口 `IMapRawData`(`packages-user/data-common/src/store/types.ts:260`):`floorId` / `width` / `map: Record<number, number[]>` / `layerAlias: Record<number, string>` / `events: Record<number, Record<number, Record<number, string>>>`。
|
||||
|
||||
### 6.1 楼层登记
|
||||
|
||||
| 文件 | 楼层 id | `width` × `height` | `map` 形状 | `events` 条目数 | 备注字段 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `public/project/floors/empty.js:1` | `empty` | 13 × 13 | 二维 13×13 | 0 | `bgm` |
|
||||
| `public/project/floors/MT0.js:1` | `MT0` | 13 × 13 | 二维 13×13 | 0 | — |
|
||||
| `public/project/floors/sample0.js:1` | `sample0` | 13 × 13 | 二维 13×13 | 7 | `fgmap` 13×13、`bgm` |
|
||||
| `public/project/floors/sample1.js:1` | `sample1` | 13 × 13 | 二维 13×13 | 15 | `weather` |
|
||||
| `public/project/floors/sample2.js:1` | `sample2` | 26 × 26 | 二维 26×26 | 3 | `upFloor` |
|
||||
|
||||
各文件字段集合(实测):`floorId` / `title` / `name` / `width` / `height` / `canFlyTo` / `canFlyFrom` / `canUseQuickShop` / `cannotViewMap` / `defaultGround` / `images` / `bgm` / `ratio` / `weather` / `map` / `firstArrive` / `eachArrive` / `parallelDo` / `events` / `changeFloor` / `afterBattle` / `afterGetItem` / `afterOpenDoor` / `cannotMove` / `cannotMoveIn` / `beforeBattle` / `autoEvent` / `upFloor` / `bgmap` / `fgmap` / `bg2map` / `fg2map`。
|
||||
|
||||
### 6.2 字段映射候选 → `IMapRawData`
|
||||
|
||||
分类口径同 §1.2;判定基准 = `IMapRawData`(`packages-user/data-common/src/store/types.ts:260`)。
|
||||
|
||||
| 旧字段 | 目标落点(候选) | 分类 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `floorId` | `IMapRawData.floorId` | 映射候选(可确定) | 直接对应(如 `MT0`,`public/project/floors/MT0.js:1`) |
|
||||
| `width` | `IMapRawData.width` | 映射候选(可确定) | 直接对应(13 / 26) |
|
||||
| `map`(二维数组 `[row][col]`) | `IMapRawData.map: Record<number, number[]>` | 映射候选(可确定) | 旧二维数组 → 新「层键 → 一维数组」;层键即行索引(`0`…`height-1`)为候选,见 `src/content/maps/MT0.jsonc:6`(`"0"` / `"10"` 两键) |
|
||||
| `layerAlias`(旧无) | `IMapRawData.layerAlias` | 映射候选(可确定) | 旧数据无该字段;默认空对象(`src/content/defaults/map.jsonc:1` 给出 `{}`) |
|
||||
| `events`(`"x,y"` → 事件数据) | `IMapRawData.events: Record<number, Record<number, Record<number, string>>>` | 待定(有目标字段但映射不确定) | **确有对应目标字段** `IMapRawData.events`;仅「层 → 位置索引 → 优先级 → 事件 id」三段嵌套由 `"x,y"` 换算的算法未定(§8.2 U-15) |
|
||||
| `title` / `name` | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 楼层显示名(如 `主塔 0 层` / `样板 0 层`);`IMapRawData` 无对应字段(§8.1 U-16) |
|
||||
| `height` | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | `IMapRawData` 无 `height`;由 `map` 层数隐含(§8.1 U-16) |
|
||||
| `firstArrive` / `eachArrive` / `parallelDo` | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 楼层到达 / 并行事件;无专用字段承载(§8.1 U-16) |
|
||||
| `changeFloor` | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 换层定义(含 `floorId` / `stair` / `loc` / `direction`);无专用字段(§8.1 U-16) |
|
||||
| `afterBattle` / `afterGetItem` / `afterOpenDoor` / `beforeBattle` / `cannotMove` / `cannotMoveIn` / `autoEvent` | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 各类钩子事件;无专用字段(§8.1 U-16) |
|
||||
| `bgmap` / `fgmap` / `bg2map` / `fg2map` | 图层机制(候选) | 待定(有目标字段但映射不确定) | 旧额外图层二维数组(如 `sample0` 的 `fgmap` 13×13,含 10169 等数字);**可能**落入 `IMapRawData.map` / `layerAlias`,但对应关系无法唯一确定(§8.2 U-16b) |
|
||||
| `images` / `bgm` / `weather` / `ratio` / `defaultGround` / `canFlyTo` / `canFlyFrom` / `canUseQuickShop` / `cannotViewMap` / `upFloor` | 无(目标接口无对应字段) | 只记录、不移植(目标接口无对应字段) | 渲染 / 规则属性;`IMapRawData` 无对应字段(§8.1 U-16) |
|
||||
|
||||
**MAP-COUNT: 5**
|
||||
|
||||
## 7. 贴图列表 schema 草案(texture/.list.jsonc)
|
||||
|
||||
依 `ITextureManager` 的能力(`packages-user/client-base/src/material/types.ts`)**反向设计** `src/content/texture/.list.jsonc`(落点由 `src/content/client.jsonc:9` 的 `textureListDir: texture/.list.jsonc` 指定;现状为 `{}`,`src/content/texture/.list.jsonc:1`)。**仅草案**;所有字段命名均为候选、标注「待用户报备批准」,**不落地写入任何文件**(D-73 / OI-3 / OI-5)。
|
||||
|
||||
能力依据:
|
||||
|
||||
- `addGrid(source, map, width, height)`(`:261`)—— 单帧网格贴图(先左到右、再上到下)。
|
||||
- `addRowAnimate(source, map, width, height)`(`:275`)—— 行动画贴图(每行帧数一致,逐行映射)。
|
||||
- `addAutotile(source, identifier, type)`(`:289`)—— 自动元件(`type: AutotileType`)。
|
||||
- `addTileset(source, identifier, cellWidth, cellHeight)`(`:302`)—— tileset 切片(`identifier: IIndexedIdentifier`)。
|
||||
|
||||
字段结构草案(与 §2 登记逐条一致):
|
||||
|
||||
| 条目 `type`(候选) | 承载来源(§2) | 字段(候选) | 对应方法 |
|
||||
| --- | --- | --- | --- |
|
||||
| `grid` | §2.4 A 组(`terrains` 单帧)、C 组(`items` 单帧) | `source`(PNG 路径)/ `map`(图块数字数组)/ `width` / `height`(单帧像素尺寸,候选 32) | `addGrid` |
|
||||
| `rowAnimate` | §2.4 B 组(animates 并入 terrains)、D 组(enemy)、E 组(npc) | `source` / `map` / `width` / `height`(每帧像素尺寸) | `addRowAnimate` |
|
||||
| `autotile` | §2.2(`autotiles/*.png`) | `source` / `identifier`(图块数字)/ `type`(`AutotileType`) | `addAutotile` |
|
||||
| `tileset` | §2.3(`tilesets/*.png`) | `source` / `identifier`(`{ index, alias }`)/ `cellWidth` / `cellHeight` | `addTileset` |
|
||||
|
||||
字段结构草案(示意,**非落地**):
|
||||
|
||||
```
|
||||
{
|
||||
"textures": [
|
||||
{ "type": "grid", "source": "<terrains 目标图>", "map": [ /* nums */ ], "width": 32, "height": 32 },
|
||||
{ "type": "rowAnimate", "source": "<terrains 动画目标图>", "map": [ /* nums */ ], "width": 32, "height": 32 },
|
||||
{ "type": "grid", "source": "<items 目标图>", "map": [ /* nums */ ], "width": 32, "height": 32 },
|
||||
{ "type": "rowAnimate", "source": "<enemy 目标图>", "map": [ /* nums */ ], "width": 32, "height": 32 },
|
||||
{ "type": "rowAnimate", "source": "<npc 目标图>", "map": [ /* nums */ ], "width": 32, "height": 32 },
|
||||
{ "type": "autotile", "source": "<autotile.png>", "identifier": 20, "type": 1 },
|
||||
{ "type": "tileset", "source": "<magictower.png>", "identifier": { "index": 0, "alias": "magictower" }, "cellWidth": 32, "cellHeight": 32 }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
一致性核对:materials 图 → `grid`(单帧)/ `rowAnimate`(多帧);`autotiles/*.png` → `autotile`;`tilesets/*.png` → `tileset`。与 §2.1–§2.4 的登记逐条对应。
|
||||
|
||||
### 7.1 显式 TypeScript 类型声明(候选,均「待用户报备批准」)
|
||||
|
||||
> 本节为 §7 schema 的**显式类型声明**(`interface` 与 `type` 别名形式),供后续「迁移计划」落地参考。**所有新增类型名 / 字段名均为「命名候选」,标注「待用户报备批准」,本盘点不落地写入任何文件**(D-73 / OI-2)。
|
||||
|
||||
```ts
|
||||
/** 图像源路径(候选命名,待用户报备批准) */
|
||||
type TextureListSource = string;
|
||||
|
||||
/** grid 条目,对应 `addGrid`(候选命名,待用户报备批准) */
|
||||
interface ITextureListGridEntry {
|
||||
/** 条目判别字段 */
|
||||
type: 'grid';
|
||||
/** 图像源 */
|
||||
source: TextureListSource;
|
||||
/** 贴图的图块数字映射,按先从左到右、再从上到下顺序映射(对应 `addGrid` 的 `map`) */
|
||||
map: number[];
|
||||
/** 每个贴图的像素宽度(对应 `addGrid` 的 `width`) */
|
||||
width: number;
|
||||
/** 每个贴图的像素高度(对应 `addGrid` 的 `height`) */
|
||||
height: number;
|
||||
}
|
||||
|
||||
/** rowAnimate 条目,对应 `addRowAnimate`(候选命名,待用户报备批准) */
|
||||
interface ITextureListRowAnimateEntry {
|
||||
/** 条目判别字段 */
|
||||
type: 'rowAnimate';
|
||||
/** 图像源 */
|
||||
source: TextureListSource;
|
||||
/** 贴图的图块数字映射,按从上到下顺序映射(对应 `addRowAnimate` 的 `map`) */
|
||||
map: number[];
|
||||
/** 每一帧的像素宽度(对应 `addRowAnimate` 的 `width`) */
|
||||
width: number;
|
||||
/** 每一帧 / 每一行的像素高度(对应 `addRowAnimate` 的 `height`) */
|
||||
height: number;
|
||||
}
|
||||
|
||||
/** autotile 条目,对应 `addAutotile`(候选命名,待用户报备批准) */
|
||||
interface ITextureListAutotileEntry {
|
||||
/** 条目判别字段 */
|
||||
type: 'autotile';
|
||||
/** 图像源 */
|
||||
source: TextureListSource;
|
||||
/** 自动元件的图块数字(对应 `addAutotile` 的 `identifier`) */
|
||||
identifier: number;
|
||||
/**
|
||||
* 自动元件类型,取 `AutotileType`(对应 `addAutotile` 的 `type` 参数)。
|
||||
* 为避免与判别字段 `type` 同名冲突,此参数以候选字段名 `autotileType` 承载(待用户报备批准,见 §8.3 U-19)。
|
||||
*/
|
||||
autotileType: AutotileType;
|
||||
}
|
||||
|
||||
/** tileset 条目,对应 `addTileset`(候选命名,待用户报备批准) */
|
||||
interface ITextureListTilesetEntry {
|
||||
/** 条目判别字段 */
|
||||
type: 'tileset';
|
||||
/** 图像源 */
|
||||
source: TextureListSource;
|
||||
/** tileset 标识符对象,取 `IIndexedIdentifier`(对应 `addTileset` 的 `identifier`) */
|
||||
identifier: IIndexedIdentifier;
|
||||
/** Tileset 中每个 tile 的宽度(对应 `addTileset` 的 `cellWidth`) */
|
||||
cellWidth: number;
|
||||
/** Tileset 中每个 tile 的高度(对应 `addTileset` 的 `cellHeight`) */
|
||||
cellHeight: number;
|
||||
}
|
||||
|
||||
/** 贴图列表条目联合类型:四类 entry 之一(候选命名,待用户报备批准) */
|
||||
type TextureListEntry =
|
||||
| ITextureListGridEntry
|
||||
| ITextureListRowAnimateEntry
|
||||
| ITextureListAutotileEntry
|
||||
| ITextureListTilesetEntry;
|
||||
|
||||
/** `texture/.list.jsonc` 顶层配置接口(候选命名,待用户报备批准) */
|
||||
interface ITextureListConfig {
|
||||
/** 贴图条目列表,元素为 `TextureListEntry` */
|
||||
textures: TextureListEntry[];
|
||||
}
|
||||
```
|
||||
|
||||
**类型声明与能力接口的对应:** `ITextureListGridEntry` ↔ `addGrid`(`packages-user/client-base/src/material/types.ts:261`);`ITextureListRowAnimateEntry` ↔ `addRowAnimate`(`:275`);`ITextureListAutotileEntry` ↔ `addAutotile`(`:289`,`type` 取 `AutotileType`,定义于 `:12`);`ITextureListTilesetEntry` ↔ `addTileset`(`:302`,`identifier` 取 `IIndexedIdentifier`,定义于 `:50`)。`ITextureListConfig.textures` 的元素即 `TextureListEntry`。
|
||||
|
||||
**待报备命名清单(OI-2):** 类型名 `TextureListSource` / `ITextureListGridEntry` / `ITextureListRowAnimateEntry` / `ITextureListAutotileEntry` / `ITextureListTilesetEntry` / `TextureListEntry` / `ITextureListConfig`,以及字段名 `type` / `source` / `map` / `width` / `height` / `identifier` / `autotileType` / `cellWidth` / `cellHeight` / `textures`;**均「待用户报备批准」**。
|
||||
|
||||
## 8. 未确定项 / 待确认观察
|
||||
|
||||
以下内容**无法从阅读 / 静态解析唯一确定**,或属**疑似不一致的观察**。依 prohibitions,**均不登记为缺陷**,仅作待确认观察,供用户裁定。
|
||||
|
||||
**分区依据(指令 2):** 按「新接口(`ITileRawData` / `ITilePassData` / `IEnemyRawData` / `IItemRawData` / `IMapRawData`)是否存在对应字段」二分 —— **§8.1** 为**无目标字段 → 只记录、不移植**(字段级);**§8.2** 为**有目标字段但映射不确定 → 待定**(字段级);**§8.3** 保留**非字段级**的其他待确认观察。§8.1 / §8.2 与 §1.2 / §3.1 / §4.2 / §6.2 的「分类」列**逐条一致**。(旧编号 U-1..U-18 全部保留;含跨类内容的项拆为 `U-10b` / `U-16b`。)
|
||||
|
||||
### 8.1 无目标字段 → 只记录、不移植(字段级)
|
||||
|
||||
判定基准:目标接口中**不存在**对应字段;旧字段只作盘点记录,不进入迁移。
|
||||
|
||||
| 编号 | 观察 / 未确定项 | 所查接口与缺失字段(执行日实测) |
|
||||
| --- | --- | --- |
|
||||
| U-4 | 图块 `canBreak`(4) / `script`(5) / `doorInfo`(17) / `animate`(21)(§1.2) | 查 `ITileRawData`(`packages-user/data-common/src/store/types.ts:47`)与 `ITilePassData`(`:38`):无承载「可破坏 / 内联脚本正文 / 门机制参数(`time`/`keys`/`openSound`/`closeSound`)/ 帧数」的字段 |
|
||||
| U-5 | 图块 `name`(32) / `faceIds`(4) / `autotileConnection`(2)(§1.2) | 查 `ITileRawData`(`:47`)/ `ITilePassData`(`:38`):无显示名 / 多面 / 自动元件连接字段(`autotileConnection` 对应 `IAutotileProcessor.setConnection`,非图块原始数据字段) |
|
||||
| U-10b | 怪物 `faceIds`(4)(§3.1) | 查 `IEnemyRawData`(`:319`):无多面怪物字段 |
|
||||
| U-13 | 道具 `hideInReplay`(2)(§4.2) | 查 `IItemRawData`(`:176`):无对应字段 |
|
||||
| U-16 | 地图 `title` / `name` / `height` / `firstArrive` / `eachArrive` / `parallelDo` / `changeFloor` / `afterBattle` / `afterGetItem` / `afterOpenDoor` / `beforeBattle` / `cannotMove` / `cannotMoveIn` / `autoEvent` / `images` / `bgm` / `weather` / `ratio` / `defaultGround` / `canFlyTo` / `canFlyFrom` / `canUseQuickShop` / `cannotViewMap` / `upFloor`(§6.2) | 查 `IMapRawData`(`:260`):无上述楼层属性的对应字段 |
|
||||
|
||||
### 8.2 有目标字段但映射不确定 → 待定(字段级)
|
||||
|
||||
判定基准:目标接口**确有**对应字段,但取值 / 展开 / 嵌套关系无法由静态解析唯一确定。
|
||||
|
||||
| 编号 | 观察 / 未确定项 | 已确认存在的目标字段(执行日实测) | 缺什么才能确定 |
|
||||
| --- | --- | --- | --- |
|
||||
| U-2 | 图块 `trigger`(`null` / `openDoor` / `ski` / `pushBox`)的具体对应(§1.2,共 20 条) | `ITileRawData.events`(`:53`)/ `eventPass`(`:62`) | 新引擎事件 id 命名与事件可通行性约定 |
|
||||
| U-3 | 图块 `canPass: true` → 四方向通行位(`PassBit`)的具体展开(§1.2,共 19 条) | `ITilePassData.inPass` / `outPass`(`:38`,位掩码见 `PassBit` `:27`) | 新引擎通行位的方向展开规则 |
|
||||
| U-10 | 怪物 `value` / `range` / `zoneSquare` / `add` / `n` / `bigImage` / `notBomb` / `atkValue` / `defValue` 与 `special` 数字键的绑定关系(§3.1) | `IEnemyRawData.special`(`:325`)/ `attribute`(`:323`) | 新引擎特殊属性数字字典 |
|
||||
| U-12 | 道具 `itemEffect` / `itemEffectTip` / `useItemEffect` / `useItemEvent` / `canUseItemEffect` 的目标落点(§4.2) | `IItemEffect`(`:138`,含 `useEvent` / `useEffect` / `canUse`) | 新引擎道具效果接口对上述字段的承载方式 |
|
||||
| U-14 | `equip.type`(单值)→ `IItemEquipData.slots`(数组)的包装;`animate` 字符串 → `AnimationIds`;`value` 属性名(`atk` / `def` / `mdef`)→ 新属性键(§4.3) | `IItemEquipData`(`:161`) | 新引擎装备槽索引、动画 id 与属性键的取值 |
|
||||
| U-15 | 地图 `events` 旧键 `"x,y"` → `IMapRawData.events` 三段嵌套(层 / 位置索引 / 优先级)的算法(§6.2) | `IMapRawData.events`(`:270`) | 新引擎事件位置索引与优先级约定 |
|
||||
| U-16b | 地图 `bgmap` / `fgmap` / `bg2map` / `fg2map` 是否并入地图图层(§6.2) | `IMapRawData.map`(`:266`)/ `layerAlias`(`:268`) | 额外图层是否编入 `map` / `layerAlias` 及对应关系 |
|
||||
|
||||
### 8.3 其他待确认观察(非字段级)
|
||||
|
||||
| 编号 | 观察 / 未确定项 | 缺什么才能确定 |
|
||||
| --- | --- | --- |
|
||||
| U-1 | D-72⑤ 读法:本盘点将「单帧按 4×4 / 多帧按帧数列 × 4 行」理解为「单帧目标图 = 4×4 网格(16 格);多帧目标图 = 帧数列 × 4 行(4 块)」,并据此得 SPLIT-COUNT = 42(§2.4)。 | 用户确认该读法,或给出目标图每图格数的确切约定 |
|
||||
| U-6 | `ground.png` / `airwall.png` / `keyboard.png` / `icons.png` / `icons_old.png` 是否属于 D-72 四类拆分范围及其归属(§2.1)。 | 用户确认其是否纳入 tile 素材及归入哪一类 |
|
||||
| U-7 | `autotile1.png`(384×128)的自动元件类型无法由尺寸唯一判定为 2×3 `Small2x3` 或 3×4 `Big3x4`(§2.2)。 | 该素材的原始自动元件规格 |
|
||||
| U-8 | `magictower.png`(256×1216)的 `cellWidth` / `cellHeight` 切格尺寸与 `identifier.index`(§2.3)。 | 该 tileset 的切格尺寸与索引约定 |
|
||||
| U-9 | `enemy48.png` / `npc48.png` 的每格像素与帧布局:本盘点按「2 帧列、128px 宽」推导(§2.1),但 48px 高度下的单元格尺寸未由数据唯一确定。 | 高 48px 素材的单元格尺寸与帧布局 |
|
||||
| U-11 | 道具 `category` 细分:`cls: items` 且带 `equip` 的剑盾(`sword1..5` / `shield1..5`)应取 `Consumable` 还是 `Equipment`(§4.1)。 | 用户确认其分类口径 |
|
||||
| U-17 | `npc48` 中的 6 个高门(319–324,48px 高)与 32px NPC 是否可混入同一目标图(受 D-72④「不同帧数不得同图」约束,§5.2)。 | 用户确认高门是否单独成图 |
|
||||
| U-18 | `blocksInfo` 中无 `None` / `Tileset` 类图块定义(§1.1);空图块(num 0)在 `map` 中大量出现但不在 `blocksInfo`。 | 新引擎对空图块 / tileset 图块的定义方式 |
|
||||
| U-19 | §7.1 中 `autotile` 条目的 `AutotileType` 参数与条目判别字段 `type` **同名**,无法同时以 `type` 承载二者(§7.1)。 | 用户确认该参数字段的最终命名(候选名 `autotileType`,待用户报备批准)(OI-2 的一部分) |
|
||||
|
||||
> **U-19 说明:** 此为**命名层面的观察**(不登记为缺陷)—— 判别字段 `type`(取 `'grid'` / `'rowAnimate'` / `'autotile'` / `'tileset'`)与 `addAutotile` 的 `type: AutotileType` 参数冲突;§7.1 暂以候选字段名 `autotileType` 消歧,最终命名待用户裁定。
|
||||
|
||||
## 9. 汇总
|
||||
|
||||
| 维度 | 计数 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 图块 tile | 235 | `public/project/maps.js` 的 `blocksInfo`(8 个 `cls`) |
|
||||
| 贴图素材 textures | 17 | materials 12 + autotiles 4 + tilesets 1 |
|
||||
| 素材拆分目标图 split | 42 | D-72 四类推导(terrains/items/enemy/npc);**`animates` 并入 `terrains`,不设独立 `animates` 素材组**(D-72③) |
|
||||
| 怪物 enemy | 81 | `public/project/enemys.js`(与 `enemys` 73 + `enemy48` 8 图块一一对应) |
|
||||
| 道具 items | 62 | `public/project/items.js`(`tools` 20 / `items` 32 / `equips` 2 / `constants` 8) |
|
||||
| NPC | 24 | `npcs` 14 + `npc48` 10(合并为 `npc`) |
|
||||
| 地图 maps | 5 | `public/project/floors/*.js` |
|
||||
|
||||
机器可读计数行:
|
||||
|
||||
```
|
||||
TILE-COUNT: 235
|
||||
MATERIAL-COUNT: 17
|
||||
SPLIT-COUNT: 42
|
||||
ENEMY-COUNT: 81
|
||||
ITEM-COUNT: 62
|
||||
NPC-COUNT: 24
|
||||
MAP-COUNT: 5
|
||||
```
|
||||
|
||||
> **命名说明:** 本盘点中提出的所有候选命名 —— 拆分后贴图文件名 `terrains*/items*/enemy*/npc*`、`addTileset` / `addAutotile` 的 `identifier` 与参数名、`texture/.list.jsonc` 字段名 `grid` / `rowAnimate` / `autotile` / `tileset`、**§1.5 的新 `num` 分配策略候选(策略 A / B / C / D)**、**§7.1 的显式 TypeScript 类型名(`TextureListSource` / `ITextureListGridEntry` / `ITextureListRowAnimateEntry` / `ITextureListAutotileEntry` / `ITextureListTilesetEntry` / `TextureListEntry` / `ITextureListConfig` 及其字段)** —— **均为「命名候选」,标注「待用户报备批准」,本计划不落地使用**(D-73 / OI-1 / OI-2)。**`animates` 并入 `terrains`,不设独立 `animates` 素材组**(D-72③)。§8 的未确定项均**未登记为缺陷**,仅作待确认观察,待用户裁定后方可另立计划。
|
||||
Loading…
Reference in New Issue
Block a user