文档索引

Cattca 脚本语法文档

Cattca 是一门嵌入 Markdown 的轻量脚本语言,专为互动叙事(Interactive Fiction)设计。脚本在 <//> 命令块中编写控制逻辑,在块外书写 Markdown 正文,两者交替构成完整的互动故事。

基本结构

一个 Cattca 脚本由文本块和命令块交替组成:

Markdown 正文…

</命令1; 命令2; …/>

更多 Markdown 正文…
  • 文本块:命令块之外的任何内容,支持标准 Markdown 语法,由浏览器端 marked.js 渲染。
  • 命令块:用 </ 和 /> 包裹,内部可包含多条命令,用分号 ; 分隔。

命令块可以跨越多行,分号是命令分隔符而非换行符。

注释

使用 /* */ 在脚本任意位置书写注释,注释内容会被解析器完全忽略:

/* 这是一条注释,不会出现在输出中 */
你醒了。
</let hp = 100; /* 初始生命值 */ />

注释可以出现在文本块和命令块中,但不能嵌套。

命令参考

let — 声明变量

声明一个新变量,可选赋初值。变量必须先 let 声明,才能用 set 修改。

let 变量名
let 变量名 = 表达式

示例:

</let name = "莱莉菥";
let hp = 100;
let maxHp = 100;
let isAlive = true;/>

变量名必须以字母或下划线开头,由字母、数字、下划线组成。

set — 修改变量

修改已声明变量的值。若变量未声明,会抛出运行时错误。

set 变量名 = 表达式

示例:

</set hp = hp - 10;
set name = "受伤的莱莉菥";/>

apply — 行内输出

将表达式的值输出到文本流中。输出会与周围的 Markdown 文本拼接后统一渲染,不会产生多余的段落换行。

apply 表达式

示例:

你当前的生命值是 </apply hp /> 点。
剩余生命值百分比:</apply hp / maxHp * 100 />%。

apply 非常适合在句中将变量值自然嵌入。它等价于其他模板语言中的 {{ variable }}。

label — 定义标签

在当前位置定义一个命名标签,供 goto 跳转。

label 标签名

标签名区分大小写。label 语句本身不产生任何输出。

示例:

</label start;/>

goto — 跳转

将执行流程跳转到指定标签处。

goto 标签名

示例:

</goto start;/>

若跳转到不存在的标签,会在日志中输出警告,脚本继续执行(防止死循环)。

if — 条件判断

根据条件执行一条命令。

if 表达式 -> 命令

示例:

</if hp <= 0 -> goto gameOver;
if hasKey -> goto openDoor;/>

条件为真(truthy)时执行 -> 右侧的命令。右侧命令可以是任何单条命令(goto、set、exit 等)。

exit — 结束脚本

立即终止脚本执行。

exit

示例:

</exit/>

input case — 选项输入

向用户展示一组选项,等待用户点击选择。选择后执行对应的命令。

input case 变量名: '选项1文本' -> 命令1: '选项2文本' -> 命令2: ...
  • 变量名: 可选——如果提供,选中的选项文本会存入该变量
  • 选项之间用 : 分隔
  • 每个选项后跟 -> 命令,选择后执行对应命令

示例(带变量):

</input case choice:
'打开宝箱' -> goto treasure:
'继续前进' -> goto nextRoom:
'原路返回' -> exit;/>

示例(不带变量):

</input case:
'继续睡觉' -> goto sleep:
'起床' -> goto wakeUp;/>

input text — 文本输入

向用户展示一个文本输入框,将输入内容存入变量。

input text 变量名

示例:(变量必须先 let 声明,理由同 random)

</let playerName = "";
请输入你的名字:
</input text playerName;/>
欢迎,</apply playerName />!

log — 调试日志

向调试日志区域输出一条信息,对玩家不可见。

log 表达式

示例:

</log "进入了房间3,当前hp=" + hp;/>

日志面板默认显示在游戏运行区底部,适合开发调试。

random — 随机数

生成一个指定范围内的随机整数(含两端)。

random 变量名 = 最小值 最大值

示例:

</let dice = 0;
random dice = 1 6;/>
骰子点数:</apply dice />

变量必须先 let 声明。最小值和最大值可以是表达式(如 random atk = baseAtk baseAtk+10)。

表达式

表达式在 let、set、if、apply、log、random 的值位置中使用,支持以下类型和运算符。

字面量

类型 示例
数字 42、-3、3.14
字符串 "hello"、'你好'
布尔 true、false
空值 null

字符串支持转义:\n(换行)、\r(回车)、\t(制表符)。

运算符

支持标准 JavaScript 运算符子集:

类别 运算符
算术 + - * / %
比较 == != > < >= <=
逻辑 && || !
三元 条件 ? 真值 : 假值

变量引用

直接使用变量名即可读取其值:

</let a = 10;
let b = a * 2;       /* b = 20 */
apply a + b;/>          /* 输出 30 */

完整示例

以下是一个完整的互动叙事脚本——"莱莉菥的早晨":

# 莱莉菥的早晨

你叫**莱莉菥**。
现在是早上六点,你醒了。
你躺在床上。

## 你要怎么做?

</let cntsleep = 0;
label 1;
input case:
'继续睡觉' -> goto 2:
'起床' -> goto 3;
/>

</label 2;
set cntsleep = cntsleep + 1;
if cntsleep > 3 ->goto 4/>
你睡不着。已经尝试了 </apply cntsleep /> 次。

### 状态
- 尝试睡觉次数:</apply cntsleep />
- 当前时间:早上</apply cntsleep+5/>点

</goto 1;/>

</label 3/>
# 结局一:起床

你成功起床了!

> 新的一天开始了,充满无限可能。

</exit/>

</label 4/>
# 结局二:睡觉

你又睡着了。

> 有时候,休息是最好的选择。

</exit/>

执行流程

  1. 显示开场叙事,声明变量 cntsleep = 0
  2. 进入 label 1,向玩家展示两个选项
  3. 选择"继续睡觉" → cntsleep + 1,显示一段带变量的文本,若 cntsleep > 3 则跳转结局二,否则循环回 label 1
  4. 选择"起床" → 跳转结局一

语法速查

命令 语法 说明
let let name = expr 声明变量(可选赋值)
set set name = expr 修改已声明的变量
apply apply expr 行内输出值到文本
label label name 定义跳转标签
goto goto name 跳转到标签
if if cond -> cmd 条件执行命令
exit exit 结束脚本
input case input case [var:] 'opt' -> cmd : ... 选项输入
input text input text var 文本输入
log log expr 调试日志
random random var = min max 随机整数

本页内容来自仓库 docs/guide/cattca-syntax.md·在 GitHub 上查看