<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>《叙事策划与叙事工艺》卷二《叙事引擎与分支系统》· 全书目录与章节索引（50 篇） on PlumePHP</title><link>https://plumephp.com/posts/books/%E5%8F%99%E4%BA%8B%E5%BC%95%E6%93%8E%E4%B8%8E%E5%88%86%E6%94%AF%E7%B3%BB%E7%BB%9F/</link><description>Recent content in 《叙事策划与叙事工艺》卷二《叙事引擎与分支系统》· 全书目录与章节索引（50 篇） on PlumePHP</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Fri, 16 Oct 2026 23:00:00 +0800</lastBuildDate><atom:link href="https://plumephp.com/posts/books/%E5%8F%99%E4%BA%8B%E5%BC%95%E6%93%8E%E4%B8%8E%E5%88%86%E6%94%AF%E7%B3%BB%E7%BB%9F/index.xml" rel="self" type="application/rss+xml"/><item><title>15.3 规模告警</title><link>https://plumephp.com/narr-sys-15-3-scale-warning/</link><pubDate>Fri, 16 Oct 2026 23:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-15-3-scale-warning/</guid><description>给规模定四条软告警阈值：可达状态数 &gt; 1e7、单次 BFS &gt; 120 秒、峰值内存 &gt; 4 GB、单条路径步数 &gt; 40。当前规格四条全未越（9895423 状态、58.6 秒、2147.1 MB、31 步）；把 flag 放大到 30 后越过三条，而内存那条在两次复跑里一次越一次未越，脚本恒 exit 0。</description></item><item><title>15.2 求值与遍历的开销</title><link>https://plumephp.com/narr-sys-15-2-eval-traversal-cost/</link><pubDate>Fri, 16 Oct 2026 22:30:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-15-2-eval-traversal-cost/</guid><description>量叙事引擎的单位成本：单次 eval_cond 求值中位数 169.9 ns，一次完整 BFS 32 层 9895423 状态、峰值 frontier 2498621、19121205 次求值、60.8 秒、峰值内存 2153 MB。给出求值次数与规格规模的比值，并声明所有耗时都是本机 proxy，只做相对比较。</description></item><item><title>15.1 规格规模的增长</title><link>https://plumephp.com/narr-sys-15-1-spec-scale-growth/</link><pubDate>Fri, 16 Oct 2026 22:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-15-1-spec-scale-growth/</guid><description>把同一份规格沿 flag、好感度、物品、节点四条轴分别放大一档，量 20 层内可达状态数与枚举耗时的增长：flag 18→30 时声明空间上界涨 4096 倍，实测可达只涨 2.096 倍；好感度轴单位倍率最高也只有 1.1285，远低于声明域的 101。给出规模表、增长阶与一张纯 xml.etree 生成的 SVG 曲线。</description></item><item><title>11.3 快照的向前兼容</title><link>https://plumephp.com/narr-sys-11-3-snapshot-forward-compatibility/</link><pubDate>Fri, 16 Oct 2026 15:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-11-3-snapshot-forward-compatibility/</guid><description>规格演化后（新增 flag、新增物品、新增好感度变量、新增节点），旧存档必须仍能读。本节实跑兼容性矩阵：四种新规格下旧存档全部读入成功并给出补默认值规则；迁移函数三条判据——缺失字段补默认、多余字段丢弃并报告、类型不符拒绝——逐条在本机实跑验证。</description></item><item><title>《叙事策划与叙事工艺》卷二《叙事引擎与分支系统》目录</title><link>https://plumephp.com/narr-sys-toc/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-toc/</guid><description>《叙事策划与叙事工艺》卷二《叙事引擎与分支系统》目录：16 章 48 节，把 story_spec.json 变成可执行的对话状态机——条件求值、效果应用、确定性回放、状态空间穷举、可玩原型与跨语言摘要。本页给出分工说明、六档可运行性口径与全书 16 章 48 节完整清单。</description></item><item><title>1.1 状态、事件、转移</title><link>https://plumephp.com/narr-sys-01-1-state-event-transition/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-01-1-state-event-transition/</guid><description>叙事引擎可以被抽象成一个三元组：状态（节点、好感度、flag、物品、路径）、事件（一次选项点击）、转移（纯函数 step）。本节把《雾港夜航》的引擎压到这三个词上，并用一份 S 层脚本打印一条 25 步路径的逐步骤状态轨迹与每一步之后的 FNV-1a 摘要。</description></item><item><title>1.2 规格驱动的对话状态机</title><link>https://plumephp.com/narr-sys-01-2-spec-driven-dialogue-state-machine/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-01-2-spec-driven-dialogue-state-machine/</guid><description>规格驱动的意思是引擎里没有一条硬编码剧情：可用的选项来自 dialogue 的 choices 加 when 求值，状态推进来自 state 的四个效果算子，终局来自 endings 的 when 判定。本节用一份 TypeScript 模块与四条断言证明这台状态机的全部行为都由 spec 的三段决定。</description></item><item><title>1.3 引擎与规格的同源</title><link>https://plumephp.com/narr-sys-01-3-engine-spec-same-origin/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-01-3-engine-spec-same-origin/</guid><description>同源的意思是同一份规格在 Python 与 TypeScript 两侧推进同一选择序列，整数状态摘要逐位相同。本节用四种确定性策略各走一条路径：Python 侧落出四条路径的选择序列与 FNV-1a 摘要，TypeScript 侧读回产物原样重放，断言规范串与摘要两侧完全一致。</description></item><item><title>10.1 注入选择序列真玩</title><link>https://plumephp.com/narr-sys-10-1-playwright-inject-choice-path/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-10-1-playwright-inject-choice-path/</guid><description>用 Playwright 无头打开 web/dist/ne10.html，靠 data-choice-id 选择器契约注入一条 25 步的完整选择序列真玩一遍：逐步记录节点 id 与当前好感度读数，并断言每一步注入的选项都落在规格该节点的可用集合里，终局摘要 4162796975。</description></item><item><title>10.2 断言终局状态与结局</title><link>https://plumephp.com/narr-sys-10-2-assert-final-state-ending/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-10-2-assert-final-state-ending/</guid><description>把 25 步序列走完后的终局状态读回来断言四件事：终局节点 e_lit、结局 灯守、终局摘要 4162796975（与 Python 与 TS 侧逐位一致）、同一序列跑两遍摘要不变；再截图到 out/shots/ 并给出 PNG 字节数。只对整数状态写逐位一致。</description></item><item><title>10.3 多路径批跑</title><link>https://plumephp.com/narr-sys-10-3-multi-path-batch-run/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-10-3-multi-path-batch-run/</guid><description>用固定种子采样 20 条路径，逐条把选择序列注入页面，断言终局节点、结局与状态摘要与 Python 侧一致，批跑通过 20/20、覆盖 4 种结局。失败时原样打印选择序列便于重放；S 层落成 JSON，P 层 core/test 回放对照。</description></item><item><title>11.1 存档的序列化</title><link>https://plumephp.com/narr-sys-11-1-save-serialization/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-11-1-save-serialization/</guid><description>存档是状态的规范序序列化：键按字典序、值全是整数、无浮点、无时间戳、无随机。本节把一条 25 步路径的终局状态写成 795 字节的存档 JSON，验证字段与 canonical 串一一对应，并让序列化到反序列化再序列化两次字节完全相同；同时点明临时 UI 状态、派生量、绝对时间不能进存档。</description></item><item><title>11.2 读档与状态恢复</title><link>https://plumephp.com/narr-sys-11-2-load-state-restore/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-11-2-load-state-restore/</guid><description>读档后从存档点继续推进，必须与从头一次走完得到逐位相同的终局状态。本节沿 25 步路径在第 1、5、10、15、20、25 步分别存档读档，终局规范串全部相同；并给出负例：把存档里的好感度篡改成 999，宽松读档钳位到 100 并记录修复，严格读档直接拒绝，检测器抓得到。</description></item><item><title>12.1 文本表与键</title><link>https://plumephp.com/narr-sys-12-1-text-table-and-key/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-12-1-text-table-and-key/</guid><description>文本是规格的一种渲染产物，而键是文本表与规格之间唯一的连接点。本节从 dialogue 段抽出全部文本键——48 条 line、1 条 else、115 条选项文本，共 164 键——给出键命名规则与漏键 / 悬空键检测，并各给一条负例。只做文本的结构一致性，不评价译文质量。</description></item><item><title>12.2 变体与复数</title><link>https://plumephp.com/narr-sys-12-2-variant-and-plural/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-12-2-variant-and-plural/</guid><description>同一条键在不同状态下要渲染不同文本，这是条件变体；同一句话在不同数量下要选不同形式，这是复数。本节给出 2 个带条件变体节点的覆盖矩阵（1 完整、1 欠声明），并给出 zh-CN 与 en-US 的最小复数规则对照——中文退化为单类，复数只在对照语言上有意义。</description></item><item><title>12.3 文本的一致性校验</title><link>https://plumephp.com/narr-sys-12-3-text-consistency-validation/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-12-3-text-consistency-validation/</guid><description>四类文本一致性校验一次算齐：漏键、悬空键、变体覆盖、占位符。前两类残差为 0；变体覆盖报出 d_lt_2 欠声明（有 line_when 无 line_else，按规则回落，只报不判失败）；占位符残差 0，并给一条负例。本章只做结构一致性，译文质量与字体覆盖需真实业务环境，命令行不可复现。</description></item><item><title>13.1 跨语言摘要与 digest</title><link>https://plumephp.com/narr-sys-13-1-cross-language-digest/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-13-1-cross-language-digest/</guid><description>摘要用 FNV-1a 32 位，只对 canonical 规范串（状态）做，不对台词文本做。本节实测同一批 500 条路径（seed=20261016）在 Python 与 TypeScript 两侧逐位相同 500 / 500，前 3 条摘要为 3976226298、3848604931、1198029437，并与卷一同种子采样逐位相同，证明卷二未另立真源。</description></item><item><title>13.2 同源不同宿主</title><link>https://plumephp.com/narr-sys-13-2-same-origin-different-host/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-13-2-same-origin-different-host/</guid><description>同一条确定性策略路径（总是选第一个可用选项，25 个事件）在 Python、Node 内核与浏览器内联三个宿主上推进，终局节点 e_lit、结局 灯守、FNV-1a 摘要 4162796975 三侧逐位相同。本节给出宿主差异清单：整数运算、取模、Math.imul 与大整数、对象键序、Unicode 归一化，逐条说明为何不影响状态摘要。</description></item><item><title>13.3 偏差与容差</title><link>https://plumephp.com/narr-sys-13-3-deviation-tolerance/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-13-3-deviation-tolerance/</guid><description>什么必须逐位相同、什么允许不同，本节写成一张容差表：整数状态（好感度、flag、item、节点 id、路径）必须逐位；浮点派生量、对象键序、文本渲染、时间戳允许不同。负例把好感度钳位上限从 100 改成 99，实测 12 / 500 条路径摘要改变，首个分歧点定位到路径 #13 第 20 步 c_fg_1a 的 shen。</description></item><item><title>14.1 属性测试与不变量</title><link>https://plumephp.com/narr-sys-14-1-property-test-invariant/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-14-1-property-test-invariant/</guid><description>属性测试不问「跑一遍对不对」，而问「一条命题是否对所有输入都成立」。本节把第 3 / 6 / 8 章的不变量写成六条属性：好感度恒在 [0,100]、set 类算子幂等、add 故意不幂等、静态死路 0、5 个结局全可达、每状态至少一个可用选项，并给每条属性配一个必须 fail 的注入式负例。</description></item><item><title>14.2 随机路径的模糊测试</title><link>https://plumephp.com/narr-sys-14-2-random-path-fuzz/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-14-2-random-path-fuzz/</guid><description>把随机路径当模糊测试的输入：用自实现可播种 PRNG 跑 20000 条路径，断言全部终止于 5 个结局之一、无卡死、无越界。实测分布为离港 10074、沉没 5507、缄默 3223、灯守 1018、真相 178，最稀有的真相仅 178 条。Python 与 TypeScript 两侧对同一批路径的终局状态摘要逐位一致。</description></item><item><title>14.3 回归与告警</title><link>https://plumephp.com/narr-sys-14-3-regression-and-warning/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-14-3-regression-and-warning/</guid><description>把基线摘要、结局分布、整数不变量残差落成回归基线文件，规格每改一次就重跑比对。本节给三类告警：摘要失配、分布漂移、残差非零，各配一个内存内注入负例，实测三组全部触发。告警只打印 WARN 并 exit 0，与 B 层口径一致；而负例测试必须硬失败。</description></item><item><title>16.1 引擎的装配检查表</title><link>https://plumephp.com/narr-sys-16-1-engine-assembly-checklist/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-16-1-engine-assembly-checklist/</guid><description>装配检查表把本卷十五节交付的零件收成十二项可断言的检查：规格可解析、引用完整、写入域合法、整数不变量残差 0、规模对账、BFS 与基线一致、goto 全部存在、结局全部可达、跨语言锚点一致、W 层零外部依赖、覆盖率达目标、无卡死路径。S 层脚本逐项跑出 PASS/FAIL 表，任一项 FAIL 即非零退出。</description></item><item><title>16.2 三处消费的联调</title><link>https://plumephp.com/narr-sys-16-2-three-consumption-integration/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-16-2-three-consumption-integration/</guid><description>把同一份规格上的三处消费串成一次联调：穷举给出完整可达状态数与结局分布，执行让确定性策略 first 走到底并算出整数摘要 4162796975，度量给出覆盖率与张力曲线残差。P 层用 TypeScript 内核重放同一条路径，摘要与 S 层逐位相同，验证引擎与规格同源。</description></item><item><title>16.3 交付卷三</title><link>https://plumephp.com/narr-sys-16-3-deliverable-handoff-volume3/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-16-3-deliverable-handoff-volume3/</guid><description>卷二交付给卷三《叙事体验与路径度量》的五类接口：规格段、内核函数、仿真产物、原型产物、判据与容差。本节用自检脚本逐项核对磁盘上的段、函数、产物与阈值，再用 W 层脚本在浏览器里复算 16.2 的锚点摘要，并声明边界——本卷只交结构量，体验度量归卷三。</description></item><item><title>2.1 条件表达式的求值器</title><link>https://plumephp.com/narr-sys-02-1-condition-expression-evaluator/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-02-1-condition-expression-evaluator/</guid><description>条件在规格里是嵌套数组写成的表达式树，求值器就是把它递归地读成真假。本节给出六种形态的求值语义，用 Python 与 TypeScript 两条链把 story_spec.json 里 57 个条件位点全部求值一遍，并把声明域与使用域分开数：声明 6 种形态只用 5 种，声明 4 个比较算子只用 &gt;= 一种。</description></item><item><title>2.2 短路与复杂度</title><link>https://plumephp.com/narr-sys-02-2-short-circuit-complexity/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-02-2-short-circuit-complexity/</guid><description>短路是求值器的一条优化纪律：and 左假即停、or 左真即停，但它绝不能改变结果。本节给出短路与不短路两种实现的节点访问步数对照——本规格 57 个位点在 16 个代表状态下 eager 1008 步、短路 992 步——并声明复杂度上界：树内 n 个节点时短路步数恒不超过 n。</description></item><item><title>2.3 条件的可满足性</title><link>https://plumephp.com/narr-sys-02-3-condition-satisfiability/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-02-3-condition-satisfiability/</guid><description>可满足性问的是：一个条件在有限状态域里到底有没有解，会不会恒假。本节用边界值枚举在「节点 × 4 个好感度 × 18 个 flag × 9 个物品」上判定，57 个条件位点里死条件 0 个；并处理一处真实特征——lin 与 hai 声明了好感度却不在状态域里，任何门限都结构性不可达。</description></item><item><title>3.1 效果的应用</title><link>https://plumephp.com/narr-sys-03-1-effect-application/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-03-1-effect-application/</guid><description>效果算子只有四个，每个只写一个命名空间：set 写 flag、add 写好感度、grant 与 revoke 写物品。本节把全规格 138 次写入摊平数一遍，校验写入域越界 0，并点出声明了却一次未用的 revoke；P 层用同一批选项断言命名空间互斥，并以把 add 放大到百万级仍被钳回证明钳位确实生效。</description></item><item><title>3.2 确定性与幂等</title><link>https://plumephp.com/narr-sys-03-2-determinism-idempotence/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-03-2-determinism-idempotence/</guid><description>确定性是同一输入同一输出，幂等是重复应用结果不变，两者常被混为一谈。本节把状态推进拆成三条可断言判据：函数性、set 类算子幂等、add 故意不幂等，并说明全书那句「同输入确定性违例 0」指的是同一状态到同一后继状态，而不是「重复 add 不累加」。</description></item><item><title>3.3 状态快照与差量</title><link>https://plumephp.com/narr-sys-03-3-state-snapshot-delta/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-03-3-state-snapshot-delta/</guid><description>快照是某一刻的完整状态，差量是相邻两快照间真正改变的字段。本节沿一条 25 步的确定性路径输出逐步骤差量表，并点出 7 个 flag 与 1 个物品被写却从未被任何条件读取——这类「只增不减的信息」按声明未用=报告处理，不判 FAIL，只如实报出。</description></item><item><title>4.1 选择序列与路径</title><link>https://plumephp.com/narr-sys-04-1-choice-sequence-and-path/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-04-1-choice-sequence-and-path/</guid><description>选择序列是玩家按下的一串 choice_id，路径是引擎走出来的 node_id 序列。本节用同一趟推进给出双表示对照，实测 115 条选项去重后只有 56 条唯一跳转，因此选项数并不等于路径形状数，并用 Kahn 拓扑排序证明 48 个对话节点构成一张无环 DAG。</description></item><item><title>4.2 同种子同回放</title><link>https://plumephp.com/narr-sys-04-2-same-seed-same-replay/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-04-2-same-seed-same-replay/</guid><description>随机路径采样只用自实现的 Lehmer MINSTD，种子一固定，回放就必然复现。本节实测同一 (seed=20261016, n=500) 采样两次 500 条选择序列逐条相同，而换到 seed=20261017 后逐条相同数为 0、结局分布也整体改变。</description></item><item><title>4.3 回放的逐位一致</title><link>https://plumephp.com/narr-sys-04-3-replay-bitwise-identity/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-04-3-replay-bitwise-identity/</guid><description>对同一串选择序列，Python 与 TypeScript 各自推进一遍，比较 canonical 串与 FNV-1a 32 位摘要。本节实测 500 条路径全部逐位相同，并给出前 3 条摘要值对照表；FNV-1a 的 Math.imul 与 Python 的 &amp; 0xFFFFFFFF 是两侧一致的关键。</description></item><item><title>5.1 状态空间的规模</title><link>https://plumephp.com/narr-sys-05-1-state-space-scale/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-05-1-state-space-scale/</guid><description>一个状态等于节点乘以 4 个好感度、18 个 flag、9 个物品。本节先算出朴素上界 48 × 101 的四次方 × 2 的 18 次方 × 2 的 9 次方约 6.70×10 的 17 次方，再用 BFS 完整枚举跑出真实可达的 9895423 个状态，并把两者相差约 11 个数量级的来源拆成好感度值域、flag 与物品位图、变量相关性三层。</description></item><item><title>5.2 可达状态的枚举</title><link>https://plumephp.com/narr-sys-05-2-reachable-state-enumeration/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-05-2-reachable-state-enumeration/</guid><description>逐层 BFS 把 9895423 个可达状态一层层展开：给出每一层的新增与累计、峰值 frontier，以及 4 个好感度变量的实际值域。去重键是状态的规范串，层号就是最短步数。本节贴出 32 层完整输出，并给出预算 12000000 与峰值内存 3132.8 MB 的口径。</description></item><item><title>5.3 不可达节点与孤儿结局</title><link>https://plumephp.com/narr-sys-05-3-unreachable-node-orphan-ending/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-05-3-unreachable-node-orphan-ending/</guid><description>把「不可达」拆成两种口径：节点不可达（BFS 从未落到它）与选项不可达（它的 when 在任何可达状态下都不成立）。实测两者都是 0，5 个结局全部可达、孤儿结局 0、分支覆盖率 1000‰。另报告规格层面的一处欠声明：节点 d_lt_2 声明了 line_when 却没有 line_else。</description></item><item><title>6.1 死路检测</title><link>https://plumephp.com/narr-sys-06-1-dead-end-detection/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-06-1-dead-end-detection/</guid><description>死路是一个节点在当前状态下没有任何可用选项、且不是结局节点，玩家就卡死了。本节把静态死路与动态死路分开查：静态 0 个；动态用投影状态上的完整 BFS 与 20000 条采样，实测卡死 0 条。再用三组注入负例证明检测器确实会开火，而不是一个永远返回空的摆设。</description></item><item><title>6.2 汇流的合法性</title><link>https://plumephp.com/narr-sys-06-2-merge-legality/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-06-2-merge-legality/</guid><description>汇聚本身不是缺陷——115 条选项去重后只剩 56 条唯一跳转。真正的非法汇流是汇聚之后状态不可区分：两条不同入边到达同一节点后，下游全部条件的求值完全一致，信息被丢弃。本节给出可判定口径 D(M)，实测 34 个汇聚节点里 22 个冗余、3 个跨源冗余，并用合成规格负例证明检测器会开火。</description></item><item><title>6.3 结局的可达性</title><link>https://plumephp.com/narr-sys-06-3-ending-reachability/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-06-3-ending-reachability/</guid><description>5 个结局（灯守 / 离港 / 真相 / 缄默 / 沉没）全部可达，但可达不等于易达。本节为每个结局给出一条真实可回放的到达路径，再用 20000 条均匀随机采样算分布：离港 10074、沉没 5507、缄默 3223、灯守 1018、真相仅 178。并厘清 endings 的 id 与 dialogue 的 ending 两个口径。</description></item><item><title>7.1 分支宽度的度量</title><link>https://plumephp.com/narr-sys-07-1-branch-width-metric/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-07-1-branch-width-metric/</guid><description>宽度就是一个节点的出度：同时摆在玩家面前的选项数。本节给 48 个对话节点量出度，实测直方图是 5 个 0 出度、16 个 2 出度、26 个 3 出度、1 个 5 出度，最宽的一步是 d_dq_2 的 5 个选项；再按边距离分 23 层看每层宽度，并把 115 个选项去重成 56 条唯一跳转、47 个不同目标。</description></item><item><title>7.2 剪枝与采样上界</title><link>https://plumephp.com/narr-sys-07-2-pruning-sampling-bound/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-07-2-pruning-sampling-bound/</guid><description>路径数有两层上界：朴素乘积上界 5 的 31 次方约 4.66×10 的 21 次方，真实结构路径数 450208471680，剪枝后 BFS 可达边 115/115 即 1000‰。本节推导优惠券收集器的采样上界（覆盖 115 条边约 613 条路径），并实测随机与贪心两种策略在 N=100/1000/10000/20000 下的覆盖率收敛曲线。</description></item><item><title>7.3 组合爆炸的控制</title><link>https://plumephp.com/narr-sys-07-3-combinatorial-explosion-control/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-07-3-combinatorial-explosion-control/</guid><description>把分支宽度与深度当两条扰动轴：宽度因子 k 把每个有选项节点的出度乘以 2、3、4，路径数从约 4.50×10 的 11 次方一路涨到 10 的 30 次方量级，而去重跳转覆盖率始终 1000‰ 纹丝不动；深度预算 L 把探索限制在 L 步内，可达覆盖率随 L 上升、在 L=22 触顶。B 层只打印软告警，恒 exit 0。</description></item><item><title>8.1 好感度的状态机</title><link>https://plumephp.com/narr-sys-08-1-affinity-state-machine/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-08-1-affinity-state-machine/</guid><description>好感度是一台受钳位约束的整数状态机：状态 = 节点 + 4 个好感度整数 + 18 个 flag + 9 个物品。本节把《雾港夜航》的完整状态空间 BFS 一遍，实测四个变量的可达值域分别是 yan 21、hui 35、shen 12、mu 16，值域之积 141120，而真正可达的好感度四元组只有 87190——四个变量之间并不独立。P 层用同一批选项断言初值来源、add 累加与钳位。</description></item><item><title>8.2 阈值门与门限扰动</title><link>https://plumephp.com/narr-sys-08-2-threshold-gate-perturbation/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-08-2-threshold-gate-perturbation/</guid><description>好感度的分段在规格里就是一串 [aff, 名, &gt;=, 整数] 阈值门，长在选项 when、节点 line_when、结局 when 三处。本节把 15 条门限全抽出来，再逐条扰动 ±5，在同一采样口径下重算覆盖率与可达结局集合，找出 4 条临界门限；并如实说明为什么放宽 5 点不起作用而收紧 5 点才起作用——基线覆盖率已饱和在 1000‰。B 层只打印 WARN，退出码 0。</description></item><item><title>8.3 好感度的不变量</title><link>https://plumephp.com/narr-sys-08-3-affinity-invariant/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-08-3-affinity-invariant/</guid><description>四条必须恒为 0 的残差：钳位（可达状态与转移后都在 [0,100] 内）、初值（每个声明角色的 init 落在自身 range 内）、累积口径（新值恒等于 clamp(旧值 + add)，set 不写好感度）、门限可达性（15 条门限均可跨过）。四条残差合计 0；lin 与 hai 有 affinity 声明却不在 state.vars，按「声明未用=报告，用了未声明=FAIL」报告。</description></item><item><title>9.1 规格内联进单文件 HTML</title><link>https://plumephp.com/narr-sys-09-1-spec-inline-single-file-html/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-09-1-spec-inline-single-file-html/</guid><description>把 config/story_spec.json 与 core/src/inkwell/engine.ts 一起内联进一个单文件 HTML，产出 web/dist/ne09.html。本节实测产物 41641 字节、script src 0、外部 http(s) 链接 0，给出零外部依赖的自检口径与双击即玩的最小交付形态。</description></item><item><title>9.2 选择界面与状态显示</title><link>https://plumephp.com/narr-sys-09-2-choice-ui-state-display/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-09-2-choice-ui-state-display/</guid><description>给可玩原型挂一套稳定的 data-* 选择器契约：当前节点、每个选择按钮、四个好感度、已置位 flag、持有物品各有一个可寻址的属性。再用 Playwright 无头打开这页单文件 HTML，断言 DOM 已绘制、按钮数等于当前可用选项数、点击后节点推进。</description></item><item><title>9.3 原型与内核的同源</title><link>https://plumephp.com/narr-sys-09-3-prototype-kernel-same-origin/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-09-3-prototype-kernel-same-origin/</guid><description>浏览器里走完同一条确定性策略路径（总是选第一个可用选项，共 25 个事件），读出终局状态，与 Python 侧产物比对 canonical 串与 FNV-1a 摘要。三侧锚点一致：摘要 4162796975、节点 e_lit、结局 灯守。只对整数状态写逐位一致。</description></item><item><title>附录 A 对话树格式、条件文法与数据集索引</title><link>https://plumephp.com/narr-sys-appendix-a/</link><pubDate>Fri, 16 Oct 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/narr-sys-appendix-a/</guid><description>《叙事策划与叙事工艺》卷二《叙事引擎与分支系统》附录 A：把全卷 16 章 48 节散落的对话树节点与选项字段、嵌套数组条件文法与四类效果算子汇成索引表，给出本卷 S/P/W/D 四层共 43 个仿真脚本、31 个内核模块与 37 份产物的实盘清点，并附一段可跑的 TypeScript 对话树格式检查器——它连同三个注入负例证明格式约定不是纸面条文。</description></item></channel></rss>