Juliamo ~amrilata serpento~ - Ren’Py 初印象

引子

ChatGPT, Bible Tower and Chinese Room 中我曾提到,2022 年末尾不幸感染 COVID-19 并卧床半月有余。 彼时除了尝试 GPT-3,也根据梦境写了一篇 galgame 的 序章初稿,痊愈后工作堆积成山,遂将其抛之脑后。 近日偶有闲暇,学习了不少解包与反汇编技巧,想着用 KrkrZ 制作游戏,但相关教程少之又少,基本都是基于 Krkr2 来讲解,并且年久失修,难堪大用, 便尝试用 Ren’Py 引擎付诸实践,花了两天速成,将文字转换为货真价实的游戏。

Willful Lynn Preview
游戏预览

得名

Ren’Py 一眼就能看出是合成词,取自日语的 ren’ai( 恋爱 ) 和引擎开发语言 Python, 甚至连看板娘 Eileen 都是身缠蟒蛇的萝莉 ( ・ˍ・) 引擎基于 pygame 开发,而 pygame 本身又是基于 Python 和 SDL。 顺带一提,作者还维护着视觉小说论坛 Lemma Soft Forums, 算是 Ren’Py 非官方论坛,域名就是 lemmasoft.renai.us

这次尝试的是 Python 3.9 的 Ren’Py 8.1.1,其实在实际使用之前,看到官网上还挂着基于 Python 2.7 的 Ren’Py 7 我是挺嫌弃的。但后来开发过程中想要 定制按键映射,debug 看了 作者 PyTom 对某条 issue 的回复 发现,Ren’Py 对于 Python 2 支持到 2024 年 5 月,而 Python 官网 显示 2.7 早在 2020 年第一天就达到了 EOL,Ren’Py 向后兼容做得还是可以的。

有的人看到文章标题前半段可能觉得不明所以(没错我就是故意的),这其实是 neta 一部 Ren’Py 游戏 恋语 Juliamo -amrilata lingvo-。除此之外最著名的 Ren’Py 游戏可能就是 心跳文学部 了。言归正传,Juliamo 是游戏中的通用语言百合语,基于世界语(Esperanto)魔改。懒得打字,直接搬上 萌娘百科 的介绍:

语言名称“Juliamo”为“七月”(Juli-)和“爱”(am-)的合成词(结尾的“-o”为名词词缀)。在日语中「七月」也可写作「 文月( ふみつき ) 」,与「( あい ) 」相连可以得到读法相同的「 文付( ふみつ ) ( ) い」,即“言语关系”。

标题中的“amrilata”为“爱”(am-)和“关系”(rilat-)的合成词(“-a”为形容词结尾),含义为“恋爱关系的”;“lingvo”为“语言”。整个标题字面意义即为“恋语”。

综上所述,在七月学百合语是坠吼的,毕竟名字里就有七月,既然我已经学会了最基本的世界语,顺便学习 Ren’Py 也很合理🦫。所以标题其实只是把 lingvo 替换为 serpento 🐍️,简介也只是 neta 恋语的续作 Distant Memoraĵo

UI

扯回引擎本身,由于之前玩过的 gal 里用 Ren’Py 的游戏大多 UI 都一言难尽,比如某汉化组移植的 CROSS†CHANNEL 最初版、山桂百曲。所以默认的 UI 让我感觉挺惊艳的,后来想想确实应该改进了很多,比如年初 KFC 发行的 候鸟 就做得挺不错(虽然主菜单的 UI 有点太简单了),候鸟通关后我重新找了 C&C 的复刻版汉化,UI 也能吊打最初版。

编辑

使用文本编辑器,自带 Atom 和 VSCode 配置,我用的 VSCodium 虽然没有,复制 launcher/Visual Studio Code (System).edit.py 后参照 集成文本编辑器 替换一下关键词就能正常使用,同时也有对应的语言插件(VS Marketplace / Open VSX),基本可以自动处理 Python 的缩进问题。

教程

Ren’Py Tutorial
Ren’Py 教程

首先是 英文文档中文文档,中文版可能修改略微落后,具体版本可见 变更日志,目前还是 8.1.0,文档内容非常详尽,对于部分需要调用 Python 库的高级定制化也给出了对应的文档链接。再就是 Ren’Py 自带的教程和 The Question 示例游戏,有意思的是自带教程也采用了 gal 的形式,介绍 Ren’Py 支持的各种功能,对教程中有疑问的地方可以随时存读档,还能跳过已读/全部文本和查看上一条,相较于视频教程可以说是降维打击,容量小、可离线、便于翻译、随时修改(还支持热加载)、便于保存关键节点(还带预览图)……

Ren’Py Debug Console
不想看教程就开个控制台表演一个那什么

开发

这部分因人而异,没什么好讲的。多看文档,文档里没有的就去 GitHub 和论坛搜索,部分页面好久没更新会显示 out of date,但实际上代码还是可以正常运行的,只是不符合官方的 best practice。实际上我在尝试给游戏添加 Konami Code 进入隐藏结局的功能时,linter 就一直提示 "ui.add": This function is obsolete or outdated.,但后来 定制按键映射 时发现自带的 renpy\common\00keymap.rpy 中也用到了 ui.add 这一指令……以及最大的感想就是免费可商用的游戏素材好难找!第一天就完成了游戏主体框架和全部文本导入,第二天找了一下午立绘、背景图、SE,lint 检查脚本还是提示缺了很多素材。

Willful Lynn Konami Code
↑↑↓↓←→←→BA

  • 文档里 开发者工具 部分介绍了几个常用的工具和快捷键
  • 照猫画虎可以参考 The Question 游戏脚本
  • 如果需要生成选择支流程图(静态图片,不是早年 élf 作品或者 妹药 那种游戏内可跳转的流程图界面),可以使用 renpy-graphviz,注意默认配置会显示 screens(界面和界面语言),只想要选择支的话可以把 screensnested-screens 的值设置为 false(注意在 options.rpy 中排除文件,不然打包也会包括这个程序)
# Show the nodes with no neighbors or not?
atoms = false # default: false

# Try to display menu choices on the edges
edges = true # default: true

# Open the .webp created directly or not?
open = true # default: true

# Shows screens or not (might be relevant to your project)
screens = false # default: true

# Shows nested screens (keyword 'use' inside screens) or not?
nested-screens = false # default: true

# Output something to the stdout, or not?
silent = false # default: false

# Debug mode
debug = false # default: false
  • 其余一些像 ATL 变换自动匹配语音非常规多语言支持Live2D 的功能就没有逐一深入体验,都是浅尝辄止,Ren’Py 提供的功能真的是琳琅满目,定制化虽然起步可能比较难写,但后续修改只会更难也会随着熟练度提高渐渐上手
  • 有的人可能发现 #得名 部分有很多注音(Ruby 文本),这算是意外收获,gal 中其实也就日语注音功能用得多,感觉挺实用就参考 hugo-ruby 写了 Hugo 使用的 Ruby shortcode,Ren’Py 文档 中的配置不太适合中文,汉字会黏在一起,贴一下我修改的版本:
# script.rpy
# 注音功能
style ruby_style is default:
    size 18
    yoffset -30

style say_dialogue:
    line_leading 18
    ruby_style style.ruby_style

style history_text:
    line_leading 18
    ruby_style style.ruby_style

label start:
    "好康的船新 Ren'Py 游戏"
    "听话,让我看看!"
    
    menu:
        "好啊好啊可以啊":
            jump ge
        "我不要!":
            jump be
    #return

label ge:
    # 此处为游戏结尾。
    "从此和杰哥过上了【幸|性】福生活,好结局。"
    return

label be:
    "你被杰哥肛了,整个人阴阳怪气的,坏结局。"
    return

归档

这部分感觉默认配置没有做好,当然这与作者对于加密的态度息息相关。文档的 归档文件 部分就建议开发者「关于游戏归档的问题,请三思。使用开放文件可能有助于后人在未来的平台上运行你的游戏 —— 那些你离开这个世界之后才出现的平台。」Delisted game 确实是个大问题,所以也有 Internet Archive、Myrient 这类平台保存 ROM,不过对于普通的 Ren’Py 游戏而言其实问题不大。归档大多时候只是减少游戏目录下的文件数量,不采取加密手段或者使用 DRM 就很容易解包。而且默认的 options.rpy 并没有排除 **/cache/**,这点实在是不敢苟同。

发行

Willful Lynn page on itch
注册了几年的开发者账号总算发布了第一款游戏

Ren’Py 构建的游戏分发包中也没有将自身和所需的 Python 库进行打包,这点不知道是系统限制还是什么原因,解压出来一千多个小文件对于部分文件系统不太友善。完成游戏后,尝试发行到 itch,Ren’Py 内置了「上传到 itch.io」功能,调用 itch 官方写的命令行工具 butler,不过默认调用的 shell 是 cmd,无法连接上 Google 服务器……还是得手写自动化脚本用 butler 上传(支持增量更新,只上传有改动的文件)或者网页端上传。itch 项目页面虽然写着游戏类型选择 Downloadable 和 Web 都可以上传任意类型的文件,但只有选择 Web 类型才支持嵌入式脚本,一番测试之后在浏览器中顺利运行,就是运行效率有点低,加载材质时人物或者背景全糊成马赛克,用户体验不太好,而且不支持视频,不过作为 demo 展示的话绰绰有余。

Willful Lynn running on Chromium
It works on my machine™

Vinfall's Geekademy

Sine īrā et studiō