docs(10): 补齐高级 I 计划的决策引用

This commit is contained in:
unanmed 2026-10-19 20:33:07 +08:00
parent f654b39b31
commit 67984660a6
2 changed files with 3 additions and 3 deletions

View File

@ -33,7 +33,7 @@ must_haves:
<objective>
新建 `docs/advanced/` 并写下高级 I 的第一篇:`declarative-vs-imperative.md`(声明式 vs 命令式接口)。本篇必须把「旧样板写一行即生效」与「新样板声明规则、引擎在合适时机执行」讲透,作为高级 I 其余六篇的共同基础。
Purpose: 高级教程后续的插件、存档、录像、钩子都要求读者先理解「执行时机由谁决定」。如果这一层没讲透,后面每篇都会变成死记接口(D-54:面向使用者,讲怎么用、怎么改、怎么自定义)。
Purpose: 高级教程后续的插件、存档、录像、钩子都要求读者先理解「执行时机由谁决定」。如果这一层没讲透,后面每篇都会变成死记接口(D-53 / D-54 / D-56:高级 I 面向使用者,讲怎么用、怎么改、怎么自定义)。
Output: 1 个新 markdown 文件。
</objective>
@ -89,7 +89,7 @@ Output: 1 个新 markdown 文件。
<task type="auto">
<name>Task 1: 编写 declarative-vs-imperative.md 正文</name>
<files>docs/advanced/declarative-vs-imperative.md</files>
<action>(1) 创建 `docs/advanced/` 并写 `declarative-vs-imperative.md`,单 H1 为「声明式 vs 命令式接口」。(2) 正文按下列顺序组织:①两种写法的一句话区别——命令式是「你写一步、代码走到就执行一步」,声明式是「你声明规则/数据/对象,引擎在定义好的时机调用」;明确「声明式不是不写代码,而是把做什么与什么时候做分开」。②旧样板命令式:用一段明确标注「旧样板示意」的短例子(例如在某段事件脚本里直接循环改周围怪物的攻击,或直接改勇士血量),说明它的后果:只在执行到的那一瞬间生效、要重算只能重跑、每次状态改动都要自己保证记录与一致。旧接口名无法核实就不要写具体名字,用行为描述。③新样板声明式,至少覆盖五组事实:怪物特殊属性与光环(数据里声明 `special`,`special.ts` 定义属性,`aura.ts` 提供转换器/视图,引擎在构建计算后怪物时执行);伤害计算器(`MainDamageCalculator.calculate` 声明 f(enemy, hero),引擎为显示、临界、战斗反复调用,所以必须无副作用);道具效果(`src/content/item.ts` 的 `useEffect` 由引擎在使用/拾取时调用);可存档对象(声明 `saveState` / `loadState`,引擎在存档/读档时调用);钩子(声明钩子类并注册,引擎在事件发生时调用)。每组都要说清「你声明什么」「引擎在哪个时机执行」「为什么这比命令式更稳」。④对照表:行至少含你写什么、何时执行、执行次数、副作用、存档一致性、录像、组合方式、常见错误;列是旧样板命令式与新样板声明式。⑤为什么这样设计:时机集中、从模板重算避免叠加、按优先级/注册表组合、录像只记录玩家入口动作而派生结果重算、计算器被反复调用。⑥「副作用」用通俗话解释:除了返回结果之外还改了外部状态;计算器有副作用会导致临界/显示/战斗结果互相污染。⑦地图伤害按「计算后怪物」计算的说明(D-51):光环若给怪物新增领域类属性,该怪物确实会有领域效果;旧样板无法动态加特殊属性。⑧什么时候仍然用命令式:玩家直接产生的一次性动作(移动、使用道具、一次性脚本)仍调用命令式接口,但这些入口必须计入录像;持续生效的规则用声明式。⑨独立小节「模板:声明式扩展的通用骨架」:给一段 class 骨架,用 `[模板]` / `[需改]` 标出「实现策略接口、注册一次、由引擎调用」的通用形状,与前面的具体示例分开;写明示例是 class 再 `new`,不建议 plain object。⑩「改内置还是自己写」:优先改 `src/data/enemy/*`、`src/data/hook/*` 等已有实现;只有需要独立成组时才自写类;写明「如果你不怎么懂代码,建议直接改内置」。⑪常见误区:把声明式当成「不用写逻辑」、在计算器里改状态、在声明式规则里依赖调用顺序、把一次性动作也硬做成声明式。⑫「怎么验证」:给读者可操作的检查——改一处声明(例如给怪物加一条光环属性或改转换器参数)后不改编排代码,观察结果是否随声明变化;把计算器连续调用两次,确认第二次结果一致且没有额外状态变化;存档后改状态再读档,确认恢复。(3) 适当加 3–5 处链接,只链已存在的页面:`../intermediate/enemy-specials.md`、`../intermediate/combat-overview.md`、`../intermediate/enemy-calculator.md`、`../intermediate/data-vs-render.md`、`../intermediate/hooks.md`。高级 II/III 的内容用代码 span 或 HTML 注释,不写真实链接。(4) 全文 CRLF、单 H1、数据端 only、加粗符合 flanking。完成后运行 `node node_modules/prettier/bin/prettier.cjs --write "docs/advanced/declarative-vs-imperative.md"`。Commit:`docs(10-13): 编写声明式与命令式接口`。</action>
<action>按 D-48 六步、D-49 改内置优先、D-50 模板独立、D-51 落点与副作用、D-52 加粗边界执行。(1) 创建 `docs/advanced/` 并写 `declarative-vs-imperative.md`,单 H1 为「声明式 vs 命令式接口」。(2) 正文按下列顺序组织:①两种写法的一句话区别——命令式是「你写一步、代码走到就执行一步」,声明式是「你声明规则/数据/对象,引擎在定义好的时机调用」;明确「声明式不是不写代码,而是把做什么与什么时候做分开」。②旧样板命令式:用一段明确标注「旧样板示意」的短例子(例如在某段事件脚本里直接循环改周围怪物的攻击,或直接改勇士血量),说明它的后果:只在执行到的那一瞬间生效、要重算只能重跑、每次状态改动都要自己保证记录与一致。旧接口名无法核实就不要写具体名字,用行为描述。③新样板声明式,至少覆盖五组事实:怪物特殊属性与光环(数据里声明 `special`,`special.ts` 定义属性,`aura.ts` 提供转换器/视图,引擎在构建计算后怪物时执行);伤害计算器(`MainDamageCalculator.calculate` 声明 f(enemy, hero),引擎为显示、临界、战斗反复调用,所以必须无副作用);道具效果(`src/content/item.ts` 的 `useEffect` 由引擎在使用/拾取时调用);可存档对象(声明 `saveState` / `loadState`,引擎在存档/读档时调用);钩子(声明钩子类并注册,引擎在事件发生时调用)。每组都要说清「你声明什么」「引擎在哪个时机执行」「为什么这比命令式更稳」。④对照表:行至少含你写什么、何时执行、执行次数、副作用、存档一致性、录像、组合方式、常见错误;列是旧样板命令式与新样板声明式。⑤为什么这样设计:时机集中、从模板重算避免叠加、按优先级/注册表组合、录像只记录玩家入口动作而派生结果重算、计算器被反复调用。⑥「副作用」用通俗话解释:除了返回结果之外还改了外部状态;计算器有副作用会导致临界/显示/战斗结果互相污染。⑦地图伤害按「计算后怪物」计算的说明(D-51):光环若给怪物新增领域类属性,该怪物确实会有领域效果;旧样板无法动态加特殊属性。⑧什么时候仍然用命令式:玩家直接产生的一次性动作(移动、使用道具、一次性脚本)仍调用命令式接口,但这些入口必须计入录像;持续生效的规则用声明式。⑨独立小节「模板:声明式扩展的通用骨架」:给一段 class 骨架,用 `[模板]` / `[需改]` 标出「实现策略接口、注册一次、由引擎调用」的通用形状,与前面的具体示例分开;写明示例是 class 再 `new`,不建议 plain object。⑩「改内置还是自己写」:优先改 `src/data/enemy/*`、`src/data/hook/*` 等已有实现;只有需要独立成组时才自写类;写明「如果你不怎么懂代码,建议直接改内置」。⑪常见误区:把声明式当成「不用写逻辑」、在计算器里改状态、在声明式规则里依赖调用顺序、把一次性动作也硬做成声明式。⑫「怎么验证」:给读者可操作的检查——改一处声明(例如给怪物加一条光环属性或改转换器参数)后不改编排代码,观察结果是否随声明变化;把计算器连续调用两次,确认第二次结果一致且没有额外状态变化;存档后改状态再读档,确认恢复。(3) 适当加 3–5 处链接,只链已存在的页面:`../intermediate/enemy-specials.md`、`../intermediate/combat-overview.md`、`../intermediate/enemy-calculator.md`、`../intermediate/data-vs-render.md`、`../intermediate/hooks.md`。高级 II/III 的内容用代码 span 或 HTML 注释,不写真实链接。(4) 全文 CRLF、单 H1、数据端 only、加粗符合 flanking。完成后运行 `node node_modules/prettier/bin/prettier.cjs --write "docs/advanced/declarative-vs-imperative.md"`。Commit:`docs(10-13): 编写声明式与命令式接口`。</action>
<verify>
<automated>$ErrorActionPreference='Stop'; $p='docs/advanced/declarative-vs-imperative.md'; if(-not(Test-Path -LiteralPath $p)){ Write-Error "MISSING $p" }; $raw=[IO.File]::ReadAllText((Resolve-Path -LiteralPath $p)); if($raw -match "(?<!`r)`n"){ Write-Error "LF-ONLY $p" }; if(([regex]::Matches($raw,'(?m)^# ')).Count -ne 1){ Write-Error "H1-COUNT $p" }; foreach($needle in @('声明式','命令式','IDamageCalculator','enemyContext.buildup','ISaveableContent','addHook','副作用','模板:声明式扩展的通用骨架','怎么验证')){ if($raw -notmatch [regex]::Escape($needle)){ Write-Error "MISSING-CONTENT $needle" } }; if($raw -match 'src/client'){ Write-Error "RENDERER-CONTENT" }; if($raw -match '\*\*[,。!?;:、()《》「」『』【】,.!?;:\(\)\[\]{}"'']' -or $raw -match '[,。!?;:、()《》「」『』【】,.!?;:\(\)\[\]{}"'']\*\*'){ Write-Error "BOLD-FLANK" }; foreach($m in [regex]::Matches($raw,'\]\((\.{1,2}/[^)#]+\.md)(#[^)]*)?\)')){ $t=Join-Path (Split-Path -Parent $p) $m.Groups[1].Value; if(-not(Test-Path -LiteralPath $t)){ Write-Error ("DEAD-LINK " + $m.Groups[1].Value) } }; Write-Output 'STATIC-OK'</automated>
<fails_when>non-zero exit, or output contains "MISSING", "LF-ONLY", "H1-COUNT", "MISSING-CONTENT", "RENDERER-CONTENT", "BOLD-FLANK", or "DEAD-LINK"; or output lacks "STATIC-OK"</fails_when>

View File

@ -42,7 +42,7 @@ must_haves:
<objective>
编写高级 I 导览并接入站点:新增 `docs/advanced/index.md`,在 `docs/.vitepress/config.ts` 增加 `/advanced/` 的 `nav` 与 `sidebar`(高级 I 组挂七篇;高级 II / III 留空分组),最后做一次全量链接、格式与构建收口。
Purpose: 六篇内容已经写好,但站点没有入口就等于不存在。导览还要承担 D-53 的分层说明与 D-55 的「优先插件」原则,否则读者不知道先读哪篇、也不知道为什么不该直接改内置。
Purpose: 六篇内容已经写好,但站点没有入口就等于不存在。导览还要承担 D-53 的分层说明、D-55 的「优先插件」原则与 D-56 的高级 I 七篇范围,否则读者不知道先读哪篇、也不知道为什么不该直接改内置。
Output: `index.md`、`config.ts` 的注册,以及七篇之间的可解析链接。
</objective>