开发复盘:一周两个Mod,哪些事情做对了,哪些做错了
一周7天完成2个Mod,霸占创意工坊首页整周。作为第一次制作完整游戏系统的尝试,这篇文章描述了我个人在开发结束之后的复盘与反思
上周,我给游戏《潜渊症》(Barotrauma)做的Mod“原版枪械改装”和“武器XML快速生成器”完成了,登顶首页长达一周。
这个mod说大不大说小不小:相当于给这游戏远程武器提供了一套完整的配件改装系统模板——你知道的,就是多数FPS做过的装个镜子、换个枪托这样的玩意,并且还把性能优化到了当前我力作能及的最大极限。我不好说它是不是还能再优化,但是整个游戏因为一把枪装了消音器就从60帧掉到30帧这种事情应该是不会出现了(点名这个游戏的另一个Mod:Combat Extended,有很长一段时间都有这种问题)。不过我并没有覆盖到游戏里的所有武器,目前只有三分之二。
至于另一个Mod“武器XML生成器”,基本就是开发配件系统时的附带产品。
在这之前,我尚未接触过完整的游戏开发,虽然参与过3、4次gamejam,但总的来说我没有感觉到自己以前的开发很有组织性,更多时候就像《游戏制作指南》里说的那样:在Deadline的三分之二时间里磨洋工、出于“必要混乱”之中,直到剩下一周或者几天时,“哦,糟糕”,发现自己要赶不上Deadline,才火速从“必要混乱”当中脱出身来,开始给自己的一团浆糊各种找补,最后端上来个四不像。
先从开发日志开始吧。
开发日志
Day1
- 初步上手
- 成功实现更为优雅简洁的配件机制
我需要开始考虑一下接下来怎么做战术插件.目前是考虑改造分为两类:战术化和暴力改造,前者就是原武器增加多个插件槽位,而后面的改造则是直接重写一个新武器出来.
对于插件槽位,目前的想法如下:
能影响的属性:
- reload & reloadnoskill 射速与无技能射速 (需要reloadskillrequirement)
- weapondamagemodifier 武器伤害倍率
- penetration 护甲/结构伤害乘数
- barrelpos 枪管位置
- spread & unskilledspread 散布和无技能散布
- crosshairscale 十字准星大小
- 移动速度
具体见 https://regalis11.github.io/BaroModDoc/ItemComponents/RangedWeapon.html
- 上插件 | 镭射/灯光/发光管/瞄准镜等 | smallScopeVGM,bigScopeVGM
- 枪管 | 消声器/消焰器/长枪管 | smallMuzzleVGM,bigMuzzleVGM
- 下挂件 | 除瞄准镜以外的所有上挂件+握把 | smallAccessoryVGM,bigAccessoryVGM
- 枪托 | 去除枪托/轻枪托/重枪托 | smallStockVGM,bigStockVGM
- 内机构 | 灵活度较大 | smallMechanicsVGM,bigMechanicsVGM
- 弹匣 | 不算在插件系统内,短弹匣/长弹匣/弹鼓 | smallMagVGM,bigMagVGM,drumMagVGM
就先做这些吧, 都是些数值增减, 应该不成问题的
明天得开始处理XML烧火棍生成器了,这下确实有实在的需求在了.
Day2
模板初步实现,做贴图时发现一个问题:配件和枪最好统一配色,不然装上去会显得突兀(尤其是握把部分),嗯,之后所有战术武器全变成暗蓝配色好了
生成器初步完工,不过还需要不少改进,目前生成的代码手动改的部分还挺多,另外最好能把贴图扔到右边,左边一栏右边一栏方便操作
发现枪握把有个问题:握把的实现略有难度:
- 需要独立调整显示层级,得覆盖在枪握把的上面
- 所有组件都最好比原枪配件大一码,以覆盖原枪
后来尝试了一下, subcontainer不响应containedspritedepth这个标签,故因握把贴图实现难度过大的原因,实现得弃用
Day3
枪械配件列表:
上插件:
步枪瞄准镜(原版) 增加武器的最远可视距离(cameraaimoffset)500单位,只有部分武器可用
ACOG瞄准镜 增加武器的最远可视(cameraaimoffset)距离250单位
全息瞄准镜 增加武器的最远可视100单位
- 变种:红点瞄准镜
- 变种:紧凑瞄准镜
狙击瞄准镜 增加武器最远可视距离700单位,只有部分武器可用,影响持握时步行速度
上下兼容插件:
激光瞄准器
手电筒
照明棒
信号弹
-以上物品安装在上插件时会导致准星消失
下插件:
垂直握把 变为战术持握(枪口向下)
直角握把 变为战术持握(枪口向上)
枪管:
消声器 修改武器枪管位置,减少5%散布,增加消音能力,增加5%伤害
消焰器 减少15%散布
长枪管 修改武器枪管位置,增加10%伤害,减少10%移动速度,增大枪口火焰
枪托:
无枪托(默认) 增加30%散布,增加15%移动速度
轻型枪托 有托武器的默认配置
重型枪托 减少5%移动速度,减少5%散布
射手枪托 减少15%移动速度,减少30%散布
(手枪枪托 减少20%散布,但是变为只能双手持握)
第一批贴图完成,只做了一半,主要是确认一下当前这套工作流可行,晚上准备开工处理代码
我把以前不知道在哪里找到的旧式工作台搬来了,现在当作这个mod的用好了
哈,幸好只做了一半,果然有坑:
xml原生支持增减这些操作,但是不支持TMD逆向操作!啥意思?老子消音器捅上去之后再拔下来,桶上去会给数值,拔下来数值没法变回去!笑死,好吧是可以变回去,用setvalue就行,但是如果一个属性被两种不同的插件影响(比如常见的,散布同时被握把和枪托影响),那逻辑上就会出现问题.
我想了想,这样的话得减一些特性:一个插件可以影响,每个属性只能固定被一种插件定义,
至于剩下的,我想之后学lua的时候试试好了…如果我还有余力去学lua而不是专注Godot的话
我就把话放在这儿了:如果不使用Lua重写的话,这个东西的拓展会很困难.所以等第一版出来以后,尽早用Lua把逻辑重写一遍
原版突击步枪的弹匣怎么贴图位置不对? 这个做完了帮官方修一下
1 | <Item identifier="tacAssaultRifleVGM" name="tacAssaultRifleVGM" tags="smallitem,weapon" category="Weapon" scale="0.5" impactsoundtag="impact_metal_light"> |
Day4
好吧,Alpha阶段算是ok了,调试了2把武器和8个配件,接下来可以进入大批量生产阶段了,哦对了,我最好确认一下合成配方,Day6做差不多的时候再添加好了
Day5
大规模生产的一天,今明两天可以把所有武器做完,不过我好像忘了做延长弹匣和弹鼓,今天还是先完成这个,并且进一步优化我的生成器好了、
本来想给弹匣设置一下影响枪械属性的,但是看到弹匣的原料后觉得没有必要,后勤和最大携带量已经足够了
我忘记给能上消音器的上aitarget标签了
另外得另起一个override文件,重写一下步枪的配方(可以在VGM加工台制作) 完工
得给所有涉及步枪镜的加个statuseffect 完工
哪些做对了
在开发初期就认识到程序化生成对批量产出的重要性
简单算笔账:
在Day4的时候,我把这个系统的核心代码实现给架构完成,整个mod一共10把武器16个配件,当我没有这个生成器的时候,在Day4做两个武器其实就花掉我半天时间,
那个XML生成器,其实就是为了枪械改装这个模组准备的,幸好我这次提前开始同时做这两个玩意儿,如果没有生成器,光是做两把武器就得花掉我半天时间。
生成器是在第五天完成的,而当我有了专门的XML生成器后,一天时间就完成了剩下的8个武器还有7个配件。开发的架构阶段很重要,要是搭好了,堆量阶段的效率甚至可以增加5倍。
生成器和Mod同步开发修缮
说实话,虽然XML生成器是全AI完成开发,但是AI开发≠不需要调试,前几天出的乱子也挺不少的,比如凭空生成游戏解析不了的格式、JS构造函数老是这里那里出问题等等。这种并行开发和迭代修正的策略,确保了工具的实用性,也让它输出的内容准确无误,避免了工具问题阻碍后续开发。
先完成代码层面的机制,然后再进行大规模开发
这个实际上我之前在《远行星号》谈mod制作的时候有讲过,这里再放一下引用:
没有美工、策划的电子游戏顶多不好玩,但没有程序的电子游戏会变得不能玩。
做mod同理。建议上来就对着技术难关搞突破——哪一部分你觉得最难搞定,那一开始就搞它。别上来就搞策划案和文案,就我个人3次 gamejam 的经历,策划案与文案是最整个游戏开发最简单的内容。把最难的部分放到最后做会让mod的难产可能性直线上升。
我就算在这说了也会有人继续往这个坑踩,我以前也踩过:主要的客观原因是写策划是整个游戏开发中正反馈最即时的部分,其他开发环节通常会延后得到反馈——两案写爽的例子不在少数,但是写程序/美工写爽的倒是挺少听到(那种爽也和写策划的不一样,更多的是一种折磨结束后的狂喜,而不是创作的快乐)。
这回算是彻底避开了这个坑,没有又一次陷入策划写10w字,代码一点没动的问题当中
终于学会如何使用AI看文档了
以前听老程序员说,看文档不如看源代码。《潜渊症》的开发文档本身也是半程序化生成的,有很多细节照顾不到位。这回我尝试了使用哈吉米(谷歌Gemini 2.5 flash,主流大模型当中最容易和用户发生争论/突发恶疾的一个因此得名)让它来帮我写一部分内容。
注意哈,我不是让它帮我搜索《潜渊症》的文档,我选择了先把游戏源脚本文件喂给它(StatusEffect.cs、Condintional.cs等)然后结合文档,问它一些更为细致的问题:比如OnInsert和OnRemove只能写在哪里哪里,某些子容器是否有限制等,事实证明这样使用AI比直接问它文档要准确得多,不容易出现AI幻觉的问题。
哪些做错了
在Mod文件夹里初始化.git仓库
如果你的游戏有1G以上的大小,或者根本不在乎游戏的体积,git仓库那50mb的体积对大多数项目来说都不是个事儿。但是当你的mod本身只有2mb的时候,让其他人为了下2mb的东西就得顺带下个50m的.git就显得有些不厚道了。
所幸这个问题被我及时发现并替换掉,看来以后做Godot的时候也得注意一下这个问题:总不能打包成web发行版时顺带给版本管理程序打包进去不是,毕竟jam上支持在线试玩与否有时候是能决定试玩量的。
没有使用fork来分化开发版和发行版
在项目管理上,缺乏开发版和发行版的清晰分离是我需要改进的地方。我这次没有使用Git的fork
机制,很可能意味着我的开发分支和主分支(或者说发行分支)没有明确的区分。这可能会导致一些问题:
发布风险: 直接在开发分支上修改并发布,很容易把那些没完成、没测试的功能或者Bug一起打包发布出去,影响用户体验。
版本混乱: 我很难清晰地追踪哪些提交是针对开发中的功能,哪些是已发布版本的修复或更新,导致版本回溯和管理变得复杂。
协作不便: 如果未来有团队协作,这种模式会让多人开发变得一团糟,很容易产生代码冲突。
我以后应该这样做:保持一个稳定的**主分支(main/master)作为发行版本,而所有的功能开发、Bug修复都在开发分支(develop)**或者特性分支上进行。当开发内容成熟并经过充分测试后,再把开发分支合并到主分支,然后打上版本标签进行发布。这样可以确保发行版本的稳定性和质量,也方便我管理和回溯版本。
版本控制函待全自动化
尽管我已经使用了Git进行版本控制,但看起来我的**版本控制流程还不够自动化。在未来,最好尝试一下以下内容:
在我把代码提交到特定分支后,自动触发构建、测试。
在满足发布条件时(例如,合并到主分支),自动创建版本标签。
自动把我编译好的Mod文件打包,并上传到指定的分发平台或存储位置。
自动化可以大大减少我的人为错误,提高发布效率和质量,让我能更专注于开发本身。
(开发日志写得比较混乱)
我不知道这算不算个问题,不过你也能看到我这一周基本是把开发日志当作随手笔记来写,我好像听说开发日志最好正规并且八股文一点?