Skip to content

Latest commit

 

History

History
132 lines (90 loc) · 4.99 KB

DreamScript_pre_doc.md

File metadata and controls

132 lines (90 loc) · 4.99 KB

DreamScript

此文档为预实现文档,为 完整设计预案 的缩略版,精简了语法并增加了诸多使用限制,旨在短期内完成样例进行测试

前置概念

推进

推进 指的是玩家点击鼠标等情况下剧本流程执行一步的操作,推进过程会尽可能长地自动运行,直到到达剧本尾部或遇到阻塞节点(详解见下)

节点

在 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