Skill: zhenruyan/webgalskill (version 1.0.0)

# Role: WebGAL 剧本编写专家 ## Profile - **描述:** 你是一个精通 WebGAL 视觉小说引擎的剧本编写专家。你深谙 WebGAL 的命令语法、演出控制、变量逻辑以及场景跳转。你的主要任务是协助用户编写、查错、优化 WebGAL 脚本，并根据用户的具体需求提供最佳实践。 - **核心语法规则:** - 所有 WebGAL 语句一般以分号 `;` 结尾。分号后面的内容视为注释。 - 基本指令格式为 `指令:值 -参数1 -参数2=值;`。 - 冒号 `:` 和分号 `;` 必须为半角英文字符。 ## 按需加载知识库 (On-Demand Loading TOC) 每个参考文件顶部均有**命令速查表**，便于快速定位所需命令。 ### 1. 基础 (references/base.md) [已加载] - `none` 关键词：关闭对象（如 `changeBg:none;`） - `-next` 参数：执行完本句后立刻执行下一句 - `-concat` / `-notend`：在对话进行中插入演出效果 ### 2. 对话 (references/dialogue.md) [已加载] - 基本格式：`角色:对话内容;`，旁白留空冒号前 `:旁白内容;` - 连续对话可省略角色名 - 变量插值：`{变量名}` - 注音：`[文本](注音)` - 文本拓展语法：`[文本](style=color:#66327C\; style-alltext=font-style:italic\; ruby=注音)` - 关闭文本框：`setTextbox:hide;`，恢复：`setTextbox:on;` - 结束游戏：`end;`，电影模式：`filmMode:enable;` ### 3. 背景与立绘 (references/bg-and-figure.md) [已加载] - 背景：`changeBg:图片名.jpg;` - 立绘：`changeFigure:图片.png;`（`-left`/`-right` 控制位置） - 带ID自由立绘：`changeFigure:图片.png -id=test1;` - 小头像：`miniAvatar:图片.png;` - CG解锁：`unlockCg:cg.jpeg -name=名称 -series=1;` ### 4. 场景与分支 (references/scenes.md) [已加载] - 场景跳转：`changeScene:文件名.txt;`（舞台不自动清除） - 场景调用：`callScene:文件名.txt;`（执行完返回） - 分支选择：`choose:选项1:文件1.txt|选项2:文件2.txt;` - 条件选项：`choose:(显示条件)[启用条件]->选项:文件;` - 标签跳转：`label:标签名;` + `jumpLabel:标签名;` ### 5. 变量 (references/variable.md) [已加载] - 设置变量：`setVar:a=1;` / `setVar:name=WebGAL;` - 随机数：`setVar:a=random(下限,上限,是否浮点);` - 条件执行：任意语句加 `-when=(a>1)` - 获取输入：`getUserInput:name -title=提示 -buttonText=确认;` - 全局变量：加 `-global` 参数 - 高级变量域：`$stage`（运行时）、`$userData`（存档） - 配置变量：直接读写 `config.txt` 中的变量（如 `setVar:Game_name=新标题 -global;`） ### 6. 音频 (references/audio.md) [待按需加载] - BGM：`bgm:文件名.mp3;`（`-volume=0-100`，`-enter=毫秒` 淡入） - BGM淡出：`bgm:none -enter=3000;` - 语音：对话后加 `-V文件名.ogg;` - 效果音：`playEffect:文件名.mp3;`（`-id` 循环，`none` 停止） - 解锁BGM：`unlockBgm:文件名.mp3 -name=名称;` ### 7. 视频 (references/video.md) [待按需加载] - 播放：`playVideo:文件名.mp4;` - 禁止跳过：`-skipOff` 参数 ### 8. 动画效果 (references/animation.md) [待按需加载] - 预制动画：`setAnimation:enter-from-bottom -target=fig-center -next;` - Target：`fig-left`/`fig-center`/`fig-right`/`bg-main`/自定义id - 预制动画名：`enter`、`exit`、`shake`、`enter-from-bottom/left/right`、`move-front-and-back` - 自定义动画：JSON文件放在 `game/animation/`，注册到 `animationTable.json` - 进出场效果：`setTransition: -target=xxx -enter=进动画 -exit=出场动画;` ### 9. 特效 (references/special-effect.md) [待按需加载] - 初始化：`pixiInit;` - 预制特效：`pixiPerform:rain/snow/heavySnow/cherryBlossoms;` - 叠加特效：多个 `pixiPerform` 不间隔 - 清除特效：重新 `pixiInit;` ## Workflows (工作流) 1. **意图识别**: 分析用户想要实现的游戏演出效果或逻辑 2. **按需检索**: 快速定位相关模块（每个文件顶部有命令速查表） 3. **编写脚本**: 严格按照 WebGAL 语法输出代码块（使用 `ws` 语言标记） 4. **注释与解释**: 合理使用分号 `;` 添加注释，代码块外简要说明 5. **串联与优化**: 善用 `-next`, `-concat`, `-notend` 确保演出流畅 ## 命令目录索引 | 功能 | 命令 | | :--- | :--- | | 场景跳转 | `changeScene` | | 场景调用 | `callScene` | | 分支选择 | `choose` | | 标签跳转 | `jumpLabel` / `label` | | 变量操作 | `setVar` | | 条件执行 | `-when` | | 用户输入 | `getUserInput` | | 播放BGM | `bgm` | | 播放语音 | `-V` | | 播放音效 | `playEffect` | | 播放视频 | `playVideo` | | 切换背景 | `changeBg` | | 切换立绘 | `changeFigure` | | 小头像 | `miniAvatar` | | CG解锁 | `unlockCg` | | BGM解锁 | `unlockBgm` | | 动画 | `setAnimation` | | 进出场 | `setTransition` | | 特效 | `pixiPerform` | | 文本框 | `setTextbox` | | 结束游戏 | `end` | ## 按需加载目录 - [基础](references/base.md) - [对话](references/dialogue.md) - [背景与立绘](references/bg-and-figure.md) - [音频](references/audio.md) - [视频](references/video.md) - [场景与分支](references/scenes.md) - [变量](references/variable.md) - [动画效果](references/animation.md) - [特效](references/special-effect.md)

path: references/animation.md
content: # 动画效果

## 命令速查

| 命令 | 语法 | 说明 |
| :--- | :--- | :--- |
| 播放动画 | `setAnimation:动画名 -target=目标;` | 为背景/立绘播放动画 |
| 设置进出场 | `setTransition:-target=目标 -enter=进动画 -exit=出场动画;` | 自定义进出场 |
| 自定义动画 | JSON文件 | 在 `game/animation/` 创建 |

## 预制动画

```ws
setAnimation:enter-from-bottom -target=fig-center -next;
```

### 动画列表

| 动画效果 | 动画名 | 持续时间 |
| :--- | :--- | :--- |
| 渐入 | `enter` | 300ms |
| 渐出 | `exit` | 300ms |
| 左右摇晃一次 | `shake` | 1000ms |
| 从下侧进入 | `enter-from-bottom` | 500ms |
| 从左侧进入 | `enter-from-left` | 500ms |
| 从右侧进入 | `enter-from-right` | 500ms |
| 前后移动一次 | `move-front-and-back` | 1000ms |

### Target 目标

| target | 说明 |
| :--- | :--- |
| `fig-left` | 左立绘 |
| `fig-center` | 中间立绘 |
| `fig-right` | 右立绘 |
| `bg-main` | 背景 |
| 自定义 `-id` | 带ID的立绘 |

## 自定义动画

动画文件存放在 `game/animation/`，使用 JSON 格式描述**动画序列**。

### JSON 结构

```json
[
  {
    "alpha": 0,
    "scale": {"x": 1, "y": 1},
    "position": {"x": -50, "y": 0},
    "rotation": 0,
    "blur": 5,
    "duration": 0
  },
  {
    "alpha": 1,
    "scale": {"x": 1, "y": 1},
    "position": {"x": 0, "y": 0},
    "rotation": 0,
    "blur": 0,
    "duration": 500
  }
]
```

### 帧属性说明

| 属性 | 说明 | 值范围 |
| :--- | :--- | :--- |
| `alpha` | 透明度 | 0-1 |
| `scale` | 缩放 | {x, y} |
| `position` | 位置偏移 | {x, y} |
| `rotation` | 旋转角度 | 弧度 |
| `blur` | 高斯模糊半径 | 数值 |
| `brightness` | 亮度 | 数值 |
| `contrast` | 对比度 | 数值 |
| `saturation` | 饱和度 | 数值 |
| `gamma` | 伽马值 | 数值 |
| `colorRed` | 红色分量 | 0-255 |
| `colorGreen` | 绿色分量 | 0-255 |
| `colorBlue` | 蓝色分量 | 0-255 |
| `duration` | 本帧持续时间 | 毫秒 |
| `oldFilm` | 老电影效果 | 0/1 |
| `dotFilm` | 点状电影效果 | 0/1 |
| `reflectionFilm` | 反射电影效果 | 0/1 |
| `glitchFilm` | 故障电影效果 | 0/1 |
| `rgbFilm` | RGB电影效果 | 0/1 |
| `godrayFilm` | 光辉效果 | 0/1 |

### 注册自定义动画

在 `animationTable.json` 中添加文件名（不含后缀）：

```json
["enter-from-left","enter-from-bottom","enter-from-right","myCustomAnimation"]
```

### 省略属性

不参与动画的属性可留空保持默认：

```json
[
  {"alpha": 0, "duration": 0},
  {"alpha": 1, "duration": 300}
]
```

### 变换（0毫秒动画）

持续时间为0且只有一个时间片的动画即变换：

```json
[{"alpha": 0, "duration": 0}]
```

## 设置进出场效果

覆盖 WebGAL 默认的渐变进出场效果。

**注意：**
- 设置进出场效果的语句必须**紧随**设置立绘/背景的语句**连续执行**
- 效果写在设置代码**之后**

```ws
changeFigure:test.png;
setTransition: -target=fig-center -enter=enter-from-bottom -exit=exit;
```

| 参数 | 说明 |
| :--- | :--- |
| `-target` | 作用目标 |
| `-enter` | 进场动画名 |
| `-exit` | 出场动画名 |

> 进场效果在立绘/背景设置后立即设置可覆盖默认动画。<br>
> 出场效果可在图像出场时正确应用。


path: references/video.md
content: # 视频

## 命令速查

| 命令 | 语法 | 说明 |
| :--- | :--- | :--- |
| 播放视频 | `playVideo:文件名.mp4;` | 播放视频 |
| 禁止跳过 | `playVideo:文件名.mp4 -skipOff;` | 禁止用户跳过 |

## 播放视频

将视频放入 `video/` 文件夹，使用 `playVideo` 播放：

```ws
playVideo:OP.mp4;
```

## 禁止跳过

使用 `-skipOff` 参数可阻止用户跳过视频：

```ws
playVideo:OP.mp4 -skipOff;
```


path: references/special-effect.md
content: # 特效

## 命令速查

| 命令 | 语法 | 说明 |
| :--- | :--- | :--- |
| 初始化Pixi | `pixiInit;` | 初始化特效系统 |
| 添加特效 | `pixiPerform:特效名;` | 添加粒子特效 |
| 清除特效 | `pixiInit;` | 重新初始化可清除所有特效 |

## 使用特效

WebGAL 特效系统由 PixiJS 实现。

### 初始化

使用特效前必须先初始化：

```ws
pixiInit;
```

> 重新初始化会清除所有已应用的效果。

### 预制特效

```ws
pixiPerform:rain;        // 雨
pixiPerform:snow;       // 雪
pixiPerform:heavySnow;  // 大雪
pixiPerform:cherryBlossoms; // 樱花
```

### 叠加特效

不使用 `pixiInit` 的情况下可叠加多个效果：

```ws
pixiPerform:rain;
pixiPerform:snow;
```

### 清除特效

重新执行 `pixiInit` 即可清除所有效果：

```ws
pixiInit; // 清除所有已叠加的特效
```

## 自定义特效

### 开发步骤

1. 下载 WebGAL 源代码
2. 在 `/Core/gameScripts/pixiPerformScripts/` 创建新的 `PIXI.Container`
3. 编译：`yarn run build`

### 代码结构

```ts
import {registerPerform} from '../pixiPerformManager';

// 获取效果容器
const effectsContainer = WebGAL.gameplay.pixiStage!.foregroundEffectsContainer!;
const app = WebGAL.gameplay.pixiStage!.currentApp!;

// 创建自定义特效容器
const container = new PIXI.Container();
effectsContainer.addChild(container);

// 注册特效
function myPerform() {
    // ... 特效逻辑
}

registerPerform('myPerform', { fg: () => myPerform() });
```

### 纹理文件

自定义特效使用的纹理文件放在 `game/tex/` 目录下。

### 调用自定义特效

```ws
pixiPerform:myPerform;
```


path: references/variable.md
content: # 变量

::: warning
在你弄清楚如何使用场景跳转和分支跳转之前，请不要轻易使用变量系统，这可能会令你感到迷惑！
:::

## 使用变量

设置变量：

``` ws
setVar:a=1; // 可以设置数字
setVar:a=true // 可以设置布尔值
setVar:a=人物名称 // 可以设置字符串
```

设置随机数，请使用 `random()`

```ws
setVar:a=random();
```

`random([lower=0], [upper=1], [floating])` 随机数是一个**内置函数**，它支持多个传参：

**参数**：
1. [lower=0] (number): 下限。
2. [upper=1] (number): 上限。
3. [floating] (boolean): 指定是否返回浮点数。

不写参数，它会生成一个是一个0-1区间的浮点数
```ws
setVar:a=random();
```

当然，我们也可以指定**范围**。比如，你想要5-10之间的随机数，你可以写成：
```ws
setVar:a=random(5,10);
```

当然你想要它使用范围生成的数值也有小数，那么可指定第三个参数：
```ws
setVar:a=random(5,10,true); # 将会生成5-10之间的浮点数
```

如果先前你定义过其他变量，也可以在设置变量时使用。

``` ws
setVar:a=1;
setVar:b=a+1;
```

## 条件执行

在语句后加上 `-when=(condition)` 参数，可以根据条件判断当前语句是否要执行。

例如：

``` ws
setVar:a=1;
; // 当 a 大于 1 时跳转到场景 1
changeScene:1.txt -when=a>1;
; // 只有 a 为 1 时才跳转，注意相等运算符是 ==
changeScene:2.txt -when=a==1;
; // 如果 a 小于 1，那么上面的语句不执行，自然就执行这一句了
changeScene:3.txt;

```

::: tip
`=` 是赋值符号，不可用于条件判断，`==`是相等运算符。
:::

任何语句都可以加上 `-when` 参数来控制是否执行。通过组合 `-when` 参数和 `jumpLabel` `callScene` `changeScene`，你可以实现带条件判断的流程控制。

## 获取用户输入

使用`getUserInput` 指令来获取用户输入，例如：

```
getUserInput:name -title=如何称呼你 -buttonText=确认; 将用户输入写入 name 变量中
```

其中，`title` 参数是提示的文本，`buttonText` 是确认按钮的文本

## 变量插值

可以在语句中使用 `{}` 语法来进行变量插值，将某个变量传入语句中，例如：

```
setVar:name=WebGAL;
setVar:engine=WebGAL;
{name}:欢迎使用 {engine}！这是一款全新的网页端视觉小说引擎。;
```

## 长效变量（全局变量）

WebGAL 的普通变量是跟随存档的，也就是说，任何变量只存在于当前的游戏场景中，只有存档才能将其保存下来，读档将其恢复。

为了解决可能存在的作者希望设置多周目的问题，提供长效（全局）变量，一旦设置，则在整个游戏中生效，除非用户清除全部数据。

加上 `-global` 参数可以设置长效（全局）变量

```ws
setVar:a=1 -global;
```

这样就设置了一个不随存档读取而改变的变量。

使用例：

```ws
jumpLabel:turn-2 -when=a>0;
setVar:a=1 -global;
一周目;
changeScene:一周目剧情.txt;
label:turn-2;
二周目;
changeScene:二周目剧情.txt;
```

## 高级用法（`>=4.5.4`）
使用内置变量进行更为高级的操作，如对配置变量进行修改，根据内置变量进行指定条件的逻辑运行等。

WebGAL 目前内置变量域有两个：`stage`和`userData`。

::: tip
`stage` 为**运行时内置变量**，`userData` 为**存档内置变量**。

`stage` 可在 WebGAL 编辑器下面的`state`选项卡查看有哪些属性，`userData`则是可以在开发者工具中`indexedDB`查看。
:::

使用`$`可以访问他们，如获取BGM的值：

```ws
setVar:a=($stage.bgm.volume);
WebGAL:当前的BGM音量为{a};
```

当然，你也可以直接在对话中使用它：

```ws
WebGAL:当前的BGM音量为{$stage.bgm.volume};
```

::: warning
获取**单值变量**时需要使用`括号`包裹，但进行数学运算时不需要。
:::

我们还可以访问`config.txt`中的全局变量：

```ws
setVar:title=(Game_name);
WebGAL:当前的游戏标题为{title};
```

修改也不例外，当要修改游戏标题为新游戏标题时，setVar的变量名称需要设置为我们将修改的变量名称

加`global`参数表示我们要修改的是配置变量：

```ws
setVar:Game_name=新游戏标题 -global;
WebGAL:当前的游戏标题为{Game_name};
```

::: warning
不加`global`则会赋值到游戏内变量，请注意何时使用`global`参数。
:::

::: tip
可以修改的原始配置变量`Title_img`、`Title_bgm`、`Game_name`、`Game_key`。
想要恢复则可以在游戏选项中使用`清空所有数据`即可恢复。
:::

当然，你也可以在`config.txt`中创建一个自定义配置变量，如 创建一个版本号：

```text
Game_name:欢迎使用WebGAL！;
Game_key:f60ad5725c1588;
Title_img:WebGAL_New_Enter_Image.png;
Title_bgm:s_Title.mp3;
Textbox_theme:imss;
; 增加版本号
version:1;
```

那么我们就可以在脚本里面对它进行获取，修改等操作：

```ws
setVar:v=(version);
WebGAL:当前的版本号为{v};
setVar:version=version*2 -global;
WebGAL:当前被修改的版本号为{version};
```

::: warning
`config.txt`暂未做特殊符号的转义处理。
:::


path: references/dialogue.md
content: # 对话

## 命令速查

| 命令 | 语法 | 说明 |
| :--- | :--- | :--- |
| 角色对话 | `角色:对话内容;` | 显示角色对话 |
| 旁白 | `:对话内容;` | 无角色名的旁白 |
| 黑屏独白 | `intro:文本1\|文本2 -hold;` | 黑屏文字独白 |
| 关闭文本框 | `setTextbox:hide;` | 隐藏文本框 |
| 显示文本框 | `setTextbox:on;` | 显示文本框 |
| 结束游戏 | `end;` | 返回标题界面 |
| 电影模式 | `filmMode:enable;` | 开启电影模式 |
| 注音 | `[文本](注音)` | 为文字添加注音 |
| 变量插值 | `{变量名}` | 将变量插入对话 |

## 基本角色对话

```ws
雪之下雪乃:请用茶;
由比滨:啊，谢谢;
小町:谢谢雪乃姐！;
一色:谢谢学姐。;
```

> 每条对话以分号 `;` 结尾。（建议始终加上分号以防止 bug）

## 连续对话

多条对话未改变角色名称时，可省略角色名：

```ws
雪之下雪乃:你到得真早;
对不起，等很久了吗？;  // 角色名仍是"雪之下雪乃"
比企谷八幡:刚到而已;
```

## 旁白

在冒号前留空表示旁白：

```ws
:这是一句旁白;
```

## 黑屏文字（独白）

使用 `intro` 命令，文本以 `|` 分隔表示换行：

```ws
intro:回忆不需要适合的剧本，|反正一说出口，|都成了戏言。;
```

渲染效果：
```
回忆不需要适合的剧本，
反正一说出口，
都成了戏言。
```

添加 `-hold` 参数可保持独白界面，不继续游戏流程：

```ws
intro:回忆不需要适合的剧本，|反正一说出口，|都成了戏言。 -hold;
```

## 变量插值

使用 `{}` 语法将变量插入对话：

```ws
WebGAL:很高兴遇见你，{name}！;
{name}:我也最喜欢 WebGAL 了！;
```

## 注音

语法：`[要注音的词](注音)`

```ws
『[笑顔](えがお)』なんて、『[笑う](わらう)』なんて、[誰](だれ)でも[出来](でき)るもん…！
```

## 文本拓展语法（4.5.3+）

为部分文字添加样式。语法：`[文本](参数)`

```ws
WebGAL:[文本](style-alltext=font-style:italic\;font-size:80%\; style=color:#66327C\; ruby=wen ben)
```

**参数说明：**

| 参数 | 作用范围 | 说明 |
| :--- | :--- | :--- |
| `style` | 文本层 | 修改文本颜色等 |
| `style-alltext` | 全部三层 | 斜体、文本大小、内外边距等 |
| `ruby` | 注音 | 书写注音 |

> 注意：由于版本 bug，必须同时包含 `style=` 才能启用文本拓展语法。<br>
> `;` 在参数中需转义为 `\;`。

## 关闭文本框

```ws
setTextbox:hide; // 关闭文本框
setTextbox:on;   // 重新显示（可以是除 hide 以外的任意值）
```

## 结束游戏

```ws
end; // 返回标题界面
```

## 电影模式（测试功能）

```ws
filmMode:enable; // 开启电影模式
filmMode:none;   // 关闭电影模式
```


path: references/scenes.md
content: # 场景与分支

## 命令速查

| 命令 | 语法 | 说明 |
| :--- | :--- | :--- |
| 场景跳转 | `changeScene:文件名.txt;` | 切换到另一场景 |
| 场景调用 | `callScene:文件名.txt;` | 调用场景后返回 |
| 分支选择 | `choose:选项1:文件1.txt\|选项2:文件2.txt;` | 用户选择分支 |
| 条件选择 | `choose:(显示条件)[启用条件]->选项:文件;` | 条件分支 |
| 创建标签 | `label:标签名;` | 在当前位置创建标签 |
| 跳转到标签 | `jumpLabel:标签名;` | 跳转到指定标签 |

## 警告

> 跳转场景、分支选择或调用场景后，**舞台不会自动清除**。背景音乐、立绘、背景等效果会被继承到下一场景。

## 场景跳转

```ws
changeScene:Chapter-2.txt;
```

跳转后，当前场景的 BGM、立绘、背景等效果会保留到新场景。

## 场景调用

`callScene` 执行完毕后**返回原场景继续执行**。

```ws
callScene:Chapter-2.txt;
// Chapter-2.txt 执行完毕后，继续执行这里
```

## 分支选择

```ws
choose:叫住她:Chapter-2.txt|回家:Chapter-3.txt;
```

选项之间用 `|` 分隔，格式：`显示文本:目标文件`

### 条件展示和选择

```ws
choose:(showConditionVar>1)[enableConditionVar>2]->叫住她:Chapter-2.txt|回家:Chapter-3.txt;
```

| 条件类型 | 语法 | 说明 |
| :--- | :--- | :--- |
| 显示条件 | `(条件)` | 条件为真时才显示选项 |
| 启用条件 | `[条件]` | 条件为真时才允许点击 |

## 标签跳转

在同一文件内实现分支跳转，避免创建过多 TXT 文件。

> 警告：TXT 行数不宜过长，否则可能导致加载慢、响应迟钝。

### 基本语法

```ws
jumpLabel:label_1; // 跳转到 label_1
......
label:label_1;     // 创建名为 label_1 的标签
```

`jumpLabel` 相当于 `goto`，`label` 是跳转的目标点。

### 分支示例

```ws
choose:分支 1:label_1|分支 2:label_2;
label:label_1;
// 分支1的内容
......
jumpLabel:end;
label:label_2;
// 分支2的内容
......
jumpLabel:end;
label:end;
// 汇合点
```

### 常见错误

每个分支结尾必须用 `jumpLabel` 跳转，否则程序会继续执行下一个分支：

```ws
// 错误示例
choose:分支 1:label_1|分支 2:label_2;
label:label_1;
// 分支1内容
// 如果没有 jumpLabel，会继续执行分支2！
label:label_2;
// 分支2内容
```


path: references/base.md
content: # 基础

## 命令速查

| 命令 | 语法 | 说明 |
| :--- | :--- | :--- |
| 注释 | `; 注释内容` | 单行注释 |
| `none` | `指令:none;` | 关闭对象（背景/立绘/BGM等） |
| `-next` | `指令:值 -next;` | 执行完本句立刻执行下一句 |
| `-concat` | `对话 -concat;` | 本句连接在上一句对话之后 |
| `-notend` | `对话 -notend;` | 本句对话未结束，可插入演出 |

## 注释

WebGAL 脚本只会解析每一行的分号前的内容，分号后的内容视为注释。

```ws
WebGAL:你好！; 分号后的内容会被视作注释
; 可以直接输入一个分号，然后写一条单行注释
```

## `none` 关键词

在设置资源时，设为 `none` 可关闭该对象：

```ws
changeBg:none;     // 关闭背景
changeFigure:none; // 关闭立绘
bgm:none;          // 停止背景音乐
```

## `-next` 参数

执行完本句后**立刻**执行下一句，用于同时触发多个动作。

```ws
changeBg:testBG03.jpg -next;
changeFigure:testFigure02.png -next;
一色:谢谢学姐！;
```

## `-notend` 和 `-concat` 参数

在对话进行中插入演出效果：

| 参数 | 作用 |
| :--- | :--- |
| `-concat` | 本句连接在上一句对话之后 |
| `-notend` | 本句对话未结束，可连接演出或对话 |

**示例：对话中切换立绘**

```ws
WebGAL:测试语句插演出！马上切换立绘...... -notend;
changeFigure:k1.png -next;
切换立绘！马上切换表情...... -notend -concat;
changeFigure:k2.png -next;
切换表情！ -concat;
```

**仅使用 `-concat`：**

```ws
这是第一句......;
用户点击鼠标后才会转到第二句 -concat;
```


path: references/audio.md
content: # 音频

## 命令速查

| 命令 | 语法 | 说明 |
| :--- | :--- | :--- |
| 播放BGM | `bgm:文件名.mp3;` | 播放背景音乐 |
| BGM淡入 | `bgm:文件名.mp3 -enter=毫秒;` | 淡入播放 |
| 停止BGM | `bgm:none -enter=毫秒;` | BGM淡出 |
| 语音 | `对话 -V文件名.ogg;` | 播放语音 |
| 效果音 | `playEffect:文件名.mp3;` | 播放效果音 |
| 效果音循环 | `playEffect:文件名.mp3 -id=xxx;` | 循环播放效果音 |
| 停止循环效果音 | `playEffect:none -id=xxx;` | 停止循环 |
| 解锁BGM | `unlockBgm:文件名.mp3 -name=名称;` | 解锁BGM鉴赏 |

## 资源文件位置

- BGM：`bgm/` 文件夹
- 语音/效果音：`vocal/` 文件夹

## 背景音乐（BGM）

```ws
bgm:夏影.mp3;
```

| 参数 | 必填 | 说明 |
| :--- | :--- | :--- |
| `-volume` | 否 | 音量 0-100，默认 100 |
| `-enter` | 否 | 淡入时间（毫秒），默认 0 |

**示例：**

```ws
bgm:夏影.mp3 -volume=30;    // 30%音量播放
bgm:夏影.mp3 -enter=3000;   // 3秒淡入播放
```

**淡出停止：**

```ws
bgm:none -enter=3000; // 3秒淡出后停止
```

## 语音

在对话后添加 `-V文件名` 参数：

```ws
比企谷八幡:刚到而已 -V3.ogg;
```

连续对话时语音语法相同：

```ws
雪之下雪乃:你到得真早 -V1.ogg;
对不起，等很久了吗？ -V2.ogg;
```

可附加 `-volume` 调整音量：

```ws
比企谷八幡:刚到而已 -V3.ogg -volume=30;
```

## 效果音

```ws
playEffect:xxx.mp3;
playEffect:xxx.mp3 -volume=30; // 30%音量播放
```

### 效果音循环

使用 `-id` 启用循环，通过 `none` 停止：

```ws
playEffect:xxx.mp3 -id=loopSound;    // 开始循环
playEffect:none -id=loopSound;       // 停止循环
```

## 解锁BGM鉴赏

```ws
unlockBgm:s_Title.mp3 -name=Smiling-Swinging!!!;
```

| 参数 | 必填 | 说明 |
| :--- | :--- | :--- |
| `-name` | 是 | BGM鉴赏中显示的名称 |


path: references/bg-and-figure.md
content: # 背景与立绘

## 命令速查

| 命令 | 语法 | 说明 |
| :--- | :--- | :--- |
| 切换背景 | `changeBg:图片名.jpg;` | 切换背景 |
| 切换立绘 | `changeFigure:图片名.png;` | 切换中间立绘 |
| 位置参数 | `-left` / 无 / `-right` | 左 / 中 / 右 位置 |
| 带ID立绘 | `changeFigure:图片.png -id=xxx;` | 自由位置立绘 |
| 小头像 | `miniAvatar:图片.png;` | 显示小头像 |
| 解锁CG | `unlockCg:图片.jpeg -name=名称 -series=1;` | 解锁CG鉴赏 |
| 变换效果 | `setTransform:{json} -target=目标;` | 为已有立绘设置效果 |

## 资源文件位置

- 背景图片：`background/` 文件夹
- 立绘图片：`figure/` 文件夹

## 切换背景

```ws
changeBg:testBG03.jpg;  // 切换背景
changeBg:none;          // 关闭背景
```

## 切换立绘

```ws
changeFigure:testFigure02.png; // 切换中间立绘
changeFigure:none;              // 关闭立绘
```

使用 `-next` 可在替换后立刻执行下一条语句：

```ws
changeBg:testBG03.jpg -next;
changeFigure:testFigure02.png -next;
一色:谢谢学姐！;
```

## 立绘位置

三个位置：左 (`-left`)、中 (无参数)、右 (`-right`)。

```ws
changeFigure:testFigure03.png -left;    // 左侧
changeFigure:testFigure04.png;           // 中间
changeFigure:testFigure03.png -right;    // 右侧
```

清除各位置立绘需分别设置：

```ws
changeFigure:none -left;
changeFigure:none;
changeFigure:none -right;
```

## 带ID的自由立绘

使用 `-id` 指定立绘 ID，可实现超过3个立绘或精确控制：

```ws
changeFigure:testFigure03.png -left -id=test1; // 初始位置在左侧
changeFigure:none -id=test1;                    // 通过ID关闭立绘
```

> 重设带ID立绘位置时，需先关闭再重新打开。

## 小头像

显示在文本框左下角：

```ws
miniAvatar:minipic_test.png; // 显示小头像
miniAvatar:none;             // 关闭小头像
```

## 解锁CG

```ws
unlockCg:xgmain.jpeg -name=星光咖啡馆与死神之蝶 -series=1;
```

| 参数 | 必填 | 说明 |
| :--- | :--- | :--- |
| `-name` | 是 | CG鉴赏中显示的名称 |
| `-series` | 否 | 系列编号，同系列CG合并展示 |

## 立绘变换效果

### 设置立绘时附加效果

```ws
changeFigure:stand.png -transform={"alpha":1,"position":{"x":0,"y":500},"scale":{"x":1,"y":1},"rotation":0} -next;
```

### 为已有立绘设置效果

```ws
setTransform:{"position":{"x":100,"y":0}} -target=fig-center -duration=0;
```

> 效果字段说明详见 [动画](animation.md)

**Target 目标：**

| target | 说明 |
| :--- | :--- |
| `fig-left` | 左立绘 |
| `fig-center` | 中间立绘 |
| `fig-right` | 右立绘 |
| `bg-main` | 背景 |
| 自定义id | 带 `-id` 的立绘 |


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)