LetsGal Studio 的剧本以 JSON 文件保存在工程目录里,结构完全公开。本页前半部分讲整体结构与引用规则,后半部分的指令全参考逐一列出全部 38 种指令的字段。
想让 AI 帮你写剧本?把本页整页复制给 AI,再附上你工程里的角色、场景、变量的 id 对照表(见页尾「让 AI 生成剧本」一节),AI 就能直接产出可以放进工程的章节 JSON。

工程里的剧本文件

一个 Studio 工程的根目录下,与剧本相关的文件如下:
路径内容
project.json工程配置与章节索引(章节顺序、目录结构)
chapters/*.json剧本正文。每个章节一个文件,文件名就是章节名(如 chapters/序章.json
characters.json角色定义:id、名字、表情、皮肤、属性模板
scenes.json场景定义:id、名字、图层
project.variables.json全局变量表:id、名字、类型、默认值
assets/素材文件,按分类分子目录(bgm/se/video/ 等)
几条基本规则:
  • 改章节名时,章节文件也会跟着改名;文件名与 JSON 里的 name 字段始终一致。
  • project.jsonchapterOrder 是一个章节名数组,决定章节的运行顺序;新章节文件必须登记进去才会被工程识别。
  • chapterOrder 的第一项是入口章节(工程模板里叫「开始」),不可删除。
  • project.json 里还有 chapterFolders(编辑器里的虚拟目录)和 chapterTreeOrder(章节树根层排序),只影响 Studio 里的展示,不影响运行顺序。

章节文件的结构

每个 chapters/*.json 的顶层结构:
{
  "id": "ch-1755500000000-1",
  "name": "第一章",
  "fragments": [
    { "id": "frag-1755500000000-2", "name": "main", "blocks": [] }
  ]
}
字段类型必填说明
idstring章节唯一标识。Studio 生成的格式是 ch-<毫秒时间戳>-<序号>,也接受 UUID;全工程内不可重复
namestring章节名,必须与文件名一致
fragments数组剧情片段列表,见下节
disabledboolean章节停用开关,省略视为 false

剧情片段

剧情片段在编辑器里叫 Fragment,是章节内的执行单元:
{
  "id": "frag-1755500000000-2",
  "name": "main",
  "blocks": [ ... ]
}
字段类型必填说明
idstring片段唯一标识,格式 frag-<毫秒时间戳>-<序号>。分支、条件、调用片段都靠它引用,必须唯一且真实存在
namestring片段名。fragments[0] 必须叫 main,是章节正文;其余片段自由命名(如「去图书馆」)
blocks数组指令序列,顺序执行

执行模型:默认线性链

理解剧本流转只需要三句话:
  1. 章节从 main 片段的第一个 Block 开始,顺序执行;一个章节执行完,进入 chapterOrder 里的下一章。
  2. 跳出线性流的手段只有三种指令:branch(玩家选项)、if(条件跳转)、callFragment(直接调用片段)。它们的目标都是同一章节内的非 main 片段。
  3. 跳转到的片段执行完毕后,回到原跳转点之后继续(汇流回主线),类似函数调用。片段之间不要循环引用。

指令的通用结构

剧本里的每条指令(Block)最多只有 4 个字段:
{
  "id": "66d4d76d-ddec-4f99-836a-50beac4f6f90",
  "type": "dialogue",
  "props": { "disabled": false, "characterId": "b8e3efe5-…" },
  "content": [
    { "type": "text", "text": "台词正文。", "styles": {} }
  ]
}
字段必填说明
idBlock 的编辑器内部 id(UUID)。可以省略,Studio 打开工程时会自动补生成;剧情跳转不依赖它
type指令类型,合法值共 38 种,全表见下文指令全参考
props该指令的全部参数。所有指令都支持 "disabled": true 把这条指令临时停用
content视类型只有携带正文的指令才有(dialoguenarrationstoryParagraphcommentfloatingText),存放文字内容

参数存储的三条约定

编辑器底层只能在 props 里保存标量(字符串、数字、布尔),因此磁盘 JSON 有几个乍看奇怪、实则一致的约定:
  1. 不少布尔与数值以字符串保存。例如 sound"loop": "true""volume": "80"scene"waitForComplete": "false"。每个字段的实际存储类型以指令参考页的标注为准,不要自行改成真布尔/真数字。
  2. 复杂结构一律是「JSON 字符串」,即把整个 JSON 数组或对象序列化成一个字符串再存入 props。涉及的字段:branch.choicesif.conditionsstageAnimation.clipJsoncallExtensionFunction.paramsJsonparticle.optionsJsoncamera.objectTargetsJson
  3. 省略即默认。Studio 自己落盘时会写全所有字段(包括默认值),但手写或 AI 生成时只需给出必填字段和想改的字段,其余省略,打开工程时会按默认值自动补齐。

正文的结构

正文是一个内联片段数组,最常用的形态:
"content": [ { "type": "text", "text": "这是一句话。", "styles": {} } ]
styles 支持 boldtextColorbackgroundColor 等富文本样式;一条正文可以拆成多段不同样式的 text 片段。纯文本剧本让 styles 保持 {} 即可。

引用规则

这是 AI 生成剧本最容易出错的地方:所有 id 引用都必须指向工程里真实存在的实体,不能凭空编造
引用格式来源
角色 characterIdUUIDcharacters.jsoncharacters[].id
场景 sceneIdUUIDscenes.jsonscenes[].id
音频 soundIdUUID资源库中音频素材的 id
片段 fragmentIdfrag-…同一章节内 fragments[].id
素材 uri相对路径assets/ 下的路径,如 bgm/主题曲.mp3video/intro.mp4
表情 expression / 皮肤 skin名字字符串该角色在 characters.json 里配置过的表情名 / 皮肤名
变量的 key 有三种命名空间:
变量种类key 写法例子
全局 / 系统变量裸名字alice_affection
角色属性变量角色UUID.属性名b8e3efe5-….好感度
扩展存档变量扩展id.键名avg.official.affection.total
其他通用格式:
  • 坐标与尺寸:写成 "(x,y)" / "(宽,高)" 的字符串,支持像素、百分比和 center / left / right / top / bottom 关键字,如 "(center,center)""(50%,200)"
  • 颜色:CSS 色值字符串,如 "#000000"
  • 站位 / 距离position 内置 left / center-left / center / center-right / rightdistance 内置 far / middle / near;空字符串表示用工程默认,也可以填工程里自定义预设的 id。

三个复杂结构详解

分支的选项列表

branch 指令的 props.choices 是一个 JSON 字符串,反序列化后是选项数组。选项有两种模式:
[
  { "mode": "jump", "text": "去图书馆", "fragmentId": "frag-3" },
  {
    "mode": "vars",
    "text": "回家休息",
    "varOps": [
      {
        "key": "b8e3efe5-….好感度",
        "op": "+=",
        "aKind": "lit",
        "aLit": "5",
        "bKind": "none",
        "binOp": "+"
      }
    ]
  }
]
字段说明
modejump = 跳转到片段;vars = 不跳转,只修改变量
text玩家看到的选项文字
fragmentIdjump:目标片段 id,空字符串表示选中后什么都不做、继续主线
varOpsvars:变量操作数组,每一项与 setver 指令的 props 同构(见下)
visibleIf可选:变量条件表达式,为真才显示该选项
isDefault可选:标记为默认选项(预览快进时自动选它),全组最多一个
写入 props 时记得把整个数组序列化成字符串:
"choices":
  "[{\"mode\":\"jump\",\"text\":\"去图书馆\",\"fragmentId\":\"f3\"}]"

条件的结构

if 指令的 props.conditions 也是 JSON 字符串,反序列化后是条件数组,多条之间用 props.logicOpand / or)连接:
[
  {
    "left": "alice_affection",
    "op": ">=",
    "rightKind": "literal",
    "rightLiteral": "50"
  },
  {
    "left": "route_flag",
    "op": "==",
    "rightKind": "variable",
    "rightRef": "target_route"
  }
]
字段说明
left左值:变量 key
op比较算子,全集:== != > >= < <= contains notContains startsWith endsWith isEmpty isNotEmpty exists notExists custom
rightKind右值类型:literal(字面量)或 variable(另一个变量)
rightLiteral右值字面量原始字符串(数字直接写 "50",不用补引号);opcustom 时这里是一段自由 JS 表达式
rightRef右值变量 key(rightKindvariable 时用)
一元算子(isEmpty / isNotEmpty / exists / notExists)不需要右值。条件为真跳 thenFragmentId(必填),为假跳 elseFragmentId(可空,空则继续当前片段)。

变量赋值的运算字段

setver 把「A 运算」拆成了几个标量字段,branch 选项里的 varOps 与它同构:
字段说明
key要写入的变量 key(必填)
op赋值算子:= += -= *= /=(必填)
aKind第一操作数类型:lit(字面量)或 var(变量)
aLit / aVaraKind 二选一填写,另一个留空字符串
bKind第二操作数类型:none / lit / var
bLit / bVarbKind 填写
binOp两个操作数之间的运算:+ - * /
两条组合规则:op 不是 =bKind 必须是 none(即 好感度 += 5 这种形态);要用双操作数(金钱 = 基础 + 奖金)时 op 必须是 =。字面量写法:true123"你好"(字符串带引号)。

指令全参考

以下是全部 38 种指令的字段字典:每种指令给出一句话用途、可抄的 JSON 示例和完整字段表;想学习在编辑器里怎么用某个指令,点各小节里的「手册」链接。

文本与角色

对白、旁白、立绘与文字样式 · 9 种

场景与演出

场景、镜头、粒子与浮动文字 · 10 种

音视频

音乐、音效与视频 · 4 种

逻辑流程

分支、条件、变量与章节流转 · 10 种

界面与扩展

消息框、自定义界面与扩展方法 · 4 种

注释

只给编辑者看的备注 · 1 种
四条阅读约定
  1. 所有指令的 props 都支持 "disabled": true(这条指令不执行),字段表里不再重复。
  2. 类型列就是磁盘存储类型:标 "true"/"false" 的是字符串布尔,标 boolean 的才是真布尔;标「JSON 字符串」的字段要把整个结构序列化成字符串存入。
  3. 省略非必填字段即取默认值,示例里只写了常用字段。
  4. 每节末尾「生成时勿填」列出的字段由编辑器自动维护,AI 生成剧本时不要输出。

文本与角色

写故事最常用的一组:说话、叙述,以及立绘和文字样式的控制。

对白

type: "dialogue" 角色说一句话,一句一个 Block,正文放 content。图形界面用法见手册:对白
{
  "type": "dialogue",
  "props": {
    "characterId": "<角色UUID>",
    "characterName": "小雪",
    "expression": "微笑",
    "position": "center"
  },
  "content": [
    { "type": "text", "text": "今天想去哪里?", "styles": {} }
  ]
}
字段类型必填默认说明
characterIdUUID""说话角色,引用 characters.json
characterNamestring""角色显示名(冗余字段,与角色同名即可)
nameVariantIdstring""角色的名字变体 id,空 = 主名称
expressionstring""该角色配置过的表情名
skinstring""立绘皮肤名,空 = 自动
distancestring""far / middle / near 或自定义距离预设 id,空 = 默认
positionstring""left / center-left / center / center-right / right 或自定义站位预设 id
showCharacterbooleantrue说话时是否同时显示立绘
dialoguePortraitOnlybooleanfalse只显示对话框头像,不上舞台立绘
keepCharacterbooleantrue这组对白结束后是否保留立绘
keepDialoguebooleantrue结束后是否保留对话框
两个常见的 AI 生成坏习惯,请避免:
  1. 不要在对白前多加「角色登场」。对白自带立绘显示(showCharacter 默认 true),说话时角色会自动登场;前面再加一个 showCharacter 指令就是重复调用。只有角色不说话就要先站上舞台时,才单独使用「角色登场」。
  2. 对话收尾要放下对话框。一段对话结束、后面不再有对白时(尤其接镜头动画、场景切换等演出),把最后一句 dialoguenarrationkeepDialogue 设为 false,对话框会自动隐藏,演出画面才干净。
生成时勿填:isFirstisLastprevExpressionprevNameVariantIdvoiceHashentryMotion* / exitMotion* 系列。

旁白

type: "narration" 无角色的叙述文字,显示在对话框里。图形界面用法见手册:旁白
{
  "type": "narration",
  "props": {},
  "content": [
    {
      "type": "text",
      "text": "放学后的教室,只剩下我们两个人。",
      "styles": {}
    }
  ]
}
字段类型必填默认说明
keepDialoguebooleantrue结束后是否保留对话框
生成时勿填:voiceHash

段落

type: "storyParagraph" 整屏长文(小说式演出),相邻的段落 Block 会合并成一屏。见手册:段落
字段类型必填默认说明
speednumber0文字速度(字/秒),0 = 跟随全局设置
生成时勿填:isFirst

角色登场

type: "showCharacter" 让角色立绘出现在舞台上(不说话)。注意:对白会自动显示立绘,本指令只用于角色不说话就登场的场合,不要作为对白的前置步骤。见手册:角色
{
  "type": "showCharacter",
  "props": {
    "characterId": "<角色UUID>",
    "expression": "微笑",
    "position": "left"
  }
}
字段类型必填默认说明
characterIdUUID""角色引用
characterNamestring""显示名冗余字段
expressionstring""空 = 角色的第一个表情
skinstring""立绘皮肤
distance / positionstring""同「对白」
cameraBoundbooleanfalse立绘是否参与镜头位移 / 震动 / 景深
cameraDistancenumber1镜头深度距离,越小越靠近镜头
生成时勿填:animatedmotion* 系列。

更新立绘

type: "updateCharacter" 修改已在场角色的表情、皮肤或站位。见手册:更新立绘
字段类型必填默认说明
characterIdUUID""角色引用
characterNamestring""显示名冗余字段
expression / skin / distance / positionstring""同「对白」,空 = 不变
placementTransitionEnabledbooleantrue换位时是否播放平移动画
placementTransitionDurationnumber350换位动画时长(毫秒)
placementTransitionEasingstring"outCubic"linear / inOutQuad / outCubic
placementTransitionBlockingbooleanfalse是否阻塞后续指令

移除立绘

type: "removeCharacter" 手册:移除立绘
字段类型必填默认说明
characterIdUUID""要移除的角色
characterNamestring""显示名冗余字段
生成时勿填:motion* 系列。

设置对话参数

type: "switchDialogueStyle" 切换对话框样式或微调打字机参数,数值参数以 -1 表示「不覆盖」。见手册:设置对话参数
字段类型必填默认说明
sourcestring""样式来源:preset / user / system / extension,空 = 只改参数不换样式
targetIdstring""对应来源下的样式 id
extensionIdstring""sourceextension 时的扩展 id
textSpeednumber-1每字间隔毫秒(0–200)
charFadeInnumber-1单字淡入时长(0–300)
waitForIconDelaynumber-1等待图标出现延迟(0–2000)
showWaitForIconstring""三态:""(不变)/ "true" / "false"

设置段落参数

type: "switchParagraphStyle" 切换段落样式与文字浮现效果,数值参数以 -1 表示「不覆盖」。见手册:设置段落参数
字段类型必填默认说明
sourcestring""preset / user / extension,空 = 只改参数
targetId / extensionIdstring""同上
textSpeednumber-1每字间隔毫秒
charFadeInnumber-1单字淡入时长
revealEffectstring""浮现效果:smooth-rise / classic / instant / smooth-drop / slide-left / slide-right / pop / flip / swing / blur,空 = 不变
revealDistancenumber-1浮现位移距离(0–48 像素)
revealScalenumber-1起始缩放(30–100,百分比)
revealRotationnumber-1起始旋转角度(0–180)
revealBlurnumber-1起始模糊(0–12 像素)
readModestring""已读段落:dim(变暗)/ keep(保留)/ hide(隐藏),空 = 不变
historyLimitnumber-1保留的历史段落数,0 = 不限

设置立绘发言状态

type: "portraitStyleRule" 一条「规则」指令:设定之后所有对白的立绘进退场动效、发言高亮和空间聚焦。字段较多,按组列出,全部为标量直存。见手册:设置立绘发言状态 总开关与版本
字段类型默认说明
enabledbooleantrue规则总开关
portraitMotionSemanticsVersionnumber0新建规则写 20 是旧工程兼容语义
进场动效 entryMotion* 与退场动效 exitMotion*(两组字段同构,仅前缀不同)
字段(以 entry 为例)类型默认说明
entryMotionEnabledbooleantrue是否启用
entryMotionPresetstring"classic"classic / fade / slide / rise / pop / swoop / drop / zoom / float / wipe / dissolve / none
entryMotionDurationnumber300时长(毫秒)
entryMotionIntensitynumber1强度,建议 0.25–2
entryMotionDirectionstring"auto"auto / left / right / up / down
entryMotionTimingstring"preset"preset / smooth / snappy / bounce / linear
entryMotionFadeEnabledbooleantrue是否叠加淡入淡出
entryMotionDistanceModestring"offset"offset(固定位移)/ offscreen(从屏幕外)
entryMotionEdgeSoftnessnumber-1wipe / dissolve 边缘柔化(0–0.25),-1 = 按预设默认
entryMotionGrainSizenumber-1dissolve 颗粒大小(2–64),-1 = 按预设默认
entryMotionWaitbooleanentry false / exit true是否等动效播完再继续
发言状态
字段类型默认说明
speakingStateEnabledbooleantrue发言高亮总开关
othersStatestring"inactive"其他角色的状态:listening / inactive
narrationStatestring"listening"旁白时全体状态:listening / inactive / keep
transitionEnabledbooleantrue状态切换是否渐变
transitionDurationnumber180渐变时长(毫秒)
transitionEasingstring"outQuad"linear / outQuad / inOutQuad / outCubic / outBack
transitionBlockingbooleanfalse渐变是否阻塞下一句台词
三态视觉参数 —— speaking / listening / inactive 三组前缀 × 六个参数(Scale / Brightness / Saturation / Contrast / Blur / Alpha),共 18 个 number 字段,如 speakingScaleinactiveBrightness。默认值:
前缀ScaleBrightnessSaturationContrastBlurAlpha
speaking1.041.081101
listening10.880.82101
inactive10.80.42101
空间聚焦 focusMotion*(发言角色向镜头前聚焦的电影感效果)
字段类型默认说明
focusMotionEnabledbooleanfalse总开关
focusMotionStrengthnumber0.16聚焦位移强度
focusMotionDistancenumber0.75发言者的镜头距离
focusMotionDefocusDistancenumber1非发言者的镜头距离
focusMotionCameraZoomnumber1发言时镜头缩放
focusMotionNarrationCamerastring"keep"旁白时镜头:center / keep
focusMotionNarrationCameraZoomnumber1旁白时镜头缩放
focusMotionScalenumber1.02发言者额外缩放
focusMotionBackgroundModestring"fixed"背景:fixed / follow
focusMotionCharacterZoomModestring"fixed"立绘缩放:fixed / follow
focusMotionCenterModestring"position"聚焦中心:position / anchor
focusMotionCenterPositionIdstring""中心站位 id
focusMotionEntryModestring"direct"入场衔接:direct / afterEnter
focusMotionWaitPreviousExitbooleanfalse是否等上一位退场
focusMotionTransitionEnabledbooleantrue聚焦切换是否渐变
focusMotionDurationnumber180渐变时长(毫秒)
focusMotionEasingstring"outQuad"同发言状态的枚举
focusMotionBlockingbooleanfalse是否阻塞
生成时勿填:placementTransition* 四个字段(换位动画已迁移到「更新立绘」)。

场景与演出

背景、镜头与视觉演出。

场景切换

type: "scene" 切换背景场景,带 22 种转场效果。见手册:场景
{
  "type": "scene",
  "props": {
    "sceneId": "<场景UUID>",
    "sceneName": "教室",
    "transitionMode": "crossfade",
    "transitionDuration": "500"
  }
}
核心字段
字段类型必填默认说明
sceneIdUUID""场景引用,来自 scenes.json
sceneNamestring""显示名冗余字段
transitionModestring"cover"转场方式,见下表
transitionDurationstring"500"转场时长(毫秒)
waitForComplete"true"/"false""false"是否等转场播完再继续
resetCamera"true"/"false""false"切换时是否复位镜头
displayTypestring"cover"铺放方式:cover / contain / by_width / by_height / stretch / center
positionstring"(center,center)"位置,"(x,y)" 格式
anchorstring"center"锚点九宫格:top-left / top-center / top-right / center-left / center / center-right / bottom-left / bottom-center / bottom-right
sizestring"""(宽,高)",空 = 按 displayType
autoAddToGallery"true"/"false""true"展示成功后自动加入鉴赏(CG 收集)
uri / galleryMethodTargetstring由资源系统 / 默认壳维护,一般不用填
22 种转场方式(transitionMode
效果效果
cover覆盖(默认)rule规则图(配 transitionRuleUri
crossfade交叉淡化radial-wipe放射扫除
fade-to-black黑场过渡barn-door对开门
fade-to-white白场过渡diagonal-wipe斜切
cut瞬切zoom-fade缩放淡化
wipe方向擦除blur-dissolve模糊溶解
slide滑入mosaic马赛克
blinds百叶窗glitch故障闪烁
rotate旋转缩放page-turn翻页
iris圆形展开checkerboard棋盘格
pixel-dissolve像素溶解random-dissolve随机溶解
转场微调参数(只在对应模式下生效)
字段默认说明
transitionDirection""方向。擦除/滑入:left-to-right / right-to-left / top-to-bottom / bottom-to-top;百叶窗/对开门:vertical / horizontal;旋转/放射:clockwise / counterclockwise;斜切:top-left-to-bottom-right 等四角方向。空 = 各模式默认
transitionStrips"12"百叶窗叶片数(2–64)
transitionRuleUri""rule 模式的灰度规则图路径,如 transitions/ink-wash.png
transitionCenterX / transitionCenterY"50"转场中心(百分比 0–100),用于 iris / radial-wipe / barn-door
transitionSoftness""边缘柔化(0–20%);空时 rule 默认 5.5
transitionZoomScale"1.14"zoom-fade 缩放(1–2)
transitionBlurStrength"16"blur-dissolve 模糊(0–32)
transitionMosaicSize"52"mosaic 块大小(2–128)
transitionGlitchStrength / ColorShift / Scanlines"100" / "4.5" / "17"glitch 专用
transitionPagePerspective / transitionPageShadow"50" / "38"page-turn 专用(百分比)
mouseParallaxEnabled"false"是否让当前场景跟随鼠标移动
mouseParallaxAmplitude"4"鼠标位于画布边缘时的最大移动幅度(画布百分比,0–100)
mouseParallaxEdgeEase"0"接近画布边缘时的跟随减速程度(0–100);0 为线性跟随
mouseParallaxReturnOnLeave"true"鼠标移出游戏画布时是否平滑回到中心
mouseParallaxScaleMode"auto"auto 根据幅度和最近图层距离防露边;custom 使用指定倍率
mouseParallaxScale"1.08"自定义缩放倍率(1–5),仅 custom 模式生效

销毁场景

type: "destroyScene" 手册:销毁场景
字段类型必填默认说明
sceneIdstring"all"场景 UUID;"all" = 销毁全部
sceneNamestring""显示名冗余字段
animated"true"/"false""true"是否播放淡出
waitForComplete"true"/"false""false"是否等待完成

帷幕

type: "curtain" 拉上 / 拉开一层纯色幕布,常用于转场和黑屏演出。见手册:帷幕
{
  "type": "curtain",
  "props": { "op": "close", "duration": "800" }
}
字段类型必填默认说明
opstring"close"close(拉上)/ open(拉开)
durationstring"1000"动画时长(毫秒)
colorstring"#000000"幕布颜色(CSS 色值)
modestring"full-screen"full-screen(全屏)/ letterbox(上下黑边)/ pillarbox(左右黑边)/ windowbox(四边)
curtainSizestring"100"黑边占比(0–100)
生成时勿填:effect(旧数据兼容)。

镜头特效

type: "camera" 控制镜头位移、缩放、对焦、震动与全部滤镜。见手册:镜头特效
所有数值字段都是字符串,空字符串 = 该参数保持不变。 只填想改的参数即可,比如推近镜头只需要 zoomduration 两个字段。
{
  "type": "camera",
  "props": {
    "zoom": "1.4",
    "offsetY": "-60",
    "colorToneMode": "sepia",
    "colorToneIntensity": "0.6",
    "duration": "800",
    "easing": "easeInOut"
  }
}
基础与补间
字段默认说明
offsetX / offsetY""镜头位移(像素),建议 ±300 / ±200
zoom""缩放,建议 0.8–2.5
focalDistance""对焦距离(0–1)
blurStrength""景深模糊强度
duration"0"补间时长(毫秒),"0" = 立即生效
easing"linear"linear / easeInOut
waitForComplete"true"是否等补间播完
targets"scene,characters"作用范围:场景、立绘或两者
tweenFields内置默认逗号分隔的字段名,只有列出的字段参与补间;一般省略
objectTargetsJson""JSON 字符串,精确指定作用对象;空 = 按 targets 全局范围
震动
字段默认说明
shakeAmplitude""振幅(4–30 像素),非空即触发震动
shakeFrequency""频率(4–20 Hz)
shakeAmplitudeRandomness / shakeFrequencyRandomness"0"随机度(0–100)
shakeFalloff"linear"衰减:linear / expo
shakeAxis"both"方向:both / x / y
色彩与基础滤镜(默认均为 "" = 不变)
字段说明
colorToneMode色调:none / grayscale(黑白)/ sepia(怀旧),默认 "none"
colorToneIntensity色调强度(0–1)
colorExposure曝光(-2–2)
colorBrightness / colorContrast亮度 / 对比度(-1–1)
colorSaturation饱和度(0–2)
colorTemperature色温(-1–1)
lutPreset / lutIntensityLUT 调色预设与强度
distortionStrength镜头畸变(-1–1)
vignetteIntensity / vignetteSize暗角强度 / 范围(0–1)
blurAmount全屏模糊(0–20)
sharpenStrength锐化(-1–1)
bloomIntensity泛光
chromaticAberration色差(-20–20)
pixelateSize像素化块大小(1–64)
glitchIntensity故障艺术强度
crtIntensityCRT 扫描线
oldFilmIntensity老电影颗粒
shockIntensity冲击波
体积光 Godray
字段说明
godrayIntensity强度,非空即启用
godrayAngle / godrayGain / godrayLacunarity / godraySpeed角度 / 增益 / 细节 / 流动速度
godrayParallel光源模式:"" / true(平行光)/ false(点光)/ spotlight(聚光)
godrayCenterX / godrayCenterY光源位置
godrayConeAngle / godrayConeSoftness / godrayDistance聚光锥角 / 边缘柔化 / 距离
方向模糊
字段说明
radialBlurStrength / radialBlurCenterX / radialBlurCenterY放射模糊:强度与中心
motionBlurStrength / motionBlurAngle运动模糊:强度与角度
zoomBlurStrength / zoomBlurCenterX / zoomBlurCenterY缩放模糊:强度与中心
氛围叠加
效果字段
漏光lightLeakIntensity / lightLeakAngle
镜头光斑lensFlareIntensity / lensFlareCenterX / lensFlareCenterY
胶片颗粒filmGrainIntensity / filmGrainSize
热浪heatHazeIntensity / heatHazeSpeed / heatHazeScale
水波waterRippleIntensity / waterRippleFrequency / waterRippleSpeed / waterRippleCenterX / waterRippleCenterY
fogIntensity / fogSpeed / fogScale
VHS 录像带vhsIntensity / vhsJitter / vhsNoise
半调网点halftoneIntensity / halftoneScale / halftoneAngle
抖动色阶ditherIntensity / ditherLevels
描边outlineIntensity / outlineThickness
速度线
字段说明
speedLinesIntensity强度,非空即启用
speedLinesModeradial(放射,默认)/ directional(定向)
speedLinesDensity / speedLinesAngle / speedLinesSpeed密度 / 角度 / 速度
speedLinesFlicker / speedLinesIrregularity闪烁 / 不规则度
speedLinesLength / speedLinesThickness / speedLinesThicknessVariation长度 / 粗细 / 粗细变化
speedLinesTone / speedLinesFocus明暗 / 聚焦范围
speedLinesCenterX / speedLinesCenterY中心位置
泼墨 / 烟雾 / 眼睑
效果字段
泼墨inkSplashIntensityinkSplashVariantcluster / burst / slash,默认 "cluster")、inkSplashScaleinkSplashRotationinkSplashToneinkSplashCenterX / inkSplashCenterY
烟雾smokeOverlayIntensitysmokeOverlayVariantleft / right / full,默认 "full")、smokeOverlayStylewarm / soft / dark,默认 "warm")、smokeOverlayTonesmokeOverlayScalesmokeOverlaySpeed
眼睑(睁眼/闭眼演出)eyelidOpenness(睁开程度)、eyelidWidtheyelidCurvatureeyelidSoftnesseyelidCenterX / eyelidCenterY;仅作用于场景层
生成时勿填:shakeDuration(旧兼容,震动时长走顶部 duration)、presetIdtargetSelectionPending

复位镜头

type: "resetCamera" 清除所有镜头位移与滤镜,恢复默认视角。见手册:复位镜头
字段类型必填默认说明
resetModestring"instant"instant(立即)/ animated(动画过渡)
durationstring"500"animated 时的过渡时长(毫秒)
easingstring"easeInOut"linear / easeInOut
waitForComplete"true"/"false""true"是否等待完成

镜头动画

type: "stageAnimation" 多轨时间轴演出,在 Studio 的演出设计视图编辑。AI 生成剧本时一般只放一个占位,由创作者在 Studio 里编排。见手册:镜头动画
字段类型必填默认说明
namestring"镜头段"演出段名称
clipJsonJSON 字符串空轨道轨道数据,默认 {"version":1,"duration":3000,"tracks":[],"events":[]}
loopstring"0"循环次数,"0" = 不循环
playbackRatestring"1"播放速率
waitForComplete"true"/"false""true"是否等待播完

粒子效果

type: "particle" 下雪、下雨、萤火虫等全屏粒子。见手册:粒子效果
{
  "type": "particle",
  "props": { "mode": "show", "preset": "LIGHT_SNOW" }
}
字段类型必填默认说明
modestring"show"show(显示)/ hide(销毁)
effectIdstring""粒子实例 id;show 时定义、hide 时引用,hide 留空 = 销毁全部
presetstring"LIGHT_SNOW"LIGHT_SNOW / MODERATE_SNOW / HEAVY_SNOW(小/中/大雪)、LIGHT_RAIN / MODERATE_RAIN / HEAVY_RAIN(小/中/大雨)、FIREFLY(萤火虫)、FALLEN_LEAVES(落叶)、custom
textureUristring""自定义粒子贴图路径
optionsJsonJSON 字符串""完整粒子参数,空 = 用预设
fadeInDuration / fadeOutDurationstring"500"淡入 / 淡出时长(毫秒)

浮动文字

type: "floatingText" 在画面任意位置显示一段可动画的文字(标题、地点提示、内心独白等)。正文放 content,支持 [color=red]…[/color][b][i][size=32] 样式标记。见手册:浮动文字
{
  "type": "floatingText",
  "props": {
    "position": "(center,20%)",
    "anchor": "top-center",
    "fontSize": "42",
    "animIn": "fade,slide"
  },
  "content": [
    { "type": "text", "text": "——三年后。", "styles": {} }
  ]
}
字段类型必填默认说明
floatingTextIdstring""实例 id,空 = 自动生成;常驻文字需自取 id 供后续隐藏
blocking"true"/"false""true"是否阻塞剧情推进
recordHistory"true"/"false""false"是否进入历史记录
positionstring"(0,0)"位置 "(x,y)"
anchorstring"top-left"锚点九宫格(同「场景切换」)
sizestring"""(宽,高)",空 = 自适应
colorstring"#ffffff"文字颜色
fontFamily / fontSize / lineHeight / letterSpacing / textShadowstring""文字样式,空 = 默认
fontWeight / fontStylestring"normal"字重 / 斜体
textAlignstring"left"对齐
durationstring"2000"显示时长(毫秒)
infinite"true"/"false""false""true" = 不自动消失,需「隐藏浮动文字」手动隐藏
animIn / animOutstring"fade"入 / 出场动画,可逗号叠加:fade / slide / scale / blur
inDuration / outDurationstring"300"入 / 出场动画时长
slideFromstring"top"slide 方向
slideDistancestring"40"slide 距离(像素)
scaleFrom / scaleTostring"0.8"scale 起止缩放
blurRadiusstring"8"blur 动画模糊半径

隐藏浮动文字

type: "hideFloatingText"
字段类型必填默认说明
floatingTextIdstring""要隐藏的实例 id,空 = 隐藏全部

精灵动画(遗留)

type: "animateSprite"
遗留类型,仅用于读取旧工程,AI 与新剧本都不要使用。移动镜头请用「镜头特效 camera」,编排演出请用「镜头动画 stageAnimation」。

音视频

播放声音

type: "sound" 手册:声音
{
  "type": "sound",
  "props": {
    "soundType": "BGM",
    "soundId": "<音频UUID>",
    "uri": "bgm/日常.mp3",
    "loop": "true",
    "volume": "80"
  }
}
字段类型必填默认说明
soundTypestring"BGM"BGM(背景音乐)/ SE(音效)/ VOCAL(语音)
soundIdUUID""音频资源引用
uristring""资源相对路径,如 bgm/主题曲.mp3
volumestring"100"音量(0–100)
loop"true"/"false""false"是否循环(BGM 通常填 "true"
fadeDurationstring""淡入时长(毫秒),空 = 立即

停止声音

type: "stopSound" 手册:停止声音
字段类型必填默认说明
soundTypestring"BGM"要停止的声音类型
soundIdstring""指定音轨 id,空 = 停止该类型的默认音轨
fadeDurationstring""淡出时长(毫秒),空 = 立即

播放视频

type: "video" 手册:视频
字段类型必填默认说明
uristring""视频路径,如 video/intro.mp4
videoIdstring"video"视频实例 id
loop"true"/"false""true"是否循环
muted"true"/"false""true"是否静音
alphastring"100"不透明度(0–100)
waitForFinished"true"/"false""false"是否等播完再继续
modestring"normal"normal / mixed(叠加发光混合,适合特效视频)

停止视频

type: "stopVideo"
字段类型必填默认说明
videoIdstring""要停止的实例 id,空 = 停止全部
fadeOutDurationstring""淡出时长(毫秒)

逻辑流程

分支、条件、变量与章节流转——剧本的骨架。

选项分支

type: "branch" 向玩家展示选项。choices 的内部结构详见上文分支的选项列表。见手册:分支
{
  "type": "branch",
  "props": {
    "title": "去哪里",
    "choices":
      "[{\"mode\":\"jump\",\"text\":\"出发\",\"fragmentId\":\"f3\"}]"
  }
}
字段类型必填默认说明
choicesJSON 字符串"[]"选项数组
titlestring""编辑器内的分支标题,不显示给玩家
branchIdUUID""叙事地图用的稳定身份,可省略(自动补)

条件

type: "if" 按变量条件跳转片段。conditions 的内部结构详见上文条件的结构。见手册:条件
字段类型必填默认说明
conditionsJSON 字符串""条件数组
logicOpstring"and"多条件连接:and / or
thenFragmentIdstring""条件为真跳转的片段(同章节、非 main)
elseFragmentIdstring""条件为假跳转的片段,空 = 继续当前片段
生成时勿填:expression(由编辑器从 conditions 派生)。

变量赋值

type: "setver" 修改变量的值。字段与组合规则详见上文变量赋值的运算字段。见手册:赋值
{
  "type": "setver",
  "props": {
    "key": "<角色UUID>.好感度",
    "op": "+=",
    "aKind": "lit",
    "aLit": "5",
    "bKind": "none",
    "binOp": "+"
  }
}
核心字段:key(必填)、op= += -= *= /=)、aKind / aLit / aVarbKind / bLit / bVarbinOp

调用片段

type: "callFragment" 跳去执行另一个片段,执行完回到此处继续(嵌套上限 30 层)。见手册:调用片段
字段类型必填默认说明
fragmentIdstring""目标片段 id(同章节)

等待

type: "wait" 手册:等待
字段类型必填默认说明
durationnumber1000等待时长(毫秒)。注意是真数字,不是字符串
waitForInputbooleanfalsetrue = 改为等玩家点击,忽略 duration

玩家输入

type: "playerInput" 弹出输入框,把玩家输入写进变量(起名字等场景)。
字段类型必填默认说明
variablestring""结果写入的变量 key
valueTypestring"string"string / number / bool
titlestring"请输入"输入框标题
descriptionstring""说明文字
placeholderstring"请输入…"占位提示
confirmTextstring"确认"确认按钮文字
requiredbooleantrue是否必填
requiredTextstring"请填写后再继续"必填提示
minLength / maxLengthnumber0 / 20字符串长度限制,0 = 不限
minValue / maxValuenumber不限数字范围(valueTypenumber
stepnumber1数字步进
trueText / falseTextstring"是" / "否"布尔选项文字(valueTypebool

终止章节

type: "endChapter" 无参数。立即结束当前章节,进入 chapterOrder 的下一章。见手册:终止章节

返回入口章节

type: "returnToEntry" 无参数。跳回工程的入口章节(常用于「回到标题」类流程)。见手册:返回入口章节

进入 / 退出自动播放

type: "enterAutoPlay" / "exitAutoPlay" 成对使用,让剧情像放映一样自动推进。见手册:自动播放
字段类型必填默认说明
allowInterrupt"true"/"false""true"enterAutoPlay"false" = 玩家不能打断(强制必看段)
exitAutoPlay 无参数。

界面与扩展

标准消息框

type: "systemMessage" 弹出提示或确认对话框。见手册:标准消息框
{
  "type": "systemMessage",
  "props": {
    "mode": "confirm",
    "title": "确认",
    "message": "要保存进度吗?",
    "resultVariable": "save_confirmed"
  }
}
字段类型必填默认说明
modestring"alert"alert(仅确认)/ confirm(确认 + 取消)
titlestring"提示"标题
messagestring""正文
confirmTextstring"知道了"确认按钮文字
cancelTextstring"取消"取消按钮文字(仅 confirm
tonestring"info"info / success / warning / danger
resultVariablestring""confirm:把结果(布尔)写入的变量 key

显示界面

type: "showExtensionUI" 打开扩展或可视化 UI 编辑器制作的界面。见手册:显示界面
字段类型必填默认说明
targetstring""三种写法:扩展id/界面idui:界面名(可视化 UI 编辑器的界面)、slot:槽位id
modalbooleanfalsetrue = 模态阻塞,关闭后剧情才继续
layerstring"topmost"层级:topmost / top / bottom / behind-scene
seekBehaviorstring"skip-if-seeking"快进 / 读档时的行为:skip-if-seeking / always-openmodaltrue 时忽略)
interactablestring""三态:""(默认)/ "true" / "false",是否接收点击
size / positionstring""覆盖尺寸 / 位置,空 = 界面自身设定

隐藏界面

type: "hideExtensionUI"
字段类型必填默认说明
targetstring""与显示时的写法一致

调用扩展方法

type: "callExtensionFunction" 调用扩展提供的方法(解锁成就、加好感度等)。见手册:调用扩展方法
{
  "type": "callExtensionFunction",
  "props": {
    "target": "avg.official.affection/add",
    "paramsJson": "{\"amount\":{\"kind\":\"lit\",\"value\":5}}"
  }
}
字段类型必填默认说明
targetstring""扩展id/方法id
paramsJsonJSON 字符串"{}"参数表;每个值形如 {"kind":"lit","value":…}(字面量)或 {"kind":"var","ref":"变量key"}(变量)

其他

注释

type: "comment" 正文放 content,只在编辑器里可见,不参与游戏编译,用于给剧本留备注。见手册:注释
以上 38 种是 type 字段的全部合法值。剧本文件里偶尔还会见到 paragraph(编辑器内部保留类型)——它不是剧本指令,生成剧本时不要使用。

完整示例章节

一个小而全的章节文件,覆盖场景、音乐、对白、选项与片段跳转(片段 id 用了缩写示意,实际生成时保持全工程唯一即可):
{
  "id": "ch-1755500000000-1",
  "name": "第一章",
  "fragments": [
    {
      "id": "f2",
      "name": "main",
      "blocks": [
        {
          "type": "scene",
          "props": {
            "sceneId": "<场景UUID>",
            "sceneName": "教室",
            "transitionMode": "crossfade",
            "transitionDuration": "500"
          }
        },
        {
          "type": "sound",
          "props": {
            "soundType": "BGM",
            "soundId": "<音频UUID>",
            "uri": "bgm/日常.mp3",
            "loop": "true",
            "volume": "80"
          }
        },
        {
          "type": "narration",
          "props": {},
          "content": [
            {
              "type": "text",
              "text": "放学后的教室,只剩下我们两个人。",
              "styles": {}
            }
          ]
        },
        {
          "type": "dialogue",
          "props": {
            "characterId": "<角色UUID>",
            "characterName": "小雪",
            "expression": "微笑",
            "position": "center"
          },
          "content": [
            { "type": "text", "text": "今天想去哪里?", "styles": {} }
          ]
        },
        {
          "type": "branch",
          "props": {
            "title": "去哪里",
            "choices":
      "[{\"mode\":\"jump\",\"text\":\"出发\",\"fragmentId\":\"f3\"}]"
          }
        },
        {
          "type": "narration",
          "props": {},
          "content": [
            {
              "type": "text",
              "text": "无论选了哪边,故事都会回到这里继续。",
              "styles": {}
            }
          ]
        },
        { "type": "endChapter", "props": {} }
      ]
    },
    {
      "id": "f3",
      "name": "去图书馆",
      "blocks": [
        {
          "type": "dialogue",
          "props": {
            "characterId": "<角色UUID>",
            "characterName": "小雪",
            "expression": "开心"
          },
          "content": [
            { "type": "text", "text": "那就走吧!", "styles": {} }
          ]
        }
      ]
    }
  ]
}
示例里的 <…UUID> 占位符必须替换成你工程里真实存在的 id,否则对应指令不会生效。角色 id 在 characters.json,场景 id 在 scenes.json

让 AI 生成剧本

把资料喂给 AI 时,建议这样组织:
  1. 复制本页全文:结构规则和指令字段明细都在这一页。
  2. 附上工程实体对照表:从 characters.jsonscenes.jsonproject.variables.json 里整理出「名字 → id」清单,以及每个角色可用的表情名。AI 只能引用这份清单里的 id,不能编造
  3. 说明你要的剧情:章节名、片段规划(哪些分支、汇流到哪)、想要的演出效果。
再叮嘱 AI 几条硬规则(也可以直接把下面这段一起复制过去):
  • 只使用本页「指令全参考」列出的 38 种 typeanimateSprite 是遗留类型,禁止生成,动镜头用 camera、动演出用 stageAnimation
  • 不要生成编辑器自动维护的字段:voiceHashisFirstisLastprevExpressionprevNameVariantId
  • fragments[0] 必须命名为 mainbranch / if / callFragment 引用的 fragmentId 必须在同一章节里真实存在。
  • 章节 id、片段 id 在工程内唯一;Block 的 id 可以整个省略。
  • 对白一句一个 dialogue,正文放 content,不要塞进 props。
  • 对白自带立绘显示(showCharacter 默认 true),不要在 dialogue 前额外加 showCharacter(那是重复调用);只有角色不说话就要登场时才用「角色登场」。
  • 一段对话结束、后面不再有对白时(尤其接镜头动画、场景切换等演出),把最后一句 dialogue / narrationkeepDialogue 设为 false,自动隐藏对话框。
生成的文件放进工程 chapters/ 目录(文件名 = 章节名),再把章节名加进 project.jsonchapterOrder 数组,重新打开工程即可在 Studio 里看到并继续编辑。也可以只让 AI 生成 fragments 里的 blocks 内容,粘贴合并进现有章节文件,这样可以完全不碰 id 和索引。