关于我们的视觉小说框架 Nova(能叶)

作者:woctordho
2020-11-05
28 22 1

能叶 Nova

GitHub 链接: https://github.com/huisedenanhai/Nova

原文首发于奶牛关:woctordho

程序员在我们 Lunatic Works 制作组里占了相当大的比重。我们的剧本是程序员写的,音乐是程序员做的,画画也有很大一部分是程序员画的。在开始制作第一部作品之前,我们就考虑到这样的作品跟目前国内或者日本主流的视觉小说风格会有很大差别,因此决定开发一个适合自己用的视觉小说框架 Nova。这个名字是一拍脑袋想出来的,但是叫 Nova 的东西太多了,所以我们又一拍脑袋想出来了一个中文/日文名字“能叶”,具体可以看我们的第一个 issue。

Nova 是一个基于 Unity、对程序员友好的视觉小说框架,可以做出丰富的演出效果,并且免费开源。由于我们的开发以自用为主,其他视觉小说框架中的一些功能在我们这里还不全,欢迎各位小伙伴来贡献代码。接下来我们从框架使用者(游戏制作者)的角度,介绍一下 Nova 的特点。

基于 Unity

其实选择 Unity 主要是因为我们组里的各位程序 dalao 对 Unity 和 C#比较熟。相反,如果你是做炼丹的,可以选择 Ren'Py;如果是做前端的,则可以选择 AVG.js。它们都是足够现代化、有靠谱团队维护的引擎。还有一些年轻的引擎,比如LibrianAVGPlusSnowing,也值得尝试。Unity 上面已经有一些视觉小说框架,比如 UTAGE 和 Naninovel,但是它们要钱。还有一个框架叫 Fungus,但是它对程序员不太友好,而且达不到我们想要的演出效果。

为什么不用 krkr 呢?虽然它是老牌的引擎(至于 NScripter、BGI 之类的就更老了),也有很大的用户基数,但它有很多历史遗留问题(即使到最近的 krkrz 还是没解决),官方文档也已经失传了。它经常遇到中文/日文编码转换的问题,也难以实现断行、字距调节等排版的细节(关于排版有多少细节问题,可以看看这个网站 https://thetype.com/ )。而且里面有很多过时的 C 语言标准和操作系统 API,甚至可能出现“Windows 系统更新导致汉化补丁不能用”这样奇怪的问题。虽然现在也有 NVLMaker、 BKEngine、TyranoBuilder 等引擎试图在 krkr 的基础上解决这些问题,但是我们觉得还不如重头来过。

用了 Unity,就是站在了现代软件工程和游戏工业的肩膀上。比如跨平台,我们支持 Windows、Linux、macOS、Android、iOS 等系统。我们在设计 UI 的时候也考虑了电脑、手机、平板、电视等多种屏幕尺寸,以及鼠标、触摸屏、键盘、Tab/方向键导航等多种输入设备,这里的许多工作都是 Unity 帮我们做好的。Unity 还有强大的图形性能,这个我们待会再说。Unity 也有图形界面的编辑器,在做 UI 和演出的时候比纯文本打坐标方便多了。

在现代软件工程的指导下,Unity 对向后兼容也做了许多考虑。尽管 krkr 已经开发了十几年,但它并没有用上这十几年里的许多新技术,反而让代码在十几年后与时代脱节,难以继续更新;而我们已经吸取了历史的教训,我们有信心让现在的代码在十几年后继续更新,这就是所谓的 future proof。

对程序员友好

使用 Nova 的游戏制作者需要有一定的编程基础。要做出一部“好看”的视觉小说,就难免会遇到图像渲染的流程、UI 切换的逻辑等等触及编程的问题,而不是光靠画板与 PS 就能解决的。对剧本作者而言,在有了一定编程基础之后,也可以用纯文本+标记语言来写剧本,并且写一些小程序来检查剧本中的人物戏份、故事节奏、图片和音乐的利用率等要素。甚至能用 git 来实现多人同时写剧本,并记录剧本的每次修订。如果用的不是纯文本,而是流程图、Excel 表格、数据库等奇怪的剧本格式,就没有这么方便。

标榜自己“不用编程就能做游戏”的引擎在网上已经够多了,但是它们的质量参差不齐,甚至有的与其说是游戏引擎,还不如说是发行渠道。如果你实在不会编程,NVLMaker 就是一个适合新人开始的选择,但我们并不想让 Nova 的功能与之雷同。还要提醒一句,制作视觉小说是一个动辄花上几个月甚至几年的工程,工作量可能比毕业论文还大。即使你现在没有学编程的打算,接下来会遇到的问题恐怕不只是不会编程而已。堕落的准备,OK?

(各家自研的视觉小说引擎现在越来越多了,为了解决碎片化的问题,已经有小伙伴准备定义一套通用的脚本格式,类似于 ONNX,希望大家支持: https://github.com/Uni-Gal/UniGal-Script

强大的演出系统

我们希望视觉小说不只是小说,还能吸取电影当中的镜头语言和剪辑语言等优势,因此制作了强大的演出系统。Unity 的一大好处就是有现代化的图形性能。从硬盘上读取一张图片,再显示到屏幕上,这个过程并没有许多小伙伴想象的那么容易。即使在 2020 年的普通电脑上,用 Win10 自带的照片查看器打开一张 1920x1080 的图片,仍然会感觉到零点几秒的卡顿。而我们如果需要每秒 60 帧的动画,就必须把卡顿控制在 0.02 秒以下。比如《魔法使之夜》有着顶级的演出,遗憾的是它仍然使用了基于 krkr 的引擎,在演出最炫酷的部分,同时有好几个图层移动的时候,就会突然变卡。好在现代的 CPU、GPU 和显示器已经能用各种技术来让图形更加流畅。

(另外,我觉得用 Python 或者 JS 来写视觉小说引擎也不会有太大的性能问题。视觉小说的性能瓶颈一是图形,二是读硬盘,这两点在各种语言里都可以调包。

Nova 的演出脚本使用 Lua 编写,许多做过游戏开发的小伙伴应该对此有所了解。因此我们不需要像 krkr 那样使用一门自创的语言,也不需要自己实现解释器甚至 JIT。Lua 本身是一门功能齐全(图灵完全)的语言,甚至可以做到读写文件、连接网络,以至于《君彼女》《心跳文学社》那样丰富的程序功能。

在设计演出系统时,我们参考了 AE 等动画软件,以及 tween.js 等网页动画框架。我们支持多图层、多段动画的串行和并行,以及演出动画与文本、UI 动画的并行。(说起并行,就会有各种各样的坑,需要巨大量的测试。。)由于组里有物理专业的同学,我们可以细致调节动画的加减速曲线,避免生硬的感觉。

Lua 与 C#之间的绑定十分方便,所以我们可以在演出系统中调用 Unity 自带的时间轴、粒子系统、shader、3D 摄像机等功能(至于怎么把 2D 纸片人放到 3D 空间里做动画,《弹丸论破》就是很好的例子)。还可以在运行过程中动态地生成动画,即使观众快速点击鼠标,在上一段动画放完之前就进入下一句对话,也可以流畅地过渡到下一段动画。如果一组动画需要反复使用,可以把它写成函数。Lua 对高阶函数也有很好的支持,可以方便地组合许多组动画,以及把同一组动画作用到不同的对象上。

至于这套演出系统的效果如何,可以在 Steam 上搜索“青箱”,看看我们的宣传片,这个宣传片可不是用 AE 做的哦。

(说实话,虽然我们的演出系统已经很厉害了,但还是比不过 PPT。有大佬已经用 PPT 的动画系统实现了 8086 指令集: https://www.youtube.com/watch?v=LArkm4v5mWA ,不要小看微软啊。。

(Unity 也可以支持任意分辨率的全屏,或者任意改变窗口大小。但是如果要支持 4K 屏的话,主要的问题不在于引擎,而在于美术。。

随时回跳功能

我们认为视觉小说的核心在于剧本,而演出和程序的各种功能最终都是为剧本服务的。但我们讲故事的手段又不限于文本,许多细节会放在演出当中。为了方便观众细致地观赏剧情,我们不但可以回顾之前的文本,还可以让整个游戏随时回跳到之前的位置。

如果要把随时回跳功能和图灵完全的演出脚本结合起来,实现的难度是巨大的。所以我们给脚本增加了一些限制,等到写文档的时候会仔细讲这个问题。我们的实现是一套 checkpoint + replay 的方法,这也是现在许多调试器的选择。我们的存档系统就是围绕这个功能写出来的。其他引擎在这一点上做得最好的应该是 Ren'Py,因为所有东西都是 Python,很容易序列化。。

免费开源

我们的代码使用 MIT 协议,完全免费,允许自行修改和商业用途,只要注明出处即可。我们使用的所有第三方代码也是兼容 MIT 协议的。就算以后有一天我们突然把协议换了,大家仍然可以使用换协议之前的代码。

开源是程序员的情怀。作为一个同人制作组,我们并没有打算靠做游戏来赚钱回本,能够增长自己的经验就已经不错了。开源与高质量的作品也不矛盾,Linux 和维基百科就是极其成功的例子(我们的很多美术素材就是在维基百科上找的)。另外,Unity 本身不是完全开源的。我个人打算有朝一日从 Unity 迁移到 Godot,但是还得等各位程序 dalao 有空才行。

至于防解包和防盗版的问题,我觉得各位 dalao 如果真想破解,没什么游戏是破解不了的。好在 Steam 圈子的扩大已经让我们提高了版权意识,愿意鼓励支持同人视觉小说的小伙伴也越来越多,所以目前不用太担心这个问题。如果需要防解包和防盗版,可以用 Unity 的其他插件。而且我们的所有资源都在本地,无需联网就能运行。


下面是惯例的广告时间:我们的第一部作品《青箱》已经在 Steam 上发布。

欢迎各位对游戏开发有兴趣的小伙伴加入 QQ 群一起交流,如果以后讨论程序的人多了可能会再开一个程序群。