此文档为预实现文档,为 完整设计预案 的缩略版,精简了语法并增加了诸多使用限制,旨在短期内完成样例进行测试
推进
指的是玩家点击鼠标等情况下剧本流程执行一步的操作,推进过程会尽可能长地自动运行,直到到达剧本尾部或遇到阻塞节点(详解见下)
在 DS 中,每一条语句都是一个 节点
,节点分为 有效节点和无效节点,无效节点包括注释节点和不符合语法规则编译失败的节点(一般而言编译失败的节点在编译阶段将会被移除),除此之外的其他语句,都是有效节点,有效节点最终都会被编译进语法树;
阻塞与非阻塞的概念指的是:在推进过程中,当前节点是否会阻碍推进自动向下进行;到目前为止,除去绑定指令(详解见下)和标签语句(详解见下)之外,其余节点均为阻塞节点
- 按行解析
- 说话者与内容使用
*
分隔,*
前后的空格将会被忽略 - 如需要在文本中使用
*
,请使用%*
替换一个*
- 说话者或者内容均可以省略
示例如下:
老八 * 今天小汉堡买一赠一
* 听到这句话,杯中82年的拉菲突然就不香了
李华 * 我%*%*尼玛,又让我给国外网友写信
- 以
%%
作为行开头的内容,整行解析为注释
示例如下:
%% 言语粗俗,可能会对未成年人产生不良影响,后续联系策划修改人物性格设定
李华 * 我%*%*尼玛,又让我给国外网友写信
- 以
%{
作为行开头,直到以}%
作为行结尾的内容,都将解析为注释 - 多行注释不支持嵌套
- 多行注释不能写在单行中
示例如下:
%{
这是一个多行注释
}%
老八 * 今天小汉堡买一赠一
- 以
@
或$
作为行开头的内容,整行解析为 Lua 代码并在合适的时机调用 @
为绑定(非阻塞)指令,$
为独立指令- 解析完成后的 Lua 代码将不做处理直接运行,所以需要注意此处的 Lua 虚拟机上下文环境
- 单行代码中遵循 Lua 的语法,如使用
--
进行行注释
绑定指令在推进到下一个阻塞节点前会被依次执行,看起来像是绑定在了这个阻塞节点(如对话脚本)之上一样
示例如下:
@ MyCommand.MakeGameAAAAAa()
老八 * 今天小汉堡买一赠一
@ favor = favor + 1 -- 好感度提升 1 点
老八 * 今天小汉堡买一赠一
- 以
@{
或${
作为行开头,直到以}@
或}$
作为行结尾的内容,都将解析为 Lua 代码并在合适的时机调用 @{
和}@
必须保持配对,${
和}$
必须保持配对@{ }@
为(向下)绑定指令,${ }$
为独立指令- 解析完成后的 Lua 代码将不做处理直接运行,所以需要注意此处的 Lua 虚拟机上下文环境
- 单行代码中遵循 Lua 的语法,如使用
--
进行行注释 - 多行代码不支持嵌套
- 多行指令不能写在单行中
示例如下:
@{
if favor > 10 then
character.SetFace("shy") -- 如果角色好感度大于 10 点,则将面部表情切换为 “害羞”
else
JumpLabelTo("battle") -- 否则跳转到 "battle" 标签处进行战斗场景
end
}@
老八 * 今天小汉堡买一赠一
- 标签是为剧本跳转锚定设计的,配合内置全局指令
@JumpToLabel
使用 - 标签以
#
开头,并且占据单独的一行 - 标签是全局可见性,即可以实现在不同脚本文件间进行跳转
- 请务必确保标签名的唯一性,重名的标签可能会发生覆盖,并且发生不可预知的执行顺序
示例如下:
%% 一直做梦……
# dream_start 1
@JumpToLabel("dream_start 2")
* 梦开始的地方
# dream_start 2
@JumpToLabel("dream_start 1")
* 继续做梦……
-
最关键的部分便是把
指令
和代码块
概念统一起来了,DS 将不会处理解析为 Lua 代码的部分,而是将解析完成的内容直接交付给 Lua 虚拟机执行,DS 所做的仅仅是选择合适的时机进行这一部分代码的执行 -
关于命名空间,DS 会加载
Command
目录下的所有以.lua
为扩展名的脚本文件,并将其放在对应文件名的包中,如:Command/MyCommand.lua
将会被加载到全局中名为MyCommand
的表中(我们希望 Command 模块返回值是一个 table),即默认执行类似MyCommand = require("Command.MyCommand")
的语句,所以,请确保您的文件名中不会出现空格或在 Lua 语法中变量命名的非法字符(如:-
、.
等等) -
移除了
RegisterToGloable
函数,这意味着所有的自定义指令模块都需要以模块名.函数名()
的方式进行调用,全局命名空间中仅存在 DS 内置的 API