简体中文
English 简体中文 繁體中文
Methodox 首页

入门

本页面用三种方式制作同一个小游戏。选择适合你的一种即可;游戏本身,以及你学到的有关脚本语言的一切,都可以沿用到其他方式中。各个工具从哪里获取,参见 安装。

开始时你不需要任何美术素材。故事中提到但找不到的图像会以占位图绘制(角色为剪影,背景为渐变),而引擎会用主题的颜色自行绘制对话框和菜单,因此故事从第一行起就可以游玩。

故事

下面的每个版本都播放这个脚本。将它保存为 game.novella(UTF-8):

define config.title = "The Garden"

character q "Qinglan" color "#c0392b" image qinglan
default met_before = false

label start:
    scene bg garden with fade
    "Plum blossom, and nobody in the garden but one girl with a guqin."
    show qinglan smile at right with dissolve
    q "You came."
    menu:
        "I did.":
            q "Then sit with me a while."
        "I was passing.":
            $ met_before = true
            q annoyed "Of course you were."
    q "Listen, then."
    return

从头读起:define config.title 为游戏命名;character 声明一个说话者,其名字以红色显示,图像标记为 qinglan;default 为变量指定初始值。游戏从 label start 开始。scene 清空舞台并显示背景 bg garden;单独一行带引号的文本是旁白;show 让 Qinglan 出现在右侧;q "..." 是她在说话;menu 提供两个选项;q annoyed "..." 在她说话时把她的表情换成 qinglan annoyed,并且此后保持不变;在无处可返回时,return 会结束游戏并回到主菜单。

方式 1:脚本文件夹

  1. 新建一个名为 The Garden 的文件夹,把 game.novella 放进去。

  2. 如果你有美术素材,就添加进来。图像按其路径命名,因此下面这些文件正好就是脚本所要求的图像:

    The Garden/
      game.novella
      bg/garden.jpg                    -> bg garden
      sprites/qinglan/smile.png        -> qinglan smile
      sprites/qinglan/annoyed.png      -> qinglan annoyed
    

    名为 images、sprites 或 characters 的顶层文件夹不计入名称,路径的其余部分成为一个个单词,名称一律小写。

  3. 运行它:

    NovellaPlayer run "The Garden"
    

    主菜单随即打开。点击 Start。

  4. 检查它:NovellaPlayer lint "The Garden" 会列出故事引用了但并不存在的任何东西,例如没有对应文件的图像名称。

编写时,NovellaPlayer run "The Garden" --developer 会打开开发者工具:Shift+R 重新加载脚本并重新开始你所在的标签,Shift+O 打开一个控制台,在其中用 jump label_name 可以直接跳转到某个标签。

方式 2:C#

创建一个引用 Novella 项目的 .NET 10 控制台程序(参见 安装),把方式 1 中的文件夹以 Assets 为名放在它旁边,然后编写:

using Novella;

NovellaGame game = new("The Garden", 1920, 1080);
game.AddAssetFolder("Assets");
game.LoadScriptsFromAssets();
game.Run();

AddAssetFolder 告诉游戏它的文件在哪里,LoadScriptsFromAssets 按路径顺序加载其中的每个 .novella 文件,Run 打开窗口,并在玩家退出时返回。脚本中的 define config.width 和 define config.height 会覆盖这里给出的分辨率。

代码能做脚本做不到的事。下面故事用 run 向程序请求一些东西:

    $ answer = "moon"
    run riddle answer
    if _return:
        q "Correct."
using Novella.Values;

game.RegisterCommand("riddle", arguments => Value.FromBoolean(arguments[0].AsText() == "moon"));

命令的结果会放入 _return。开发 完整介绍了 C# API,包括把游戏写成一个类。

不使用脚本

故事也可以用 C# 编写。故事构建器写出的标签与上面的脚本相同,因此该游戏的存档、读档和回滚与脚本版完全一样;此时 Assets 文件夹中只需要美术素材:

using Novella;
using Novella.Building;

NovellaGame game = new("The Garden", 1920, 1080);
game.AddAssetFolder("Assets");
game.WriteStory(story =>
{
    story.Character("q", "Qinglan", color: "#c0392b", image: "qinglan")
        .Default("met_before", false);
    story.Label("start", s => s
        .Scene("bg garden", with: "fade")
        .Narrate("Plum blossom, and nobody in the garden but one girl with a guqin.")
        .Show("qinglan smile", at: "right", with: "dissolve")
        .Say("q", "You came.")
        .Menu(m => m
            .Choice("I did.", c => c.Say("q", "Then sit with me a while."))
            .Choice("I was passing.", c => c.Set("met_before", true).Say("q", "Of course you were.", "annoyed")))
        .Say("q", "Listen, then.")
        .Return());
});
game.Run();

条件可以是 C# lambda,例如 .If(v => v.Flag("met_before"), ...),也可以是构建出来的、能读回为脚本的值。完整的构建器参见 开发。

方式 3:Divooka

作为过程(Routine 图)

  1. 创建一个带有 Routine 图的文档。
  2. 打开文档的资源库(在 Divooka Compute 中为 Asset library 工具或 Ctrl+Shift+A),使用 Import files… 导入 game.novella 和所有美术素材,并保持脚本所依赖的文件夹名称。
  3. 从 Novella 工具箱中,在执行路径上依次串联以下节点:
    1. Make Novella Game,标题为 The Garden,宽度为 1920,高度为 1080。
    2. Add Library Assets,连入游戏。它的库输入由文档提供,因此不需要连线。
    3. Load Scripts From Assets,文件夹留空,以加载库中的所有脚本。
    4. Run。
  4. 运行该图。游戏会在自己的窗口中打开。

运行中的 Hello Novella,此时还没有任何美术素材

你也可以不导入脚本文件,而是把脚本输入到 Load Script 节点中;或者完全不用脚本,用 Define Character 和 Set Config 等节点来定义内容。

作为数据(Function 图)

故事也可以完全不用脚本,而写成节点:

  1. 创建一个 Function 图。
  2. 串联 Start Sequence → Scene(bg garden,使用 fade)→ Show(qinglan smile,位于 right,使用 dissolve)→ Say(角色 q,文本 You came.)。
  3. 用名称 start 和该序列创建 Make Label。
  4. Start Story → Add Label(该标签)→ Add Character,由 Make Character(q、Qinglan、#c0392b、图像 qinglan)提供输入。
  5. 用标题和故事创建 Make Game Definition。
  6. 选中 Make Game Definition 节点,在 Properties 面板中打开它的 Custom Preview。游戏会在窗口中运行,存档保存在内存中,开发者控制台处于开启状态。

链上的任何节点都可以预览:序列以单标签故事的形式播放,没有 start 标签的故事从其第一个标签开始。条件和对变量的更改也是节点(If 搭配 Variable At Least,Apply Effect 搭配 Add To Variable);游戏还可以用 Make Scene 写成一个个场景,每个场景包含背景、音乐、台词以及故事接下来的去向。不使用自定义预览时,这些值会以它们所对应的脚本形式预览,因此你可以读到一串节点写出了什么。

在 Divooka 中使用 Novella 讲解了每个节点、用 Events 图编写游戏的方式,以及如何从 Flows 图调用描述游戏的 Function 图。

下一步

  • 概念:故事、舞台和检查点是什么。
  • 脚本语言:脚本能表达的一切。
  • 主题设置:字体、颜色,以及使用你自己美术素材的对话框。