跳转到内容

锚点与修饰符体系

Ktory 的核心语法哲学与执行拍模型

锚点声明执行拍或选项,修饰符携带参数。本文采用 2026-10-22 新规格;本轮实现与验证进行中,不代表已安装版本已更新。

写法 结构 默认行为
角色: 台词/: 旁白 TextStep Main 默认等待有效输入
空 :/: .effect() TextStep 进入时结束本头前句显示,执行标签后等输入;不停止 BGM 等持续资源
#/#.effect()/无子项的 #do DirectiveStep 独立指令默认自动继续
有缩进 */+ 的 #choice ContainerStep Main 选择;辅助整体忽略

结构仍由锚点和缩进决定,不把所有 # 都当自动指令。章节和播放头身份分离。旧 #parallel/#lane 需显式迁移,不能当作新轨语法继续执行。

爱丽丝: 真是不可思议…… .next(seconds=0.5)
#.sfx("door")
: .camera_shake(0.5)
#.wait(seconds=3)

内建参数先完整具名:.clock(name="song")、.track(source="Lyrics", name="lyric")、.at(value=3, clock="song")、.wait(seconds=2)、.next(seconds=1)、.duration(seconds=3)、.skippable(enabled=false, seconds=3)、.loop(count=2)。本版不提供内建位置参数语法糖;未知宿主标签如 .bgm("main", volume=0.6) 仍可按位置传参,宿主负责实际动作。

.tag 与 .tag() 无参等价,零值与省略不同;可选参数不要求填满。无参 wait 估算主语言阅读时间,无参 next 为 0 秒。无上方锚点的修饰符仍是可定位语法错误,不跨分支/节吸附。

wait 与 next 从全文显示完成同时起算;无文本拍从进入起算。wait 是最低限制,不自行启用自动;next 安排自动推进,组合取 max。.wait(seconds=2).next(seconds=5) 在 2 秒后可点击,5 秒自动;.wait(seconds=5).next(seconds=2) 在 5 秒自动。受 wait 或 skippable 限制的人工点击丢弃,不缓存。

普通 # 已默认自动,所以 #.wait(seconds=3) 在 3 秒后继续;: .wait(seconds=3) 解除限制后仍等点击。允许的打印中点击只快显,不同时推进。AUTO 作用于 Main,仍遵循最低停留。

duration 与 wait 同起点,但不阻滞 advance。有效 advance 可提前进入下一句;同头后句进入就撤下前句,即使改用另一显示位置。空 : 也结束前句显示。等待后句的 at 时前句可按自身寿命保留,EOF/stop 的末句也可延续。显示到期不会推进 Main,wait 不隐含隐藏文字。

辅助输出后直接继续至 at/Core 边界,不受上述 wait/next/AUTO 影响,也不默认阅读;duration 仍只影响其显示。旧 duration/淡出通知只能处理旧内容,不能清除新句。

支持 *斜体*、**粗体**、~~删除线~~ 和 [书桌]{desk}。当前脱糖输出为标签字符串,例如 <ruby="desk">书桌</ruby>,并非独立的 Ruby 结构化对象。原生标签也会透传,具体标签能否显示由渲染器决定。

使用反斜杠转义需要按字面显示的保留字符。不要把块级 Markdown 标题、列表或代码围栏当作对白结构。跨 Web 与 Unity 的富文本显示需要分别验证。

用三个或更多 ASCII 单引号包住需要原样显示的内容,可内嵌,也可跨多行:

爱丽丝: 我想写'''.wait''',这里的 **粗体** 仍然生效。 .wait(seconds=1)
爱丽丝:
@zh: '''
.wait
// 这也是正文
<b>**不会变成粗体**</b>
'''
@en: Text containing '''.wait'''.
.next(seconds=1)
: ''''这里直接显示 ''' 三个单引号''''

围栏内不解析 tag、注释、语言标签、控制流、Markdown、Ruby 或原生富文本,也不处理反斜杠转义。围栏外的修饰符属于整拍;多行区块仍只有一拍,各语言版本可独立选择普通或纯文本写法。

开始和结束围栏必须包含同样数量的单引号,且至少三个;内部其他长度的引号串都是文字,不嵌套解析。选择比内容中连续单引号更长的围栏。只显示 ''' 时,用四个单引号包成多行区块,避免边界与正文连成一串。中文弯引号始终是文字。

单行片段保留内部空白。开始围栏后直接换行的区块移除首尾排版换行及正文公共缩进,保留相对缩进、内部空行和行尾空格;tab 按两列计算。围栏未闭合会报告开始行/列并停止加载。

接入层读取各语言结果的 Segments(如果存在),将 IsLiteral=true 的片段按纯文本显示并保留空白;其他片段沿用富文本处理。仅把拼接的 Content 再当富文本显示会丢失这层区别。共用 Reader 已支持;其他宿主需落实对应渲染。