跳到主要内容

Lattice 语法参考 · 第 4 章,共 4 章

校验与诊断

Lattice 先读取文件,再按大纲或发布就绪标准校验结构。创作检查会把这个类型化结构与精确、感知语言区域的正文统计结合起来。预览或交付前应使用发布就绪标准,最后还要亲自阅读受影响的路线。

Parse 与 Validate 是不同关卡

Parse

Parse 检查:

  • 每个已载入 .la 文件的 Lattice 语法;
  • 带引号的相对 use 路径;
  • 导入是否留在项目内;
  • 重复导入与导入循环。

没有语法或导入错误时,parse 结果有效。但它不保证元数据类型、引用、图结构或运行时路径有效。

Validate

Validate 接着检查:

  • 必填元数据和值类型;
  • 实体、Scene、Block、批注、Predicate、State、Group、Pool 和 Module 引用;
  • 所选故事类型允许的声明和流转终结语句;
  • 链接是否留在主故事或当前 Module 内;
  • 叙事 setup、requirement、resolution、beat 与 reveal 属性;
  • 线性或分支图属性;
  • 有限状态运行时可达性、软锁、循环和 Module 有用性;
  • 是否能够完整检查每一种可能路线。

只有选定校验路径完整结束且没有 error 诊断时,validate 结果才有效。警告和信息消息不会让故事失效。

outline 就绪会执行相同的结构检查,但暂时只忽略“缺少读者正文”错误。作者因此可以先建立稳定的 Scene 和 Block ID、摘要、目的、流转、预算与连续性关系,再开始创作正文。publish 是默认值,并保留完整校验规则。

检查创作进度

创作检查会报告从源码衍生的正文目标、Story、Scene 与 Block 的精确计数、当前就绪阶段,以及最大的局部缺口。Scene 和 Block 目标是创作预算。只有当前获批任务明确选择 Story 最小值或最大值时,它们才成为硬性的完成门槛。

必须遵守的编辑循环

  1. 编辑一组连贯改动。
    让改动足够小,以便把诊断与真正原因联系起来。
  2. 解析配置的入口。
    先修复语法与导入错误,再解释元数据或图消息。
  3. 校验并检查大纲。
    正文尚未完成时,检查结构、精确进度和局部缺口。
  4. 按发布标准校验。
    恢复可见内容要求,修复每一个错误,并有意识地判断每一条警告。
  5. 体验受影响的路径。
    结构有效无法证明语气、节奏或选择是否有意义。

始终校验配置入口及其完整导入展开。只解析一个孤立文件,可能漏掉重复 ID、无法解析的跨文件目标和全局路径失败。

如何阅读诊断

有用的诊断会提供:

  • 稳定诊断代码;
  • 级别(errorwarning 或信息);
  • 精确文件和源码范围;
  • 描述违反规则的消息;
  • 其他声明或边参与问题时的相关源码位置;
  • 已知安全修复方式时的帮助文本。

先处理最早的语法/导入错误。缺失分隔符会移动解析位置,使后续诊断产生误导。语法层可靠后,沿引用找到声明和相关位置,不要只修改最终消息所在处。

级别与创作行动

级别含义必须采取的行动
Error故事无法产生有效的阅读体验完成前必须修复
Warning结构可以运行,但可能存在非预期内容结合语境检查
信息不影响有效性的补充说明作为指导使用

不要把警告自动改写成内容。永远不可用的 Module 可能是意外死内容,也可能是等待另一条路线的有意草稿。修改前先检查创作意图。

常见语法失败

缺少分号

text
# 错误
use "./story/opening.la"

# 正确
use "./story/opening.la";

注意:scenemodule 主体,以及外层 choice 主体,结束后不加分号;它们内部的内容和 option 仍然需要分号。

错误注释标记

text
# 正确注释
# 玛拉从西边进入。

# 错误
// 玛拉从西边进入。

把引用写成带引号字符串

text
# 错误:字符串
entry: "opening"

# 正确:Block ID
entry: opening

需要字符串时使用了标识符

text
# 错误
language: zh-CN

# 正确
language: "zh-CN"

重复或未知元数据

text
# 错误:重复 title 且 color 不受支持
scene garden (
  title: "花园",
  title: "那座花园",
  color: "blue"
) { ... }

每个键只保留一次。删除不支持字段;如果它确实只是扩展元数据,则改成 x_ 键,同时理解它不会影响内置语义。

常见引用与所有权失败

实体类型错误

Dialogue 说话者或 Scene pov 必须引用角色。Scene location 必须引用地点。CYOA 事件元组必须精确符合 Predicate 模式。

ID 缺失或改名

修改标题不会影响引用。修改 ID 则需要更新每一处使用它的 entry、流转目标、所有者字段、Guard、Effect 和批注引用。

跨所有者流转

主故事 Block 不能通过 nextchoice 进入 Module。Module 不能指向主故事或另一个 Module。主故事只通过 enter <pool> -> <resume> 进入 Module 工作流;Module 只通过 complete 返回。

故事类型不匹配

线性故事不允许选择、有限 State、Pool、Module、entercompleteinitial_state。只有故事确实需要分支或记忆 State 时才切换到 CYOA,不要只为了消除错误而切换。

修复线性结构

遇到线性错误时,从 story.entry 画出唯一链,并确认:

  1. 入口没有入边;
  2. 其他每个 Block 恰好有一条 next 入边;
  3. 所有 Block 都可达;
  4. 没有 Block 能回到自身;
  5. 恰好一个 Block 以 end; 结束。

声明顺序和 Scene 分组与这些图规则无关。孤立 Block 必须连接进链或删除;把它放到另一个 Block 旁边不会创建连接。

修复分支 CYOA

对没有 Pool/Module 的 CYOA:

  1. story.entry 开始;
  2. 跟随每个 option,而不只是首选路径;
  3. 确认每个目标存在且留在主故事;
  4. 检查所有 Block 可达;
  5. 拒绝循环;
  6. 确认每条最长路径都到达 end;

合流是允许的。一个共享 Block 可以有多条 choice 入边。

检查 Pool 与 Module

运行完整校验前,逐个枚举每个 Pool:

  1. 进入 Pool 时激活的 State;
  2. 每个符合条件且未完成的 Module;
  3. 每种可能 completion 产生的 State;
  4. 每次完成后退出 Guard 是否成立;
  5. 退出仍为假时,是否还有另一个未完成 Module 可用;
  6. 恢复路径是否能到达结局。

这项检查有助于找到路线卡住的位置,但不能取代 Validate。TypeApe 仍会检查每一种可达的 Module 顺序和 State 组合。

软锁模式

如果没有 Module 能激活 st_knows_signal,这个 Pool 就会失败:

text
pool investigation (
  title: "调查",
  exit_requires: [st_knows_signal]
);

退出为假且没有符合条件的未完成 Module 时,读者没有任何动作能改变 State。应该增加可达 Module/Effect、修正 Guard 或修改退出条件,而不是用扩展元数据隐藏问题。

运行时循环模式

即使每个所有者内部的 Block 图都无环,State 与 Pool 转移仍可能重复同一个运行时配置。完整校验会拒绝可达运行时循环,因为读者可能永远继续而无法保证终止。

校验不会替你决定什么

校验负责检查结构,不会判断创作体验的所有方面:

  • 分支连续性不一定对所有路径成立。 在只有分支的图中,一条 setup 警告可能只能证明“某个”更早铺垫能到达该 Block,而不是所有进入路线都有铺垫。
  • Floating beat-order 诊断有限。 Pool/Module 运行时校验目前不会发出所有静态 beat_order 警告。
  • Floating 故事的同 Block 事件顺序较保守。 如果路径敏感顺序很重要,把互相链接的 foreshadowing 和 reveal 放到不同 Block。
  • 叙事标记 ID 是幂等集合事实。 重复一个标记不会创建可计数的多次出现。
  • Predicate 是带类型的元组标签,不是规则引擎。 不会隐含传递性、本体推理或通配符匹配。
  • requires 有两个领域。 Block requires 指叙事标记;Module requires 与 Pool exit_requires 指运行时 State ID。
  • 有效不等于文学质量。 校验不会证明正文连贯、选择有意义或结局令人满意。

手册与 TypeApe 不一致时

以 TypeApe 显示的诊断为准,不要用未记录语法或 x_ 元数据绕过结果。寻求帮助时,请附上诊断代码和能够重现问题的最小源码示例。

返回 Lattice 语言概览,或继续阅读 Agent 工作流