2017年4月24日16点23分。
刚从床上爬起来的我肩颈酸痛,饥肠辘辘。昨夜难熬的腹泻和呕吐似乎已经消失了,想来应该是吃的药管用了。并不是因为贪睡——事实上,在刚刚结束的五个小时睡眠之前的48小时内,我在进行一场和自己的战斗。
我是去年才知道Ludam Dare的。这是一个线上的游戏开发比赛,和Global Game Jam(一个线下极限游戏开发比赛)类似,参与者需要在限定的时间内根据给定的主题完成一个游戏原型。比赛分为两组,Compo和Jam,限定的时间分别为48小时和72小时。其中Compo的要求更为严格,参与者需要遵循这些规定:
- 在48小时内提交游戏的可玩版本,48小时后有一小时的额外时间,用于打包和发布
- 除了代码可以用第三方库或者基于自己以往的积累外,美术资源和声音资源必须是在这48小时之内完成的
- 只允许单人参赛
- 必须公开源代码和游戏内使用的资源文件
而Jam组的要求则相对宽松一些:时间更为宽裕、可以组队参加、可以使用别人的美术资源(需要无法律风险)、不必公开代码。
我选择了参加Compo组,想试试自己能够达到什么程度。虽然作为程序员已经有将近十年,但真正参与游戏开发也不过才两年多,我需要对自己的能力有一个了解。而且48小时内做出一款游戏难道不是一件很狂霸酷炫吊的事情吗?
怀着这样的心情,我迎来了自己的第一次Ludum Dare,也是这个活动创办的15周年纪念。
以下简称Ludum Dare为LD
DAY 1 2017.4.22
选题
比赛主题发布是在中国时间的周六上午9:00,这也是比赛开始的时间。在此之前,LD官方网站上进行了为期两周的主题投票,这些主题是网站的注册用户提交的,而得票最高者即是本次比赛的主题。
平时周末我都会起的比较晚,这次9:40就起了。虽然比赛已经开始了40分钟,但我更需要保存更多精力来应付这场战争。
用手机打开官网,页面顶部赫然写着比赛主题:A Small World。
这是什么?
我本来期待着看到更出人意料、更奇特的主题。这个主题看起来平淡无奇,甚至让人耳朵长茧。一时间我蒙圈了。
这是第一个挑战。
我调整了一下自己的心态,开始琢磨如何解读这个主题。好在LD对于主题的解读范围十分宽容,而且官方本身并不会限定你是否要使用这个主题——当然作为评判力量的其他玩家和开发者会更严格些。
我并不打算做一个和地球/星球相关的游戏,这个角度已经被用烂了。既然是独立游戏挑战赛,当然是要做一些自己更喜欢、脑洞更大一点的游戏。在经过了20分钟的思考后,我决定做一款献给我们家主子“二狗子”的游戏,因为我的家对于她来说就是整个世界。
大概的思路是,二狗子为了展现自己是这个世界统治者,决心收集世界中的所有“财宝”。但愚蠢的人类不会让她把东西都藏起来,因此二狗子必须要在人类的眼皮子底下获得这些财宝,而且不能被抓住。
开工
有了思路便要尽快开始了。对于48小时,我仅有个模糊的概念——不能在对目标没有帮助的事情上浪费时间。最终的结果证明了整个开发节奏远比我想象的还要紧张。
游戏的风格是斜45度角的RTT(Real-time tactics,即时战术游戏)游戏,代表作有《盟军敢死队》、《赏金奇兵》和最近的新作《影子战术》。和这些游戏不同的是,我的游戏的关卡很小,“敌人”也只有一个,但是在纵向上活动的范围会很大,毕竟猫是很善于跳跃的。
首先要解决的是角色控制的问题。在3D场景中进行路径导航最简便的方法便是使用NavMesh计算移动路线,一般也都能获得不错的效果。在以往的项目中,我一直使用一个功能超级强大的名为A* Project的第三方库,但对于这个小项目,使用这种重型武器未免有些过了,毕竟我只需要简单场景的路径导航。我决定试试Unity自带的NavMesh模块,虽然并不很熟悉,但在项目中学习和尝试也是参加LD的意义所在。
我搭建了一个简单的测试场景,花了两个多小时的时间学习Unity NavMesh并完成了鼠标点击控制角色移动的功能。午饭过后,又花了几个小时完成了敌人的视线检测、状态切换、索敌行为,以及小猫拿到宝物并藏到自己宝库里的编码工作。
此时整个游戏流程已经初具雏形,虽然细节部分基本都没有经过打磨,但在我的计划里是打算将这些放到收尾阶段再进行的。
抬头看表,已经是晚饭时间了。此时距离开始开发已经经过了大概7个小时,整个进度看起来很乐观,我甚至还录了一小段游戏原型视频上传到了YouTube,并在活动网站上发了个博客向其他人介绍我的进展。
晚饭过后,我开始为游戏添加一些小细节,例如鼠标移到可交互物体上出现的提示框、在OffMesh路径节点上进行跳跃控制等,然后对之前完成的内容进行了一系列测试。在这个过程中,我还重构了一部分代码。
坑
一切看起来都跟美好——直到我遇到了第一个自己给自己挖的坑。
在此之前我并没有完整的AI开发经验,自己也没有成熟的AI框架,所以在开发敌人的控制脚本时,几乎是两眼一摸黑,按着感觉走。而当我要为敌人添加对猫叫声的反应时,噩梦来了。
在一开始的设计中,敌人的行为只有巡逻、索敌、注视、追赶几种情况,基本是纯线性的过程,所以用几个if...else
已经足够处理。而新增的行为“听见声音并前往调查”立刻使AI决策的复杂度上升了,更别提以后在AI层面进行扩展了。
思前想后,我还是决定把AI部分重写。
此时的我脑子已经开始发蒙,想到进度被耽搁和AI系统设计的种种细节更是头痛欲裂。抬头看表已经接近午夜,我必须得休息休息了。
看了两集《武林外传》乐呵了一下后,我还是决定在睡觉前把AI做完,这样明天就可以专注于美术和关卡。
AI系统我使用了状态机的设计:
通过触发事件让敌人生成一个“想法”,然后敌人再根据当前最高优先级的“想法”来行动;行动结束后继续执行其他被放置的“想法”。
通过将决策和行动独立成两个单独执行的层面,不仅可以让逻辑更清晰可控,而且也便于状态的切换和回溯。
一夜无话。AI系统完成时已经是凌晨五点,天快亮了。在LD网站上发了一篇博客记录了自己一天的成果后,我拖着疲惫的身体爬上了床。设置好闹钟后我便失去了知觉。
DAY 2 2017.4.23
闹钟催了几遍我才被叫醒。抓起手机看了眼,已经是上午十点,五个小时的睡眠使我的精神好了很多。我强打起精神从被窝里爬出来,毕竟还有一堆工作等着完成。
构建世界
由于昨晚睡觉前已经完成了核心的游戏逻辑,今天把世界搭建好了应该就差不多了。
嗯,至少当时的我是这么想的。
考虑到自己的3D建模水平实在捉鸡,在有限的时间内我也不打算真的用Blender去一点一点抠模型了。
我想起自己在Steam花68块钱买过一款名为Qubicle Voxel Editor的体素艺术软件,一直躺在库里还没下载过,就是为了有一天能派上用场。对于学了一点像素画的我来说,这种用方块拼成的世界既可行,又具有强烈的独立游戏风格。
我一边看着官方的帮助文档,一边尝试着建模还原我住的小公寓。考虑到场景的可玩性和复杂度,我去掉了家里的厨房和厕所。建模、导出、改贴图、在场景中放置……一件件家具被创造出来,游戏场景也越来越充实。看着自己创造的小世界,一阵强烈的满足感袭来——我突然意识到这就是激励我开始做游戏的初衷,也是对“a small world”这个主题的最好诠释。
随着对建模越来越熟练,更多物件被创造出来:猫咪玩具、散落的臭袜子、手机、猫咪二狗子……媳妇的“这不是满屏马赛克么”的吐槽并没有影响我对体素艺术的热情。
二狗子的模型被做出来后,我曾一度打算在Blender中通过骨骼动画来完成猫的各种动作动画,然而时钟上无情的指针让我打消了这个念头——我没有时间再去学习怎么做骨骼动画了。最终我放弃了二狗子的四肢,用Unity自带的动画工具把它做成了一只像史莱姆一样跳来跳去的生物。
此时已经超过半夜十二点了。做模型花了我五个多小时的时间,制作和绑定小猫的动画又花了我两三个小时的时间。
期间为了换换脑子,我又进行了一些编码工作,主要是在沙发底下、床底下、堆着的纸盒上加上小猫的藏匿点,让二狗子能够在狭小的房间里躲开人类的视线。而我还没有完成关卡设计和财宝的摆放,没有制作游戏的UI和教程,也没有完整的测试过我的游戏。
我感觉可能要熬夜才能完成了。
腹泻、呕吐、与时间战斗
不知道是因为巨大的压力还是晚上吃了不干净的东西,我开始上吐下泻,困在厕所里迟迟不能出来。吞了六颗调理肠胃的药,我头晕眼花地跟领导请了假,说明了我的身体状况并申请周一休息一天。在身体状况稍微好转了一些后,我收到了公司领导同意的回复。强打起精神,我又坐回了电脑前。
在被电脑屏幕和台灯照亮的黑暗中,我尽可能快地完成着收尾的开发工作,不时抬头看看表,然后为后面的工作粗略地分配着时间。
为了给游戏配上猫叫的音效,我在半夜里举着手机满屋子追二狗子想让她叫一声,但是这小王八蛋估计是听懂了我的话,自始至终一声不吭。气急败坏的我最终只能自己学猫叫——而此时我才发现我的嗓子已经快出不来声了。
窗外射进了清晨的曙光,我也终于进入了最终的测试阶段。我对于自己的成果并不满意:跳跃动画和位移的衔接并不流畅、UI过于简陋、人类的视线检测很不准确、模型碰撞的检测范围经常出现错误、没有用更合适的方式控制摄影机跟踪……但此时已经是早上七点多,距离提交只有不到两个小时了。我不得不放弃了很多细节调整,甚至放弃了忘了做的人类模型和动画,而只是用一个简陋胶囊体代替。
时间一分一秒的走着,往往觉得只做了一个很小的调整和修复,但转头发现时间已经过去了二十多分钟。我感觉缓缓前行的时间像一台巨大的压路机向我逼来,而我必须在这恐怖的压力下拖着身躯在泥泞中奋力爬行。
终于在8:59分时,我上传了全部代码和资源文件。
最后一小时
根据LD的规则,在开发时限到期后还有一个小时额外的打包提交时间。我直到这时才发现,网站上赫然写着:“我们建议您尽早提交,因为人们总是在最后一小时发现各种技术问题。”
我竭力按捺住心中的草泥马,脑子发木地开始打包,同时祈祷着不要出幺蛾子。
为了能让更多人不用下载即可玩到我的游戏,我决定发布WebGL版本。而当游戏打包完毕,在我的电脑上本地运行时,我却傻眼了:整个场景的光照效果和在编辑器中大相径庭,满屏幕充斥着屎的颜色,光照不足使场景模型的细节根本看不清。
我马上意识到应该是光照贴图的锅,但这部分我仅仅有所了解,并不十分熟练。于是我赶紧回到编辑器中,开始尝试调整各种参数,一次次的打包测试,直至最终达到了基本满意的效果。
进行这些调整花费了我近半小时的时间,我必须硬着头皮发布了,否则我将失去提交到Compo组的机会。
接下来的事情比较顺利:我将游戏上传到了itch.io上,并在ldjam.com上发布了我的游戏项目,甚至还写了篇博客来记录自己当时的一些感受。
9:45分左右,完成了全部提交工作的我长出一口气。我的肩颈火辣辣地疼着,眼皮重的抬不起来,巨大的疲惫让我感觉自己活在另一个次元。
但是这些又有什么关系呢?毕竟我完成了我的第一次48小时极限开发,而这也绝对不会是最后一次。
后记
经过48小时玩命一样的开发,我越发意识到自己在独立游戏开发过程中的不足之处:对于很多技术还是一知半解,而且有些喜欢钻牛角尖。这些问题在日常工作上是体现不出来的,充足的时间让我可以有一万种方法赶上进度。但在这压榨般的极限挑战中,任何错误都可能让你付出沉重的代价,一不小心就会失败——例如我对于游戏设计的把控能力不足、AI设计经验不足等,都使我进行了大量返工,并且很多设想中的游戏机制也没有来得及实现。这不得不说是一个遗憾。
然而相对于比赛竞争,LD给我更大的启示是:永远不要低估你的极限,永远带着一颗拥抱学习和挑战的心。你永远不知道等待你的是什么,而作为独立游戏开发者,你能做的只有勇敢面对,即使前路迷雾重重。
对于LD比赛,在下列方面我也深有体会:
- 不要用传统商业游戏的思路来设计游戏,你会发现那根本不现实。LD讲求的是小而美。
- 对自己的工作效率要有充分的了解,并且要给自己限定一个大致的时间表,以便合理安排时间精力。
- 要注重平时的积累,临时抱佛脚不可取。即使要抱,也要能知道自己要抱的是哪位佛的脚,否则绝对抓瞎。
- 做自己力所能及的事,不要尝试花太多的时间来做技术研究,更要学会做减法。
- 在紧急情况下可以写一些丑陋的实现,但还是应该保持整洁的编码风格和设计思路。经常重构代码(比如我是完成一个模块就进行一次),这会使你在遇到问题时受益无穷。
最后是我的游戏,欢迎大家体验吐槽
Ludum Dare作品页面:https://ldjam.com/events/ludum-dare/38/$19648
游戏页面: https://wizcas.itch.io/ld38