马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本帖最后由 Maz马 于 2025-9-29 18:29 编辑
前言:
·仅在renpy环境下讨论
·仅在开发者视角下讨论
·任何言语不针对任何人及不包含恶劣侮辱意味
本篇涉及的内容包括游戏的立项,制作过程,并不涉及任何代码
是个人对这一两年走的弯路直路的总结
并非是实际的代码或案例,而是形而上学的思维方式或经验
由于本人本职是美术,既非编程也非策划,因此措辞可能会略显小白
也不会引经据典,亦可能有所谬误或缺漏,仅供入门参考
目录:
一 立项与规划
二 工程与管理
三 叙事类型
四 体验反馈
五 杂项总结统筹
工程与管理
这部分将会涉及一些代码知识,首先先来介绍一个核心概念
“高内聚,低耦合”
这是一个编程概念,但不仅仅适用于编程,而是一种模块化思维,也许这样说,编程小白还是不懂,以下举例。
假设现在有这几样东西:A,a,B,b,C,c,1,2,3,那么将他们分门别类的放置好,你会怎么选择?
[RenPy] 纯文本查看 复制代码 #是这样?
define x=[A,a,1,B,b,2,C,c,3]
#还是这样?
define x=[A,a,B,b,C,c,1,2,3]
#还是这样?
define x=[(A,a,B,b,C,c),(1,2,3)]
#还是这样?
define x=[(A,B,C),(a,b,c),(1,2,3)]
#还是这样?
define x=[(A,a,1),(B,b,2),(C,c,3)]
毋庸置疑,明显是后三种方式更为直观
第三种方式是划分了【英文】,【数值】
第四种方式是划分了【大写】,【小写】,【数值】
第五种方式是划分了【代表1的组】,【代表2的组】,【代表3的组】
我们的核心概念就是,你应该把具有相同属性的东西分为一组,不要和其他东西藕断丝连
那么,简单分类就可以了吗?并不是,而是你需要成组的东西分在一起
我用第五种方式来抽象举例。
假如你在使用时,并不是按照【代表1的组】,【代表2的组】,【代表3的组】来使用
而是按照【英文】与【数值】来使用,那你这个分组将会毫无意义,在使用时还会更加麻烦
高内聚 是指同一个模块内的东西关联性非常强(就像(A,a,1)是一个完整的概念)
低耦合 是指不同模块之间尽可能独立(修改(A,a,1)模块时,不会影响到(B,b,2)模块)
我们的目标就是让项目由许多个“高内聚,低耦合”的小积木构成。
管理,就是不断“解开耦合”的过程,提高 清晰度 和 效率 的行为
到了这里,你应该对这个概念有了一些了解,接下来,我们
进入正题
首先,在对代码,美术,音乐,视频进行分类之前,我们有这几点尽量要做,养成良好习惯。
提前说明:以下几点看不懂没关系,不是为了让你今天看懂,是为了让未来的你,以及你的合作伙伴还能一眼看懂你的项目。
1.不要使用非Ascll编码的字符对文件或文件夹命名
人话:不要用奇怪的符号和中文或其他语言对文件或文件夹命名(更不要用emoji和颜文字来命名!(+_+)?)
在renpy引擎中,由于安卓打包使用了java,因此任何和读写相关的(文件路径)含有非法字符,都会打包失败
最保守的命名方式应该是:只使用英文字母、数字和下划线
无论你的游戏是否想要打包安卓,站在开发者角度,我们应该采用”多一事,少一个BUG“的思维来制作游戏,在前期就做好最坏的打算,
这样,万一你哪天想打包安卓了,也不需要对项目大动刀。
2.建立图像库
人话:不要为了偷懒,在代码中直接使用图片或文件的名称和路径
在renpy引擎中,允许直接使用图片名称,或在某个组件里使用路径。但我们仍旧应该建立一个新的文件,为每一张图片进行image声明
为什么?这有好几个优点:
1.renpy的直接使用图片名称是一种猜测功能,“renpy猜你会使用这张图片”。在大部分情况下不会出错,但是永远没有你直接告诉它,“我要使用这张图片”可靠。
2.解耦。如果你为了方便,在某个组件里直接使用了路径,那么当你重复使用或者移动了这个文件时,你就要一个个的去翻,如果你显式的声明了image,那么你只要改一个image的路径就足够了
3.可读性。按照以上的思路,对资源进行image声明,那么,我们对一些同种作用的资源整合到一个文件里,是否比东翻西找舒服?当然,也不一定所有的图片都整合在这个文件中,这个具体情况后面分析。
4.性能优化。image声明会在开始游戏时预先缓存,比运行时读取路径要快。这一点性能并不是很重要,但哪怕这点性能不重要,但既然有这么多优点,那就应该从一开始就这样做,这是纯纯的“高回报”行为
(实际上,音乐资源也是可以声明的,但考虑到视觉小说往往美术资源的任务更为繁重,因此仅以image说明,当你的音声资源非常多时,也应该建立库,重要的是整合库的思维)
3.清晰你的命名规则
人话:不要因为只能用英语了,就开始用中文拼音、缩写来对文件和变量命名
第一个例子,我想写一个好感度功能,我把变量名取为hg,此时...我有一个角色叫做“昊哥”...昊哥长得“很高”...今天他有一个工作“很赶”...
所以你的变量是hg,hg,hg,hg吗?我想很多人不会这样...他知道要区分,又不是白痴
然后他的变量就变成了hg,haoge,hengao,hengan。
那我问你,万一你碰上了“很干”呢?中文可是有同音字的!
第二个例子,那我完全缩写,写的够长,就不怕重名了,我的变量叫做“用于好感度的变量”
所以你的变量是 yyhgddbl
不是哥们,你是人类吗?1000行代码之后你还能想起这个变量是干嘛的不?
正常的,健康的命名应该是这样的:
功能_名字_扩展
是的,很简单,只要为你的变量名加上限定就可以了,这样可以保证不重名,而且清晰明了
重要的是职责的划分,在这一条件下,你使用只有你能理解的缩写,也是可行的
例如:好感_昊哥,身高_很高 ————> hg_haoge,sg_hengao
无论你使用下划线或是大小写,也就是蛇形命名法或驼峰命名法,还是别的什么方法
这套命名规则你是出于什么考虑无关紧要,有没有规则,才是最重要的。
4.给脚本文件编号
人话:编号是为了控制脚本的加载和初始化顺序,和image相同,让引擎自己处理,不如我写死来,更加直观清晰
在renpy引擎中,模板工程的脚本文件是没有顺序的,这会使得我们添加新脚本文件时变得混乱,那不如给所有脚本文件都打上编号
而你损失的只是无法在引擎中快速打开,但打开VSC后,这点损失相当于没有。
这一步,可以不做,因为这一步对于新手来说有风险
缺点:对于初始化顺序理解不足的朋友来说,可能导致后续自己创建的代码块读取顺序错误,虽然排查简单,但总归影响了效率。
优点:对于复杂的项目,能够让你直观的感受运行顺序,你有自己设计的严格规则。
关于编号,我们应该使用0_xxx.rpy或a_xxx.rpy的形式来进行编号,引擎会自动根据编号的大小来顺序读取文件,但重要的是
不要使用00_xxx.rpy或更多的0来编号,因为00,01这种预留多一个0的文件是引擎底层的代码,或许会导致代码块的读取顺序出错
关于代码读取的顺序,和文档中的”游戏的生命周期“有关,此处不过多赘述,仅给出参考的编号方式
options.rpy,gui.rpy涉及配置项定义,应优先于screen.rpy和script.rpy,按代码块来看,读取顺序应该是以下这样的
options.rpy -> gui.rpy -> screen.rpy -> script.rpy 从前往后读取文件
至于使用数字排序还是英文排序,甚至不排序,这一步无关紧要,是锦上添花的一步。
(其实刚入门,比起初始化顺序,学会写基础代码更重要,但这里仍旧提出,作为参考意见)
开始分类
啊,现在的内容已经非常多了,根据以上的内容,应该对分类有一个基础的认识,所以,以下将不会过多的赘述一些无用的的东西
比如:
建立一个以角色名字为名字的文件夹,把这个角色的所有图像都放进去,整合成角色库,你一定是能够理解的吧?
同理:
建立一个BG文件夹,把所有的BG放进去,整合成背景库,你一定是能够理解的吧?
建立一个UI文件夹,把你新写的功能ui放进去,整合成UI库,你一定是能够理解的吧?
GUI如何成库? (好了,难点来了)
如何把 自己的ui 和 模板工程的ui 区分开呢?看起来这里似乎是一个耦合的重灾区!
是的,这里确实十分耦合,因为本身的gui就已经十分完善,我想大部分人,都不会愿意去对这个模板大刀阔斧的改动,那样太费事了。
那么我给出两种建议方案。
1.凡是涉及了screen.rpy,gui.rpy的文件和代码改动,文件都放回到模板的GUI文件夹中,代码也在原脚本里更改
反之,自写的ui,涉及的代码也自己新建文件夹,且代码不能写在screen.rpy,gui.rpy中,彻底分离开两部分。
2.所有ui,都放在GUI文件夹中,对GUI文件夹进行整理,代码也在screen.rpy,gui.rpy中进行续写,把模板文件当成自己的亲儿子。
这两种方案的优点和缺点是显而易见的,这里需要开发者自己权衡
方案一(分离):适合中小型项目,快速编写或希望与引擎更新保持同步的开发者。引擎大版本更新时,你可以相对安全地替换掉原生GUI文件,哪怕排查,也仅仅是小部分。
方案二(融合):适合大型项目或对模板的GUI有深刻的理解。你几乎不会再更新引擎版本,而是把它当成完全属于自己的代码基底,哪怕更新,对于你来说,改动它简直易如反掌。
整体来说二号方案当然是更优的
毕竟引擎更新并不是特别的快。而且迁移和复用更加方便。
但是有没有这个必要呢?事实上,只有在你的功能需要高度修改时,才会这样做。他需要你有一定理解,和整理它的时间。
方案一对于视觉小说来说已经足够了
本身renpy就是作为轻量开发的引擎,如果过度追求“高内聚”导致整理时间过长,开发效率下降,反而是舍本逐末了
都这样了,藕就藕吧。
“高内聚,低耦合”是我们的目标,“能跑就行”才是我们的指标。当你开发项目时,有意识向其靠拢,就足够保证你的项目优秀了。
脚本如何拆分?
以上,关于角色库,背景库,UI库,我们已经分好了,那么在脚本中,我们就应该拆分成
char_lib.rpy存放角色数据、图片,image_lib.rpy存放背景图片或其他杂七杂八的图像声明,如果代码行数少还可以合并。
那么剧情呢?剧情的脚本该如何拆分?其实此事上篇已有提及。
还记得规划好的大纲曲线吗?
[RenPy] 纯文本查看 复制代码 s
h /\
d /\ o / \
a b /\ f / \ i k /\ q / \
故事开始—/\/\ / \/\—————\ / \/\ /\—————\ m / \ /\ / \——————>故事结束
\/ e \/ \/ \/\ / \/ \/
c g j l \/ p r
n
剧情脚本,正是按照这个来分。
你已经有了每一个小情节了,只需要按照它新建脚本文件就可以了,
例如:此处我把完整的上升下降的过程a,写成一个单独的文件9_story_a.rpy
把完整的上升下降的过程b,写成一个单独的文件10_story_b.rpy。
它可以保证你的各个小情节互不干扰,可修改性强,可调用性强
如果你做的是多语言游戏,每个小脚本也保证了翻译文件更新时,修改的便利性。
同时,每个小情节的CG也可以显式的声明在对应的剧情中,再次执行了“高内聚”。
如果你做了一些小游戏,或是功能,同样的去思考,这个东西,是局部的?还是整个游戏中经常使用的?
如果是局部的,则并入你的小情节脚本,如果是全局的,则单拎出来,写成一个文件。
“高内聚 低耦合” 是我们管理项目的方法,但我们在做的实际是
“关注点分离” 让不同的代码、资源只管好自己分内的事(角色管角色,UI管UI,剧情管剧情)
* 这并不需要记忆
项目管理是迭代的,持续优化的。而我只是出于经验提出了我的建议,这一篇比较长,理解也有些难度。
但你并不需要完全理解,只要你快速的浏览,大概有个概念,引发了你的自我思考,这篇文章就已经起到作用了
* 这并不是圣经
也许有人会觉得,通篇都是废话!这不是常识吗?
但是在执行过程中,由于没有人与他互相验证,导致了他在执行过程中的不肯定和茫然,所以应该不算废话
对于小白来说,这篇文章是“蒙学”,对于入门者来说则是查漏补缺和“肯定”
“是的!你是对的!时刻记住,就这样干!”
|