mirror of
https://github.com/motajs/template.git
synced 2026-10-21 23:00:29 +08:00
docs(10): create phase plan (intermediate tutorial 24 docs + site registration)
This commit is contained in:
parent
7af881d655
commit
6a42bf42d4
@ -547,14 +547,21 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 →
|
||||
| 7. 数据端缺陷修复 | 15/16 | Complete(07-16 superseded) | - |
|
||||
| 8. 测试重构与接口对齐 | 11/11 | Complete | 2026-10-08 |
|
||||
| 9. 最小浏览器可运行版本 | 15/16 | In Progress| |
|
||||
| 10. 文档重构 | 0/0 | Not Planned | - |
|
||||
| 10. 文档重构 | 0/6 | Planned | - |
|
||||
|
||||
### Phase 10: 文档重构
|
||||
|
||||
**Goal:** [To be planned]
|
||||
**Requirements**: TBD
|
||||
**Goal:** 重构过老、结构不佳、新人难懂的项目文档,面向多背景读者(完全新手 / 不懂代码的作者 / 有基础的作者 / AI Agent)提供分层指南。本阶段采用「伞阶段 + 增量派发」:每次只规划执行一个已派发的具体小任务。**第一批已派发 = 中级教程(`docs/intermediate/`,24 篇中文 markdown)+ 在 VitePress 站点注册它们**(D-01..D-44)。
|
||||
**Requirements**: (无专属需求 ID;以 `10-CONTEXT.md` 的 D-01..D-44 为需求基线,验收锚在 D-09:用户人工审阅 + 链接全部有效 + 构建通过)
|
||||
**Depends on:** Phase 9
|
||||
**Plans:** 0 plans
|
||||
**Plans:** 6 plans(第一批:中级教程 24 篇 + 站点注册)
|
||||
|
||||
Plans:
|
||||
- [ ] TBD (run /gsd-plan-phase 10 to break down)
|
||||
- [ ] 10-01-PLAN.md — Wave 0:站点前置与注册(`tsx docs/.vitepress/init.ts` 生成 `apiSidebar.ts`、建 `docs/intermediate/`、`config.ts` 新增 nav 入口 + `sidebar['/intermediate/']` 4 组/24 条;D-13 命名 checkpoint)
|
||||
- [ ] 10-02-PLAN.md — 概念与导航 4 篇(`data-vs-render` / `src-tour` / `code-basics` / `hooks`)
|
||||
- [ ] 10-03-PLAN.md — 基础接口 8 篇(`data-state-overview` … `flags`)
|
||||
- [ ] 10-04-PLAN.md — 战斗 9 篇(`combat-overview` + 8 篇子系统;N-1/N-2/N-3/N-7 留余地)
|
||||
- [ ] 10-05-PLAN.md — 其他 3 篇(`events` / `replay-commands` / `data-plugins`)
|
||||
- [ ] 10-06-PLAN.md — 全批验收(构建通过 + 链接有效 + 交付 D-09 人工审阅)
|
||||
|
||||
**说明:** 每篇中级教程遵循 `10-CONTEXT.md` D-21..D-44 的逐篇要点与阅读顺序(4/8/9/3)。文档仅新增 `docs/intermediate/*.md` 与修改 `docs/.vitepress/config.ts`;**不**触碰 `docs/guide/*`、`docs/dev/*`、`docs/logger/*`(旧内容删除为 D-04 的后续派发)。构建命令须先跑 `tsx docs/.vitepress/init.ts`(`config.ts:3` 静态 import `./apiSidebar`,该文件 gitignored 且当前缺失)。本机 PowerShell 禁止 `pnpm.ps1`,命令经 `cmd /c "..."` / `pnpm.cmd` 执行。
|
||||
|
||||
129
.planning/phases/10-docs-restructure/10-01-PLAN.md
Normal file
129
.planning/phases/10-docs-restructure/10-01-PLAN.md
Normal file
@ -0,0 +1,129 @@
|
||||
---
|
||||
phase: 10-docs-restructure
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- docs/.vitepress/config.ts
|
||||
autonomous: false
|
||||
requirements: []
|
||||
user_setup: []
|
||||
estimate:
|
||||
tokens: 22000
|
||||
raw_tokens: 15000
|
||||
tasks: 2
|
||||
confidence: low
|
||||
must_haves:
|
||||
truths:
|
||||
- "顶栏 `nav` 出现「中级教程」入口,指向 `/intermediate/data-vs-render`,且既有 `主页/指南/API/错误代码` 四条逐字不变"
|
||||
- "侧边栏新增 `'/intermediate/'` 键,含 4 个分组(概念与导航 / 基础接口 / 战斗 / 其他)、共 24 条链接,顺序为 D-20 的 4/8/9/3"
|
||||
- "既有 `'/guide/'`、`'/logger/'`、`'/api/'` 三个 sidebar 键与既有 nav 条目零改动"
|
||||
- "`docs:build` 在生成 `apiSidebar.ts` 后成功通过"
|
||||
artifacts:
|
||||
- "docs/.vitepress/config.ts(仅新增 nav 一条 + sidebar['/intermediate/'] 键)"
|
||||
key_links:
|
||||
- "config.ts:3 静态 import './apiSidebar' ← 依赖 docs/.vitepress/init.ts 生成(否则构建起步即失败)"
|
||||
- "config.ts:59-156 既有 guide/logger/api sidebar 键必须逐字保留"
|
||||
---
|
||||
|
||||
<objective>
|
||||
在中级教程正文成批编写之前,先把 24 篇的**站点注册**落地:生成构建前置文件 `docs/.vitepress/apiSidebar.ts`、创建 `docs/intermediate/` 目录、在 `docs/.vitepress/config.ts` 新增顶栏入口与 `'/intermediate/'` 侧边栏分组。
|
||||
|
||||
Purpose: 没有侧边栏注册,24 篇会「写了但看不见」,D-09 的人工审阅将直接不通过(RESEARCH Pitfall 1);没有 `apiSidebar.ts`,`docs:build` 会因 `config.ts:3` 的静态 import 失败(RESEARCH Pitfall 2)。本计划是后续全部写作计划的硬前置(Wave 0)。
|
||||
Output: 已注册的 `docs/.vitepress/config.ts` + 已生成的 `docs/.vitepress/apiSidebar.ts`(gitignored,不提交)+ 空目录 `docs/intermediate/`。
|
||||
</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/10-docs-restructure/10-CONTEXT.md
|
||||
@.planning/phases/10-docs-restructure/10-RESEARCH.md
|
||||
@.planning/phases/10-docs-restructure/10-PATTERNS.md
|
||||
@.planning/phases/10-docs-restructure/10-VALIDATION.md
|
||||
@docs/.vitepress/config.ts
|
||||
@docs/.vitepress/init.ts
|
||||
|
||||
**约定(dev.md / AGENTS.md):**
|
||||
- 本批只改 `docs/intermediate/*`(新增)与 `docs/.vitepress/config.ts`(注册);**禁止**删除或修改 `docs/guide/*`、`docs/dev/*`、`docs/logger/*`,**禁止**改动既有 `nav`/`sidebar` 的 guide/logger/api 键(D-14)。
|
||||
- 本机 PowerShell 禁止运行 `pnpm.ps1`/`npx.ps1`,命令一律经 `cmd /c "..."` 或 `pnpm.cmd` 执行(RESEARCH Environment Availability)。
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking-human">
|
||||
<name>Task 0: 向用户汇报本计划并申请 D-13 命名批准</name>
|
||||
<action>在写入任何文件之前,向用户汇报本计划内容并停下等待。汇报须包含:**要做什么**(在 VitePress 站点注册中级教程的顶栏入口与侧边栏分组,并生成本地构建前置文件)、**为什么**(24 篇正文没有侧边栏注册会「写了但看不见」,且缺 `apiSidebar.ts` 会导致构建失败)、**大致怎么做**(先 `tsx docs/.vitepress/init.ts` 生成 `apiSidebar.ts`、创建 `docs/intermediate/` 目录,再在 `config.ts` 的 `nav` 新增一条、`sidebar` 新增 `'/intermediate/'` 键)、**影响范围**(仅 `docs/.vitepress/config.ts` 一个受跟踪文件被修改,外加一个 gitignored 生成文件)。同时按 D-13 **申请新增命名的批准**,逐条列出:(a) `nav` 新条目显示名 `中级教程`(`link: '/intermediate/data-vs-render'`);(b) 四个分组标题 `概念与导航` / `基础接口` / `战斗` / `其他`;(c) 24 条侧边栏显示名——`数据端与渲染端` / `src 导览` / `代码基础` / `钩子` / `数据端总览` / `勇士属性` / `勇士道具` / `勇士装备` / `勇士位置` / `地图结构` / `地图图块` / `Flag 变量` / `战斗总览` / `怪物特殊属性` / `光环` / `查询效果` / `最终属性` / `伤害计算` / `地图伤害` / `战斗脚本` / `状态钩子` / `自定义事件` / `录像指令` / `数据插件`(分别对应 D-20 文件名 `data-vs-render` / `src-tour` / `code-basics` / `hooks` / `data-state-overview` / `hero-attribute` / `hero-items` / `hero-equipment` / `hero-location` / `map-structure` / `map-tiles` / `flags` / `combat-overview` / `enemy-specials` / `enemy-aura` / `enemy-query` / `enemy-final` / `enemy-calculator` / `enemy-map-damage` / `enemy-combat-script` / `enemy-status-hooks` / `events` / `replay-commands` / `data-plugins`)。在收到用户明确回复「可以执行」四个字、且对上述命名给出(可含微调的)确认之前,不得开始 Task 1 的任何一步,也不得派发执行子代理。 </action>
|
||||
<what-built>本计划内容:在 VitePress 站点注册中级教程的顶栏入口与 `'/intermediate/'` 侧边栏分组(4 组 / 24 条),并生成本地构建前置文件 `apiSidebar.ts`;申请 D-13 命名的批准。</what-built>
|
||||
<how-to-verify>阅读上面的「要做什么 / 为什么 / 大致怎么做 / 影响范围」四段;逐条审阅 nav 显示名 `中级教程`、四个分组标题、24 条显示名,确认或提出修改。</how-to-verify>
|
||||
<resume-signal>回复「可以执行」以继续;如对命名有修改,请一并给出,待修正后再回复「可以执行」。其它回复视为未批准,本计划停在此处。</resume-signal>
|
||||
<verify>
|
||||
<human-check>用户已回复「可以执行」,并对 nav 显示名、四个分组标题、24 条显示名给出确认或修改意见。</human-check>
|
||||
</verify>
|
||||
<done>用户回复「可以执行」且命名经批准(含修改);未获批准前本计划不得继续。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: 生成 apiSidebar.ts 并创建 docs/intermediate/ 目录</name>
|
||||
<files>docs/.vitepress/apiSidebar.ts, docs/intermediate/</files>
|
||||
<action>先生成构建前置文件,再准备正文目录。执行 `cmd /c "pnpm exec tsx docs/.vitepress/init.ts"`,它会运行 `docs/.vitepress/api.ts` 的 `generateSidebar()` 并写出 `docs/.vitepress/apiSidebar.ts`(该文件被 `.gitignore:54` 忽略,属本地生成物,不提交)。随后创建目录 `docs/intermediate/`(`New-Item -ItemType Directory -Force -Path docs/intermediate`)——它在第一次写入正文前是空的,git 不跟踪空目录,本步仅为让后续写作计划与本地预览有落点。不要触碰 `docs/.vitepress/api.ts`、`init.ts` 或既有 `apiSidebar.ts` 的生成逻辑(D-14 越界红线;RESEARCH Anti-Patterns)。</action>
|
||||
<verify>
|
||||
<automated>cmd /c "pnpm exec tsx docs/.vitepress/init.ts"; if ($?) { if (-not (Test-Path docs/.vitepress/apiSidebar.ts)) { exit 1 }; if (-not (Test-Path docs/intermediate)) { exit 1 }; echo "W0-PREP-OK" } else { exit 1 }</automated>
|
||||
<fails_when>non-zero exit, or output lacks "W0-PREP-OK", or docs/.vitepress/apiSidebar.ts / docs/intermediate/ 不存在</fails_when>
|
||||
</verify>
|
||||
<done>`docs/.vitepress/apiSidebar.ts` 已生成且非空,`docs/intermediate/` 目录已存在;两文件之外的仓库内容零改动。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: 在 config.ts 注册 nav 入口与 '/intermediate/' 侧边栏分组</name>
|
||||
<files>docs/.vitepress/config.ts</files>
|
||||
<action>用**就地编辑(Edit,最小作用域)**修改 `docs/.vitepress/config.ts`,只做两处新增、不动任何既有键。(1) 在 `nav` 数组(现为 `config.ts:53-58`)末尾追加一条 `{ text: '中级教程', link: '/intermediate/data-vs-render' }`,保留既有 `主页`/`指南`/`API`/`错误代码` 四条逐字不变。(2) 在 `sidebar` 对象(现为 `config.ts:59-156`)中新增 `'/intermediate/'` 键,其值为一个 `{ text: '中级教程', collapsed: false, items: [...] }`,`items` 内按 D-20 顺序嵌套四个分组:`概念与导航`(`data-vs-render` / `src-tour` / `code-basics` / `hooks`)、`基础接口`(`data-state-overview` / `hero-attribute` / `hero-items` / `hero-equipment` / `hero-location` / `map-structure` / `map-tiles` / `flags`)、`战斗`(`combat-overview` / `enemy-specials` / `enemy-aura` / `enemy-query` / `enemy-final` / `enemy-calculator` / `enemy-map-damage` / `enemy-combat-script` / `enemy-status-hooks`)、`其他`(`events` / `replay-commands` / `data-plugins`)。每条写为 `{ text: '<Task 0 已批准的显示名>', link: '/intermediate/<文件名>' }`(绝对路径、不带 `.md`,写法和 `config.ts:64-124` 既有条目一致;分组嵌套写法参照 `config.ts:70-86`)。`'/guide/'`、`'/logger/'`、`'/api/'` 三个键与其中全部内容**逐字保留**。新增后运行构建命令确认站点可通过(命令本身先跑 init.ts,避免 `config.ts:3` 的 import 失败)。</action>
|
||||
<verify>
|
||||
<automated>cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"</automated>
|
||||
<fails_when>non-zero exit, or output contains "dead link(s) found.", or "Failed to resolve import", or the build does not print "build complete"</fails_when>
|
||||
</verify>
|
||||
<done>config.ts 仅新增 nav 一条与 `'/intermediate/'` sidebar 键(24 条 link、4 个分组,顺序 4/8/9/3);既有 guide/logger/api 键与 nav 条目零 diff;`docs:build` 通过并打印 build complete。</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| 构建期 markdown/config → 静态站点 | 配置与文档内容由构建期静态处理,无运行时用户输入 |
|
||||
| 站点 → 浏览器读者 | 外链是唯一的对外指向面 |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|----------|-------------|-----------------|
|
||||
| T-10-01 | Tampering | `docs/.vitepress/config.ts` 新增内容 | low | mitigate | 只新增 `nav`/`sidebar` 静态文本条目,不写原始 HTML/`<script>`;不改动构建插件与 api 生成逻辑 |
|
||||
| T-10-02 | Spoofing | 本计划不引入任何外链 | low | accept | 唯一获批外链(D-23 的 `h5mota.com` 论坛)在后续正文计划引入;本计划无外链面 |
|
||||
| T-10-03 | Information Disclosure | 配置示例 | low | mitigate | 不写入任何密钥/内部账号;只引用仓库已公开的路径与接口名 |
|
||||
| T-10-SC | Tampering | npm/pip/cargo installs | low | accept | 本阶段**不安装任何包**(纯文档 + 站点配置),无供应链安装面 |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- 构建门禁:`cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"` 通过(打印 build complete,无 dead link / import 错误)。
|
||||
- 结构门禁(静态):`docs/.vitepress/config.ts` 的 `'/intermediate/'` 键恰含 4 个分组、24 条 `link`,与 D-20 顺序一一对应。
|
||||
- 越界门禁:`git diff --name-only` 中仅出现 `docs/.vitepress/config.ts`(外加 gitignored、未跟踪的 `apiSidebar.ts` 与本地空目录)。
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- `docs/.vitepress/config.ts` 已注册 `nav` 入口与 `'/intermediate/'` 侧边栏(4 组 / 24 条,顺序 4/8/9/3),既有键零改动。
|
||||
- `docs/.vitepress/apiSidebar.ts` 已生成,`docs/intermediate/` 目录已存在。
|
||||
- `docs:build` 通过。
|
||||
- 显示名经用户 D-13 批准。
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/10-docs-restructure/10-01-SUMMARY.md` when done
|
||||
</output>
|
||||
141
.planning/phases/10-docs-restructure/10-02-PLAN.md
Normal file
141
.planning/phases/10-docs-restructure/10-02-PLAN.md
Normal file
@ -0,0 +1,141 @@
|
||||
---
|
||||
phase: 10-docs-restructure
|
||||
plan: 02
|
||||
type: execute
|
||||
wave: 2
|
||||
depends_on: [10-01]
|
||||
files_modified:
|
||||
- docs/intermediate/data-vs-render.md
|
||||
- docs/intermediate/src-tour.md
|
||||
- docs/intermediate/code-basics.md
|
||||
- docs/intermediate/hooks.md
|
||||
autonomous: false
|
||||
requirements: []
|
||||
user_setup: []
|
||||
estimate:
|
||||
tokens: 26000
|
||||
raw_tokens: 17000
|
||||
tasks: 2
|
||||
confidence: low
|
||||
must_haves:
|
||||
truths:
|
||||
- "四篇概念文档存在且为 kebab-case 文件名、CRLF 行尾、单 H1"
|
||||
- "`data-vs-render` 讲数据端/渲染端分工与录像验证,含 mermaid 图,不提『渲染端不能反向推送』"
|
||||
- "`src-tour` 详讲 src/data、src/client、src/content、src/constant.ts,含『该不该改』表,不讲已弃用的 main.ts/App.vue/types/"
|
||||
- "`code-basics` 按 ①语法 ②模块 ③类型 三段,泛型比作『类型的函数』,结尾给出 D-23 指定外链"
|
||||
- "`hooks` 含『需求→钩子对照表』,讲 addHook/removeHook;四篇均无元叙述(D-16)"
|
||||
artifacts:
|
||||
- "docs/intermediate/data-vs-render.md"
|
||||
- "docs/intermediate/src-tour.md"
|
||||
- "docs/intermediate/code-basics.md"
|
||||
- "docs/intermediate/hooks.md"
|
||||
key_links:
|
||||
- "四篇为后续所有分组的前置阅读;本组不向前引用尚未写就的页面"
|
||||
- "`code-basics` 结尾外链 = https://h5mota.com/bbs/thread/?tid=1018&p=3#p41(D-23,本阶段唯一获批外链)"
|
||||
---
|
||||
|
||||
<objective>
|
||||
编写「概念与导航」组 4 篇中级教程:`data-vs-render`、`src-tour`、`code-basics`、`hooks`。本组是读者的入口,负责建立「数据端算 / 渲染端画」「src 里该改哪」「代码与类型基础」「钩子机制」四个共同前提。
|
||||
|
||||
Purpose: 读完后读者具备阅读后续「基础接口」「战斗」各组的最小语言与心智模型(D-15:只讲顶层常用内容)。
|
||||
Output: 4 个新 markdown 文件(中文正文,英文标识符)。
|
||||
</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/phases/10-docs-restructure/10-CONTEXT.md
|
||||
@.planning/phases/10-docs-restructure/10-RESEARCH.md
|
||||
@.planning/phases/10-docs-restructure/10-PATTERNS.md
|
||||
@dev.md
|
||||
@docs/guide/quick-start.md
|
||||
@docs/guide/system.md
|
||||
|
||||
**写作约定:**
|
||||
- 文件命名 kebab-case(dev.md:68)、内容 CRLF(dev.md:116);页面骨架为单 `#` 主标题 + `##` 小节(PATTERNS「单 H1」)。
|
||||
- 每篇 2–5 处跳转链接即可(D-17);**禁止**任何「后续再讲/留到高级教程/届时」式元叙述(D-16);指向渲染端内容时当作指向一个**已存在的平行部分**。
|
||||
- 本组为阅读顺序最前,**不得**在正文中以 markdown 链接指向尚未写就的 `docs/intermediate/` 其它页面(否则构建报 dead link);确需提及时以代码span形式书写页面名,不加链接。
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking-human">
|
||||
<name>Task 0: 向用户汇报本组计划并等待「可以执行」</name>
|
||||
<action>向用户汇报:**要做什么**(编写 4 篇概念与导航文档 `data-vs-render` / `src-tour` / `code-basics` / `hooks`)、**为什么**(为读者建立数据端/渲染端分工、src 目录导航、代码与类型基础、钩子机制四项共同前提)、**大致怎么做**(逐篇按 D-21..D-24 的要点与 10-RESEARCH「24 篇文档的源码入口·概念与导航」的 `file:line` 核对后落笔;页面骨架照 `docs/guide/quick-start.md`)、**影响范围**(仅新增 4 个 `docs/intermediate/*.md`,不改任何生产代码与既有文档)。停下等待用户明确回复「可以执行」四个字;未收到前不得写任何文件,也不得派发执行子代理。 </action>
|
||||
<what-built>本计划内容:编写「概念与导航」组 4 篇中级教程 `data-vs-render` / `src-tour` / `code-basics` / `hooks`(仅新增 `docs/intermediate/*.md`)。</what-built>
|
||||
<how-to-verify>阅读上面的「要做什么 / 为什么 / 大致怎么做 / 影响范围」四段,确认范围与做法无异议。</how-to-verify>
|
||||
<resume-signal>回复「可以执行」以继续;其它回复视为未批准,本计划停在此处。</resume-signal>
|
||||
<verify>
|
||||
<human-check>用户已回复「可以执行」。</human-check>
|
||||
</verify>
|
||||
<done>用户回复「可以执行」。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: 编写 data-vs-render 与 src-tour</name>
|
||||
<files>docs/intermediate/data-vs-render.md, docs/intermediate/src-tour.md</files>
|
||||
<behavior>
|
||||
- `data-vs-render.md`:一级标题「数据端与渲染端」;正文讲「数据端负责算、渲染端负责画」,比喻「棋局/账本」对「棋盘/摄像机」;指明两者分别在 `src/data`、`src/client`;重点讲**录像验证**(只跑数据端);含一张 mermaid 图;**不**出现「渲染端不能反向推送」的表述(留高级)。
|
||||
- `src-tour.md`:一级标题「src 导览」;详讲 `src/data`、`src/client`、`src/content`、`src/constant.ts`;**一句带过** `src/bootstrap.ts`、`src/data.ts`、`src/package.json`、`src/styles.less`;**不讲** `src/main.ts`、`src/App.vue`、`src/types/`;含一张「该不该改」表。
|
||||
</behavior>
|
||||
<action>按 D-21 写 `data-vs-render.md`:先给结论(数据端「算」、渲染端「画」),用「棋局/账本」对「棋盘/摄像机」的比喻点明职责边界,说明二者分别在 `src/data` 与 `src/client`,然后重点展开**录像验证只跑数据端**这一好处并给出 mermaid 图(图用 ` ```mermaid ` 代码块,语法照 `docs/guide/quick-start.md:27-31`)。素材:`dev.md:125-158`(双端分离)、`src/data.ts:1-5`、`dev.md:132`(`Mota.r()` 门控)。不要写渲染端反向推送相关结论(D-21)。\n\n按 D-22 写 `src-tour.md`:以目录导览方式详讲 `src/data`(数据端)、`src/client`(渲染端)、`src/content`(内容层)、`src/constant.ts`(常量),素材 `file:line` 见 10-RESEARCH「概念与导航 · src-tour」(如 `src/data/entry.ts:1-32`、`src/data/initialize.ts:1-85`、`src/content/item.ts:1-24`、`src/constant.ts:1-51`);`src/bootstrap.ts`、`src/data.ts`、`src/package.json`、`src/styles.less` 各用一句话带过(一般不需改动);不含 `src/main.ts`、`src/App.vue`、`src/types/`;末尾用一张 markdown 表格回答「该不该改」(列出目录/文件 → 是否通常需要改动)。两篇均遵守写作约定(kebab-case 文件名、CRLF、单 H1、无元叙述、跳转链接适量;本组不链接尚未写就的页面)。接口名/路径须逐字核对源码(RESEARCH Pitfall 5)。</action>
|
||||
<verify>
|
||||
<automated>$ErrorActionPreference='Stop'; $files=@('docs/intermediate/data-vs-render.md','docs/intermediate/src-tour.md'); foreach($p in $files){ if(-not(Test-Path $p)){ Write-Error "MISSING $p" }; $raw=[IO.File]::ReadAllText((Resolve-Path $p)); if($raw -match "(?<!`r)`n"){ Write-Error "LF-ONLY $p" }; if(([regex]::Matches($raw,'(?m)^# ')).Count -ne 1){ Write-Error "H1-COUNT $p" } }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/data-vs-render.md')) -notmatch 'mermaid')){ Write-Error "NO-MERMAID data-vs-render" }; Write-Output 'STATIC-OK'</automated>
|
||||
<fails_when>non-zero exit, or output contains "MISSING", "LF-ONLY", "H1-COUNT", or "NO-MERMAID"</fails_when>
|
||||
</verify>
|
||||
<done>两文件存在、CRLF、单 H1;`data-vs-render` 含 mermaid 且含录像验证要点、无「反向推送」表述;`src-tour` 含「该不该改」表且不含已弃用项。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 2: 编写 code-basics 与 hooks</name>
|
||||
<files>docs/intermediate/code-basics.md, docs/intermediate/hooks.md</files>
|
||||
<behavior>
|
||||
- `code-basics.md`:一级标题;按 ①简明语法 ②模块与引入 ③类型入门 顺序;类型部分把**泛型比喻成「类型的函数」**;讲 `interface` → `implements` 约定(**建议但非强制**);结尾给出外链 `https://h5mota.com/bbs/thread/?tid=1018&p=3#p41`。
|
||||
- `hooks.md`:一级标题;讲钩子是什么;列常用钩子族一览;含**「需求 → 钩子」对照表**(核心);讲 `addHook` / `removeHook`;`hook/initialize.ts` 一笔带过;标明哪些是 async 钩子;用一句话说明「钩子可能被非本对象触发」。
|
||||
</behavior>
|
||||
<action>按 D-23 写 `code-basics.md`:三段式——①简明语法(变量、函数、分支等基础,可参照 `docs/guide/system.md:160-191` 的模块化示例风格);②模块与引入(`import`/`export`,用 ` ```ts ` 代码块);③类型入门(基础类型 → 接口 → 泛型;把**泛型比作「类型的函数」**,讲 `interface` → `implements` 是**建议但非强制**的约定)。结尾以一句自然引导给出**唯一获批外链** `https://h5mota.com/bbs/thread/?tid=1018&p=3#p41`(D-23;不得新增其它外链)。本页无源码依赖。\n\n按 D-24 写 `hooks.md`:先从概念讲「钩子是什么」,再列**常用钩子族一览**(族名清单的 `file:line` 见 10-RESEARCH「概念与导航 · hooks」,如 `IHeroAttributeHooks`、`IHeroLocationHooks`、`IObjectMoverHooks`、`ICombatFlowHooks`、`IMapLayerHooks` 等),核心是**「需求 → 钩子」对照表**(markdown 表格,左列需求、右列对应钩子/族);然后讲 `addHook` / `removeHook` 的用法(顶层接口名,D-15;机制接口在 `packages/common/src/hook.ts:23-52`);`hook/initialize.ts` 一句带过(注册点,`src/data/hook/initialize.ts:17-26`);标注哪些钩子族是 async;末尾一句说明「钩子可能被非本对象触发」(多主对象时才需判断)。两篇遵守写作约定;`hooks` 的对照表若需引用后续页面,用代码span写页面名而不加链接。</action>
|
||||
<verify>
|
||||
<automated>$ErrorActionPreference='Stop'; $files=@('docs/intermediate/code-basics.md','docs/intermediate/hooks.md'); foreach($p in $files){ if(-not(Test-Path $p)){ Write-Error "MISSING $p" }; $raw=[IO.File]::ReadAllText((Resolve-Path $p)); if($raw -match "(?<!`r)`n"){ Write-Error "LF-ONLY $p" }; if(([regex]::Matches($raw,'(?m)^# ')).Count -ne 1){ Write-Error "H1-COUNT $p" } }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/code-basics.md')) -notmatch 'https://h5mota\.com/bbs/thread/\?tid=1018')){ Write-Error "NO-APPROVED-LINK code-basics" }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/hooks.md')) -notmatch 'addHook')){ Write-Error "NO-ADDHOOK hooks" }; Write-Output 'STATIC-OK'</automated>
|
||||
<fails_when>non-zero exit, or output contains "MISSING", "LF-ONLY", "H1-COUNT", "NO-APPROVED-LINK", or "NO-ADDHOOK"</fails_when>
|
||||
</verify>
|
||||
<done>两文件存在、CRLF、单 H1;`code-basics` 含 D-23 指定外链且仅此一处外链;`hooks` 含 addHook 与「需求→钩子」对照表。</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| 构建期 markdown → 静态站点 | 正文由构建期静态渲染,无运行时输入 |
|
||||
| 站点 → 浏览器读者 | 外链是唯一对外指向面 |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|----------|-------------|-----------------|
|
||||
| T-10-04 | Tampering / XSS | 4 篇 markdown 正文 | low | mitigate | 只写文本、代码块、mermaid;不引入原始 `<script>`/内联 HTML(mermaid 由已启用插件渲染) |
|
||||
| T-10-05 | Spoofing | `code-basics` 外链 | low | mitigate | 仅使用 D-23 唯一获批外链 `h5mota.com`;不新增未经验证的外链(verify 已断言该链接存在) |
|
||||
| T-10-06 | Information Disclosure | 正文示例 | low | mitigate | 示例只用源码已公开的接口/路径;不写真实密钥、账号、内部地址 |
|
||||
| T-10-SC | Tampering | npm/pip/cargo installs | low | accept | 本阶段不安装任何包,无供应链安装面 |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- 计划级构建门禁:`cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"` 通过(打印 build complete,无 dead link / import 错误)。本组不向前链接未写就页面,故本计划构建可独立通过。
|
||||
- 结构门禁:4 个文件均为 kebab-case、CRLF、单 H1。
|
||||
- 内容门禁(人工,随 D-09):无元叙述(D-16);接口名与源码一致(RESEARCH Pitfall 5)。
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- 4 篇概念文档落位且构建通过。
|
||||
- 每篇覆盖 D-21..D-24 的全部要点,未越界讲底层/渲染端结构性内容。
|
||||
- 无元叙述;唯一外链为 D-23 指定链接。
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/10-docs-restructure/10-02-SUMMARY.md` when done
|
||||
</output>
|
||||
166
.planning/phases/10-docs-restructure/10-03-PLAN.md
Normal file
166
.planning/phases/10-docs-restructure/10-03-PLAN.md
Normal file
@ -0,0 +1,166 @@
|
||||
---
|
||||
phase: 10-docs-restructure
|
||||
plan: 03
|
||||
type: execute
|
||||
wave: 3
|
||||
depends_on: [10-02]
|
||||
files_modified:
|
||||
- docs/intermediate/data-state-overview.md
|
||||
- docs/intermediate/hero-attribute.md
|
||||
- docs/intermediate/hero-items.md
|
||||
- docs/intermediate/hero-equipment.md
|
||||
- docs/intermediate/hero-location.md
|
||||
- docs/intermediate/map-structure.md
|
||||
- docs/intermediate/map-tiles.md
|
||||
- docs/intermediate/flags.md
|
||||
autonomous: false
|
||||
requirements: []
|
||||
user_setup: []
|
||||
estimate:
|
||||
tokens: 46000
|
||||
raw_tokens: 30000
|
||||
tasks: 3
|
||||
confidence: low
|
||||
must_haves:
|
||||
truths:
|
||||
- "8 篇基础接口文档存在且为 kebab-case、CRLF、单 H1"
|
||||
- "`data-state-overview` 以表列常用对象与获取方式,并按 L0–L3 轻量分组标注,放在本组最前"
|
||||
- "`hero-attribute` 讲基础/最终属性、ValueModifier/PercentageModifier、addModifier/deleteModifier、save 参数语义,并回指 hooks 篇"
|
||||
- "`hero-items` 区分 Constant/Consumable/Pick/Equipment 四类;`hero-location` 只讲获取位置与楼层"
|
||||
- "`map-structure` 含楼层激活与事件层;`map-tiles` 只讲 get/set/remove/putMapData/getMapData/iterateBlocks(getLocationData 留高级);`flags` 讲全部接口含 occupied"
|
||||
artifacts:
|
||||
- "docs/intermediate/data-state-overview.md"
|
||||
- "docs/intermediate/hero-attribute.md"
|
||||
- "docs/intermediate/hero-items.md"
|
||||
- "docs/intermediate/hero-equipment.md"
|
||||
- "docs/intermediate/hero-location.md"
|
||||
- "docs/intermediate/map-structure.md"
|
||||
- "docs/intermediate/map-tiles.md"
|
||||
- "docs/intermediate/flags.md"
|
||||
key_links:
|
||||
- "`hero-attribute` 回指概念组 `./hooks.md`(已写就,链接可解析)"
|
||||
- "组内互链(如 data-state-overview → hero-attribute)在本计划构建时已全部存在"
|
||||
- "接口定义以各包 `types.ts` 为准;示例为内嵌 markdown 代码块,不改生产代码"
|
||||
---
|
||||
|
||||
<objective>
|
||||
编写「基础接口」组 8 篇:`data-state-overview`、`hero-attribute`、`hero-items`、`hero-equipment`、`hero-location`、`map-structure`、`map-tiles`、`flags`。本组是作者日常最常用的顶层接口手册。
|
||||
|
||||
Purpose: 让读完概念组的作者能查表调用数据端常用对象与接口(D-15:只讲顶层常用接口,不深挖底层)。
|
||||
Output: 8 个新 markdown 文件。
|
||||
</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/phases/10-docs-restructure/10-CONTEXT.md
|
||||
@.planning/phases/10-docs-restructure/10-RESEARCH.md
|
||||
@.planning/phases/10-docs-restructure/10-PATTERNS.md
|
||||
@docs/guide/implements/special.md
|
||||
|
||||
**写作约定:**
|
||||
- 骨架统一照 Analog C(`docs/guide/implements/special.md`):`# 标题` → 引言 → `## 小节` → ` ```ts ` 代码块;标新增行用 `// [!code ++]`,标改动区块用 ` ```ts {起-止} `。**只借结构、不抄旧接口名**。
|
||||
- 代码块内每处接口名/字段名必须按 10-RESEARCH「基础接口」表的 `file:line` 逐字核对(RESEARCH Pitfall 5)。
|
||||
- kebab-case 文件名、CRLF、单 H1、无元叙述(D-16);跳转链接 2–5 处/篇(D-17)。
|
||||
- 组内互链与回指概念组 `./hooks.md` 均指向已写就页面,可安全加链接;**不得**链接尚未写就的战斗/其他组页面(否则构建报 dead link)。
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking-human">
|
||||
<name>Task 0: 向用户汇报本组计划并等待「可以执行」</name>
|
||||
<action>向用户汇报:**要做什么**(编写 8 篇基础接口文档)、**为什么**(作者日常最常用的顶层接口手册)、**大致怎么做**(逐篇按 D-25..D-32 与 10-RESEARCH「基础接口」表的 `file:line` 核对接口名后落笔;骨架照 `special.md`)、**影响范围**(仅新增 8 个 `docs/intermediate/*.md`,不改生产代码与既有文档)。停下等待用户明确回复「可以执行」四个字;未收到前不得写任何文件。 </action>
|
||||
<what-built>本计划内容:编写「基础接口」组 8 篇中级教程(`data-state-overview` 等,仅新增 `docs/intermediate/*.md`)。</what-built>
|
||||
<how-to-verify>阅读上面的「要做什么 / 为什么 / 大致怎么做 / 影响范围」四段,确认范围与做法无异议。</how-to-verify>
|
||||
<resume-signal>回复「可以执行」以继续;其它回复视为未批准,本计划停在此处。</resume-signal>
|
||||
<verify>
|
||||
<human-check>用户已回复「可以执行」。</human-check>
|
||||
</verify>
|
||||
<done>用户回复「可以执行」。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: 编写 data-state-overview、hero-attribute、hero-items</name>
|
||||
<files>docs/intermediate/data-state-overview.md, docs/intermediate/hero-attribute.md, docs/intermediate/hero-items.md</files>
|
||||
<behavior>
|
||||
- `data-state-overview`(放本组最前):以 `state` 为访问一切入口;一张表列常用对象与获取方式(`hero`/`maps`/`flags`/`enemyManager`/`enemyContext`/`combat`/`eventSystem`/`pathfinding`/`tileStore`/`itemStore`/`mapStore`/`eventStore`/`faceManager`/`roleFace`/`replaySystem`/`loader`/`loadManager`/`getDataPlugin(id)`/`emitTip(...)`);按 L0–L3 **轻量分组标注**(分层不影响接口使用,细讲留高级)。
|
||||
- `hero-attribute`:属性列表;基础 vs 最终(`getBaseAttribute`/`getFinalAttribute`);改基础属性 `set`/`add`/`mul`/`div`(经 `getModifiableAttribute()`);修饰器 `ValueModifier`(`@system/value`)与 `PercentageModifier`(按基础值算百分比,`@system/percentage`);`addModifier`/`deleteModifier`;`save` 参数语义;`getAttribute()` 只读、`getIsolatedAttribute()` 试算;示例「攻击 +N 永久 / 防御 −X% 临时」;回指 `./hooks.md`。
|
||||
- `hero-items`:`IHeroItems`(`addItem` 可传负数、`Pick` 立刻生效、`getItemState`、`iterateItems`、`useItem` 仅 Constant/Consumable、`itemCount`);四种类别 `Constant`/`Consumable`/`Pick`/`Equipment` 区分;道具效果属内容层一句话;示例「发黄钥匙 / 减道具 / 使用道具」。
|
||||
</behavior>
|
||||
<action>三篇均按 D-25/D-26/D-27 与 RESEARCH「基础接口」表核对后撰写。`data-state-overview` 的 L0–L3 分组字段来源为 `packages-user/data-common/src/types.ts:60-82`(L0 `IDataCommon`)、`data-base/src/types.ts:17-41`(L1 `IStateBase`)、`data-system/src/types.ts:7-16`(L2 `IStateSystem`)、`data-state/src/types.ts:92-122`(L3 `ICoreState`);`getDataPlugin` 见 data-state/types.ts:103-105、`emitTip` 见 data-common/types.ts:81。`hero-attribute` 素材见 `data-base/src/hero/types.ts:104-283`(属性接口)、`hero/modifier.ts:42-78`(`ValueModifier` `@system/value`、`PercentageModifier` `@system/percentage`)、`hero/types.ts:964-977`(`getModifiableAttribute`/`getAttribute`/`getIsolatedAttribute`)、`hero/types.ts:224-228`(`addModifier(name, modifier, save?)` 的 `save` 参数)——`save` 不进存档时须由外部系统负责分配该修饰器以避免读档不一致,用 `:::warning` 表达。`hero-items` 素材见 `data-base/src/hero/types.ts:585-647`(`IHeroItems`/`IHeroItemState`)、`hero/items.ts:18-176`(`addItem` 的 `Pick` 分支:62-67、`Equipment` 分支:69-74;`useItem` 的 Constant/Consumable 限制:94-99)、`data-common/src/store/types.ts:125-136`(`ItemCategory`)、`src/content/item.ts:1-24` 与 `IItemEffect`(data-common/store/types.ts:138-159)。遵守写作约定。</action>
|
||||
<verify>
|
||||
<automated>$ErrorActionPreference='Stop'; $files=@('docs/intermediate/data-state-overview.md','docs/intermediate/hero-attribute.md','docs/intermediate/hero-items.md'); foreach($p in $files){ if(-not(Test-Path $p)){ Write-Error "MISSING $p" }; $raw=[IO.File]::ReadAllText((Resolve-Path $p)); if($raw -match "(?<!`r)`n"){ Write-Error "LF-ONLY $p" }; if(([regex]::Matches($raw,'(?m)^# ')).Count -ne 1){ Write-Error "H1-COUNT $p" } }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/hero-attribute.md')) -notmatch 'PercentageModifier')){ Write-Error "NO-MODIFIER hero-attribute" }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/hero-items.md')) -notmatch 'Consumable')){ Write-Error "NO-CATEGORY hero-items" }; Write-Output 'STATIC-OK'</automated>
|
||||
<fails_when>non-zero exit, or output contains "MISSING", "LF-ONLY", "H1-COUNT", "NO-MODIFIER", or "NO-CATEGORY"</fails_when>
|
||||
</verify>
|
||||
<done>三文件存在、CRLF、单 H1;`data-state-overview` 含对象表与 L0–L3 标注;`hero-attribute` 含修饰器与 save 语义、回指 `./hooks.md`;`hero-items` 含四类区分。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 2: 编写 hero-equipment、hero-location、map-structure</name>
|
||||
<files>docs/intermediate/hero-equipment.md, docs/intermediate/hero-location.md, docs/intermediate/map-structure.md</files>
|
||||
<behavior>
|
||||
- `hero-equipment`:`IHeroEquipment`(`slots`/`canEquipTo`/`equip` 含 `autoUnload`/`unequip`/`equipped`/`getEquipped`/`getEquips`);`IHeroEquipsStore`(`add`/`delete`/`get`/`instancesOf`/`instances`/`count`);`IEquipmentState` 的 `value`/`percentage`(本质是修饰器);`compareEquip` 简单讲;**排序器不讲**。
|
||||
- `hero-location`:只讲获取位置(`hero.location` 的 `x`/`y`/`direction`、`hero.getLocation()`)与获取楼层(`floorId`/`map`);移动/切层留高级。
|
||||
- `map-structure`:`IMapState` 楼层集合(`maps`/`getMap`/`getActiveMap`/`iterateAllMaps`)与楼层激活(`active`);`IGameMap`(`layerList`/`eventLayer`/`tileStore`/宽高);`IMapLayer`(`alias`/宽高);**事件层本质就是个图层,归本篇**。
|
||||
</behavior>
|
||||
<action>按 D-28/D-29/D-30 与 RESEARCH 表核对撰写。`hero-equipment` 素材见 `data-base/src/hero/types.ts:651-883`(`IHeroEquipment`/`IHeroEquipsStore`/`IEquipmentState`/`EquipStatus`)、`hero/equipment.ts:13-361`(`equip` 含 `autoUnload`:153-199、`compareEquip`:257-335)、`hero/equipStore.ts:251-381`(`HeroEquipsStore`)、`equipStore.ts:83-104,123-128`(`value`/`percentage` 即修饰器)。`hero-location` 素材见 `data-base/src/hero/types.ts:287-333`(`IHeroLocation`/`IHeroLocationSave`)、`hero/location.ts:22-87`(`x`/`y` 字段:26-27、`floorId`:28、`map`:29)、`hero/types.ts:959-962`(`hero.getLocation()`)。`map-structure` 素材见 `data-base/src/map/types.ts:760-861`(`IMapState`)、同文件:651-740(`IGameMap`,`layerList`:659、`eventLayer`:669、`tileStore`:661)、:478-600(`IMapLayer`,`alias`:505-506)、`active`:662-663。遵守写作约定;组内/回指链接安全。</action>
|
||||
<verify>
|
||||
<automated>$ErrorActionPreference='Stop'; $files=@('docs/intermediate/hero-equipment.md','docs/intermediate/hero-location.md','docs/intermediate/map-structure.md'); foreach($p in $files){ if(-not(Test-Path $p)){ Write-Error "MISSING $p" }; $raw=[IO.File]::ReadAllText((Resolve-Path $p)); if($raw -match "(?<!`r)`n"){ Write-Error "LF-ONLY $p" }; if(([regex]::Matches($raw,'(?m)^# ')).Count -ne 1){ Write-Error "H1-COUNT $p" } }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/hero-equipment.md')) -notmatch 'autoUnload')){ Write-Error "NO-AUTOUNLOAD hero-equipment" }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/map-structure.md')) -notmatch 'eventLayer')){ Write-Error "NO-EVENTLAYER map-structure" }; Write-Output 'STATIC-OK'</automated>
|
||||
<fails_when>non-zero exit, or output contains "MISSING", "LF-ONLY", "H1-COUNT", "NO-AUTOUNLOAD", or "NO-EVENTLAYER"</fails_when>
|
||||
</verify>
|
||||
<done>三文件存在、CRLF、单 H1;`hero-equipment` 含 `autoUnload` 且未讲排序器;`hero-location` 只讲获取;`map-structure` 含事件层。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 3: 编写 map-tiles 与 flags</name>
|
||||
<files>docs/intermediate/map-tiles.md, docs/intermediate/flags.md</files>
|
||||
<behavior>
|
||||
- `map-tiles`:只讲 `getBlock`/`setBlock`/`removeBlock`/`putMapData`/`getMapData`/`iterateBlocks`;`getLocationData` 留高级(不展开)。
|
||||
- `flags`:全局可存档变量系统;讲全部接口(含 `occupied`):`setField`/`getField`/`getOrInsert`/`getOrInsertComputed`/`deleteField`/`setFieldValue`/`addFieldValue`/`getFieldValue`/`getFieldValueDefaults`;说明会进存档;建议不滥用、不用的变量及时 `deleteField`;示例「记录开关 / 计数」。
|
||||
</behavior>
|
||||
<action>按 D-31/D-32 与 RESEARCH 表核对撰写。`map-tiles` 素材见 `data-base/src/map/types.ts:294-378`(`ILayerStatic` 的 `getBlock`/`setBlock`/`removeBlock`/`putMapData`/`getMapData`/`iterateBlocks`);`getLocationData` 在 `map/types.ts:527-532`,仅一句说明其属低级需求、留高级,不展开。`flags` 素材见 `data-base/src/flag/types.ts:47-136`(`IFlagSystem`,含 `occupied`)与 `:5-36`(`IFlagCommonField`)。只用顶层常用接口(D-15),不深挖底层。遵守写作约定。</action>
|
||||
<verify>
|
||||
<automated>$ErrorActionPreference='Stop'; $files=@('docs/intermediate/map-tiles.md','docs/intermediate/flags.md'); foreach($p in $files){ if(-not(Test-Path $p)){ Write-Error "MISSING $p" }; $raw=[IO.File]::ReadAllText((Resolve-Path $p)); if($raw -match "(?<!`r)`n"){ Write-Error "LF-ONLY $p" }; if(([regex]::Matches($raw,'(?m)^# ')).Count -ne 1){ Write-Error "H1-COUNT $p" } }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/map-tiles.md')) -notmatch 'iterateBlocks')){ Write-Error "NO-ITERATEBLOCKS map-tiles" }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/flags.md')) -notmatch 'getOrInsertComputed')){ Write-Error "NO-GETORINSERTCOMPUTED flags" }; Write-Output 'STATIC-OK'</automated>
|
||||
<fails_when>non-zero exit, or output contains "MISSING", "LF-ONLY", "H1-COUNT", "NO-ITERATEBLOCKS", or "NO-GETORINSERTCOMPUTED"</fails_when>
|
||||
</verify>
|
||||
<done>两文件存在、CRLF、单 H1;`map-tiles` 含全部六个常用接口;`flags` 含全部接口(含 `occupied`、`getOrInsertComputed`)。</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| 构建期 markdown → 静态站点 | 正文由构建期静态渲染,无运行时输入 |
|
||||
| 站点 → 浏览器读者 | 外链是唯一对外指向面(本篇不引入外链) |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|----------|-------------|-----------------|
|
||||
| T-10-07 | Tampering / XSS | 8 篇 markdown 正文 | low | mitigate | 只写文本、代码块、表格;不引入原始 `<script>`/内联 HTML |
|
||||
| T-10-08 | Spoofing | 外链 | low | mitigate | 本组不引入任何外链(D-23 唯一外链仅在 `code-basics`) |
|
||||
| T-10-09 | Information Disclosure | 正文示例 | low | mitigate | 只用源码已公开接口/路径;不写密钥、账号 |
|
||||
| T-10-SC | Tampering | npm/pip/cargo installs | low | accept | 本阶段不安装任何包,无供应链安装面 |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- 计划级构建门禁:`cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"` 通过(组内互链与回指概念组链接均指向已写就页面,构建可独立通过)。
|
||||
- 结构门禁:8 文件均 kebab-case、CRLF、单 H1。
|
||||
- 内容门禁(人工,随 D-09):D-25..D-32 要点齐全;接口名与源码一致(RESEARCH Pitfall 5)。
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- 8 篇基础接口文档落位且构建通过。
|
||||
- 每篇覆盖对应 D-2x 全部要点,未越界讲底层/排序器/移动切换楼层等留高级项。
|
||||
- 无元叙述;无新增外链。
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/10-docs-restructure/10-03-SUMMARY.md` when done
|
||||
</output>
|
||||
172
.planning/phases/10-docs-restructure/10-04-PLAN.md
Normal file
172
.planning/phases/10-docs-restructure/10-04-PLAN.md
Normal file
@ -0,0 +1,172 @@
|
||||
---
|
||||
phase: 10-docs-restructure
|
||||
plan: 04
|
||||
type: execute
|
||||
wave: 4
|
||||
depends_on: [10-03]
|
||||
files_modified:
|
||||
- docs/intermediate/combat-overview.md
|
||||
- docs/intermediate/enemy-specials.md
|
||||
- docs/intermediate/enemy-aura.md
|
||||
- docs/intermediate/enemy-query.md
|
||||
- docs/intermediate/enemy-final.md
|
||||
- docs/intermediate/enemy-calculator.md
|
||||
- docs/intermediate/enemy-map-damage.md
|
||||
- docs/intermediate/enemy-combat-script.md
|
||||
- docs/intermediate/enemy-status-hooks.md
|
||||
autonomous: false
|
||||
requirements: []
|
||||
user_setup: []
|
||||
estimate:
|
||||
tokens: 56000
|
||||
raw_tokens: 37000
|
||||
tasks: 3
|
||||
confidence: low
|
||||
must_haves:
|
||||
truths:
|
||||
- "9 篇战斗文档存在且为 kebab-case、CRLF、单 H1"
|
||||
- "`combat-overview` 含伤害流程 mermaid 图与「流程步骤 → 对应文档」对照表;`combat-overview` 先于各子系统文档"
|
||||
- "`enemy-query` 明确标注为「引擎未内置」的新增内容,按接口 + 三个示例(抱团/同化/号角)讲;`enemy-map-damage` 的「内置五类表」code/实现位置按写作时核对源码所得书写,并对未定项留余地"
|
||||
- "`enemy-aura` 先讲优先级并含基础光环与特殊光环两个自定义示例;`enemy-final` 含三方对比;`enemy-calculator` 讲 f(enemy,hero) 且支援怪可跳过、不讲二分过程"
|
||||
- "`enemy-combat-script` 含「脚本 vs 钩子」选型表;`enemy-status-hooks` 强调一个状态可能用多个钩子并串起 `enemy-calculator`"
|
||||
artifacts:
|
||||
- "docs/intermediate/combat-overview.md"
|
||||
- "docs/intermediate/enemy-specials.md"
|
||||
- "docs/intermediate/enemy-aura.md"
|
||||
- "docs/intermediate/enemy-query.md"
|
||||
- "docs/intermediate/enemy-final.md"
|
||||
- "docs/intermediate/enemy-calculator.md"
|
||||
- "docs/intermediate/enemy-map-damage.md"
|
||||
- "docs/intermediate/enemy-combat-script.md"
|
||||
- "docs/intermediate/enemy-status-hooks.md"
|
||||
key_links:
|
||||
- "组内互链(combat-overview → 各子系统;enemy-final/enemy-status-hooks 回指 combat-overview / enemy-calculator)在本计划构建时已全部存在"
|
||||
- "回指基础组 `./hero-attribute.md`(修饰器概念)指向已写就页面"
|
||||
- "N-1 查询未内置 / N-2·N-3 地图伤害 code↔视图不一致 / N-7 结算待补齐 —— 以当时代码为准并留余地"
|
||||
---
|
||||
|
||||
<objective>
|
||||
编写「战斗」组 9 篇(本批重点,也是作者最常修改的部分):`combat-overview` 与 8 篇子系统文档。
|
||||
|
||||
Purpose: 让作者理解战斗伤害的整体流程,并能按需自定义特殊属性、光环、查询、最终属性、伤害公式、地图伤害、战斗脚本与状态钩子。
|
||||
Output: 9 个新 markdown 文件。
|
||||
</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/phases/10-docs-restructure/10-CONTEXT.md
|
||||
@.planning/phases/10-docs-restructure/10-RESEARCH.md
|
||||
@.planning/phases/10-docs-restructure/10-PATTERNS.md
|
||||
@docs/guide/implements/special.md
|
||||
@docs/dev/enemy/enemy-combat-flow.md
|
||||
|
||||
**写作约定与前置:**
|
||||
- 骨架照 Analog C(`docs/guide/implements/special.md`):`# 标题` → 引言 → `## 小节` → 代码块;`// [!code ++]` 标新增行,` ```ts {起-止} ` 标改动区块。**只借结构、不抄旧接口名**(旧文档对应旧接口)。
|
||||
- 代码块内每处接口名/字段名按 10-RESEARCH「战斗」表 `file:line` 逐字核对(RESEARCH Pitfall 5)。
|
||||
- kebab-case、CRLF、单 H1、无元叙述(D-16);跳转链接 2–5 处/篇。
|
||||
- **尚未可用项(D-18/N-1..N-7)**:查询效果引擎未内置(`enemy-query`);地图伤害 code↔视图映射与 `special.ts` 注册码可能不一致、`MapDamageType` 无「伏击」(`enemy-map-damage`);部分特殊属性/结算待用户补齐。相关篇目**按接口讲概念 + 示例**,对未定项明确留余地、以当时代码为准,不臆造已内置事实。
|
||||
- 本组回指基础组(如修饰器见 `./hero-attribute.md`)与组内互链均指向已写就/同计划页面,可安全加链接。
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking-human">
|
||||
<name>Task 0: 向用户汇报本组计划并等待「可以执行」</name>
|
||||
<action>向用户汇报:**要做什么**(编写 9 篇战斗文档,本批重点)、**为什么**(作者最常修改战斗,需要流程总览与各子系统 how-to)、**大致怎么做**(逐篇按 D-33..D-41 与 10-RESEARCH「战斗」表核对后落笔;对 N-1/N-2/N-3/N-7 等未内置/待补齐项按接口讲、留余地)、**影响范围**(仅新增 9 个 `docs/intermediate/*.md`,不改生产代码与既有文档)。特别说明:`enemy-query` 为引擎未内置的新增内容、`enemy-map-damage` 的 code↔视图映射写作前会核对当时代码。停下等待用户明确回复「可以执行」四个字;未收到前不得写任何文件。 </action>
|
||||
<what-built>本计划内容:编写「战斗」组 9 篇中级教程(`combat-overview` 与 8 篇子系统,仅新增 `docs/intermediate/*.md`)。</what-built>
|
||||
<how-to-verify>阅读上面的「要做什么 / 为什么 / 大致怎么做 / 影响范围」四段,确认范围与做法无异议(含对 N-1/N-2/N-3/N-7 留余地的说明)。</how-to-verify>
|
||||
<resume-signal>回复「可以执行」以继续;其它回复视为未批准,本计划停在此处。</resume-signal>
|
||||
<verify>
|
||||
<human-check>用户已回复「可以执行」。</human-check>
|
||||
</verify>
|
||||
<done>用户回复「可以执行」。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: 编写 combat-overview、enemy-specials、enemy-aura</name>
|
||||
<files>docs/intermediate/combat-overview.md, docs/intermediate/enemy-specials.md, docs/intermediate/enemy-aura.md</files>
|
||||
<behavior>
|
||||
- `combat-overview`:讲伤害大致怎么算;流程(基础数据 → 光环/查询/最终 → 伤害计算 → 战前脚本 → 战斗 → 战后结算 + 状态钩子);含 mermaid 图;末尾「流程步骤 → 对应文档」对照表;临界值不在本篇提。
|
||||
- `enemy-specials`:特殊属性是什么、在数据里的样子、两类定义(无参 `defineNonePropertySpecial` / 有参 `defineCommonSerializableSpecial`);注册在 `src/data/enemy/special.ts`;如何自定义新属性(步骤);「属性实现位置」对照表;多个示例(有参/无参、`name`/`desc` 用字符串与函数);编辑器识别约定(`// {code} - {name}`、`/** {code} - {name} */`、`ISpecial{code}Value`、`#region` 不能删);怪物比较简单说。
|
||||
- `enemy-aura`:先讲优先级(高优先级可影响低优先级、反之不行;与查询共用优先级);内置光环(普通 23 / 支援 24 / 特殊光环 26);运作方式(转换器 + 视图并注册);四种内置范围只列名;多个自定义示例(基础光环「减少周围怪物金币与经验」+ 高级特殊光环「给周围怪物上光环、优先级高于特殊光环」);讲清 `apply` 与 `applySpecial` 差别。
|
||||
</behavior>
|
||||
<action>按 D-33/D-34/D-35 撰写。`combat-overview` 素材:`packages-user/data-system/src/combat/types.ts:847-901`(`ICombatFlow`)、同文件:747-755(`IEnemyContext.buildup()` 四阶段文档)、`src/data/enemy/initialize.ts:27-70`(注册与装配全流程)、`packages-user/data-state/src/core.ts:79-83,123-127`(L2 装配);mermaid 图照 D-33 流程,写法参照 `docs/guide/quick-start.md:27-31`。`enemy-specials` 素材:`data-base/src/enemy/types.ts:31-75,164-248`(`ISpecial`/`IReadonlyEnemy`/`IEnemyManager`/`SpecialCreation`)、`data-base/src/enemy/special.ts:136-150`(两类定义函数)、`src/data/enemy/special.ts:1-477`(内置注册;注释清单:72-84;编辑器识别注释:8-14,98,100,473)、`src/data/enemy/comparer.ts:1-31`(怪物比较)。`enemy-aura` 素材:`src/data/enemy/aura.ts:1-301`(`CommonAura` code 23:29-119;`GuardAura` code 24:125-184;`SpecialAura` code 26:190-299;`SpecialAuraModifier`:206-242;`priority` 实测值 CommonAura=10、GuardAura=5、SpecialAura=20,见 aura.ts:50,147,249)、`data-system/src/combat/types.ts:99-191`(`IAuraView`/`IEnemyAuraView`/`IAuraConverter`/`IEnemySpecialModifier`)、注册 `registerAuraConverter`:638、全局光环 `addAura`:727、范围类 `FullRange`/`RectRange`/`ManhattanRange`/`RayRange` 来自 `@motajs/common`。遵守写作约定。</action>
|
||||
<verify>
|
||||
<automated>$ErrorActionPreference='Stop'; $files=@('docs/intermediate/combat-overview.md','docs/intermediate/enemy-specials.md','docs/intermediate/enemy-aura.md'); foreach($p in $files){ if(-not(Test-Path $p)){ Write-Error "MISSING $p" }; $raw=[IO.File]::ReadAllText((Resolve-Path $p)); if($raw -match "(?<!`r)`n"){ Write-Error "LF-ONLY $p" }; if(([regex]::Matches($raw,'(?m)^# ')).Count -ne 1){ Write-Error "H1-COUNT $p" } }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/combat-overview.md')) -notmatch 'mermaid')){ Write-Error "NO-MERMAID combat-overview" }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/enemy-aura.md')) -notmatch 'applySpecial')){ Write-Error "NO-APPLYSPECIAL enemy-aura" }; Write-Output 'STATIC-OK'</automated>
|
||||
<fails_when>non-zero exit, or output contains "MISSING", "LF-ONLY", "H1-COUNT", "NO-MERMAID", or "NO-APPLYSPECIAL"</fails_when>
|
||||
</verify>
|
||||
<done>三文件存在、CRLF、单 H1;`combat-overview` 含 mermaid 流程与对照表;`enemy-specials` 含两类定义与实现位置表;`enemy-aura` 含优先级与 `apply`/`applySpecial` 差别。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 2: 编写 enemy-query、enemy-final、enemy-calculator</name>
|
||||
<files>docs/intermediate/enemy-query.md, docs/intermediate/enemy-final.md, docs/intermediate/enemy-calculator.md</files>
|
||||
<behavior>
|
||||
- `enemy-query`:**明确写为新增内容(引擎未内置)**;解决「特殊属性查询外部状态」;常规查询 `CommonQuery`(`registerCommonQueryEffect(code, effect)`,`apply(handler, special, query)`)与特殊查询 `SpecialQuery`(`registerSpecialQueryEffect(effect)`,`for(ctx)` → 修饰器 `shouldQuery`/`add`/`delete`/`modify`);与光环共用优先级;三个示例:抱团、同化、号角;用**抱团**对比「用光环实现复杂度更高」;设计原因留高级。
|
||||
- `enemy-final`:最终属性效果「只影响自身、不依赖也不影响外部环境」;内置坚固(3)、模仿(8);接口 `IEnemyFinalEffect`(`priority` + `apply`)、`registerFinalEffect`;三方对比(光环/查询/最终);示例「仿攻」(怪物攻击 = 玩家攻击);`priority` 一句带过;回指 `./combat-overview.md`。
|
||||
- `enemy-calculator`:`IDamageCalculator`(`calculate` → `{ damage, turn }`、`getCriticalLimit`);注册 `useCalculator`;逐段导读内置伤害公式并指明「加自己的属性加在哪一步」;支援怪较难 → 写「实在理解不了可暂时跳过」;示例「等差数列属性」;讲明调整的是 `f(enemy, hero)` 里的 `f`;临界只讲定义与「伤害值单调递减」约定、不讲二分过程。
|
||||
</behavior>
|
||||
<action>按 D-36/D-37/D-38 撰写。`enemy-query`:接口见 `data-system/src/combat/types.ts:193-201`(`IEnemySpecialQueryModifier`)、:203-213(`IEnemySpecialQueryEffect`)、:215-227(`IEnemyCommonQueryEffect`);注册 `registerSpecialQueryEffect`:660、`registerCommonQueryEffect`:677;**`src/` 未注册任何查询效果**(`src/data/enemy/initialize.ts:27-70` 只注册光环/最终/脚本/钩子)——据此按「未内置、新增内容」讲解,不假设引擎已内置(N-1)。`enemy-final`:素材 `src/data/enemy/final.ts:4-27`(`MainEnemyFinalEffect`,坚固=3、模仿=8)、`combat/types.ts:229-237`(`IEnemyFinalEffect`)、注册 `registerFinalEffect`:696、装配 `src/data/enemy/initialize.ts:57`。`enemy-calculator`:素材 `src/data/enemy/calculator.ts:10-179`(`calculate`:17-160、`getCriticalLimit`:162-178)、`combat/types.ts:408-426`(`IDamageCalculator`)、`useCalculator`:491、临界 `calculateEnemyCritical`:472 / `calculateViewCritical`:459、`CriticalableHeroStatus`:404-406、装配 `src/data/enemy/initialize.ts:44`、`{damage, turn}` 见 types.ts:377-382。遵守写作约定。</action>
|
||||
<verify>
|
||||
<automated>$ErrorActionPreference='Stop'; $files=@('docs/intermediate/enemy-query.md','docs/intermediate/enemy-final.md','docs/intermediate/enemy-calculator.md'); foreach($p in $files){ if(-not(Test-Path $p)){ Write-Error "MISSING $p" }; $raw=[IO.File]::ReadAllText((Resolve-Path $p)); if($raw -match "(?<!`r)`n"){ Write-Error "LF-ONLY $p" }; if(([regex]::Matches($raw,'(?m)^# ')).Count -ne 1){ Write-Error "H1-COUNT $p" } }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/enemy-query.md')) -notmatch 'registerSpecialQueryEffect')){ Write-Error "NO-REGISTER enemy-query" }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/enemy-calculator.md')) -notmatch 'getCriticalLimit')){ Write-Error "NO-CRITICAL enemy-calculator" }; Write-Output 'STATIC-OK'</automated>
|
||||
<fails_when>non-zero exit, or output contains "MISSING", "LF-ONLY", "H1-COUNT", "NO-REGISTER", or "NO-CRITICAL"</fails_when>
|
||||
</verify>
|
||||
<done>三文件存在、CRLF、单 H1;`enemy-query` 标注「未内置」且含三个示例;`enemy-final` 含三方对比与仿攻示例;`enemy-calculator` 含 `{damage, turn}`、`f` 说明与临界约定。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 3: 编写 enemy-map-damage、enemy-combat-script、enemy-status-hooks</name>
|
||||
<files>docs/intermediate/enemy-map-damage.md, docs/intermediate/enemy-combat-script.md, docs/intermediate/enemy-status-hooks.md</files>
|
||||
<precondition>写作前已阅读当时代码 `src/data/enemy/mapDamage.ts`、`src/data/enemy/special.ts`、`src/data/enemy/types.ts`,并逐码核对地图伤害的 code↔视图映射(N-2/N-3 提示可能与注册码不一致)</precondition>
|
||||
<behavior>
|
||||
- `enemy-map-damage`:概念(领域/夹击/阻击/激光/伏击);三部分(伤害视图/转换器/合并器,浅讲);注册 `useConverter`/`useReducer`;内置五类表(`code`/实现位置,**按写作时核对源码所得**书写);自定义示例「受地形遮挡的激光」;合并器简单讲;「实际结算用户届时补」(对未定项留余地,不臆造)。
|
||||
- `enemy-combat-script`:战斗脚本(战前 `before` 返回 `bool` 拦截、战后 `after` 结算,按 `priority`);内置 `MainCombatScript`;注册 `addCombatScript`;「脚本 vs 钩子」选型表;战前示例「怪物拥有某特殊属性时无法与其战斗」、战后示例「战后玩家回复固定量生命值」;`priority` 一句。
|
||||
- `enemy-status-hooks`:状态类属性(中毒/衰弱/重生)必须挂钩子;三类内置(中毒:`onStepEnd` + `onAfterTeleportTo` 两个钩子;衰弱:`onAfterCombat` + 修饰器;重生:`onAfterCombat` + `onSetFloor`);注册在 `initialize.ts`;强调一个状态可能要用多个钩子;自定义示例「下次战斗伤害乘二」(并说明还要改伤害计算器,串起 `./enemy-calculator.md`);修饰器概念见 `./hero-attribute.md`。
|
||||
</behavior>
|
||||
<action>按 D-39/D-40/D-41 撰写。`enemy-map-damage`:素材 `src/data/enemy/mapDamage.ts:1-359`(`ZoneDamageView`:84-119、`RepulseDamageView`:121-153、`LaserDamageView`:155-184、`BetweenDamageView`:186-255、`AmbushDamageView`:257-282、`MainMapDamageConverter`:288-325、`MainMapDamageReducer`:331-357)、`combat/types.ts:241-371`(`IMapDamageView`/`IMapDamageConverter`/`IMapDamageReducer`/`IMapDamageInfo`/`IMapDamage`)、注册 `useConverter`:313 / `useReducer`:319、`MapDamageType`: `src/data/enemy/types.ts:1-12`、触发结算 `src/data/enemy/hook.ts:74-133`。**N-2**:转换器实际按 `getSpecial(15)`→领域(:299)、`hasSpecial(16)`→夹击(:304)、`getSpecial(18)`→阻击(:308)、`getSpecial(24)`→激光(:313)、`hasSpecial(27)`→伏击(:319),而 `special.ts` 注册 13=领域/14=夹击/16=阻击/22=激光且无 27(`src/data/enemy/special.ts:252-367,439-471`)——写作时以**当时代码**为准并保留余地;`BetweenDamageView` 读全局 `core.flags.betweenAttackMax`(mapDamage.ts:238)。**N-3**:`MapDamageType` 无「伏击」(Unknown/Zone/Layer/Repulse/Between,types.ts:1-12),伏击视图返回 `MapDamageType.Unknown`(mapDamage.ts:278),文档据此说明。`enemy-combat-script`:素材 `src/data/enemy/script.ts:8-62`(`before` 返回 bool:11-23、`after`:25-61)、`combat/types.ts:813-836`(`ICombatScript`)、:784-797(`ICombatFlowHandler`)、注册 `addCombatScript`:897、装配 `src/data/enemy/initialize.ts:60`、钩子对照 `ICombatFlowHooks`:799-811。`enemy-status-hooks`:素材 `src/data/enemy/hook.ts:38-151`(`EnemyMoveHooks`,中毒 `onStepEnd`)、:153-186(`EnemyPathfindingHooks`,中毒 `onAfterTeleportTo`)、:188-281(`EnemyCombatHooks`,中毒/衰弱/退化/重生 `onAfterCombat`)、:283-321(`EnemyChangeFloorHooks`,重生 `onSetFloor`)、注册 `src/data/enemy/initialize.ts:62-67`。遵守写作约定。</action>
|
||||
<verify>
|
||||
<automated>$ErrorActionPreference='Stop'; $files=@('docs/intermediate/enemy-map-damage.md','docs/intermediate/enemy-combat-script.md','docs/intermediate/enemy-status-hooks.md'); foreach($p in $files){ if(-not(Test-Path $p)){ Write-Error "MISSING $p" }; $raw=[IO.File]::ReadAllText((Resolve-Path $p)); if($raw -match "(?<!`r)`n"){ Write-Error "LF-ONLY $p" }; if(([regex]::Matches($raw,'(?m)^# ')).Count -ne 1){ Write-Error "H1-COUNT $p" } }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/enemy-map-damage.md')) -notmatch 'useReducer')){ Write-Error "NO-REDUCER enemy-map-damage" }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/enemy-status-hooks.md')) -notmatch 'onAfterTeleportTo')){ Write-Error "NO-MULTIHOOK enemy-status-hooks" }; Write-Output 'STATIC-OK'</automated>
|
||||
<fails_when>non-zero exit, or output contains "MISSING", "LF-ONLY", "H1-COUNT", "NO-REDUCER", or "NO-MULTIHOOK"</fails_when>
|
||||
</verify>
|
||||
<done>三文件存在、CRLF、单 H1;`enemy-map-damage` 五类表按当时代码书写且对不一致留余地;`enemy-combat-script` 含选型表与两个示例;`enemy-status-hooks` 强调多钩子协同并串起 `./enemy-calculator.md`。</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| 构建期 markdown → 静态站点 | 正文由构建期静态渲染,无运行时输入 |
|
||||
| 站点 → 浏览器读者 | 外链是唯一对外指向面(本篇不引入外链) |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|----------|-------------|-----------------|
|
||||
| T-10-10 | Tampering / XSS | 9 篇 markdown 正文 | low | mitigate | 只写文本、代码块、mermaid、表格;不引入原始 `<script>`/内联 HTML |
|
||||
| T-10-11 | Spoofing | 外链 | low | mitigate | 本组不引入任何外链 |
|
||||
| T-10-12 | Information Disclosure | 正文示例 | low | mitigate | 只用源码已公开接口/路径;不写密钥、账号、内部地址 |
|
||||
| T-10-SC | Tampering | npm/pip/cargo installs | low | accept | 本阶段不安装任何包,无供应链安装面 |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- 计划级构建门禁:`cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"` 通过(组内互链与回指基础组/概念组链接均指向已写就页面,`combat-overview` 的向前对照表目标在本计划末尾已全部存在)。
|
||||
- 结构门禁:9 文件均 kebab-case、CRLF、单 H1。
|
||||
- 内容门禁(人工,随 D-09):D-33..D-41 要点齐全;N-1/N-2/N-3/N-7 相关篇目留余地、不臆造已内置;接口名与源码一致。
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- 9 篇战斗文档落位且构建通过。
|
||||
- 每篇覆盖对应 D-3x 全部要点;`combat-overview` 先于子系统文档且末尾对照表链接全部解析。
|
||||
- 未内置/待补齐项按接口讲、留余地;无元叙述;无新增外链。
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/10-docs-restructure/10-04-SUMMARY.md` when done
|
||||
</output>
|
||||
125
.planning/phases/10-docs-restructure/10-05-PLAN.md
Normal file
125
.planning/phases/10-docs-restructure/10-05-PLAN.md
Normal file
@ -0,0 +1,125 @@
|
||||
---
|
||||
phase: 10-docs-restructure
|
||||
plan: 05
|
||||
type: execute
|
||||
wave: 5
|
||||
depends_on: [10-04]
|
||||
files_modified:
|
||||
- docs/intermediate/events.md
|
||||
- docs/intermediate/replay-commands.md
|
||||
- docs/intermediate/data-plugins.md
|
||||
autonomous: false
|
||||
requirements: []
|
||||
user_setup: []
|
||||
estimate:
|
||||
tokens: 22000
|
||||
raw_tokens: 15000
|
||||
tasks: 1
|
||||
confidence: low
|
||||
must_haves:
|
||||
truths:
|
||||
- "3 篇「其他」文档存在且为 kebab-case、CRLF、单 H1"
|
||||
- "`events` 只讲如何自定义新事件(内建函数),不讲原理、不列内建全量;含自定义示例「设置 flag」「勇士回血」;编辑器识别方式留余地"
|
||||
- "`replay-commands` 讲核心原则「玩家直接产生、会影响最终成绩的行为必须计入录像」+ 主动/被动录像 + `@shouldReplay`/`@ignoreReplay` 的 begin/end 检测;**不给示例**"
|
||||
- "`data-plugins` 讲 `IDataPluginDefine` 与 awake/initialize/afterLoad 时机次序、注册在 `src/data/plugin/list.ts`;示例为占位/待提供"
|
||||
artifacts:
|
||||
- "docs/intermediate/events.md"
|
||||
- "docs/intermediate/replay-commands.md"
|
||||
- "docs/intermediate/data-plugins.md"
|
||||
key_links:
|
||||
- "本组可回指已写就的基础/战斗页面(如事件示例涉及 flag → `./flags.md`;插件涉及接口分层);不链接尚未写就的页面"
|
||||
- "D-43:本页不给录像示例;后续其它教程引入自定义录像时链接到本页"
|
||||
- "N-4/N-5/N-6:插件示例占位、内建事件仅 7 个、事件编辑器识别未设计完 —— 按实际情况留余地"
|
||||
---
|
||||
|
||||
<objective>
|
||||
编写「其他」组 3 篇:`events`、`replay-commands`、`data-plugins`。
|
||||
|
||||
Purpose: 覆盖中级作者会遇到的另外三类扩展点——自定义事件内建函数、自定义录像指令、数据插件。
|
||||
Output: 3 个新 markdown 文件。
|
||||
</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/phases/10-docs-restructure/10-CONTEXT.md
|
||||
@.planning/phases/10-docs-restructure/10-RESEARCH.md
|
||||
@.planning/phases/10-docs-restructure/10-PATTERNS.md
|
||||
@docs/guide/implements/special.md
|
||||
@docs/dev/replay/replay-system.md
|
||||
|
||||
**写作约定与前置:**
|
||||
- 骨架照 Analog C(`special.md`);`replay-commands` 的组织方式可借 `docs/dev/replay/replay-system.md:29-40` 的「核心概念定义」分节写法,但**不沿用**其「每节都是 `#`」风格(本批用单 H1 + `##`)。
|
||||
- 代码块接口名/字段按 10-RESEARCH「其他」表 `file:line` 逐字核对(RESEARCH Pitfall 5)。
|
||||
- kebab-case、CRLF、单 H1、无元叙述(D-16);跳转链接 2–5 处/篇。
|
||||
- **N-4**:`data-plugins` 示例占位/待提供(不用商店插件,D-44/D-19)。**N-5**:内建事件仅 7 个。**N-6**:事件编辑器识别方式未设计完,文档留余地。
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking-human">
|
||||
<name>Task 0: 向用户汇报本组计划并等待「可以执行」</name>
|
||||
<action>向用户汇报:**要做什么**(编写 3 篇「其他」文档:`events`/`replay-commands`/`data-plugins`)、**为什么**(覆盖自定义事件、自定义录像、数据插件三类扩展点)、**大致怎么做**(逐篇按 D-42..D-44 与 10-RESEARCH「其他」表核对后落笔;插件示例按 D-19 写为占位待提供)、**影响范围**(仅新增 3 个 `docs/intermediate/*.md`,不改生产代码与既有文档)。停下等待用户明确回复「可以执行」四个字;未收到前不得写任何文件。 </action>
|
||||
<what-built>本计划内容:编写「其他」组 3 篇中级教程 `events` / `replay-commands` / `data-plugins`(仅新增 `docs/intermediate/*.md`)。</what-built>
|
||||
<how-to-verify>阅读上面的「要做什么 / 为什么 / 大致怎么做 / 影响范围」四段,确认范围与做法无异议(含插件示例占位的说明)。</how-to-verify>
|
||||
<resume-signal>回复「可以执行」以继续;其它回复视为未批准,本计划停在此处。</resume-signal>
|
||||
<verify>
|
||||
<human-check>用户已回复「可以执行」。</human-check>
|
||||
</verify>
|
||||
<done>用户回复「可以执行」。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: 编写 events、replay-commands、data-plugins</name>
|
||||
<files>docs/intermediate/events.md, docs/intermediate/replay-commands.md, docs/intermediate/data-plugins.md</files>
|
||||
<behavior>
|
||||
- `events`:只讲如何自定义新事件(内建函数),不讲原理、不列内建全量;`BuiltInFunction`(`name` + `func(param, env)`);`IBlockEventEnv` 常用字段(其余指向 API);参数接口在 `types.ts`;注册在 `createEventRegistrations()`;内置示例导读(仅少量);自定义示例「设置 flag」「勇士回血」;编辑器识别方式未设计完 → 留余地。
|
||||
- `replay-commands`:录像系统用途 + 核心原则「玩家直接产生、会影响最终成绩的行为必须计入录像」并解释其含义;如何新增自定义录像需改 `packages-user` 下的引擎内容;主动录像 vs 被动录像(`ReplayCommandType.Active`/`Passive`);`@shouldReplay`/`@ignoreReplay` 的功能与 begin/end 区间检测;**不给示例**(后续其它教程引入时链接过来)。
|
||||
- `data-plugins`:插件是强拓展系统,中级只讲基础(高级教程详解其工作原理);`IDataPluginDefine`(`id`/`dependencies`/`awake`/`initialize`/`afterLoad`);时机次序 `awake`(装配)→ `initialize`(加载前)→ `afterLoad`(加载后);注册在 `src/data/plugin/list.ts` 的 `dataPlugins`;`state.addSaveableContent`;示例**占位/待提供**,并写明「是否纳入本中级篇取决于示例难度」。
|
||||
</behavior>
|
||||
<action>按 D-42/D-43/D-44 撰写。`events`:素材 `src/data/event/map.ts:1-78`、`hero.ts:1-41`、`event.ts:1-54`(内建实现)、`src/data/event/types.ts:1-66`(参数接口)、`src/data/event/registrations.ts:9-24`(`createEventRegistrations()`,仅 7 个:setBlock/moveBlock/removeBlock/moveHero/stepHero/insertEvents/insertEvent —— 只导读少量、不列全量)、`src/data/event/utils.ts:1-30`、`BuiltInFunction` 见 `packages/anon-tokyo/src/interpreter.ts:11-18`、`IBlockEventEnv`/`IBlockEventParam` 见 `packages-user/data-system/src/event/types.ts:25-49`。示例「设置 flag」「勇士回血」为自写内嵌代码;「设置 flag」可回指 `./flags.md`。编辑器识别方式未设计完(N-6)→ 留余地、不写死规则。`replay-commands`:素材 `src/data/replay/commands.ts:14-225`(命令实现)、`src/data/replay/initialize.ts:15-35`(注册)、`packages-user/data-common/src/replay/types.ts:5-22`(`ReplayCode`)、:24-29(`ReplayCommandType`)、:31-38(`ReplayCommandResult`)、:62-78(`IReplayCommand`)、:42-49(`IReplayStepHandler`)、`packages-user/data-common/src/replay/func.ts:62-111`(`beginReplaySafetyCollection`/`endReplaySafetyCollection` 检测区间)、:149-194(`@shouldReplay`/`@ignoreReplay` 装饰器本体)。**不给示例**(D-43)。`data-plugins`:素材 `packages-user/data-state/src/types.ts:10-81`(`IDataPluginDefine`/`IDataPlugin`/`PluginStatus`/`ICoreStateConfig.dataPlugins`)、`data-state/src/core.ts:160-225`(`awake`/`initialize`/`afterLoad` 次序)、:231-235(`load()`)、`addSaveableContent`:241-248、`data-state/src/plugin.ts:32-121`(`orderPlugins` 依赖排序)、`src/data/plugin/list.ts:1-5`(注册列表)、参考实现 `src/data/plugin/shop/plugin.ts:7-32`(仅内部参考,不作为示例,D-44)、主插件 `src/data/initialize.ts:17-85`。示例章节按 N-4 写为占位/待提供。遵守写作约定。</action>
|
||||
<verify>
|
||||
<automated>$ErrorActionPreference='Stop'; $files=@('docs/intermediate/events.md','docs/intermediate/replay-commands.md','docs/intermediate/data-plugins.md'); foreach($p in $files){ if(-not(Test-Path $p)){ Write-Error "MISSING $p" }; $raw=[IO.File]::ReadAllText((Resolve-Path $p)); if($raw -match "(?<!`r)`n"){ Write-Error "LF-ONLY $p" }; if(([regex]::Matches($raw,'(?m)^# ')).Count -ne 1){ Write-Error "H1-COUNT $p" } }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/events.md')) -notmatch 'createEventRegistrations')){ Write-Error "NO-REGISTRATION events" }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/replay-commands.md')) -notmatch '@shouldReplay')){ Write-Error "NO-DECORATOR replay-commands" }; if(([IO.File]::ReadAllText((Resolve-Path 'docs/intermediate/data-plugins.md')) -notmatch 'afterLoad')){ Write-Error "NO-LIFECYCLE data-plugins" }; Write-Output 'STATIC-OK'</automated>
|
||||
<fails_when>non-zero exit, or output contains "MISSING", "LF-ONLY", "H1-COUNT", "NO-REGISTRATION", "NO-DECORATOR", or "NO-LIFECYCLE"</fails_when>
|
||||
</verify>
|
||||
<done>三文件存在、CRLF、单 H1;`events` 含 `createEventRegistrations` 与两个自定义示例;`replay-commands` 含核心原则与 `@shouldReplay`/`@ignoreReplay` 且无示例;`data-plugins` 含 `afterLoad` 时机与占位示例。</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| 构建期 markdown → 静态站点 | 正文由构建期静态渲染,无运行时输入 |
|
||||
| 站点 → 浏览器读者 | 外链是唯一对外指向面(本篇不引入外链) |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|----------|-------------|-----------------|
|
||||
| T-10-13 | Tampering / XSS | 3 篇 markdown 正文 | low | mitigate | 只写文本、代码块、表格;不引入原始 `<script>`/内联 HTML |
|
||||
| T-10-14 | Spoofing | 外链 | low | mitigate | 本组不引入任何外链 |
|
||||
| T-10-15 | Information Disclosure | 正文示例 | low | mitigate | 只用源码已公开接口/路径;不写密钥、账号 |
|
||||
| T-10-SC | Tampering | npm/pip/cargo installs | low | accept | 本阶段不安装任何包,无供应链安装面 |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- 计划级构建门禁:`cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"` 通过(回指已写就页面,构建可独立通过)。
|
||||
- 结构门禁:3 文件均 kebab-case、CRLF、单 H1。
|
||||
- 内容门禁(人工,随 D-09):D-42..D-44 要点齐全;N-4/N-5/N-6 相关处留余地。
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- 3 篇「其他」文档落位且构建通过。
|
||||
- 每篇覆盖对应 D-4x 全部要点;`replay-commands` 不给示例;`data-plugins` 示例为占位。
|
||||
- 无元叙述;无新增外链。
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/10-docs-restructure/10-05-SUMMARY.md` when done
|
||||
</output>
|
||||
123
.planning/phases/10-docs-restructure/10-06-PLAN.md
Normal file
123
.planning/phases/10-docs-restructure/10-06-PLAN.md
Normal file
@ -0,0 +1,123 @@
|
||||
---
|
||||
phase: 10-docs-restructure
|
||||
plan: 06
|
||||
type: execute
|
||||
wave: 6
|
||||
depends_on: [10-05]
|
||||
files_modified: []
|
||||
autonomous: false
|
||||
requirements: []
|
||||
user_setup: []
|
||||
estimate:
|
||||
tokens: 16000
|
||||
raw_tokens: 11000
|
||||
tasks: 2
|
||||
confidence: low
|
||||
must_haves:
|
||||
truths:
|
||||
- "`docs/intermediate/` 下恰有 D-20 的 24 个 kebab-case markdown 文件"
|
||||
- "`docs/.vitepress/config.ts` 的 `'/intermediate/'` 侧边栏含 4 分组、24 条 link,顺序为 4/8/9/3 且与 24 个文件名一一对应"
|
||||
- "`docs:build` 通过且无 dead link;构建产物出现在 `public/_docs`"
|
||||
- "站内链接全部可解析;唯一外链为 D-23 指定的 `h5mota.com` 论坛链接"
|
||||
- "用户完成人工审阅(D-09:内容正确、可读、无元叙述)"
|
||||
artifacts:
|
||||
- ".planning/phases/10-docs-restructure/10-06-SUMMARY.md"
|
||||
key_links:
|
||||
- "24 篇正文 ⇄ config.ts 的 24 条 sidebar link(一一对应,缺一即人工审阅不通过)"
|
||||
- "构建期 VitePress 链接解析覆盖所有正文互链(RESEARCH A3)"
|
||||
---
|
||||
|
||||
<objective>
|
||||
全批验收:确认 24 篇中级教程全部落位、站点注册完整、构建通过、链接有效,并把站点交付用户做 D-09 人工审阅。
|
||||
|
||||
Purpose: 满足 D-09 验收标准(用户人工审阅 + 链接全部有效 + 构建通过)的机器可核部分,并为人工审阅提供明确入口。
|
||||
Output: 验收摘要 `10-06-SUMMARY.md`;站点构建产物 `public/_docs`(gitignored)。
|
||||
</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/phases/10-docs-restructure/10-CONTEXT.md
|
||||
@.planning/phases/10-docs-restructure/10-RESEARCH.md
|
||||
@.planning/phases/10-docs-restructure/10-VALIDATION.md
|
||||
@docs/.vitepress/config.ts
|
||||
|
||||
**约定:** 本计划只做验收,不新增/修改任何文档或配置;如发现缺页或链接错误,只报告并回到对应写作计划修复,不在本计划内擅自补写。
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking-human">
|
||||
<name>Task 0: 向用户汇报本验收计划并等待「可以执行」</name>
|
||||
<action>向用户汇报:**要做什么**(对 24 篇中级教程做全批判收:文件齐全、注册完整、构建通过、链接有效,并交付人工审阅)、**为什么**(D-09 验收 = 人工审阅 + 链接有效 + 构建通过)、**大致怎么做**(跑全量构建 + 静态核对 24 文件与 24 条 sidebar、单 H1/CRLF、外链白名单,然后请用户审阅构建产物)、**影响范围**(不改任何文件,仅生成 SUMMARY 与 gitignored 构建产物)。停下等待用户明确回复「可以执行」四个字;未收到前不得执行任何检查。 </action>
|
||||
<what-built>本计划内容:对 24 篇中级教程做全批验收(文件齐全、注册完整、构建通过、链接有效)并交付人工审阅。</what-built>
|
||||
<how-to-verify>阅读上面的「要做什么 / 为什么 / 大致怎么做 / 影响范围」四段,确认验收范围与做法无异议。</how-to-verify>
|
||||
<resume-signal>回复「可以执行」以继续;其它回复视为未批准,本计划停在此处。</resume-signal>
|
||||
<verify>
|
||||
<human-check>用户已回复「可以执行」。</human-check>
|
||||
</verify>
|
||||
<done>用户回复「可以执行」。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: 全量构建 + 静态验收核对</name>
|
||||
<files>docs/.vitepress/config.ts</files>
|
||||
<action>先跑全量构建,再做静态核对。(1) 构建:`cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"`,确认打印 build complete、无 `dead link(s) found.`、无 `Failed to resolve import`,且产物目录 `public/_docs` 已生成。(2) 静态核对 24 个文件:`docs/intermediate/` 下恰存在 D-20 的 24 个文件名(`data-vs-render`/`src-tour`/`code-basics`/`hooks`/`data-state-overview`/`hero-attribute`/`hero-items`/`hero-equipment`/`hero-location`/`map-structure`/`map-tiles`/`flags`/`combat-overview`/`enemy-specials`/`enemy-aura`/`enemy-query`/`enemy-final`/`enemy-calculator`/`enemy-map-damage`/`enemy-combat-script`/`enemy-status-hooks`/`events`/`replay-commands`/`data-plugins`,各加 `.md`);每个文件 CRLF、单 H1。(3) 核对 `config.ts` 的 `'/intermediate/'` 键恰含 24 条 `link: '/intermediate/<名>'`,且与 24 个文件名一一对应。(4) 外链白名单:全 24 篇内出现的外链仅为 `https://h5mota.com/bbs/thread/?tid=1018&p=3#p41`(若文本中还出现其它 `http`,逐一报告供用户判断,不擅自删改)。发现任何缺页/错链只报告,不擅自补写。</action>
|
||||
<verify>
|
||||
<automated>cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"; if (-not $?) { exit 1 }; $names=@('data-vs-render','src-tour','code-basics','hooks','data-state-overview','hero-attribute','hero-items','hero-equipment','hero-location','map-structure','map-tiles','flags','combat-overview','enemy-specials','enemy-aura','enemy-query','enemy-final','enemy-calculator','enemy-map-damage','enemy-combat-script','enemy-status-hooks','events','replay-commands','data-plugins'); $missing=@(); foreach($n in $names){ $p="docs/intermediate/$n.md"; if(-not(Test-Path $p)){ $missing+=$p; continue }; $raw=[IO.File]::ReadAllText((Resolve-Path $p)); if($raw -match "(?<!`r)`n"){ Write-Error "LF-ONLY $p" }; if(([regex]::Matches($raw,'(?m)^# ')).Count -ne 1){ Write-Error "H1-COUNT $p" } }; if($missing.Count -gt 0){ Write-Error ("MISSING: " + ($missing -join ',')) }; $cfg=[IO.File]::ReadAllText((Resolve-Path 'docs/.vitepress/config.ts')); $links=([regex]::Matches($cfg,"link:\s*'/intermediate/")).Count; if($links -ne 24){ Write-Error "SIDEBAR-COUNT $links" }; $ext=@(); foreach($n in $names){ $p="docs/intermediate/$n.md"; if(-not(Test-Path $p)){continue}; $m=[regex]::Matches([IO.File]::ReadAllText((Resolve-Path $p)),'https?://[^\s\)]+'); foreach($x in $m){ if($x.Value -notmatch '^https://h5mota\.com/bbs/thread/\?tid=1018'){ $ext+=$x.Value } } }; if($ext.Count -gt 0){ Write-Error ("EXT-LINK-NOT-APPROVED: " + (($ext | Select-Object -Unique) -join ',')) }; Write-Output 'ACCEPTANCE-OK'</automated>
|
||||
<fails_when>non-zero exit, or output contains "dead link(s) found.", "Failed to resolve import", "MISSING:", "LF-ONLY", "H1-COUNT", "SIDEBAR-COUNT", or "EXT-LINK-NOT-APPROVED"; or output lacks "ACCEPTANCE-OK"</fails_when>
|
||||
</verify>
|
||||
<done>构建通过且产物生成;24 个文件齐全、CRLF、单 H1;sidebar 恰 24 条并与文件一一对应;无非白名单外链;输出 ACCEPTANCE-OK。</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking-human">
|
||||
<name>Task 2: 交付构建产物供用户人工审阅(D-09)</name>
|
||||
<action>向用户交付验收结果并请求 D-09 人工审阅。提供审阅方式:本地 `cmd /c "pnpm docs:preview"` 预览 `public/_docs`,或让用户自行浏览构建产物;并附上 Task 1 的核对结果摘要(文件数、sidebar 条目数、外链白名单命中、构建结论)。请用户核对三项:**内容正确且可读**、**侧边栏分组与顺序符合 4/8/9/3**、**无元叙述(D-16)**。等待用户确认通过;若用户指出缺页/错链/需修改项,记录并转交对应写作计划(10-02..10-05)修复,不在本计划内擅自补写。本任务与 `/gsd-verify-work 10` 的收尾互为补充,不替代阶段级验证。 </action>
|
||||
<what-built>已构建的站点产物 `public/_docs`(含 24 篇中级教程与注册好的侧边栏/导航)与 Task 1 的验收结果摘要。</what-built>
|
||||
<how-to-verify>本地运行 `cmd /c "pnpm docs:preview"` 预览,或浏览构建产物;核对三项:内容正确且可读、侧边栏分组与顺序符合 4/8/9/3、无元叙述。如有缺页/错链/修改项请指出。</how-to-verify>
|
||||
<resume-signal>回复「通过」表示 D-09 人工审阅通过;如给出修改意见,请一并说明,待修正对应计划后再回复「通过」。其它回复视为未通过。</resume-signal>
|
||||
<verify>
|
||||
<human-check>用户已完成审阅并对 24 篇内容、侧边栏结构、链接给出通过或具体修改意见。</human-check>
|
||||
</verify>
|
||||
<done>用户确认 D-09 人工审阅通过(或产出的修改意见已登记并转交对应计划)。</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| 构建期 markdown → 静态站点 | 构建期静态渲染,无运行时输入 |
|
||||
| 站点 → 浏览器读者 | 外链是唯一对外指向面 |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|----------|-------------|-----------------|
|
||||
| T-10-16 | Tampering / XSS | 构建产物 | low | mitigate | 构建为纯静态 markdown 渲染;无原始 `<script>` 注入 |
|
||||
| T-10-17 | Spoofing | 外链 | low | mitigate | Task 1 断言全批唯一外链为 D-23 批准的 `h5mota.com` 链接 |
|
||||
| T-10-18 | Information Disclosure | 构建产物/摘要 | low | mitigate | 构建产物 gitignored;正文不含密钥/账号 |
|
||||
| T-10-SC | Tampering | npm/pip/cargo installs | low | accept | 本阶段不安装任何包,无供应链安装面 |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- 构建门禁:`cmd /c "pnpm exec tsx docs/.vitepress/init.ts && pnpm docs:build"` 通过。
|
||||
- 完整性门禁:24 文件齐全 + sidebar 24 条 + 文件/条目一一对应。
|
||||
- 外链门禁:全批唯一外链为 D-23 批准的链接。
|
||||
- 人工门禁:用户完成 D-09 审阅。
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- D-09 三项(人工审阅 + 链接有效 + 构建通过)全部满足。
|
||||
- 24 篇中级教程全部落位、注册、可构建、可预览。
|
||||
- 无越界改动(仅 `docs/intermediate/*` 与 `docs/.vitepress/config.ts`)。
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/10-docs-restructure/10-06-SUMMARY.md` when done
|
||||
</output>
|
||||
455
.planning/phases/10-docs-restructure/10-PATTERNS.md
Normal file
455
.planning/phases/10-docs-restructure/10-PATTERNS.md
Normal file
@ -0,0 +1,455 @@
|
||||
# Phase 10: 文档重构 - Pattern Map
|
||||
|
||||
**Mapped:** 2026-10-16
|
||||
**Files analyzed:** 25(24 篇 `docs/intermediate/*.md` 新增 + `docs/.vitepress/config.ts` 修改)
|
||||
**Analogs found:** 25 / 25
|
||||
|
||||
> 本阶段为**纯文档产出**。这里的「Pattern」指 **markdown 页面骨架 / VitePress 语法 / config 条目形状**,analog 是仓库现存的文档文件与站点配置。所有引用均为 `file:line`,且经 `git ls-files` 核实为**已跟踪源码**(非 gitignore 镜像)。
|
||||
|
||||
---
|
||||
|
||||
## File Classification
|
||||
|
||||
| New/Modified File | Role | Data Flow | Closest Analog | Match Quality |
|
||||
|-------------------|------|-----------|----------------|---------------|
|
||||
| `docs/.vitepress/config.ts` | config(站点配置) | navigation(nav + sidebar 静态数组) | 自身(就地编辑);形状参照同文件 `53-156` | exact(edit-in-place) |
|
||||
| `docs/intermediate/data-vs-render.md` | doc-page(概念+图) | content/diagram | `docs/guide/system.md:55-71`(渲染端与数据端通信) | exact(同主题) |
|
||||
| `docs/intermediate/src-tour.md` | doc-page(概念+目录导览) | content/overview+table | `docs/guide/implements/index.md:1-8` + `docs/guide/coding.md:9-21`(目录树 mermaid) | role-match |
|
||||
| `docs/intermediate/code-basics.md` | doc-page(概念+教程) | content/tutorial | `docs/guide/system.md:160-191`(ES6 模块化) | role-match |
|
||||
| `docs/intermediate/hooks.md` | doc-page(概念+对照表) | content/reference+codesample | `docs/guide/system.md:73-86`(钩子示例) | role-match |
|
||||
| `docs/intermediate/data-state-overview.md` | doc-page(总览+表) | content/overview+table | `docs/guide/implements/index.md:1-42` + `docs/api/index.md:1-31` | role-match |
|
||||
| `docs/intermediate/hero-attribute.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md` | role-match |
|
||||
| `docs/intermediate/hero-items.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md`;主题 `docs/dev/hero/hero-items.md` | role-match |
|
||||
| `docs/intermediate/hero-equipment.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md`;主题 `docs/dev/hero/hero-equipment.md` | role-match |
|
||||
| `docs/intermediate/hero-location.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md` | role-match |
|
||||
| `docs/intermediate/map-structure.md` | doc-page(结构说明+表) | content/overview+table | `docs/guide/implements/index.md` | role-match |
|
||||
| `docs/intermediate/map-tiles.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md`;主题 `docs/dev/store/tile-store.md` | role-match |
|
||||
| `docs/intermediate/flags.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md` | role-match |
|
||||
| `docs/intermediate/combat-overview.md` | doc-page(流程+图+对照表) | content/diagram+table | `docs/guide/coding.md:9-21`(mermaid)+ `docs/dev/enemy/enemy-combat-flow.md:1-27` | role-match |
|
||||
| `docs/intermediate/enemy-specials.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md`(**同主题**) | exact |
|
||||
| `docs/intermediate/enemy-aura.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md:163-265`(拓展-光环属性,**同主题**) | exact |
|
||||
| `docs/intermediate/enemy-query.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md`(骨架) | no-subject-analog(新功能) |
|
||||
| `docs/intermediate/enemy-final.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md`(骨架) | no-subject-analog |
|
||||
| `docs/intermediate/enemy-calculator.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md:27-119`(伤害计算,**同主题**) | exact |
|
||||
| `docs/intermediate/enemy-map-damage.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md:121-161`(地图伤害,**同主题**) | exact |
|
||||
| `docs/intermediate/enemy-combat-script.md` | doc-page(how-to+代码) | content/code-heavy | `docs/dev/enemy/enemy-combat-flow.md` + `special.md` 骨架 | role-match |
|
||||
| `docs/intermediate/enemy-status-hooks.md` | doc-page(how-to+代码) | content/code-heavy | `docs/dev/enemy/enemy-combat-flow.md` + `special.md` 骨架 | role-match |
|
||||
| `docs/intermediate/events.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md`(骨架) | role-match |
|
||||
| `docs/intermediate/replay-commands.md` | doc-page(原则+说明) | content/reference | `docs/dev/replay/replay-system.md:1-40`(概念定义结构) | role-match |
|
||||
| `docs/intermediate/data-plugins.md` | doc-page(how-to+代码) | content/code-heavy | `docs/guide/implements/special.md`(骨架) | role-match |
|
||||
|
||||
**说明:** `enemy-specials` / `enemy-aura` / `enemy-calculator` / `enemy-map-damage` 与既有 `docs/guide/implements/special.md` 是**同一主题**(特殊属性 / 光环 / 伤害计算 / 地图伤害),是最强 analog;但该旧文档对应**旧接口**,本批要重写为新接口,故**只借结构、不抄接口名**。
|
||||
|
||||
---
|
||||
|
||||
## Pattern Assignments
|
||||
|
||||
### 通用页面骨架(24 篇全部适用)
|
||||
|
||||
**Analog A:`docs/guide/quick-start.md`(简洁页 + 相对链接 + mermaid + `:::info`)**
|
||||
|
||||
**页面开头**(`docs/guide/quick-start.md:1-7`)——单 `#` 一级标题 + 引言 + `##` 小节 + 相对链接:
|
||||
```md
|
||||
# 快速开始
|
||||
|
||||
本章节主要帮助你快速上手 2.B 样板。
|
||||
|
||||
## 常见需求实现指南
|
||||
|
||||
参考[此文档](./implements/index.md)
|
||||
```
|
||||
|
||||
**相对链接写法**(`docs/guide/quick-start.md:7`、`docs/guide/system.md:46`):
|
||||
- 同目录:`[此文档](./implements/index.md)`
|
||||
- 带锚点:`[系统说明](./system.md#渲染端与数据端通信)`(`docs/guide/coding.md:46` 亦同)
|
||||
- D-17 要求「适当链接、不要过多」——每篇 2–5 处即可。
|
||||
|
||||
**mermaid 代码块**(`docs/guide/quick-start.md:27-31`):
|
||||
````md
|
||||
```mermaid
|
||||
graph TD
|
||||
A[下载安装包] --> B[安装启动服务] --> C[运行启动服务] --> D[选择样板文件夹] --> E[安装依赖] --> F[启动服务器];
|
||||
F -- 造完塔 --> G[构建游戏] --> H[发布或更新游戏]
|
||||
```
|
||||
````
|
||||
|
||||
**提示容器**(`docs/guide/quick-start.md:42-44`;`docs/guide/system.md:152-154` 为 `::: warning`):
|
||||
```md
|
||||
:::info
|
||||
由于 `opus` 格式的音频……
|
||||
:::
|
||||
```
|
||||
|
||||
**Analog B:`docs/guide/system.md`(front matter + 警示容器 + 外链)**
|
||||
|
||||
**front matter(可选)**(`docs/guide/system.md:1-3`、`docs/api/index.md:1-3`):
|
||||
```md
|
||||
---
|
||||
lang: zh-CN
|
||||
---
|
||||
|
||||
# 系统说明
|
||||
```
|
||||
> 现有多数 `docs/guide/*` 无 front matter,仅首页(`docs/index.md:1-27`,`layout: home`)与部分页有。新增 24 篇**不强制**加 front matter;如需中文显式声明可照 `system.md:1-3`。
|
||||
|
||||
**警示容器**(`docs/guide/system.md:152-154`):
|
||||
```md
|
||||
::: warning
|
||||
**注意**,在渲染端重写的函数在录像验证中将无效,因为录像验证不会执行任何渲染端内容!
|
||||
:::
|
||||
```
|
||||
|
||||
**外链**(`docs/guide/system.md:189`、`docs/guide/coding.md:42`):
|
||||
```md
|
||||
更多模块化语法内容请查看[这个文档](https://h5mota.com/bbs/thread/?tid=1018&p=3#p33)
|
||||
```
|
||||
> D-23 指定 `code-basics` 结尾须给 `https://h5mota.com/bbs/thread/?tid=1018&p=3#p41`(同 `coding.md:42` 的链接)。
|
||||
|
||||
**Analog C:`docs/guide/implements/special.md`(代码重型 how-to:`// [!code ++]` 高亮、行号高亮、`拓展-x` 小节)**
|
||||
|
||||
**代码行高亮**(`docs/guide/implements/special.md:13-25`,`// [!code ++]` 逐行标记新增行):
|
||||
```ts
|
||||
export const specials: SpecialDeclaration[] = [
|
||||
// ... 原有属性定义
|
||||
|
||||
// 自定义属性
|
||||
{
|
||||
code: 30, // 特殊属性代码,用于 hasSpecial 判断 // [!code ++]
|
||||
name: '自定义特殊属性', // 特殊属性名称 // [!code ++]
|
||||
desc: '勇士对该怪物造成的伤害减少 10%', // 特殊属性描述 // [!code ++]
|
||||
color: '#ffd' // 特殊属性显示的颜色 // [!code ++]
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
**区块行号高亮**(`special.md:54` 的 ```` ```js {4-10} ````;`special.md:250` 的 ```` ```ts {2-9} ````):
|
||||
````md
|
||||
```js {4-10}
|
||||
"enemys": {
|
||||
...
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
**「打开文件→在最后/搜索某函数→添加代码」的 how-to 叙述**(`special.md:11`、`:29`、`:123`):
|
||||
> 打开 `packages-user/data-state/src/enemy/special.ts`,在最后添加一个属性定义:
|
||||
> ……直接 `ctrl+F` 搜索 `calMapDamage` 即可找到……
|
||||
|
||||
**代码块语言标注**:TS 用 ```` ```ts ````(`special.md:13`)、JSONC 用 ```` ```js ````(`special.md:54`)、shell 用 ```` ```bash ````。
|
||||
|
||||
**❌ 不要照搬的:** `special.md:46,121,163` 的 `## 拓展-xxx` 小节命名是旧文档遗留风格;新文档按各自 D-2x 内容组织标题即可。**禁用**任何「渲染端教程后续再讲 / 留到高级教程」式元叙述(D-16,RESEARCH Pitfall 4)。
|
||||
|
||||
---
|
||||
|
||||
### `docs/.vitepress/config.ts`(config, navigation)
|
||||
|
||||
**Analog:** 自身(edit-in-place),形状参照同文件既有 `nav`/`sidebar`。
|
||||
|
||||
**现有 `nav`(待新增一条,不改旧条目)**(`docs/.vitepress/config.ts:53-58`):
|
||||
```ts
|
||||
nav: [
|
||||
{ text: '主页', link: '/' },
|
||||
{ text: '指南', link: '/guide/quick-start' },
|
||||
{ text: 'API', link: '/api/' },
|
||||
{ text: '错误代码', link: '/logger/' }
|
||||
],
|
||||
```
|
||||
|
||||
**现有 `sidebar` 顶层结构(按路径前缀分键)**(`docs/.vitepress/config.ts:59-156`):
|
||||
- `'/guide/'`(`60-127`)
|
||||
- `'/logger/'`(`128-149`)
|
||||
- `'/api/'`(`150-155`,`items: api`,`api` 来自 `import api from './apiSidebar'`,`config.ts:3`)
|
||||
|
||||
**嵌套分组写法(本批新键照此形状)**(`docs/.vitepress/config.ts:70-86`):
|
||||
```ts
|
||||
{
|
||||
text: 'UI 系统',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: '快速浏览', link: '/guide/ui/' },
|
||||
{ text: '编写 UI', link: '/guide/ui/ui' },
|
||||
...
|
||||
]
|
||||
},
|
||||
```
|
||||
|
||||
**必须新增的形状(示意;`text` 显示名须先经用户批准,D-13)**(参照 `config.ts:59-156` 结构;链接写法与 `config.ts:64-124` 一致,用绝对路径且不带 `.md`):
|
||||
```ts
|
||||
sidebar: {
|
||||
'/intermediate/': [
|
||||
{
|
||||
text: '中级教程',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
text: '概念与导航',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: '数据端与渲染端', link: '/intermediate/data-vs-render' }
|
||||
// …按 D-20 的 4 组顺序
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
'/guide/': [ /* 原样保留,禁止改动 */ ],
|
||||
'/logger/': [ /* 原样保留,禁止改动 */ ],
|
||||
'/api/': [{ text: 'API 列表', items: api }]
|
||||
}
|
||||
```
|
||||
|
||||
**硬约束:**
|
||||
- 只**新增** `nav` 一条 + `sidebar['/intermediate/']` 键;**禁止**改动/删除 `'/guide/'`、`'/logger/'`、`'/api/'` 及既有 `nav` 条目(D-14 / RESEARCH Pitfall 3)。
|
||||
- **不要**触碰 `docs/.vitepress/api.ts`、`init.ts`、`apiSidebar.ts`(后者 gitignored 且会被覆盖,`api.ts:71`)。
|
||||
- 24 条链接必须全部挂上,否则页面「写了但看不见」(RESEARCH Pitfall 1 / D-09 人工审阅)。
|
||||
|
||||
---
|
||||
|
||||
### 概念与导航组(4 篇)
|
||||
|
||||
#### `data-vs-render.md`(doc-page, content/diagram)
|
||||
|
||||
**Analog(结构与主题):** `docs/guide/system.md:55-71`(「渲染端与数据端通信」——同主题,讲数据端不能引渲染端、录像只跑数据端);`docs/guide/quick-start.md:67-73`(构建分两次打包、录像验证只跑数据端)。
|
||||
|
||||
**可复用图示素材**(`docs/guide/system.md:88-121` 是加载流程图,本页应改为「双端分离」mermaid 图;mermaid 语法照 `quick-start.md:27-31`):
|
||||
````md
|
||||
```mermaid
|
||||
graph LR
|
||||
A[数据端 src/data<br/>负责算] -->|录像验证只跑这里| A
|
||||
B[渲染端 src/client<br/>负责画]
|
||||
```
|
||||
````
|
||||
> D-21:提两者分别在 `src/data`、`src/client`;重点讲录像验证;**不提**「渲染端不能反向推送」(留高级);禁止「后续再讲」。
|
||||
|
||||
#### `src-tour.md`(doc-page, content/overview+table)
|
||||
|
||||
**Analog:** `docs/guide/coding.md:9-21`(`packages-user` 目录树 mermaid `graph LR`)+ `docs/guide/implements/index.md:1-8`(「只在某些文件夹写代码」的清单)。
|
||||
|
||||
**目录树 mermaid 照抄形状**(`docs/guide/coding.md:9-21`):
|
||||
````md
|
||||
```mermaid
|
||||
graph LR
|
||||
root(package-user)
|
||||
root --> A(client-modules) --> A1(渲染层主要代码)
|
||||
root --> B(data-base) --> B1(数据层底层代码)
|
||||
```
|
||||
````
|
||||
**「该不该改」表**:用 markdown 表格(参照 `docs/api/index.md:7-31` 的清单式表格/列表)。
|
||||
> D-22:详讲 `src/data`/`src/client`/`src/content`/`src/constant.ts`;一句带过 `bootstrap.ts`/`data.ts`/`package.json`/`styles.less`;**不讲** `main.ts`/`App.vue`/`types/`(已弃用)。主题素材见 RESEARCH「24 篇文档的源码入口 · 概念与导航」。
|
||||
|
||||
#### `code-basics.md`(doc-page, content/tutorial)
|
||||
|
||||
**Analog:** `docs/guide/system.md:160-191`(ES6 模块化语法:`import`/`export` 代码块 + 外链)。
|
||||
|
||||
**语法小节代码形状**(`docs/guide/system.md:164-170`):
|
||||
```ts
|
||||
import { Patch } from '@motajs/legacy-common'; // 从样板库中引入接口
|
||||
import { patchMyFunctions } from './override';
|
||||
```
|
||||
**外链**(照 `docs/guide/system.md:189`/`coding.md:42`):
|
||||
```md
|
||||
更多模块化语法内容请查看[这个文档](https://h5mota.com/bbs/thread/?tid=1018&p=3#p33)
|
||||
```
|
||||
> D-23:顺序 ①简明语法 ②模块与引入 ③类型入门;泛型比喻「类型的函数」;`interface` → `implements` 建议但非强制;结尾链接必须是 `https://h5mota.com/bbs/thread/?tid=1018&p=3#p41`。**无源码依赖**(唯一一篇)。
|
||||
|
||||
#### `hooks.md`(doc-page, content/reference+codesample)
|
||||
|
||||
**Analog:** `docs/guide/system.md:73-86`(钩子 `hook.on('afterBattle', ...)` 示例)。
|
||||
|
||||
**钩子示例代码形状**(`docs/guide/system.md:75-85`):
|
||||
```ts
|
||||
import { hook } from '@user/data-base';
|
||||
hook.on('afterBattle', enemy => {
|
||||
console.log('与怪物战斗:', enemy.id);
|
||||
});
|
||||
```
|
||||
**「需求 → 钩子」对照表**:markdown 表格(列 `需求` / `钩子`),照 `data-state-overview` 的表格风格。
|
||||
> D-24:`addHook`/`removeHook`;`hook/initialize.ts` 一笔带过;async 钩子只提哪些是。钩子族清单(`IHeroAttributeHooks` 等)的 `file:line` 见 RESEARCH「概念与导航 · hooks」。**注意**:RESEARCH 给的是**接口定义**(`packages/common/src/hook.ts`、`types.ts`),文中用 `addHook`/`removeHook` 的**顶层接口名**(D-15:只讲顶层常用接口)。
|
||||
|
||||
---
|
||||
|
||||
### 基础接口组(8 篇)
|
||||
|
||||
> 组内 8 篇均为「how-to + 代码」型,统一套用 Analog C(`docs/guide/implements/special.md`)的骨架:`# 标题` → 引言 → `## 小节` → ```` ```ts ```` 代码块 → `// [!code ++]` 标新增行。**代码块内每一处接口名/字段名必须按 RESEARCH 源码入口逐字核对**(RESEARCH Pitfall 5)。
|
||||
|
||||
#### `data-state-overview.md`(doc-page, content/overview+table)
|
||||
|
||||
**Analog:** `docs/guide/implements/index.md:1-8`(「只在这些文件夹写」清单)+ `docs/api/index.md:7-31`(表格/列表总览)。
|
||||
**核心风格:** 一张表列「对象 / 获取方式」,列如 `对象` / `获取方式` / `分层(L0–L3)`。
|
||||
> D-25 给出完整对象清单与 L0–L3 分组;字段来源 `file:line` 见 RESEARCH「基础接口 · data-state-overview」。放在基础接口组最前。
|
||||
|
||||
#### `hero-attribute.md`(doc-page, content/code-heavy)
|
||||
|
||||
**Analog:** `docs/guide/implements/special.md`(how-to 骨架)。
|
||||
**主题素材:** `packages-user/data-base/src/hero/types.ts:104-283`、`.../hero/modifier.ts:42-78`(RESEARCH)。
|
||||
**要点示范代码:** `getModifiableAttribute().add(...)`、`ValueModifier`/`PercentageModifier`、`addModifier(name, modifier, save?)`。
|
||||
> D-26:基础 vs 最终属性、修饰器、`save` 参数语义、「不进存档时由外部系统分配」的提示用 `:::warning` 表达。
|
||||
|
||||
#### `hero-items.md`(doc-page, content/code-heavy)
|
||||
|
||||
**Analog(结构):** `docs/guide/implements/special.md`。**主题(旧设计):** `docs/dev/hero/hero-items.md:1-24`(四类道具 Constant/Consumable/Equipment/Pick 的划分——**只取分类语义**,接口名以新源码为准)。
|
||||
**要点示范代码:** `addItem`、`getItemState`、`iterateItems`、`useItem`、`itemCount`。
|
||||
> D-27:四种类别区分;`Pick` 即捡即用;道具效果属内容层(可调用 `state`、道具数据)。示例:发黄钥匙 / 减道具 / 使用道具。
|
||||
|
||||
#### `hero-equipment.md`(doc-page, content/code-heavy)
|
||||
|
||||
**Analog(结构):** `docs/guide/implements/special.md`。**主题(旧设计):** `docs/dev/hero/hero-equipment.md`。
|
||||
**要点示范代码:** `equip`(含 `autoUnload`)、`unequip`、`getEquipped`、`getEquips`;`IHeroEquipsStore` 的 `add`/`get`/`instancesOf`/`count`。
|
||||
> D-28:以「会用常用接口」为界;`compareEquip` 简单讲;**排序器不讲**(高级)。
|
||||
|
||||
#### `hero-location.md`(doc-page, content/code-heavy)
|
||||
|
||||
**Analog:** `docs/guide/implements/special.md` 骨架。
|
||||
**要点示范代码:** `hero.location.x / .y / .direction`、`hero.getLocation()`、`floorId` / `map`。
|
||||
> D-29:**只讲获取**位置与楼层;移动/切层留高级。
|
||||
|
||||
#### `map-structure.md`(doc-page, content/overview+table)
|
||||
|
||||
**Analog:** `docs/guide/implements/index.md`(结构说明 + 清单)。
|
||||
**要点示范代码:** `maps.getMap(id)` / `getActiveMap()` / `iterateAllMaps()`;`IGameMap.layerList` / `eventLayer` / `tileStore`。
|
||||
> D-30:事件层本质就是个图层,归本篇。接口 `file:line` 见 RESEARCH「基础接口 · map-structure」。
|
||||
|
||||
#### `map-tiles.md`(doc-page, content/code-heavy)
|
||||
|
||||
**Analog(结构):** `docs/guide/implements/special.md`。**主题(旧设计):** `docs/dev/store/tile-store.md`。
|
||||
**要点示范代码:** `getBlock` / `setBlock` / `removeBlock` / `putMapData` / `getMapData` / `iterateBlocks`。
|
||||
> D-31:`getLocationData` **留高级**。示例按 how-to 叙述(「打开 X 文件,在 Y 处调用 Z」)。
|
||||
|
||||
#### `flags.md`(doc-page, content/code-heavy)
|
||||
|
||||
**Analog:** `docs/guide/implements/special.md` 骨架(仓库无同主题旧文档)。
|
||||
**要点示范代码:** `setField` / `getField` / `getOrInsert` / `getFieldValue` / `addFieldValue`。
|
||||
> D-32:全局可存档变量;**所有接口都讲(含 `occupied`)**;建议不滥用、及时 `deleteField`。示例:记录开关 / 计数。
|
||||
|
||||
---
|
||||
|
||||
### 战斗组(9 篇)
|
||||
|
||||
> 组内 9 篇多为「how-to + 代码」型,统一套用 Analog C 骨架。**本组是重点,且多项「尚未可用」(N-1/N-2/N-3/N-7),写作以当时代码为准、留余地**(D-18 / RESEARCH「尚未可用」)。
|
||||
> 组内各篇的**详细主题对照**(接口 `file:line`)见 `10-RESEARCH.md`「24 篇文档的源码入口 · 战斗」表。
|
||||
|
||||
| 文档 | 结构 analog | 主题素材(现有文档 / 源码) |
|
||||
|------|-------------|---------------------------|
|
||||
| `combat-overview.md` | mermaid 图照 `docs/guide/coding.md:9-21`;末尾「流程→文档」对照表 | `docs/dev/enemy/enemy-combat-flow.md:1-27`(三阶段:战前/战斗/战后);`combat/types.ts:747-755`(buildup 四阶段) |
|
||||
| `enemy-specials.md` | `docs/guide/implements/special.md`(**同主题**) | `special.md:1-119`(属性定义 / 函数声明属性 / 编辑器表格);`src/data/enemy/special.ts` |
|
||||
| `enemy-aura.md` | `special.md:163-265`(**同主题**,光环) | `docs/guide/implements/special.md:163-265`;`src/data/enemy/aura.ts` |
|
||||
| `enemy-query.md` | `special.md` 骨架 | 无同主题旧文档;`combat/types.ts:193-227`(**引擎未内置**,N-1) |
|
||||
| `enemy-final.md` | `special.md` 骨架 | 无同主题旧文档;`src/data/enemy/final.ts:4-27` |
|
||||
| `enemy-calculator.md` | `special.md:27-119`(**同主题**,伤害计算) | `docs/guide/implements/special.md:27-119`;`src/data/enemy/calculator.ts:10-179` |
|
||||
| `enemy-map-damage.md` | `special.md:121-161`(**同主题**,地图伤害) | `docs/guide/implements/special.md:121-161`;`src/data/enemy/mapDamage.ts`(**code↔视图不一致,N-2/N-3**) |
|
||||
| `enemy-combat-script.md` | `special.md` 骨架 + `enemy-combat-flow.md` | `docs/dev/enemy/enemy-combat-flow.md`;`src/data/enemy/script.ts:8-62` |
|
||||
| `enemy-status-hooks.md` | `special.md` 骨架 + `enemy-combat-flow.md` | `docs/dev/enemy/enemy-combat-flow.md`;`src/data/enemy/hook.ts:38-321` |
|
||||
|
||||
**`combat-overview.md` 的 mermaid 流程示意(照 `docs/guide/quick-start.md:27-31` 写法;D-33 流程):**
|
||||
````md
|
||||
```mermaid
|
||||
graph LR
|
||||
A[基础数据] --> B[光环/查询/最终] --> C[伤害计算] --> D[战前脚本] --> E[战斗] --> F[战后结算/状态钩子]
|
||||
```
|
||||
````
|
||||
> D-33:末尾加「流程步骤 → 对应文档」对照表;临界值不在本篇提。
|
||||
|
||||
**`enemy-calculator.md` 的临界叙事**(D-38):只讲定义与「伤害值单调递减」约定,**不讲二分过程**;支援怪写「实在理解不了可暂时跳过」。
|
||||
|
||||
**`enemy-map-damage.md` 的「内置五类表」**(D-39):`code` / 实现位置**写文档时核对源码**(N-2 提示 code↔视图映射可能不一致,须向用户确认/核对当时代码)。
|
||||
|
||||
**`enemy-status-hooks.md`**:强调「一个状态可能要用多个钩子」(如中毒 = `onStepEnd` + `onAfterTeleportTo`),示例「下次战斗伤害乘二」串起 `enemy-calculator`。
|
||||
|
||||
---
|
||||
|
||||
### 其他组(3 篇)
|
||||
|
||||
#### `events.md`(doc-page, content/code-heavy)
|
||||
|
||||
**Analog:** `docs/guide/implements/special.md` 骨架(仓库无同主题旧文档)。
|
||||
**要点示范代码:** `BuiltInFunction`(`name` + `func(param, env)`)、`createEventRegistrations()` 注册、`IBlockEventEnv` 常用字段。
|
||||
> D-42:只讲**如何自定义新事件**(内建函数),不讲原理、不列内建全量;自定义示例「设置 flag」「勇士回血」。编辑器识别方式未设计完(N-6)→ **文档留余地**。
|
||||
|
||||
#### `replay-commands.md`(doc-page, content/reference)
|
||||
|
||||
**Analog(结构):** `docs/dev/replay/replay-system.md:1-40`(概念定义小节:需求综述 → 需求理解 → 核心概念定义)。
|
||||
**可借的结构**(`docs/dev/replay/replay-system.md:29-40` 的「核心概念定义」分节写法):
|
||||
```md
|
||||
# 核心概念定义
|
||||
|
||||
## 录像步
|
||||
|
||||
一段游戏流程中不可再分的最小操作单元。……
|
||||
```
|
||||
> D-43:核心原则「玩家直接产生、会影响最终成绩的行为必须计入录像」+ 解释;主动/被动录像(`ReplayCommandType.Active`/`Passive`);`@shouldReplay`/`@ignoreReplay` 的 `begin`/`end` 区间检测;**不给示例**,后续教程链接过来即可。
|
||||
> **注意:** `dev/*` 的 `# 一级标题分节` 风格**不沿用**(新页用单 `#` 主标题 + `##` 小节);此处仅借其「概念定义」的组织方式。
|
||||
|
||||
#### `data-plugins.md`(doc-page, content/code-heavy)
|
||||
|
||||
**Analog:** `docs/guide/implements/special.md` 骨架。
|
||||
**要点示范代码:** `IDataPluginDefine`(`id`/`dependencies`/`awake`/`initialize`/`afterLoad`)、注册在 `src/data/plugin/list.ts` 的 `dataPlugins`、`state.addSaveableContent`。
|
||||
> D-44:时机次序 `awake`(装配)→ `initialize`(加载前)→ `afterLoad`(加载后);示例**占位 / 待提供**(N-4,不用商店插件),并写明「是否纳入本中级篇取决于示例难度」。
|
||||
|
||||
---
|
||||
|
||||
## Shared Patterns
|
||||
|
||||
### 文件命名(kebab-case)
|
||||
**Source:** `dev.md:68`(RESEARCH 已核实)
|
||||
**Apply to:** 全部 24 个新 `.md` 文件名 + `docs/intermediate/` 目录名。
|
||||
> 目录/文件名一律**连字符英文**(D-02)。24 个文件名已由 D-20 锁定,不得自创。
|
||||
|
||||
### 换行符(CRLF)
|
||||
**Source:** `dev.md:116`、`.prettierrc:12`
|
||||
**Apply to:** 全部 24 个新 `.md` 文件。
|
||||
> markdown **无 lint/prettier 门禁**(RESEARCH 已核实),但仓库约定 CRLF;执行时须确保写入为 CRLF,否则 git diff 会整文件变红(RESEARCH Pitfall 6)。
|
||||
|
||||
### 单 H1 + H2/H3 层级
|
||||
**Source:** `docs/guide/quick-start.md:1`、`docs/guide/system.md:5`
|
||||
**Apply to:** 全部 24 篇。
|
||||
> 每页**仅一个** `#` 主标题(照 `quick-start.md:1`/`system.md:5`),其后用 `##`/`###`。**不要**照抄 `docs/dev/*` 的「每个小节都是 `#`」风格(`docs/dev/template.md:3,7,24` 等)。
|
||||
|
||||
### 链接
|
||||
**Source:** `docs/guide/quick-start.md:7`、`docs/guide/coding.md:46`
|
||||
**Apply to:** 全部 24 篇的站内互引。
|
||||
> 同目录用 `./x.md`,跨目录用相对当前文件的路径;带锚点用 `./x.md#锚点`。D-17「适当、不过多」。
|
||||
|
||||
### 提示容器
|
||||
**Source:** `docs/guide/quick-start.md:42-44`(`:::info`)、`docs/guide/system.md:152-154`(`::: warning`)
|
||||
**Apply to:** 需要提示 / 警示 / 注意事项处。
|
||||
> 用 VitePress 容器(D-01 明确 `:::info`、mermaid 可用)。
|
||||
|
||||
### 代码块高亮
|
||||
**Source:** `docs/guide/implements/special.md:19-23`(`// [!code ++]`)、`:54`(`{4-10}`)
|
||||
**Apply to:** 全部含「在既有文件上增改」示例的 how-to(基础接口组 + 战斗组 + `events`/`data-plugins`)。
|
||||
> 标出**新增行**用 `// [!code ++]`;标出**改动区块**用 ```` ```ts {起-止} ````。
|
||||
|
||||
### 禁止元叙述
|
||||
**Source:** D-16(CONTEXT)
|
||||
**Apply to:** 全部 24 篇。
|
||||
> 不得出现「渲染端教程后续再讲」「留到高级教程再说」「届时」等(RESEARCH Pitfall 4)。指向渲染端内容时,当作指向一个**已存在的平行部分**。
|
||||
|
||||
### 越界红线
|
||||
**Source:** D-14(CONTEXT)、RESEARCH Pitfall 3
|
||||
**Apply to:** 本批**全部**改动。
|
||||
> 本批**只**做 `docs/intermediate/*` + `config.ts` 的 intermediate 注册。**禁止**删除/修改 `docs/guide/*`、`docs/dev/*`、`docs/logger/*`,也**禁止**改动 `nav`/`sidebar` 的既有 guide/logger/api 键与 `api.ts`/`init.ts`。越界项只记录、不实施。
|
||||
|
||||
---
|
||||
|
||||
## No Analog Found
|
||||
|
||||
> 本批「无同主题旧文档」但**仍有结构 analog**(`special.md` 骨架)的页面。下方列出**主题素材**来源,供写作时按 RESEARCH 逐字核对:
|
||||
|
||||
| File | Role | Data Flow | 缺什么 | 主题素材来源 |
|
||||
|------|------|-----------|--------|-------------|
|
||||
| `docs/intermediate/enemy-query.md` | doc-page | content/code-heavy | 无同主题旧文档;且引擎**未内置**查询效果(N-1) | `packages-user/data-system/src/combat/types.ts:193-227,660,677`(RESEARCH) |
|
||||
| `docs/intermediate/enemy-final.md` | doc-page | content/code-heavy | 无同主题旧文档 | `src/data/enemy/final.ts:4-27`;`combat/types.ts:229-237,696`(RESEARCH) |
|
||||
| `docs/intermediate/flags.md` | doc-page | content/code-heavy | 无同主题旧文档 | `packages-user/data-base/src/flag/types.ts:47-136`(RESEARCH) |
|
||||
| `docs/intermediate/code-basics.md` | doc-page | content/tutorial | 无任何源码依赖(纯语法教学) | 外链 `h5mota.com/bbs/thread/?tid=1018&p=3#p41`(D-23) |
|
||||
| `docs/intermediate/data-plugins.md` | doc-page | content/code-heavy | 示例**占位待提供**(N-4) | `data-state/src/types.ts:10-81`;`src/data/plugin/*`(RESEARCH) |
|
||||
|
||||
> `enemy-map-damage` 虽有同主题旧文档(`special.md:121-161`),但存在 **N-2/N-3 的 code↔视图不一致**与「实际结算待用户补」(D-18/D-39),计划须在写作前核对当时代码并留余地。
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
**Analog search scope:** `docs/guide/**`、`docs/dev/**`、`docs/api/index.md`、`docs/index.md`、`docs/.vitepress/config.ts`(全部经 `git ls-files` 核实为已跟踪;无 gitignore 镜像路径)
|
||||
**Files scanned:** 既有文档约 10 篇(`quick-start.md`、`system.md`、`coding.md`、`implements/index.md`、`implements/special.md`、`index.md`、`api/index.md`、`dev/template.md`、`dev/hero/hero-items.md`、`dev/enemy/enemy-combat-flow.md`、`dev/replay/replay-system.md`)+ `config.ts`
|
||||
**Pattern extraction date:** 2026-10-16
|
||||
**下游注意:** 本阶段「pattern」为文档结构而非生产代码;`10-RESEARCH.md` 的「24 篇文档的源码入口」表提供每篇应读的**接口 `file:line`**,与本文档的**结构 analog**配合使用。
|
||||
687
.planning/phases/10-docs-restructure/10-RESEARCH.md
Normal file
687
.planning/phases/10-docs-restructure/10-RESEARCH.md
Normal file
@ -0,0 +1,687 @@
|
||||
# Phase 10: 文档重构 - Research
|
||||
|
||||
**Researched:** 2026-10-16
|
||||
**Domain:** VitePress 文档编写与站点配置(文档重构,纯文档产出,无生产代码改动)
|
||||
**Confidence:** HIGH(全部结论基于本仓库源码 / 配置的直接阅读)
|
||||
|
||||
## Summary
|
||||
|
||||
本阶段是**纯文档产出**阶段。第一批范围 = 24 篇中文中级教程 markdown,落在 `docs/intermediate/`,外加把它们注册进 VitePress 站点(`docs/.vitepress/config.ts` 的 `nav` 与 `sidebar`)。验收标准(CONTEXT D-09)= **用户人工审阅 + 链接全部有效 + 构建通过**。
|
||||
|
||||
站点现状已核实:VitePress 站点在 `docs/`,配置在 `docs/.vitepress/config.ts`;`nav` 与 `sidebar` 均为**手写静态配置**([VERIFIED: docs/.vitepress/config.ts:53-156]),`sidebar` 按路径前缀分键(`'/guide/'`、`'/logger/'`、`'/api/'`)。`docs/api/` 的**侧边栏**由 `docs/.vitepress/api.ts` 的 `generateSidebar()` 扫描目录自动生成(写入 gitignore 的 `apiSidebar.ts`),但 `docs/api/` 下的 markdown 正文本身是**已检入仓库的静态文件**,仓库脚本**不重新生成它们**(D-03 的 API 参考"按包生成"指的是这套既有文件树 + 扫描侧边栏机制)。因此本批任务的配置改动量很小:新增 `'/intermediate/'` 侧边栏键 + 一个 `nav` 入口即可,新增 markdown 文件本身不需要为构建做其它注册。
|
||||
|
||||
**Primary recommendation:** 计划拆为「配置任务(改 `config.ts` 注册 intermediate 侧边栏/nav)」+「按阅读顺序分组的 24 篇写作任务(4 组:概念与导航 4 篇 / 基础接口 8 篇 / 战斗 9 篇 / 其他 3 篇)」,写作前先按下方"24 篇文档源码入口"表逐篇锁定要读的 `file:line`,并对标注为"尚未可用"的接口(战斗查询、地图伤害实际结算、`data-plugins` 示例、部分事件)保留余地、以当时代码为准。
|
||||
|
||||
## 关键验收前提(先读)
|
||||
|
||||
- **链接有效性**:VitePress 站点的相对链接形如 `./x.md` 或绝对路径 `/intermediate/x`。跨目录链接需写成相对当前文件的路径。没有自动化死链检查脚本——验收靠用户人工审阅 + 构建时的 VitePress 警告(VitePress 对无法解析的 markdown 链接会报错/警告)。
|
||||
- **构建通过**:`pnpm docs:build` = `vitepress build docs`([VERIFIED: package.json:27])。注意 `docs/.vitepress/config.ts` 顶部静态 import 了 `./apiSidebar`([VERIFIED: docs/.vitepress/config.ts:3]),而该文件由 `docs/.vitepress/init.ts` → `generateSidebar()` 生成([VERIFIED: docs/.vitepress/init.ts:3-5]),且被 `.gitignore` 忽略([VERIFIED: .gitignore:54])。**当前工作区 `docs/.vitepress/apiSidebar.ts` 不存在**(本会话实测 `Test-Path` = False)。因此只跑 `docs:build` 会因该 import 失败;需先跑 `pnpm docs:dev`(它内部先执行 `tsx docs/.vitepress/init.ts`,见 [VERIFIED: package.json:26]),或手动 `tsx docs/.vitepress/init.ts`,生成后再构建。此为事实陈述,供计划选择验收命令时参考,不判定为问题。
|
||||
|
||||
<user_constraints>
|
||||
## User Constraints (from CONTEXT.md)
|
||||
|
||||
### Locked Decisions
|
||||
|
||||
(以下逐字复制自 `10-CONTEXT.md` 的 `## Implementation Decisions`)
|
||||
|
||||
#### 载体与整体形式
|
||||
|
||||
- **D-01:** 文档载体沿用现有 **VitePress** 站点(`docs/.vitepress/`);**不要求**脱离 VitePress 的纯 markdown 兼容,按 VitePress 语法书写即可(`:::info`、`mermaid` 等可用,mermaid 插件已安装)。
|
||||
- **D-02:** 六大块各建**独立文件夹**,命名已获用户批准:
|
||||
- `docs/overview`(总览)
|
||||
- `docs/beginner`(初级文档)
|
||||
- `docs/intermediate`(中级教程)
|
||||
- `docs/advanced`(高级教程)
|
||||
- `docs/api`(API 参考,已存在)
|
||||
- `docs/agent`(Agent 参考)
|
||||
- 按 `dev.md`,目录 / 文件名一律使用连字符英文命名。
|
||||
|
||||
#### API 参考(第 5 部分)
|
||||
|
||||
- **D-03:** 继续按包生成 API 列表(保留 `docs/api/` 现有生成机制),但**正文讲解由人手写**,不是自动生成;对**重点接口额外详细讲解**。
|
||||
|
||||
#### 旧内容处置
|
||||
|
||||
- **D-04:** 现有旧文档内容**全部删除、重写**,不保留——旧接口设计与当前实现差距较大。范围包括 `docs/guide/*`、`docs/dev/*`、`docs/logger/*` 等既有旧内容。
|
||||
|
||||
#### 范围界定
|
||||
|
||||
- **D-05:** API 参考**不含 legacy 包**(`@motajs/legacy-*`、`@user/legacy-*`、`@user/data-fallback`)——这部分尚未重构完。
|
||||
- **D-06:** **初级文档**暂缓——待**编辑器实装后**由用户再派发;具体范围届时另行说明。
|
||||
- **D-07:** **高级教程**暂缓——待**引擎整体完工后**由用户再派发。
|
||||
- **D-08:** **Agent 参考**放 `docs/agent`,具体内容后续再讨论。
|
||||
|
||||
#### 验收与流程
|
||||
|
||||
- **D-09:** 验收标准 = **用户人工审阅** + **链接全部有效** + **构建通过**。
|
||||
- **D-10:** 本阶段采用**增量派发**:用户每次派发一个具体小任务,AI 只针对该任务在 Phase 10 下创建独立计划;不得预先把整个阶段规划到底。可先行部分先做,未完工部分挂起待派发。
|
||||
|
||||
#### 执行方式(本阶段特有,优先级最高)
|
||||
|
||||
- **D-11:** 阶段计划随任务累积,可反复追加/重规划;新任务到来时可新增计划而不必重排既有计划。
|
||||
- **D-12:** 每个计划执行前,第一个 block 点必须**先向用户汇报计划内容**(要做什么、为什么、大致怎么做、影响范围)并等待用户明确回复「可以执行」;未收到「可以执行」前不得开始该计划的任何一步,也不得派发执行子代理。
|
||||
- **D-13:** 新增或修改任何公共、受保护、私有方法/字段等命名,以及文档目录/文件名,均**必须先向用户反馈并获批准**后方可使用。
|
||||
- **D-14:** 每个任务的范围由用户界定;AI 不擅自扩大范围。发现的越界内容只记录、不实施。
|
||||
|
||||
#### 中级教程(第一批派发内容:`docs/intermediate`,24 篇)
|
||||
|
||||
**总原则**
|
||||
|
||||
- **D-15:** 本批只写**中级教程**;面向「读完初级 / 只懂一点代码的作者」。只讲**必须用代码完成**的内容与**顶层常用接口**,不深挖底层原理;**底层 / 不常用接口不讲**(留高级教程)。
|
||||
- **D-16:** **不写**「渲染端教程后续再讲」这类元叙述;**假设渲染端教程已存在**,指向渲染端内容时如指向一个平行部分。
|
||||
- **D-17:** 全文**适当加跳转链接**,但不要过多。
|
||||
- **D-18:** 部分特殊属性与**地图伤害实际结算**尚未内置,用户会在编写文档前补齐;写作以当时代码为准。
|
||||
- **D-19:** 标注「占位 / 待提供」的示例,待用户提供后再写。
|
||||
- **D-20:** 阅读顺序(4 + 8 + 9 + 3 = 24 篇):
|
||||
- 概念与导航:`data-vs-render`、`src-tour`、`code-basics`、`hooks`
|
||||
- 基础接口:`data-state-overview`、`hero-attribute`、`hero-items`、`hero-equipment`、`hero-location`、`map-structure`、`map-tiles`、`flags`
|
||||
- 战斗:`combat-overview`、`enemy-specials`、`enemy-aura`、`enemy-query`、`enemy-final`、`enemy-calculator`、`enemy-map-damage`、`enemy-combat-script`、`enemy-status-hooks`
|
||||
- 其他:`events`、`replay-commands`、`data-plugins`
|
||||
|
||||
**逐篇内容**
|
||||
|
||||
- **D-21(概念·`data-vs-render`)** 数据端负责「算」、渲染端负责「画」;比喻「棋局 / 账本」对「棋盘 / 摄像机」;两者分别在 `src/data`、`src/client`;只讲好处,重点**录像验证**(只跑数据端);附 mermaid 图;**不提**「渲染端不能反向推送」(留高级);不提「后续再讲」。
|
||||
- **D-22(概念·`src-tour`)** 详讲 `src/data`、`src/client`、`src/content`、`src/constant.ts`;**一句带过** `src/bootstrap.ts`、`src/data.ts`(数据端入口、需外部 bootstrap)、`src/package.json`、`src/styles.less`(一般不需要动);**不讲** `src/main.ts`、`src/App.vue`、`src/types/`(均已弃用);含一张「该不该改」表。
|
||||
- **D-23(概念·`code-basics`)** 顺序 ①简明语法 ②模块与引入 ③类型入门;类型把**泛型比喻成「类型的函数」**;讲 `interface` → `implements` 约定(**建议但非强制**,不遵循也不会出问题);三者都大概讲;结尾给 JS/TS 教程链接 `https://h5mota.com/bbs/thread/?tid=1018&p=3#p41`(该教程针对本引擎设计、更适合本引擎作者)。
|
||||
- **D-24(概念·`hooks`)** 钩子是什么;常用钩子族一览;**需求 → 钩子对照表**(核心);`addHook` / `removeHook`;`hook/initialize.ts` 一笔带过;async 钩子只提哪些是;「钩子可能被非本对象触发」简说一句(多主对象时才需要判断,一般不会串)。
|
||||
- **D-25(基础·`data-state-overview`)** 数据端主对象 `state` 是访问一切入口;一张表列常用对象与获取方式:`hero` / `maps` / `flags` / `enemyManager` / `enemyContext` / `combat` / `eventSystem` / `pathfinding` / `tileStore` / `itemStore` / `mapStore` / `eventStore` / `faceManager` / `roleFace` / `replaySystem` / `loader` / `loadManager` / `getDataPlugin(id)` / `emitTip(...)`;按 L0–L3 **轻量分组标注**(分层不影响接口使用,细讲留高级)。放在基础接口组最前。
|
||||
- **D-26(基础·`hero-attribute`)** 属性列表;基础 vs 最终属性(`getBaseAttribute` / `getFinalAttribute`);改基础属性 `set` / `add` / `mul` / `div`(经 `getModifiableAttribute()`);**修饰器**:内置 `ValueModifier`(数值加减,`@system/value`)与 `PercentageModifier`(**按基础值算百分比**,`@system/percentage`);`addModifier` / `deleteModifier`;提 `save` 参数——**不进存档时,应由外部其它系统负责分配该修饰器,避免读档后不一致**;`getAttribute()` 只读、`getIsolatedAttribute()` 试算;示例:攻击 +N 永久、防御 −X% 临时;指回 hooks 篇。
|
||||
- **D-27(基础·`hero-items`)** `IHeroItems`(`addItem` 可传负数、`Pick` 立刻生效、`getItemState`、`iterateItems`、`useItem` 仅 `Constant` / `Consumable`、`itemCount`);**四种类别区分**:`Constant`(永久)/ `Consumable`(消耗)/ `Pick`(即捡即用)/ `Equipment`(装备,虽是道具但属单独系统);道具效果提一句属**内容层**,并说明道具效果可调用哪些内容(`state`、道具数据);示例:发黄钥匙 / 减道具 / 使用道具。
|
||||
- **D-28(基础·`hero-equipment`)** `IHeroEquipment`(`slots` / `canEquipTo` / `equip` 含 `autoUnload` / `unequip` / `equipped` / `getEquipped` / `getEquips`);`IHeroEquipsStore`(`add` / `delete` / `get` / `instancesOf` / `instances` / `count`);`IEquipmentState` 的 `value` / `percentage`(本质是修饰器);`compareEquip` **简单讲**;**排序器不讲**(高级);以「会用常用接口」为界。
|
||||
- **D-29(基础·`hero-location`)** 只讲**获取位置**(`hero.location` 的 `x` / `y` / `direction`、`hero.getLocation()`)与**获取楼层**(`floorId` / `map`);移动位置、切换楼层留高级。
|
||||
- **D-30(基础·`map-structure`)** `IMapState` 楼层集合(`maps` / `getMap` / `getActiveMap` / `iterateAllMaps`)与**楼层激活**(active);`IGameMap`(`layerList` / `eventLayer` / `tileStore` / 宽高);`IMapLayer`(`alias` 别名、宽高);**事件层本质就是个图层,归本篇**。
|
||||
- **D-31(基础·`map-tiles`)** 只讲 `getBlock` / `setBlock` / `removeBlock` / `putMapData` / `getMapData` / `iterateBlocks`;`getLocationData` 属低级需求,**留高级**。
|
||||
- **D-32(基础·`flags`)** 全局**可存档**变量系统;**所有接口都讲(含 `occupied`)**:`setField` / `getField` / `getOrInsert` / `getOrInsertComputed` / `deleteField` / `setFieldValue` / `addFieldValue` / `getFieldValue` / `getFieldValueDefaults`;会进存档;**建议**不滥用、不用的变量及时 `deleteField`;示例:记录开关 / 计数。
|
||||
- **D-33(战斗·`combat-overview`)** 伤害大致怎么算;流程(基础数据 → 光环 / 查询 / 最终 → 伤害计算 → 战前脚本 → 战斗 → 战后结算 + 状态钩子);mermaid 图;末尾「流程步骤 → 对应文档」对照表;临界值不在本篇提。
|
||||
- **D-34(战斗·`enemy-specials`)** 特殊属性是什么、在数据里的样子、两类定义(无参 `defineNonePropertySpecial` / 有参 `defineCommonSerializableSpecial`);`src/data/enemy/special.ts` 注册;**如何自定义新特殊属性**(步骤);**「属性实现位置」对照表**(内置属性各自实现在哪);**多个示例**(有参 / 无参、`name` / `desc` 用字符串与函数);编辑器识别约定(`// {code} - {name}`、`/** {code} - {name} */`、`ISpecial{code}Value`、`#region` 不能删);**怪物比较**简单说、一般不改、真要改参考高级教程。
|
||||
- **D-35(战斗·`enemy-aura`)** **先讲优先级**(高优先级可影响低优先级、反之不行;与查询效果共用优先级);内置光环(普通 23 / 支援 24 / 特殊光环 26);运作方式(写「转换器 + 视图」并注册,**不深讲为何**);四种内置范围只列名(`FullRange` / `RectRange` / `ManhattanRange` / `RayRange`);**多个自定义示例**:基础光环(减少周围怪物金币与经验)+ 高级特殊光环(给周围怪物上光环、优先级高于特殊光环);借示例讲清基础光环 vs 特殊光环差距;`apply` 与 `applySpecial` 差别讲清。
|
||||
- **D-36(战斗·`enemy-query`)** **新增内容(引擎未内置)**;解决「特殊属性查询外部状态」;常规查询 `CommonQuery`(`registerCommonQueryEffect(code, effect)`,`apply(handler, special, query)`)与特殊查询 `SpecialQuery`(`registerSpecialQueryEffect(effect)`,`for(ctx)` → 修饰器 `shouldQuery` / `add` / `delete` / `modify`);与光环共用优先级;**三个示例**:抱团(范围内每有一个带该属性的怪物就给自身加成)、同化(把范围内怪物特殊属性同化到自身,数值型加算叠加、否则取位置索引最小者)、号角(场上每有一只怪物就给自身加成);说明三者能干什么即可;用**抱团**对比「用光环实现复杂度更高」;设计原因留高级。
|
||||
- **D-37(战斗·`enemy-final`)** 最终属性效果:**只影响自身、不依赖也不影响外部环境**的一段收尾调整;内置坚固(3)、模仿(8);接口 `IEnemyFinalEffect`(`priority` + `apply`)、`registerFinalEffect`;**三方对比**(光环:不依赖外部但影响外部;查询:依赖外部仅影响自身;最终:两者皆无);示例:**仿攻**(怪物攻击 = 玩家攻击);`priority` 一句带过;回指 `combat-overview` 流程。
|
||||
- **D-38(战斗·`enemy-calculator`)** `IDamageCalculator`(`calculate` → `{ damage, turn }`、`getCriticalLimit`);注册 `useCalculator`;**逐段导读**内置伤害公式并指明「加自己的属性加在哪一步」;**支援怪**较难 → 写「实在理解不了可暂时跳过」;示例:**等差数列属性**(怪物攻击每回合按固定值递增,等差公式)等;核心讲明调整的是 `f(enemy, hero)` 里的 **`f`**;**临界**:定义 + 现有约定(伤害值单调递减;不单调也可、但临界不准)+ 临界值唯一依赖「最后的伤害值」,**不讲二分过程**。
|
||||
- **D-39(战斗·`enemy-map-damage`)** 概念(领域 / 夹击 / 阻击 / 激光 / 伏击);三部分(伤害视图 / 转换器 / 合并器,浅讲);注册 `useConverter` / `useReducer`;内置五类表(`code` / 实现位置**写文档时核对源码**);自定义示例:**受地形遮挡的激光**;合并器简单讲(决定一个点受多个地图伤害时取什么伤害类型,深入留高级);**实际结算用户届时补**。
|
||||
- **D-40(战斗·`enemy-combat-script`)** 战斗脚本(战前 `before` 返回 `bool` 拦截、战后 `after` 结算,按 `priority`);内置 `MainCombatScript`;注册 `addCombatScript`;**「脚本 vs 钩子」选型表**;战前示例「怪物拥有某特殊属性时无法与其战斗」、战后示例「战后玩家回复固定量生命值」;`priority` 一句。
|
||||
- **D-41(战斗·`enemy-status-hooks`)** 状态类属性(中毒 / 衰弱 / 重生)必须挂钩子;三类内置(中毒:`onStepEnd` + `onAfterTeleportTo` **两个钩子**;衰弱:`onAfterCombat` + 修饰器;重生:`onAfterCombat` + `onSetFloor` **跨钩子协同**);注册在 `initialize.ts`;**强调一个状态可能要用多个钩子**;自定义示例「下次战斗伤害乘二」(并说明还要改伤害计算器,串起 `enemy-calculator`);修饰器概念见 `hero-attribute`。
|
||||
- **D-42(其他·`events`)** 只讲**如何自定义新事件**(内建函数),不讲原理、不列内建全量;`BuiltInFunction`(`name` + `func(param, env)`);`IBlockEventEnv` 常用字段(其余指向 API);参数接口在 `types.ts`;注册在 `createEventRegistrations()`;内置示例导读;**自定义示例:设置 flag、勇士回血**;编辑器识别方式未设计完 → 文档留余地。
|
||||
- **D-43(其他·`replay-commands`)** 录像系统用途 + **核心原则**「玩家直接产生、会影响最终成绩的行为必须计入录像」并解释其含义;**如何新增自定义录像需改 `packages-user` 下的引擎内容**;主动录像 vs 被动录像(`ReplayCommandType.Active` / `Passive`);`@shouldReplay` / `@ignoreReplay` 的功能与检测(`begin` / `end` 区间);**不给示例**,后续其他教程引入自定义录像时直接链接过去。
|
||||
- **D-44(其他·`data-plugins`)** 插件是强拓展系统,中级只讲基础、**高级教程详解其工作原理**;`IDataPluginDefine`(`id` / `dependencies` / `awake` / `initialize` / `afterLoad`);时机次序 `awake`(装配)→ `initialize`(**加载前**)→ `afterLoad`(加载后);注册在 `src/data/plugin/list.ts` 的 `dataPlugins`;`state.addSaveableContent`;示例**占位**(待用户提供**较简单**插件,**不用商店插件**);写明「是否纳入本中级篇取决于示例难度」。
|
||||
|
||||
### the agent's Discretion
|
||||
|
||||
CONTEXT.md 中**没有**显式的 `## the agent's Discretion` 小节。可据 D-10/D-14 推断:具体计划的切分方式、每篇的详略排布、示例的组织形式属执行自由度,但**范围**(哪些篇、哪些接口)由 D-15..D-44 锁定,AI 不得擅自扩大。
|
||||
|
||||
### Deferred Ideas (OUT OF SCOPE)
|
||||
|
||||
(逐字复制自 `10-CONTEXT.md` 的 `## Deferred Ideas`)
|
||||
|
||||
- **初级文档**(第 2 部分)完整范围与内容 —— 待编辑器实装后再规划。
|
||||
- **高级教程**(第 4 部分)完整范围与内容 —— 待引擎整体完工后再规划;中级教材中明确「留高级」的项包括:渲染端结构性内容、地图通行性/移动/踩踏触发、静态与动态图块设计、光环/查询的设计原理、插件系统工作原理、`map-tiles.getLocationData`、装备排序器、修饰器的底层原理、数据端分层原理、位置移动与切换楼层。
|
||||
- **总览**(第 1 部分)—— 待文档整体做完后最后写。
|
||||
- **Agent 参考**(第 6 部分)——「游戏数值设计、游戏地图设计」的具体内涵与内容来源。
|
||||
- 中级教程中标注「占位 / 待提供」的示例(`data-plugins` 的简单插件示例)。
|
||||
- 旧内容删除的具体时机与清单核对。
|
||||
|
||||
</user_constraints>
|
||||
|
||||
<phase_requirements>
|
||||
## Phase Requirements
|
||||
|
||||
Phase 10 在 `.planning/REQUIREMENTS.md` 中**没有专属需求 ID**(REQUIREMENTS.md 的 v1 需求均映射到 Phase 1–9,见 [VERIFIED: .planning/REQUIREMENTS.md:58-72])。本阶段以 CONTEXT.md 的决策 D-01..D-44 为需求基线,验收锚在 D-09(人工审阅 + 链接有效 + 构建通过)。
|
||||
|
||||
| ID | Description | Research Support |
|
||||
|----|-------------|------------------|
|
||||
| (无) | Phase 10 无专属需求 ID;以 10-CONTEXT.md D-01..D-44 为准 | 见本文件「用户约束」与「24 篇文档源码入口」两节 |
|
||||
|
||||
</phase_requirements>
|
||||
|
||||
## Architectural Responsibility Map
|
||||
|
||||
本阶段无运行时架构,能力均落在「文档站点」这一层。映射如下:
|
||||
|
||||
| Capability | Primary Tier | Secondary Tier | Rationale |
|
||||
|------------|-------------|----------------|-----------|
|
||||
| 24 篇中级教程正文 | `docs/intermediate/*.md`(内容层) | — | 纯静态 markdown,构建期由 VitePress 渲染 |
|
||||
| 站点导航(顶栏 `nav`) | `docs/.vitepress/config.ts`(站点配置层) | — | `nav` 是手写静态数组,见 config.ts:53-58 |
|
||||
| 中栏侧边栏(`sidebar['/intermediate/']`) | `docs/.vitepress/config.ts`(站点配置层) | — | `sidebar` 按路径前缀手写,见 config.ts:59-156 |
|
||||
| API 参考侧边栏自动扫描 | `docs/.vitepress/api.ts` + `apiSidebar.ts`(构建期脚本层) | `init.ts`(dev 时触发) | `generateSidebar()` 扫描 `docs/api/` 目录生成侧边栏条目,见 api.ts:13-72 |
|
||||
| API 参考正文 | `docs/api/**/*.md`(已检入的静态文件) | — | 仓库脚本不重生成正文;D-03 的"生成"指既有文件树 + 扫描侧边栏 |
|
||||
| 跨页链接 | 各 markdown 文件内部(内容层) | — | VitePress 解析相对/绝对链接,无外置死链检查 |
|
||||
|
||||
## Standard Stack
|
||||
|
||||
本阶段**不安装任何新的运行时/构建依赖**,只使用仓库既有的文档工具链。
|
||||
|
||||
### Core
|
||||
|
||||
| Library | Version (package.json range) | Purpose | Why Standard |
|
||||
|---------|------------------------------|---------|--------------|
|
||||
| `vitepress` | `^1.6.4` | 文档站点静态生成器 | 仓库既有站点载体(D-01);导航/侧边栏/搜索均由其提供 |
|
||||
| `vitepress-plugin-mermaid` | `^2.0.17` | 在 markdown 中渲染 mermaid 图 | 已安装并在 config.ts 启用(config.ts:2,46,192),D-21/D-33 需画图 |
|
||||
| `mermaid` | `^11.12.3` | mermaid 运行时 | 插件依赖;`optimizeDeps.include` / `ssr.noExternal` 已配置(config.ts:193-198) |
|
||||
|
||||
(版本来源:[VERIFIED: package.json:92-104])
|
||||
|
||||
### Supporting
|
||||
|
||||
| Library | Version | Purpose | When to Use |
|
||||
|---------|---------|---------|-------------|
|
||||
| 内置 VitePress 容器 | 随 VitePress | `:::info` / `:::tip` / `:::warning` 等提示框 | 提示、注意事项(既有文档已在用,例 `docs/guide/quick-start.md:42-44`) |
|
||||
| `tsx` | `^4.21.0` | 运行 `docs/.vitepress/init.ts` 生成 `apiSidebar.ts` | `docs:dev` 已内置;构建前亦可手动执行 |
|
||||
|
||||
**Installation:**
|
||||
```bash
|
||||
# 本阶段不需要安装任何东西;工具链已在 devDependencies 中
|
||||
# 若需校验:
|
||||
node --version # 需 ^24.0.0(dev.md:14)
|
||||
```
|
||||
|
||||
**Version verification:** 本会话以 `package.json` 为准(站点依赖已在 `node_modules` 中存在,实测 `node_modules/vitepress`、`node_modules/vitepress-plugin-mermaid`、`node_modules/mermaid` 均存在)。外部 registry 版本核对因本机环境限制未逐项执行(`package-legitimacy` 结果见下)。
|
||||
|
||||
## Package Legitimacy Audit
|
||||
|
||||
本阶段**不安装任何外部包**(纯文档 + 站点配置修改),因此无需安装前门禁。为完整起见,对本阶段用到的既有文档工具链做了 registry 校验:
|
||||
|
||||
| Package | Registry | Age (latest publish) | Downloads | Source Repo | Verdict | Disposition |
|
||||
|---------|----------|----------------------|-----------|-------------|---------|-------------|
|
||||
| `vitepress` | npm | 2025-08-05 | 1,369,027/wk | github.com/vuejs/vitepress | [OK] | 既有依赖,沿用 |
|
||||
| `vitepress-plugin-mermaid` | npm | 2024-09-24 | 399,394/wk | github.com/emersonbottero/vitepress-plugin-mermaid | [OK] | 既有依赖,沿用 |
|
||||
| `mermaid` | npm | 2026-10-13 | 18,782,236/wk | github.com/mermaid-js/mermaid | [SUS](`too-new`) | 既有依赖,本阶段不安装;仓库锁定 `^11.12.3`,非最新版 |
|
||||
|
||||
**Packages removed due to [SLOP] verdict:** none
|
||||
**Packages flagged as suspicious [SUS]:** `mermaid`(仅因"最新发布过新"被 seam 标记;本阶段不安装、不升级,无动作。`[ASSUMED]`:该 verdict 不影响本阶段,因为不触发任何 install。)
|
||||
|
||||
*来源:`gsd-tools query package-legitimacy check --ecosystem npm`,2026-10-16。*
|
||||
|
||||
## Architecture Patterns
|
||||
|
||||
### System Architecture Diagram
|
||||
|
||||
```
|
||||
作者/AI 编写
|
||||
│
|
||||
├─► docs/intermediate/*.md (24 篇正文,新增)
|
||||
│ │ (相对/绝对链接互引)
|
||||
│ ▼
|
||||
└─► docs/.vitepress/config.ts (手写 nav + sidebar,本批需编辑)
|
||||
│ nav: 53-58 sidebar: 59-156
|
||||
│ import api from './apiSidebar' (line 3)
|
||||
▼
|
||||
┌────────────────────────── 构建期 (vitepress build docs) ──────────────────────────┐
|
||||
│ config.ts 加载 │
|
||||
│ ├─ 静态 import './apiSidebar' ← 由 docs/.vitepress/init.ts 的 generateSidebar │
|
||||
│ │ 生成(api.ts:13-72 扫描 docs/api/**/ 目录)→ 写入 docs/.vitepress/ │
|
||||
│ │ apiSidebar.ts(gitignored) │
|
||||
│ └─ 处理 markdown:mermaid(MermaidMarkdown)、math、容器、链接解析 │
|
||||
│ ▼ │
|
||||
│ outDir = public/_docs (config.ts:49) │
|
||||
└────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
关键点:**正文文件不会被任何脚本生成或扫描注册**——`sidebar` 是手写数组,`nav` 是手写数组。新增 markdown 只需(a)写文件、(b)若要在侧边栏出现则手工加 `sidebar['/intermediate/']` 条目、(c)若要顶栏出现则手工加 `nav` 条目。
|
||||
|
||||
### 新增 24 篇文档需要在 config.ts 改什么(精确到行)
|
||||
|
||||
现状([VERIFIED: docs/.vitepress/config.ts:53-58]):
|
||||
|
||||
```ts
|
||||
nav: [
|
||||
{ text: '主页', link: '/' },
|
||||
{ text: '指南', link: '/guide/quick-start' },
|
||||
{ text: 'API', link: '/api/' },
|
||||
{ text: '错误代码', link: '/logger/' }
|
||||
],
|
||||
```
|
||||
|
||||
现状侧边栏分三个路径键([VERIFIED: docs/.vitepress/config.ts:59-156]):`'/guide/'`(line 60)、`'/logger/'`(line 128)、`'/api/'`(line 150,`items: api`,其中 `api` 来自 `import api from './apiSidebar'`,[VERIFIED: docs/.vitepress/config.ts:3])。
|
||||
|
||||
**必须新增:**
|
||||
|
||||
1. **顶栏入口**(可选但建议,D-09 未强制):在 `nav`(config.ts:53-58)加入一条,例如 `{ text: '中级教程', link: '/intermediate/data-vs-render' }`。
|
||||
2. **侧边栏分组**(必需,否则 24 篇无侧边栏导航):在 `sidebar` 对象(config.ts:59-156)新增 `'/intermediate/'` 键,值为一个 `{ text: '中级教程', collapsed: false, items: [...] }` 分组。`items` 依 D-20 的 4 组顺序组织,可嵌套子分组(参考 `'/guide/'` 的嵌套写法,config.ts:70-124):
|
||||
- 概念与导航:`data-vs-render`、`src-tour`、`code-basics`、`hooks`
|
||||
- 基础接口:`data-state-overview`、`hero-attribute`、`hero-items`、`hero-equipment`、`hero-location`、`map-structure`、`map-tiles`、`flags`
|
||||
- 战斗:`combat-overview`、`enemy-specials`、`enemy-aura`、`enemy-query`、`enemy-final`、`enemy-calculator`、`enemy-map-damage`、`enemy-combat-script`、`enemy-status-hooks`
|
||||
- 其他:`events`、`replay-commands`、`data-plugins`
|
||||
|
||||
链接写法:`{ text: '数据端与渲染端', link: '/intermediate/data-vs-render' }`(与既有 `'/guide/'` 写法一致,用绝对路径、不带 `.md`)。
|
||||
|
||||
**不需要改的:** `docs/.vitepress/api.ts`、`init.ts`(它们的 `generateSidebar` **只**扫描 `docs/api/`,与本批无关,[VERIFIED: docs/.vitepress/api.ts:5,19])。
|
||||
|
||||
**注意(D-04 与本批的关系):** 计划**不要**在本批删除 `docs/guide/*`、`docs/dev/*`、`docs/logger/*` 或改动既有 `nav`/`sidebar` 的 guide/logger 键——旧内容删除是 D-04 的独立任务,本批只负责 intermediate(见 CONTEXT「第一批已派发内容」界定与 D-14)。若计划顺带改了旧键,属越界。
|
||||
|
||||
### API 参考生成机制(回答 research question 2)
|
||||
|
||||
- `docs/api/` 下是**按包分目录**的静态 markdown 文件树(如 `docs/api/motajs-common/index.md`、`docs/api/user-data-base/index.md`),外加 `docs/api/index.md` 手写列表([VERIFIED: docs/api/index.md:1-31])。
|
||||
- `docs/.vitepress/api.ts` 的 `generateSidebar()`(api.ts:13-72)**只做一件事**:遍历 `docs/api/` 下的一级目录,把每个目录内的 `.md` 文件名作为侧边栏条目,写进 `docs/.vitepress/apiSidebar.ts`(api.ts:64-72)。它**不生成也不改写任何 API 正文 markdown**。
|
||||
- 触发方式:仅通过 `docs/.vitepress/init.ts`(init.ts:3-5)在 `docs:dev` 时执行(package.json:26);并有一个 vite dev 插件 `listenSidebar()` 在文件增删/重命名时重新生成(config.ts:7-36,192)。
|
||||
- 没有 `typedoc` / `api-extractor` 的仓库内脚本或配置(`package.json` scripts 无相关命令;`.github/`、`script/` 下无相关配置)。`pnpm-lock.yaml` 里存在 `@microsoft/api-extractor@7.57.6`(作为某依赖的传递依赖),但**仓库没有任何脚本调用它**。
|
||||
|
||||
**结论(供 D-03 计划):** 「API 参考按包生成」的现有机制 = 已检入的 `docs/api/**/*.md` 文件树 + `generateSidebar()` 扫描。本批(中级教程)**不涉及** `docs/api/` 的改动;且 `docs/api/` 当前**已含 legacy 包条目**(`docs/api/index.md:10-13,25,30-31` 列出 `@motajs/legacy-*`、`@user/legacy-plugin-*`、`@user/data-fallback`),与 D-05「排除 legacy」冲突——但 D-05 属第 5 部分(API 参考)任务,**不在本批范围**,仅记录备用。
|
||||
|
||||
### 写作 / 验收工作流(回答 research question 3)
|
||||
|
||||
1. 写 markdown 到 `docs/intermediate/<kebab-case>.md`。
|
||||
2. 编辑 `docs/.vitepress/config.ts` 注册 `nav`/`sidebar`。
|
||||
3. 本地预览:`pnpm docs:dev`(= `tsx docs/.vitepress/init.ts && vitepress dev docs`,[VERIFIED: package.json:26])——先跑会**确保 `apiSidebar.ts` 被生成**,避免 config.ts:3 的 import 失败。
|
||||
4. 构建验收:`pnpm docs:build`(= `vitepress build docs`,[VERIFIED: package.json:27]),输出到 `public/_docs`([VERIFIED: docs/.vitepress/config.ts:49])。
|
||||
5. 预览产物:`pnpm docs:preview`([VERIFIED: package.json:28])。
|
||||
6. **链接有效性**:无独立死链脚本;靠用户人工审阅 + 构建期 VitePress 的链接解析警告/报错(`docs/.vitepress/config.ts:160-182` 启用了本地搜索 `provider: 'local'`)。
|
||||
|
||||
*环境提示:本机 PowerShell 执行策略禁止运行 `pnpm.ps1`/`npx.ps1`(本会话实测被 `PSSecurityException` 拦截);如需跑脚本用 `pnpm.cmd` 或在 `cmd.exe` 下执行,或直接 `node node_modules/vitepress/bin/vitepress.js build docs`。*
|
||||
|
||||
### Recommended Project Structure(本批)
|
||||
|
||||
```
|
||||
docs/
|
||||
├── intermediate/ # 本批新增:24 篇
|
||||
│ ├── data-vs-render.md
|
||||
│ ├── src-tour.md
|
||||
│ ├── code-basics.md
|
||||
│ ├── hooks.md
|
||||
│ ├── data-state-overview.md
|
||||
│ ├── hero-attribute.md
|
||||
│ ├── hero-items.md
|
||||
│ ├── hero-equipment.md
|
||||
│ ├── hero-location.md
|
||||
│ ├── map-structure.md
|
||||
│ ├── map-tiles.md
|
||||
│ ├── flags.md
|
||||
│ ├── combat-overview.md
|
||||
│ ├── enemy-specials.md
|
||||
│ ├── enemy-aura.md
|
||||
│ ├── enemy-query.md
|
||||
│ ├── enemy-final.md
|
||||
│ ├── enemy-calculator.md
|
||||
│ ├── enemy-map-damage.md
|
||||
│ ├── enemy-combat-script.md
|
||||
│ ├── enemy-status-hooks.md
|
||||
│ ├── events.md
|
||||
│ ├── replay-commands.md
|
||||
│ └── data-plugins.md
|
||||
└── .vitepress/
|
||||
└── config.ts # 本批编辑:nav + sidebar['/intermediate/']
|
||||
```
|
||||
|
||||
### Pattern 1: VitePress 页面 + 相对链接
|
||||
|
||||
**What:** 每个文件是纯 markdown,首行一级标题;链接用相对路径(同目录 `./x.md`)或站点绝对路径(`/intermediate/x`)。
|
||||
**When to use:** 所有 24 篇。
|
||||
**Example(参照既有 `docs/guide/quick-start.md:1-7`):**
|
||||
```md
|
||||
# 快速开始
|
||||
|
||||
本章节主要帮助你快速上手 2.B 样板。
|
||||
|
||||
## 常见需求实现指南
|
||||
|
||||
参考[此文档](./implements/index.md)
|
||||
```
|
||||
(来源:仓库既有文档 [CITED: docs/guide/quick-start.md:1-7];D-17 要求"适当加跳转链接,不要过多")
|
||||
|
||||
### Pattern 2: mermaid 图(D-21、D-33 需要)
|
||||
|
||||
**What:** 直接写 ```mermaid 代码块,插件已在 config.ts 启用。
|
||||
**Example(参照既有 `docs/guide/quick-start.md:27-31`):**
|
||||
````md
|
||||
```mermaid
|
||||
graph TD
|
||||
A[基础数据] --> B[光环/查询/最终] --> C[伤害计算] --> D[战前脚本] --> E[战斗] --> F[战后结算/状态钩子]
|
||||
```
|
||||
````
|
||||
|
||||
### Pattern 3: 提示容器(`:::info` 等)
|
||||
|
||||
**What:** VitePress 默认主题容器,既有文档已在用。
|
||||
**Example([CITED: docs/guide/quick-start.md:42-44]):**
|
||||
```md
|
||||
:::info
|
||||
提示内容
|
||||
:::
|
||||
```
|
||||
|
||||
### Anti-Patterns to Avoid
|
||||
|
||||
- **手改 `docs/.vitepress/apiSidebar.ts`:** 它被 `.gitignore` 忽略(.gitignore:54)、被 `.prettierignore` 忽略(.prettierignore:17)、且每次 `generateSidebar()` 运行会被覆盖(api.ts:71)。改它无效。
|
||||
- **在本批删除旧文档:** D-04 的删除是独立任务;本批只做 intermediate(D-14 不擅自扩大范围)。
|
||||
- **新增文档却忘了注册 sidebar:** 不会导致构建失败,但页面在导航中不可见——D-09 的人工审阅会因此不通过。
|
||||
- **在文档里写"渲染端教程后续再讲"之类元叙述:** D-16 明令禁止。
|
||||
|
||||
## 仓库文档约定(回答 research question 4)
|
||||
|
||||
| 约定 | 内容 | 来源 |
|
||||
|------|------|------|
|
||||
| 文件命名 | Markdown 文档文件名用**连字符命名法**(kebab-case) | [VERIFIED: dev.md:68] "Markdown 文档文件名 \| 连字符命名法" |
|
||||
| 目录/文件名 | 按 dev.md 一律连字符英文命名 | D-02(CONTEXT) |
|
||||
| 换行符 | **CRLF** | [VERIFIED: dev.md:116] "换行使用 `CRLF` 格式" |
|
||||
| Prettier | `printWidth 80`、`tabWidth 4`、`singleQuote true`、`endOfLine crlf` | [VERIFIED: .prettierrc:1-13] |
|
||||
| Prettier 忽略 | `docs/.vitepress/apiSidebar.ts` 被忽略(不影响本批) | [VERIFIED: .prettierignore:17] |
|
||||
| ESLint 范围 | 配置只解析 `**/*.{js,mjs,cjs,vue}` 与 `**/*.{ts,tsx,vue}`;**没有** eslint-plugin-markdown,**markdown 文件不被 lint** | [VERIFIED: eslint.config.js:18,33,53] |
|
||||
| Markdown 格式门禁 | `package.json` scripts **没有** `prettier --check`/`format` 脚本;markdown 无自动化格式门禁 | [VERIFIED: package.json:11-32] |
|
||||
| 测试文件规则 | 不适用(本批无测试文件) | — |
|
||||
|
||||
**结论:** 新增 markdown 只需遵守 kebab-case 命名与 CRLF;无 lint/prettier 门禁会拦截 markdown。若计划希望保持与仓库一致,可按 `.prettierrc` 手动格式化(4 空格缩进、单引号、CRLF)——但注意 `.prettierrc` 的 markdown 排版规则会重排表格/换行,非强制。
|
||||
|
||||
## Don't Hand-Roll
|
||||
|
||||
| Problem | Don't Build | Use Instead | Why |
|
||||
|---------|-------------|-------------|-----|
|
||||
| 文档站点/导航/搜索 | 自建静态站或纯 markdown 渲染 | 既有 VitePress 站点(D-01) | 站点、搜索、mermaid、容器均已就绪 |
|
||||
| API 参考侧边栏 | 手写 `docs/api/` 的每一条侧边栏 | `generateSidebar()`(api.ts) | 该机制已自动扫描 `docs/api/` 目录并写文件 |
|
||||
| API 正文生成 | 写脚本从源码抽取并生成 API 正文 | 手工编写正文(D-03) | D-03 明确正文人工写,重点接口额外详讲 |
|
||||
| mermaid 图渲染 | 直接内嵌 SVG/图片 | ```mermaid 代码块 | 插件已安装并启用(config.ts:2,46,192) |
|
||||
| 死链检查 | 自建链接校验脚本 | 用户人工审阅 + 构建期 VitePress 链接解析 | D-09 验收即人工审阅 + 构建通过;仓库无死链脚本 |
|
||||
|
||||
**Key insight:** 本阶段所有"可生成"的东西(站点、侧边栏扫描、图渲染)都已存在;本批唯一要"造"的就是**内容**与**两处手写配置**。
|
||||
|
||||
## 24 篇文档的源码入口(回答 research question 5)
|
||||
|
||||
> 下表把每篇文档应读的**当前**源码入口(文件 + 行区间)列出,供计划逐篇限定阅读范围。所有 `[VERIFIED: …]` 均来自本会话对源码的直接阅读。命中 CONTEXT `canonical_refs` 的项已在"备注"注明;补充的项即 CONTEXT 未点名、由本次核对补齐的。
|
||||
|
||||
### 概念与导航(4 篇)
|
||||
|
||||
| 文档 | 源码入口(file:line) | 备注 |
|
||||
|------|----------------------|------|
|
||||
| `data-vs-render` | `dev.md:125-158`(双端分离章节);`src/data/`(数据端目录);`src/client/`(渲染端目录,含 `client/entry.ts`、`client/initialize.ts`、`client/plugin/`、`client/ui/`);`src/data.ts:1-5`(数据端入口,仅录像验证时运行);`dev.md:132`(`Mota.r()` 门控) | CONTEXT 只给概念;此处补齐目录与入口 file:line |
|
||||
| `src-tour` | `src/data/`(`entry.ts:1-32`、`initialize.ts:1-85`、`types.ts:1-7`、`enemy/*`、`event/*`、`hero/*`、`hook/*`、`loader/*`、`plugin/*`、`replay/*`);`src/client/`;`src/content/`(`item.ts:1-24`、`core.jsonc`、`enemy.jsonc`、`item.jsonc`、`maps/*`);`src/constant.ts:1-51`;一句带过:`src/bootstrap.ts:1-16`、`src/data.ts:1-5`、`src/package.json:1-9`、`src/styles.less:1-7`;弃用项:`src/main.ts`、`src/App.vue`、`src/types/` | 补齐 `entry.ts`/`initialize.ts`/`content/item.ts` 等 file:line |
|
||||
| `code-basics` | 无源码依赖(纯 JS/TS 语法教学);外链 `https://h5mota.com/bbs/thread/?tid=1018&p=3#p41` | 外链与 D-23 一致;`dev.md:88-101`(类型规范)可作"约定"参考 |
|
||||
| `hooks` | `packages/common/src/hook.ts:23-52`(`addHook`/`removeHook`/`removeHookByController`)、`packages/common/src/types.ts:62-104`(`IHookBase`/`IHookable`/`IHookController`);`src/data/hook/initialize.ts:17-26`(注册点);`src/data/hook/index.ts:1-6`;钩子族:`IHeroAttributeHooks`(`packages-user/data-base/src/hero/types.ts:95-102`)、`IHeroLocationHooks`(同文件:289-302)、`IHeroStateHooks`(:900-914)、`IEquipmentStateHooks`(:669-677)、`IHeroFollowersControllerHooks`(:498-518)、`IHeroRenderingHooks`(:440-446)、`IObjectMoverHooks`(`packages-user/data-common/src/common/mover.ts:166-233`)、`ICombatFlowHooks`(`packages-user/data-system/src/combat/types.ts:799-811`)、`IPathfindingSystemHooks`(`.../path/types.ts:164-182`)、`IGameEventExecutorHooks`(`.../event/types.ts:108-130`)、`IMapLayerHooks`(`packages-user/data-base/src/map/types.ts:225-282`)、`IGameMapHooks`(同文件:622-642)、`IReplaySystemHooks`(`.../replay/types.ts:342-360`)、`IReplaySandboxHooks`(:80-112)、`IDataCommonHooks`(`packages-user/data-common/src/types.ts:51-58`) | 补齐全部钩子族的 file:line |
|
||||
|
||||
### 基础接口(8 篇)
|
||||
|
||||
| 文档 | 源码入口(file:line) | 备注 |
|
||||
|------|----------------------|------|
|
||||
| `data-state-overview` | L0 `IDataCommon`:`packages-user/data-common/src/types.ts:60-82`;L1 `IStateBase`:`packages-user/data-base/src/types.ts:17-41`;L2 `IStateSystem`:`packages-user/data-system/src/types.ts:7-16`;L3 `ICoreState`:`packages-user/data-state/src/types.ts:92-122`;实现与分层注释:`packages-user/data-state/src/core.ts:60-88`;`getDataPlugin`:data-state/types.ts:103-105;`emitTip`:data-common/types.ts:81 | CONTEXT 已给分层;补齐逐字段 file:line,与 D-25 列表逐项对上 |
|
||||
| `hero-attribute` | `IHeroAttribute`/`IReadonlyHeroAttribute`:`packages-user/data-base/src/hero/types.ts:104-283`;`ValueModifier`/`PercentageModifier`:`packages-user/data-base/src/hero/modifier.ts:42-78`(`@system/value` line 43;`@system/percentage` line 62);`getModifiableAttribute`/`getAttribute`/`getIsolatedAttribute`:`.../hero/types.ts:964-977` | 修饰器 type 字符串与 `save` 参数(`addModifier(name, modifier, save?)`,类型定义在 hero/types.ts:224-228)逐条对上 D-26 |
|
||||
| `hero-items` | `IHeroItems`/`IHeroItemState`:`packages-user/data-base/src/hero/types.ts:585-647`;实现 `HeroItems`:`packages-user/data-base/src/hero/items.ts:18-176`(`addItem` 的 `Pick` 分支:62-67、`Equipment` 分支:69-74;`useItem` 的 Constant/Consumable 限制:94-99);`ItemCategory`:`packages-user/data-common/src/store/types.ts:125-136`;道具效果内容层:`src/content/item.ts:1-24` + `IItemEffect`(data-common/store/types.ts:138-159) | 补齐 item.ts 与 IItemEffect file:line |
|
||||
| `hero-equipment` | `IHeroEquipment`/`IHeroEquipsStore`/`IEquipmentState`/`EquipStatus`:`packages-user/data-base/src/hero/types.ts:651-883`;实现 `HeroEquipment`:`packages-user/data-base/src/hero/equipment.ts:13-361`(`equip` 含 `autoUnload`:153-199;`compareEquip`:257-335);`HeroEquipsStore`:`packages-user/data-base/src/hero/equipStore.ts:251-381`;`value`/`percentage`→修饰器:equipStore.ts:83-104,123-128 | 补齐 `EquipStatus` 与实现 file:line |
|
||||
| `hero-location` | `IHeroLocation`/`IHeroLocationSave`:`packages-user/data-base/src/hero/types.ts:287-333`;实现 `HeroLocation`:`packages-user/data-base/src/hero/location.ts:22-87`(`x`/`y` 字段:26-27、`floorId`:28、`map`:29);`hero.getLocation()`:`.../hero/types.ts:959-962` | 补齐字段 file:line |
|
||||
| `map-structure` | `IMapState`:`packages-user/data-base/src/map/types.ts:760-861`;`IGameMap`:同文件:651-740;`IMapLayer`::478-600(`alias`:505-506);`layerList`:659、`eventLayer`:669、`active`:662-663;`tileStore`:661 | 补齐 `IMapLayer` file:line |
|
||||
| `map-tiles` | `ILayerStatic`(`getBlock`/`setBlock`/`removeBlock`/`putMapData`/`getMapData`/`iterateBlocks`):`packages-user/data-base/src/map/types.ts:294-378`;`getLocationData`(留高级):同文件:527-532 | 与 D-31 逐接口对上 |
|
||||
| `flags` | `IFlagSystem`(含 `occupied`):`packages-user/data-base/src/flag/types.ts:47-136`;字段对象 `IFlagCommonField`::5-36;实现 `FlagSystem`:`packages-user/data-base/src/flag/system.ts`(存在,本会话未逐行读);`field.ts` | CONTEXT 已给全部接口名;此处给出 interface file:line |
|
||||
|
||||
### 战斗(9 篇)
|
||||
|
||||
| 文档 | 源码入口(file:line) | 备注 |
|
||||
|------|----------------------|------|
|
||||
| `combat-overview` | `ICombatFlow`:`packages-user/data-system/src/combat/types.ts:847-901`;`IEnemyContext.buildup()` 四阶段文档:同文件:747-755(① 光环/查询构建 ② 普通光环改基础属性 ③ 常规查询 ④ 最终效果);注册与装配全流程:`src/data/enemy/initialize.ts:27-70`;L2 装配:`packages-user/data-state/src/core.ts:79-83,123-127` | 补齐 `buildup()` 四阶段 file:line,正好对应 D-33 流程 |
|
||||
| `enemy-specials` | `ISpecial`/`IReadonlyEnemy`/`IEnemyManager`/`SpecialCreation`:`packages-user/data-base/src/enemy/types.ts:31-75,164-248`;`defineNonePropertySpecial`/`defineCommonSerializableSpecial`:`packages-user/data-base/src/enemy/special.ts:136-150`;内置注册与"实现位置一览":`src/data/enemy/special.ts:1-477`(注释清单:72-84;编辑器识别注释:8-14,98,100,473);怪物比较 `MainEnemyComparer`:`src/data/enemy/comparer.ts:1-31` | 与 D-34 全部要素对上(含 `ISpecial{code}Value`、`#region` 约定) |
|
||||
| `enemy-aura` | 内置光环转换器/视图:`src/data/enemy/aura.ts:1-301`(`CommonAura` code 23:29-119;`GuardAura` code 24:125-184;`SpecialAura` code 26:190-299;`SpecialAuraModifier`:206-242);接口 `IAuraView`/`IEnemyAuraView`/`IAuraConverter`/`IEnemySpecialModifier`:`packages-user/data-system/src/combat/types.ts:99-191`;注册 `registerAuraConverter`:同文件:638;全局光环 `addAura`::727;范围类 `FullRange`/`RectRange`/`ManhattanRange`/`RayRange` 由 `@motajs/common` 提供(aura.ts:1-9 导入) | 与 D-35 对上;注意 `priority` 实际值(CommonAura=10、GuardAura=5、SpecialAura=20,见 aura.ts:50,147,249) |
|
||||
| `enemy-query` | 接口:`IEnemySpecialQueryModifier`(`.../combat/types.ts:193-201`)、`IEnemySpecialQueryEffect`(:203-213)、`IEnemyCommonQueryEffect`(:215-227);注册:`registerSpecialQueryEffect`(:660)、`registerCommonQueryEffect`(:677)。**`src/` 未注册任何查询效果**(`src/data/enemy/initialize.ts:27-70` 只注册光环/最终/脚本/钩子) | 与 D-36「引擎未内置」一致 |
|
||||
| `enemy-final` | 内置最终效果 `MainEnemyFinalEffect`(坚固=3、模仿=8):`src/data/enemy/final.ts:4-27`;接口 `IEnemyFinalEffect`:`.../combat/types.ts:229-237`;注册 `registerFinalEffect`::696;装配处:`src/data/enemy/initialize.ts:57` | 与 D-37 对上 |
|
||||
| `enemy-calculator` | 内置 `MainDamageCalculator`:`src/data/enemy/calculator.ts:10-179`(`calculate`:17-160;`getCriticalLimit`:162-178);接口 `IDamageCalculator`:408-426;`useCalculator`:491;临界 `calculateEnemyCritical`:472、`calculateViewCritical`:459;`CriticalableHeroStatus`:404-406;装配处:`src/data/enemy/initialize.ts:44` | 与 D-38 对上(`{damage, turn}` 见 types.ts:377-382) |
|
||||
| `enemy-map-damage` | 视图/转换器/合并器:`src/data/enemy/mapDamage.ts:1-359`(`ZoneDamageView`:84-119、`RepulseDamageView`:121-153、`LaserDamageView`:155-184、`BetweenDamageView`:186-255、`AmbushDamageView`:257-282、`MainMapDamageConverter`:288-325、`MainMapDamageReducer`:331-357);接口 `IMapDamageView`/`IMapDamageConverter`/`IMapDamageReducer`/`IMapDamageInfo`/`IMapDamage`:241-371;注册 `useConverter`:313、`useReducer`:319;`MapDamageType`: `src/data/enemy/types.ts:1-12`;触发结算:`src/data/enemy/hook.ts:74-133` | 与 D-39 对上;**但 code↔视图映射与 `special.ts` 注册码不一致,见下节"尚未可用"** |
|
||||
| `enemy-combat-script` | 内置 `MainCombatScript`:`src/data/enemy/script.ts:8-62`(`before` 返回 bool:11-23;`after` 结算:25-61);接口 `ICombatScript`:813-836、`ICombatFlowHandler`:784-797;注册 `addCombatScript`:897;装配处:`src/data/enemy/initialize.ts:60`;钩子对照 `ICombatFlowHooks`:799-811 | 与 D-40 对上 |
|
||||
| `enemy-status-hooks` | `EnemyMoveHooks`(中毒 `onStepEnd` 走 `handlePoison`+`handleMapDamage`):`src/data/enemy/hook.ts:38-151`;`EnemyPathfindingHooks`(中毒 `onAfterTeleportTo`)::153-186;`EnemyCombatHooks`(中毒/衰弱/退化/重生等 `onAfterCombat`)::188-281;`EnemyChangeFloorHooks`(重生 `onSetFloor`)::283-321;注册:`src/data/enemy/initialize.ts:62-67` | 与 D-41 对上 |
|
||||
|
||||
### 其他(3 篇)
|
||||
|
||||
| 文档 | 源码入口(file:line) | 备注 |
|
||||
|------|----------------------|------|
|
||||
| `events` | 内建函数实现:`src/data/event/map.ts:1-78`、`hero.ts:1-41`、`event.ts:1-54`;参数接口:`src/data/event/types.ts:1-66`;注册:`src/data/event/registrations.ts:9-24`(**共 7 个**:setBlock/moveBlock/removeBlock/moveHero/stepHero/insertEvents/insertEvent);工具:`src/data/event/utils.ts:1-30`;`BuiltInFunction`(`name`+`func`):`packages/anon-tokyo/src/interpreter.ts:11-18`;`IBlockEventEnv`/`IBlockEventParam`:`packages-user/data-system/src/event/types.ts:25-49` | 与 D-42 对上("不列内建全量"但可作示例导读) |
|
||||
| `replay-commands` | 命令实现:`src/data/replay/commands.ts:14-225`;注册:`src/data/replay/initialize.ts:15-35`;`ReplayCode`: `packages-user/data-common/src/replay/types.ts:5-22`;`ReplayCommandType`(Active/Passive):24-29;`ReplayCommandResult`:31-38;`IReplayCommand`:62-78;`IReplayStepHandler`:42-49;`@shouldReplay`/`@ignoreReplay` 与检测区间:`packages-user/data-common/src/replay/func.ts:62-111`(`beginReplaySafetyCollection`/`endReplaySafetyCollection`)、:149-194(装饰器本体) | 与 D-43 对上 |
|
||||
| `data-plugins` | `IDataPluginDefine`/`IDataPlugin`/`PluginStatus`/`ICoreStateConfig.dataPlugins`:`packages-user/data-state/src/types.ts:10-81`;生命周期实现(`awake`/`initialize`/`afterLoad` 次序):`packages-user/data-state/src/core.ts:160-225`、`:231-235`(`load()`);`addSaveableContent`::241-248;依赖排序 `orderPlugins`:`packages-user/data-state/src/plugin.ts:32-121`;注册列表:`src/data/plugin/list.ts:1-5`;参考实现 `DataShopPlugin`:`src/data/plugin/shop/plugin.ts:7-32`(+ `state.ts`);主插件示例 `MainDataPlugin`:`src/data/initialize.ts:17-85` | 与 D-44 对上;D-19 示例**占位** |
|
||||
|
||||
## 尚未可用 / 会变动的项(回答 research question 6)
|
||||
|
||||
> 下列各项**不是缺陷判定**,而是"写作时可能不成立、需以当时代码为准或需用户补齐"的**事实记录**(D-18/D-19 已预设这类情形)。计划应据此为相关文档留余地、或在写作前与用户确认状态。
|
||||
|
||||
| # | 项 | 事实(本会话核对) | 影响的文档 | 建议 |
|
||||
|---|----|-------------------|-----------|------|
|
||||
| N-1 | **战斗查询效果未内置** | `registerSpecialQueryEffect` / `registerCommonQueryEffect` 在 `packages-user/data-system/src/combat/types.ts:660,677` 有接口,但 `src/` **无任何注册调用**(`src/data/enemy/initialize.ts:27-70` 未注册) | `enemy-query`(D-36 已注明"新增内容(引擎未内置)") | 文档按接口 + 示例讲,不假设引擎已内置 |
|
||||
| N-2 | **地图伤害 code↔视图映射与 `special.ts` 注册码不一致** | `src/data/enemy/mapDamage.ts` 转换器按 `getSpecial(15)`→领域视图(:299)、`hasSpecial(16)`→夹击视图(:304)、`getSpecial(18)`→阻击视图(:308)、`getSpecial(24)`→激光视图(:313)、`hasSpecial(27)`→伏击视图(:319);而 `special.ts` 注册的是 13=领域、14=夹击、16=阻击、22=激光、且**没有 27**(`src/data/enemy/special.ts:252-367,439-471`)。另 `BetweenDamageView` 读全局 `core.flags.betweenAttackMax`(mapDamage.ts:238) | `enemy-map-damage`(D-39 已注明"实际结算用户届时补") | 写作前向用户确认;按当时代码逐码核对,D-39 已要求"内置五类表 code/实现位置写文档时核对源码" |
|
||||
| N-3 | **`MapDamageType` 枚举无"伏击"** | `MapDamageType = Unknown/Zone/Layer/Repulse/Between`(`src/data/enemy/types.ts:1-12`),无 Ambush;`AmbushDamageView` 返回 `type: MapDamageType.Unknown`(mapDamage.ts:278) | `enemy-map-damage` | 说明"伏击"当前以 Unknown 类型表现 |
|
||||
| N-4 | **`data-plugins` 示例待用户提供** | 现有唯一数据端插件是商店插件 `DataShopPlugin`(`src/data/plugin/shop/plugin.ts:7-32`),但 D-44 明确不用商店插件作示例、待提供更简单的插件 | `data-plugins`(D-19) | 例子章节先写「占位 / 待提供」,其余按 `IDataPluginDefine` 讲 |
|
||||
| N-5 | **内建事件仅 7 个** | `createEventRegistrations()` 仅返回 setBlock/moveBlock/removeBlock/moveHero/stepHero/insertEvents/insertEvent(`src/data/event/registrations.ts:9-24`) | `events`(D-42"D-42 不讲原理、不列内建全量") | 只导读少量内置示例;自定义示例(设 flag、回血)需自写 |
|
||||
| N-6 | **事件编辑器识别方式未设计完** | D-42 明示;源码中亦无编辑器识别注释约定(对比 `special.ts` 有明确的识别注释) | `events` | 文档留余地,不写死编辑器识别规则 |
|
||||
| N-7 | **部分特殊属性/结算待补齐** | D-18 明示"部分特殊属性与地图伤害实际结算尚未内置,用户会在编写文档前补齐";`special.ts:71` 有 `// TODO: 注释需要更新` | 战斗组全部 | 写作前确认补齐状态;以当时代码为准 |
|
||||
| N-8 | **API 参考现状与 D-05 不一致(不属本批)** | `docs/api/index.md:10-13,25,30-31` 仍列出 legacy 包;且缺 `user-data-common`/`user-data-system` 目录、含不存在的 `@user/data-utils`(`docs/api/` 目录树实测:有 `user-data-utils` 目录但 `packages-user/` 下无 `data-utils`) | 非本批(第 5 部分) | 仅记录,供 D-05 任务使用;本批不动 |
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
### Pitfall 1: 忘记注册 sidebar,页面"写了但看不见"
|
||||
**What goes wrong:** 24 篇写了、构建也过,但侧边栏没有入口,用户审阅(D-09)判定不合格。
|
||||
**Why it happens:** `sidebar` 是手写数组(config.ts:59-156),没有自动扫描 `docs/intermediate/`。
|
||||
**How to avoid:** 计划里必须有一步编辑 `config.ts`,新增 `sidebar['/intermediate/']` 键并逐条挂 24 个链接。
|
||||
**Warning signs:** 预览站点的"中级教程"分组不出现或条目缺失。
|
||||
|
||||
### Pitfall 2: 直接跑 `docs:build` 因缺 `apiSidebar.ts` 失败
|
||||
**What goes wrong:** `docs:build` 静态 import `./apiSidebar`(config.ts:3),而该文件当前不存在、且仅在 `docs:dev`(=先跑 `init.ts`)时生成。
|
||||
**Why it happens:** `docs:build` 脚本未前置运行 `init.ts`(package.json:27)。
|
||||
**How to avoid:** 先 `pnpm docs:dev` 或 `tsx docs/.vitepress/init.ts` 生成后再构建;或把构建命令写成先 init 再 build。
|
||||
**Warning signs:** 构建报 `Failed to resolve import "./apiSidebar"`。
|
||||
|
||||
### Pitfall 3: 越界改旧文档
|
||||
**What goes wrong:** 顺手删/改了 `docs/guide/*`、`docs/dev/*`、`docs/logger/*` 或改动了 `nav`/`sidebar` 的 guide/logger 键。
|
||||
**Why it happens:** D-04 确有"旧内容全删重写"的总目标,但那是独立任务。
|
||||
**How to avoid:** 严守 D-14 与"第一批 = 中级教程"的界定;越界项只记录不实施。
|
||||
**Warning signs:** 计划 diff 触及 `docs/guide/**`、`docs/dev/**`、`docs/logger/**`。
|
||||
|
||||
### Pitfall 4: 写出被禁止的元叙述
|
||||
**What goes wrong:** 出现"渲染端教程后续再讲""这块留到高级教程再说"之类。
|
||||
**Why it happens:** 写作时的自然冲动。
|
||||
**How to avoid:** D-16 —— 指向渲染端内容时,当作指向一个**已存在的平行部分**来写。
|
||||
**Warning signs:** 文中出现"后续""届时""以后再讲"。
|
||||
|
||||
### Pitfall 5: 文档里的接口名/字段/路径与源码不符
|
||||
**What goes wrong:** 新手照抄出错。
|
||||
**Why it happens:** 凭记忆写 `getFinalAttribute`/`addItem` 之类。
|
||||
**How to avoid:** 每篇写作前按"24 篇文档源码入口"表打开对应 `file:line` 核对;接口定义以 `types.ts` 为准。
|
||||
**Warning signs:** 文档中的成员名在对应 `interface` 里搜不到。
|
||||
|
||||
### Pitfall 6: 行尾 / 命名不合规
|
||||
**What goes wrong:** 文件用 LF、文件名用 camelCase 或中文。
|
||||
**Why it happens:** 编辑器默认。
|
||||
**How to avoid:** 文件名 kebab-case(dev.md:68),文件内容 CRLF(dev.md:116;.prettierrc:12)。
|
||||
**Warning signs:** git diff 显示整文件行尾变化;文件名含大写或非连字符。
|
||||
|
||||
## Code Examples
|
||||
|
||||
### 在 config.ts 里注册 intermediate 侧边栏(本批唯一必改的配置)
|
||||
|
||||
```ts
|
||||
// 依据现有写法:docs/.vitepress/config.ts:59-156 的 sidebar 为按路径前缀分键的手写对象
|
||||
// 在 sidebar 对象中新增一个键(示意;具体分组文字由计划定,但 D-13 要求命名先经用户批准)
|
||||
sidebar: {
|
||||
'/intermediate/': [
|
||||
{
|
||||
text: '中级教程',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
text: '概念与导航',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: '数据端与渲染端', link: '/intermediate/data-vs-render' },
|
||||
{ text: 'src 导览', link: '/intermediate/src-tour' },
|
||||
{ text: '代码基础', link: '/intermediate/code-basics' },
|
||||
{ text: '钩子', link: '/intermediate/hooks' }
|
||||
]
|
||||
}
|
||||
// …基础接口 8 篇 / 战斗 9 篇 / 其他 3 篇,按 D-20 顺序
|
||||
]
|
||||
}
|
||||
],
|
||||
'/guide/': [ /* 原样保留 */ ],
|
||||
'/logger/': [ /* 原样保留 */ ],
|
||||
'/api/': [{ text: 'API 列表', items: api }]
|
||||
}
|
||||
```
|
||||
(来源:结构参照仓库现行 `docs/.vitepress/config.ts:59-156`;`link` 写法与 config.ts:64-124 一致)
|
||||
|
||||
### VitePress 页面骨架(每篇起始)
|
||||
|
||||
```md
|
||||
# 文档标题
|
||||
|
||||
(引言一段)
|
||||
|
||||
## 小节
|
||||
|
||||
正文…
|
||||
|
||||
:::info
|
||||
可选提示
|
||||
:::
|
||||
```
|
||||
(来源:仓库现行文档 [CITED: docs/guide/quick-start.md:1-7,42-44])
|
||||
|
||||
## State of the Art
|
||||
|
||||
| Old Approach | Current Approach | When Changed | Impact |
|
||||
|--------------|------------------|--------------|--------|
|
||||
| `docs/guide/*`、`docs/dev/*`、`docs/logger/*` 旧文档结构 | `docs/overview · beginner · intermediate · advanced · api · agent` 六块 | 2026-10-14(D-02) | 本批先落地 intermediate;其余块待派发 |
|
||||
| `docs/api/index.md` 含 legacy 包 | 计划排除 legacy(D-05) | 2026-10-14 | 非本批 |
|
||||
|
||||
**Deprecated/outdated:**
|
||||
- 详细介绍引擎接口设计的旧"开发文档"(`docs/dev/*`,含 `template.md` 的「需求综述 → 需求理解 → 接口设计分析 → 实现思路」方法论)——D-04 将删除重写;本批不涉及。
|
||||
|
||||
## Assumptions Log
|
||||
|
||||
| # | Claim | Section | Risk if Wrong |
|
||||
|---|-------|---------|---------------|
|
||||
| A1 | `pnpm docs:build` 因为 `docs/.vitepress/apiSidebar.ts` 缺失而直接构建会失败(仅在未先跑 `init.ts` 的情况下) | 关键验收前提 / Pitfall 2 | 若实际能构建,则计划的"先 init"步骤冗余,无实质风险 |
|
||||
| A2 | mermaid / vitepress 的 registry 校验与本阶段无关(本阶段不安装依赖) | Package Legitimacy Audit | 无(不安装) |
|
||||
| A3 | VitePress 对无法解析的 markdown 链接会在构建时产生警告/报错,因此"构建通过"与"链接有效"部分重叠 | 写作 / 验收工作流 | 若 VitePress 仅警告不报错,则"链接有效"更依赖人工审阅(D-09 已含人工审阅,风险低) |
|
||||
| A4 | `docs/intermediate/` 目录当前不存在,需新建 | Recommended Project Structure | 若已存在则跳过建目录;风险可忽略 |
|
||||
| A5 | `IFlagSystem` 的实现文件为 `packages-user/data-base/src/flag/system.ts`(本会话只读了 interface,未逐行读实现) | flags 源码入口 | 若实现文件名不同,计划按 interface 文件即可 |
|
||||
|
||||
**若上表非空:** A1、A3 建议由用户在计划前的汇报中被确认(涉及验收命令);A4 可在执行时直接观察。
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **验收命令的确切形态**
|
||||
- What we know: `docs:dev` 会生成 `apiSidebar.ts`;`docs:build` 不会;当前工作区无该文件。
|
||||
- What's unclear: 用户验收时是否要求规范化 `docs:build` 前置步骤,还是以 `docs:dev` 预览为准。
|
||||
- Recommendation: 计划里把"先生成 `apiSidebar.ts` 再 `docs:build`"写成验收命令;不擅自改动 `package.json` scripts(改脚本属范围外,需用户批准)。
|
||||
|
||||
2. **中间文档分组的中文标题与文件名之外的显示名**
|
||||
- What we know: 文件名为 kebab-case(D-02、dev.md:68 已定)。sidebar 的 `text` 显示名需中文。
|
||||
- What's unclear: 24 条的显示名措辞(D-13 要求命名先经用户批准)。
|
||||
- Recommendation: 计划汇报阶段把 24 个显示名一并呈请用户批准。
|
||||
|
||||
3. **N-1 / N-2 / N-7 的补齐时点**
|
||||
- What we know: D-18 说"用户会在编写文档前补齐"。
|
||||
- What's unclear: 本批执行时这些是否已补齐。
|
||||
- Recommendation: 执行 `enemy-query`、`enemy-map-damage` 两篇前,先核对当时代码;如未补齐则按接口讲概念、明确标注"待实现/待补"。
|
||||
|
||||
4. **示例代码的落点**
|
||||
- What we know: D-15 只讲顶层常用接口;D-19 的插件示例待提供。
|
||||
- What's unclear: 示例代码是内嵌代码块,还是指向 `src/` 中的实际文件改动。
|
||||
- Recommendation: 默认内嵌 markdown 代码块(本批为纯文档,不改生产代码);若用户希望示例落在 `src/`,需另行派发。
|
||||
|
||||
## Environment Availability
|
||||
|
||||
| Dependency | Required By | Available | Version | Fallback |
|
||||
|------------|------------|-----------|---------|----------|
|
||||
| Node.js | 运行 vitepress / init.ts | ✓ | v24.21.0 | — |
|
||||
| `vitepress` | 站点 dev/build | ✓ | 已安装于 `node_modules/vitepress`(package.json `^1.6.4`) | — |
|
||||
| `vitepress-plugin-mermaid` / `mermaid` | mermaid 图 | ✓ | 已安装(package.json `^2.0.17` / `^11.12.3`) | 若图渲染异常,退化为普通代码块/文字 |
|
||||
| `tsx` | 运行 `docs/.vitepress/init.ts` | ✓ | `^4.21.0`(devDependencies) | 直接 `node` 亦可运行该 TS(依 tsx) |
|
||||
| `pnpm` CLI 可执行性 | 跑 `pnpm docs:*` | ⚠ | — | 本机 PowerShell 执行策略禁止 `pnpm.ps1`/`npx.ps1`;改用 `pnpm.cmd` / `cmd.exe` / 直接 `node node_modules/vitepress/...` |
|
||||
|
||||
**Missing dependencies with no fallback:** 无
|
||||
**Missing dependencies with fallback:** `pnpm` 脚本在本机 shell 的直呼受限(用 `pnpm.cmd` 或 cmd 替代)。
|
||||
|
||||
## Validation Architecture
|
||||
|
||||
`workflow.nyquist_validation` 为 `true`([VERIFIED: .planning/config.json]),故含本节。
|
||||
|
||||
### Test Framework
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Framework | 无单元测试框架适用于纯文档(仓库用 `vitest`,但本批不写测试) |
|
||||
| Config file | none — 见 Wave 0 |
|
||||
| Quick run command | `pnpm docs:dev`(起本地预览,人工检查导航与链接) |
|
||||
| Full suite command | `pnpm docs:build`(构建通过 = D-09 的"构建通过") |
|
||||
|
||||
### Phase Requirements → Test Map
|
||||
|
||||
| Req ID | Behavior | Test Type | Automated Command | File Exists? |
|
||||
|--------|----------|-----------|-------------------|-------------|
|
||||
| D-09(人工审阅) | 24 篇内容正确、可读、无元叙述 | manual-only | 无(用户人工审阅) | — |
|
||||
| D-09(链接有效) | 站内链接均可解析 | integration | `pnpm docs:build`(VitePress 链接解析;如仅警告则辅以人工) | ❌ 依赖构建 |
|
||||
| D-09(构建通过) | 站点可构建 | smoke | 先 `tsx docs/.vitepress/init.ts`,再 `pnpm docs:build` | ❌ 需先生成 `apiSidebar.ts` |
|
||||
| D-20(阅读顺序) | 侧边栏分组与顺序符合 4/8/9/3 | manual-only(构建后可肉眼核对) | 无 | — |
|
||||
|
||||
*说明:本批无可自动化的"行为断言"——产物是 markdown。Nyquist 意义上的"自动化验证"退化为构建 smoke + 人工审阅,这正与 D-09 的验收标准一致。*
|
||||
|
||||
### Sampling Rate
|
||||
- **Per task commit:** 每篇/每组写完后 `pnpm docs:dev` 预览(或至少构建一次)
|
||||
- **Per wave merge:** `pnpm docs:build` 全量构建
|
||||
- **Phase gate:** 构建通过 + 用户人工审阅通过(D-09)
|
||||
|
||||
### Wave 0 Gaps
|
||||
- [ ] 前置:生成 `docs/.vitepress/apiSidebar.ts`(`tsx docs/.vitepress/init.ts`)——否则构建起步即失败
|
||||
- [ ] 新建目录 `docs/intermediate/`
|
||||
- [ ] `docs/.vitepress/config.ts` 增加 `nav` + `sidebar['/intermediate/']`
|
||||
- [ ] (如决定自动化)无既存死链检查工具——若需,属新增工具,需用户批准
|
||||
|
||||
*(无单元测试框架缺口:本批无测试需求。)*
|
||||
|
||||
## Security Domain
|
||||
|
||||
`security_enforcement` 为 `true`、`security_asvs_level` 为 `1`([VERIFIED: .planning/config.json]),故含本节。
|
||||
|
||||
### Applicable ASVS Categories
|
||||
|
||||
| ASVS Category | Applies | Standard Control |
|
||||
|---------------|---------|-----------------|
|
||||
| V2 Authentication | no | 本批为静态文档,无认证面 |
|
||||
| V3 Session Management | no | 无会话 |
|
||||
| V4 Access Control | no | 无访问控制面 |
|
||||
| V5 Input Validation | no | 文档由构建期静态处理,无运行时用户输入 |
|
||||
| V6 Cryptography | no | 无加密 |
|
||||
|
||||
### Known Threat Patterns for {VitePress 静态文档}
|
||||
|
||||
| Pattern | STRIDE | Standard Mitigation |
|
||||
|---------|--------|---------------------|
|
||||
| 文档内嵌入恶意/不可信 HTML 或脚本 | Tampering / XSS | VitePress 默认转义 markdown 中的 HTML;本批只写文本、代码块、mermaid,不引入原始 `<script>` |
|
||||
| 外链指向钓鱼/不安全站点 | Spoofing | 仅使用 D-23 指定的唯一外链(`h5mota.com` 论坛);不新增未经验证的外链 |
|
||||
| 文档泄露密钥/内部路径 | Information Disclosure | 示例只用源码中已公开的接口与路径,不写真实密钥/账号 |
|
||||
|
||||
**结论:** 本阶段无运行时攻击面;安全风险仅为"文档内容注入/外链"类,按上表控制即可。无阻塞项。
|
||||
|
||||
## Sources
|
||||
|
||||
### Primary (HIGH confidence)
|
||||
- `docs/.vitepress/config.ts`、`docs/.vitepress/api.ts`、`docs/.vitepress/init.ts` — 站点配置、侧边栏生成、入口(本会话逐行读取)
|
||||
- `package.json`、`.prettierrc`、`.prettierignore`、`.gitignore`、`eslint.config.js`、`dev.md` — 脚本/约定(逐行读取)
|
||||
- `src/data/**`、`src/content/item.ts`、`src/constant.ts`、`src/bootstrap.ts`、`src/data.ts`、`src/package.json`、`src/styles.less` — 数据端入口与 24 篇写作素材(逐行读取)
|
||||
- `packages-user/{data-common,data-base,data-system,data-state}/src/**/types.ts` 及相关实现 — 全部接口定义(逐行读取)
|
||||
- `packages/anon-tokyo/src/interpreter.ts`、`packages/common/src/{hook.ts,types.ts}` — `BuiltInFunction` 与钩子机制(逐行读取)
|
||||
- `.planning/REQUIREMENTS.md`、`.planning/PROJECT.md`、`.planning/config.json` — 需求与配置(逐行读取)
|
||||
- `gsd-tools query package-legitimacy check` / `graphify status` — 包校验与图谱状态(本会话执行)
|
||||
|
||||
### Secondary (MEDIUM confidence)
|
||||
- `docs/guide/quick-start.md` — 既有文档的写法/容器样例(仅前 60 行)
|
||||
|
||||
### Tertiary (LOW confidence)
|
||||
- 无(本会话未做外部 web 检索;项目 config 中 `brave_search`/`exa`/`tavily`/`perplexity`/`ref`/`jina` 均为 `false`,无外部 provider 可用;本阶段亦不需要外部资料)
|
||||
|
||||
**图谱状态提示:** `.planning/graphs/graph.json` 存在但 `stale: true`(`last_build` 2026-09-18,`age_hours` ≈ 672,较当前落后 783 commit)。本文件的结论**全部来自直接读源码**,未依赖图谱关系;凡涉及图谱的推断均视为近似。
|
||||
|
||||
## Metadata
|
||||
|
||||
**Confidence breakdown:**
|
||||
- Standard Stack: HIGH — 工具链版本与启用方式直接读自 `package.json`/`config.ts`
|
||||
- Architecture: HIGH — 站点结构、侧边栏机制、构建脚本均逐行核实
|
||||
- Pitfalls: HIGH — 基于确证的配置事实(如 `apiSidebar.ts` 缺失、手写 sidebar)推导
|
||||
- 24 篇源码入口: HIGH(接口定义均逐行读取);个位数项为 MEDIUM(见 Assumptions A5)
|
||||
|
||||
**Research date:** 2026-10-16
|
||||
**Valid until:** 2026-11-15(约 30 天;但注意 N-1/N-2/N-7 等"待补齐"项可能在用户补齐后立即变化——写作前须重新核对当时代码)
|
||||
|
||||
## RESEARCH COMPLETE
|
||||
|
||||
**Phase:** 10 - 文档重构
|
||||
**Confidence:** HIGH
|
||||
|
||||
**要点回顾:**
|
||||
1. 本批 = 24 篇中文中级教程(`docs/intermediate/`)+ 在 `docs/.vitepress/config.ts` 新增 `nav` 与 `sidebar['/intermediate/']`;API 参考与旧文档删除**不在本批**。
|
||||
2. 站点 `nav`/`sidebar` 为手写(config.ts:53-156);`docs/api/` 侧边栏由 `generateSidebar()` 扫描生成,正文为已检入静态文件,仓库无 typedoc/api-extractor 脚本。
|
||||
3. 验收命令:先 `tsx docs/.vitepress/init.ts`(生成 gitignored 的 `apiSidebar.ts`,当前工作区缺失),再 `pnpm docs:build`;预览用 `pnpm docs:dev`。
|
||||
4. 24 篇的源码入口已逐篇核实到 `file:line`(见「24 篇文档的源码入口」表)。
|
||||
5. 8 项「尚未可用/会变动」项(N-1..N-8)已列出,其中 N-1(查询未内置)、N-2/N-3(地图伤害 code 与视图不一致)、N-4(插件示例待提供)、N-7(结算待补齐)直接影响战斗组与 `data-plugins` 的写作,须以当时代码为准或先与用户确认。
|
||||
|
||||
|
||||
83
.planning/phases/10-docs-restructure/10-VALIDATION.md
Normal file
83
.planning/phases/10-docs-restructure/10-VALIDATION.md
Normal file
@ -0,0 +1,83 @@
|
||||
---
|
||||
phase: "10"
|
||||
slug: "docs-restructure"
|
||||
status: draft
|
||||
nyquist_compliant: false
|
||||
wave_0_complete: false
|
||||
created: "2026-10-16"
|
||||
---
|
||||
|
||||
# Phase 10 — Validation Strategy
|
||||
|
||||
> Per-phase validation contract for feedback sampling during execution.
|
||||
|
||||
---
|
||||
|
||||
## Test Infrastructure
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Framework** | none for the docs themselves (repo uses `vitest`, but this batch writes no tests) |
|
||||
| **Config file** | none — VitePress CLI only |
|
||||
| **Quick run command** | `pnpm docs:dev` (local preview; manually inspect nav + links) |
|
||||
| **Full suite command** | `tsx docs/.vitepress/init.ts` then `pnpm docs:build` (build success == D-09 "构建通过") |
|
||||
| **Estimated runtime** | ~20–60 seconds (VitePress build; `init.ts` a few seconds) |
|
||||
|
||||
> NOTE: `docs/.vitepress/config.ts` statically imports `./apiSidebar`; that file is gitignored and currently absent, so `docs:build` fails until `tsx docs/.vitepress/init.ts` regenerates it. Wave 0 must run it first.
|
||||
|
||||
---
|
||||
|
||||
## Sampling Rate
|
||||
|
||||
- **After every task commit:** `pnpm docs:dev` preview (or at minimum one `docs:build`)
|
||||
- **After every plan wave:** `tsx docs/.vitepress/init.ts && pnpm docs:build`
|
||||
- **Before `/gsd-verify-work`:** Full build must pass and the user must have reviewed (D-09)
|
||||
- **Max feedback latency:** ~60 seconds
|
||||
|
||||
---
|
||||
|
||||
## Per-Task Verification Map
|
||||
|
||||
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|
||||
|---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------|
|
||||
| 10-W0-CFG | W0 | 1 | D-02/D-20 | — | Sidebar/nav edits are same-dir docs config only; no raw HTML/script | smoke | `tsx docs/.vitepress/init.ts && pnpm docs:build` | ❌ W0 | ⬜ pending |
|
||||
| 10-TBD | TBD | TBD | D-09 (links) | T-10-info | Doc pages contain no secrets/internal paths; only the single approved external link | integration (build link resolution) + manual | `pnpm docs:build` | ❌ | ⬜ pending |
|
||||
|
||||
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
|
||||
|
||||
*Rows are seeded from RESEARCH.md; the planner must replace the generic rows with the concrete task IDs it defines.*
|
||||
|
||||
---
|
||||
|
||||
## Wave 0 Requirements
|
||||
|
||||
- [ ] Run `tsx docs/.vitepress/init.ts` — regenerate gitignored `docs/.vitepress/apiSidebar.ts` (build prerequisite)
|
||||
- [ ] Create directory `docs/intermediate/`
|
||||
- [ ] Edit `docs/.vitepress/config.ts` — add `nav` entry + `sidebar['/intermediate/']` for the 24 pages
|
||||
|
||||
*No unit-test framework install needed — this batch has no test requirements.*
|
||||
|
||||
---
|
||||
|
||||
## Manual-Only Verifications
|
||||
|
||||
| Behavior | Requirement | Why Manual | Test Instructions |
|
||||
|----------|-------------|------------|-------------------|
|
||||
| 24 篇内容正确、可读、无元叙述 | D-09 (人工审阅), D-16 | Content quality/judgment — not machine-checkable | User reads the built site |
|
||||
| 侧边栏分组与顺序符合 4/8/9/3 | D-20 | Visual/structural | Inspect sidebar after build |
|
||||
| `data-plugins` 占位示例是否可替换 | D-19/D-44 | Depends on user-supplied plugin example | Confirm example provided before finalizing |
|
||||
|
||||
*All machine-checkable behaviors (build + link resolution) are covered by `pnpm docs:build`.*
|
||||
|
||||
---
|
||||
|
||||
## Validation Sign-Off
|
||||
|
||||
- [ ] All tasks have `<automated>` verify or Wave 0 dependencies
|
||||
- [ ] Sampling continuity: no 3 consecutive tasks without automated verify
|
||||
- [ ] Wave 0 covers all MISSING references
|
||||
- [ ] No watch-mode flags
|
||||
- [ ] Feedback latency < 60s
|
||||
- [ ] `nyquist_compliant: true` set in frontmatter
|
||||
|
||||
**Approval:** pending
|
||||
Loading…
Reference in New Issue
Block a user