« 有惊无险的一次网站系统升级 | 返回首页

深远未来开发总结

桌游 Deep Future(深远未来)开发搞一段落,我为它创建了一个 itch.io 的页面 发布第一个试玩版本。接下来的 bugfix 会在 github 继续,等积累一定更新后再发布下一个小版本。

这是一个兴趣驱动的项目。正如上一篇 blog 中写到,驱使我写它的一大动力是在实践中探索游戏开发的难题。写这么一篇总结就是非常必要的了。

开发过程

我在 2025 年 7 月底写下了项目的第一行代码。在前三周并没有在实现游戏方面有太多进展。一开始的工作主要在思考实现这么一个游戏,底层需要怎样的支持。我使用的引擎 soluna 也只是一个雏形,只提供非常基础的功能。我想这样一个卡牌向桌游数字化程序,更好的文本排版功能比图形化支持更为迫切。固然,我可以先做一个 UI 编辑器,但那更适合和美术合作使用。而我现在只有一个开发者,应该用更适合自己的开发工具。应该更多考虑自己开发时的顺手,这样才能让开发过程保持好心情,这样项目才可能做完。所以我选择用结构化文本描述界面:容易在文本编辑器内编写,方便修改,易于跟踪变更和版本维护。

在 8 月的前两周,开发工作更多倾向于 soluna

  1. 维护 yoga 的集成,编写布局模块。
  2. 增加文本块的支持,支持简单的文字排版。
  3. 增加 icon 的支持,可以和文本混合排版。
  4. 增加单色无贴图矩形。这样可以视觉化布局的 box 。
  5. 增加嵌套图层,而不是之前的平坦化图元。

期间有两个和游戏无关的(看起来很小的)问题花掉了我很多时间:

  1. 设置窗口标题 api 的多线程竞争引起的死锁
  2. 我按照过去的习惯,使用预乘 alpha 的方式处理半透明混合。后将其修改为非预乘模式。

关于 alpha 混合这点。根源在于 20 多年前我使用 CPU 计算 alpha 混合。当时如果将图片像素预先乘上一次 alpha ,可以减少一点运行时的 CPU 开销。这个习惯我一直带到现在 GPU 时代,本以为只是现代图形管线中的一个设置而已。当我独立开发时才发现,现在的图片处理软件默认都不会预乘方式导出图片,这让我自己使用 gimp 编辑带 alpha 通道的图片时,工作流都多了一步。因为 gimp 也是现学的,一下子也没有找到特别方便的方法给图片预乘 alpha ;使用 imagemagick 用命令行处理虽不算麻烦,但增加了工作流的负担。我在上面花掉了十多个小时后(主要花在学习 gimp 和 imagemaick 的用法)才醒悟,配合已有成熟工具简化开发工作流才是最适合我这样独立开发。所以我把引擎中的默认行为改成了非预乘 alpha 。

到 8 月的第三周,已经可以拼出静态的游戏界面:有棋盘、卡片、带文字的桌面布局。虽然从外观上,只是实现一个简陋的静态的带图层排版系统,但视觉上感觉游戏已经有点样子了,而不再仅仅是脑补的画面,这让开发的心情大好。

同时,我实现了基本的本地化模块。其实不仅仅是本地化需求,即使是单一语言,这种重规则的桌游,在描述暂时游戏规则时也非常依赖文本拼接。因为维护了多年 stellaris 的中文 mod ,我受 Paradox 的影响很深。早就想自己设计一套本地化方案了,这次得以如愿。

接下来的四周游戏开发速度很快。在之前三周的引擎补完过程中,我在脑中已经大致计划好后续的游戏开发流程:按游戏规则流程次序,拆分为布局阶段、开始阶段、行动阶段、结算阶段、胜利阶段、文明及奇迹分开实现。每个流程在实现时根据需要再完善引擎以及游戏底层设施。

以游戏玩的流程来依次实现,可以让游戏逐步从静态画面变成可交互的,这种体验能提供一种开发的目标感:让我觉得开发进度在不断推进;而每个步骤其实要解决和补充底层设施的不同方面,解决问题是不一样的,这样可以缓解开发的枯燥感。保持开发的心情最重要,这是我近二十年学到的东西。只是过去我一直偏重于底层开发,一直回避了相对枯燥繁琐重复的游戏功能开发。开发游戏中的不确定性,实现一点点交互功能也要花费大量时间的确是非常打击开发心情的东西。这并不像底层开发有一个确定目标,和 API 打交道(而不是纠缠在低效的人机交互中)也可以直指问题本身。


实现游戏布局设置时,我顺道完善了桌面布局模块,让棋盘、手牌、胜利轨道、中立卡牌区等展示得好看一些。并增加了和鼠标的交互,卡片在区域间的运动等。

待到游戏有了基本的交互,变得可以“玩”了。我发现,一个数字化的桌游最重要的是引导玩家熟悉桌游规则。重要不是做一个详尽的手把手一二三的教学,而是玩家一开始无意识操作中给出有价值的信息反馈。玩家可以学到每个操作对游戏状态造成了怎样的影响。玩家还应该可以随时点击桌面元素去了解这各东西是什么。虽然大段的文字描述对电子游戏玩家来说并不友好,但对桌游玩家来说是必修课。数字版能提供更好的交互手段,让玩家可以悬停或点击一个元素,获得文本解释,已经比阅读桌游说明书友好太多了。

所以我在一开始就花时间在底层设计了这样的提示系统。

打算往下实现更复杂的游戏流程时,我意识到这类流程复杂的游戏,主框架镶嵌一个简单的游戏主循环显然不够用。我需要一个状态机来管理交互状态。一开始并不需要将状态机实现得面面俱到,有个简单的架子即可。Lua 的 coroutine 是实现这样的状态管理非常舒适的工具,几十行代码就够了:gameplay 的状态切换很轻松的就和渲染循环分离开了。


游戏的“开始阶段”本身并无太多特有的 gameplay 需要实现。但是,这套游戏规则中最复杂的 advancement effect 机制在这个阶段就有体现。最难的部分是设计 advancement 的交互。在桌游原版规则中,玩家可以任意指定触发哪些 advancement ,它们的来源也很多样:弃掉手牌、母星区卡片的持久能力、殖民地区卡片的一次性能力等等。每张卡片上可触发的 advancement 数量不一,从 0 到 3 皆有可能,玩家可以选择触发或忽略,最后还可以自由决定对应 effect 的执行次序。

对于桌游来说,这是非常自然的形式:桌游玩家的脑海中一开始就包含了所有游戏规则,大脑会将这些散布在桌面各处的元素聚集起来,筛选出需要的信息,排序,执行,一气呵成。但对于数字版,很容易变成冗长的人机交互过程。每个步骤都需要和玩家确认,因为轻微的差别都有可能影响 effect 结算的效果。这不光实现繁琐、对玩家更是累赘。

所以,电子游戏中更倾向于自动结算的规则,减少玩家的决定权。玩家也不需要了解所有的游戏规则。只有在玩家成长中,从新手到老鸟的过程,玩家可能去关注这些自动结算是怎样进行的,电子规则则提供一些中途干预的手段帮助高级玩家,所谓提高玩法深度。以万智牌和炉石传说相比较,就能体会到内核相似但卡牌效果结算方式的巨大差异。前者是为桌面设计的,后者则天生于电脑上。

不过这次,我不打算对桌游规则做任何调整。专心实现桌游的数字化。有些看似有绝对最佳选择的 advancement ,我也没有让系统自动结算,还是交给玩家决定。一是复原桌游的游戏感觉,二是让玩家参与结算推演的过程,让玩家逐步熟悉游戏规则。

当然,一个 advancement 当下是否可用,这是由严格规则约束的。桌游中需要玩家自己判定(也非常容易玩出村规),而数字版则可以做严格检查,节省玩家记忆规则细节的负担。这个负担依旧存在,转嫁到数字版开发者身上了。为此我在桌游论坛和桌游规则作者探讨了多处细节,以在实现中确定。

advancement 结算这块一开始就决定仔细抽象好,这样可以复用到后续的行动结算部分。不过我还是低估了一次设计好的难度,后来又重构了一次。

另外,从这里开始,我发现这个游戏的规则细节太多以至于我必须提升测试玩法过程的效率。所以设计了一个测试模块。并不是一个自动化测试,而仅仅是为人工测试做好 setup ,不必每次从头游戏。我有两个方案:其一是写一个简单的脚本描述测试用的 setup ;其二是完善存档模块,及作弊模块,玩到一个特定状态就存档,利用存档来促使。

我选择了方案一,在编辑器里编写 setup 脚本。以我的经历,似乎很多游戏项目偏向于方案二,好像有纯设计人员(策划)和测试人员共同参与开发的项目更喜欢那样。他们讨厌写脚本。


行动阶段的开发基本可以按游戏规则中定义的 8 种行动分别实现。其中 EVOKE 涉及文明卡,第一局游戏中不会出现,本着能省则省早日让游戏可玩的想法,我一开始就没打算实现。

而 PLAN 行动是最简单的:只是让玩家创造一张特定卡片,而且不会触发 advancement 。我就从这里开始热身。不过,PLAN 行动和其它行动不同,它不是靠丢弃手牌触发的,而是一个专有行动。这似乎必须引入一种非点击卡片的交互手段。我就分出时间来给界面实现了 button 这个基础特性。同时确定了这个游戏的基本交互手段:当玩家需要做出选择时,使用多张卡片标注上选项,让玩家选择卡片;而不是使用一个文本选择菜单。交互围绕卡片做选择,一是我像偷懒不做选择菜单,二是希望突出游戏以卡牌为主体的玩法。当然,也需要多做一些底层设施上的工作:一开始我打算让每张卡片都在游戏中有唯一确定的实体,但既然卡片本身又可以用来提供玩家决策的选项,就在底层增加了一种叫做卡片副本的对象。

某些行动有独自的额外需求。像 POWER 行动最为简单,只是抽牌而已。但 SETTLE 就涉及和中立区卡牌的交互;GROW 涉及在版图上添加 token ;ADVANCE 涉及科技卡的生成;BATTLE 和 EXPAND 涉及版图区域管理。这些需求一开始在 gameplay 底层都没有实现,只在碰到时添加。

好在这些需求天生就可以分拆。我大致保持一天实现一个行动的节奏,像和银河地图的交互也会单独拿出一天来实现。让每天工作结束时游戏可以玩的部分更多一点,可以自己玩玩,录个短视频上传到 twitter 上展示一下。

部分复杂的部分很快经历了重构。例如星图的管理,从粗糙到完善。一开始只是对付一下,随着更丰富的需求出现很快就无法应对,只能重新实现。中间我花了一天复习六边形棋盘的处理方法

交互部分给图形底层也提出了新的需求:我给 soluna 增加了蒙版的支持,用来绘制彩色的卡片。


按我的预想,按部就班的把游戏行动逐步做完,游戏的框架就被勾勒出来了。让游戏内容一步步丰富起来会是我完成这个项目的动力。这个过程耗时大约 2 周,代码产出速度非常快,但也略微枯燥。感觉代码信息密度比较低,往往用打算代码实现一点点功能。这种信息密度低的代码很容易消耗掉开发热情。但它们又很容易出错,因为原本的桌游规则细节就很繁杂,一不小心就会漏掉边界处理。gameplay 的测试也不那么方便,如果依赖人去补充详尽的测试案例,开发周期会成倍的增加,恐怕不等我实现周全,精神上就不想干了。期间主要还是靠脑中预演,只在必要时(感觉一次会做不到位)才补充一个测试案例。

按节奏做到回合结算阶段时,我发现虽然看起来游戏可以玩了,工作其实还有很多:结算的交互和前面的差别很大、还需要补充 upkeep 方块的实现。回合结算事实上是系统行动阶段,虽然玩家参与的交互变少了,但自动演绎的东西增加了。系统结算过程可能导致玩家失败,所以必须再实现一个玩家失败的清点流程才能完整。

到 9 月初的时候,我完成了以上的工作。正好碰上每年一度的 indieplay 评审工作(四天),我在评审前一晚完成了第一个可玩版本(只有失败结算,没有胜利结算),第二天带到评审处,给一个评委试玩。这是第一个除我之外的玩家,表现还不错,居然只碰到 1 个中断游戏的 bug ,还只是发生在游戏最后一回合。来自于专业玩家的评价是:这么复杂的游戏规则想想也知道需要大量的开发工作,一个月就实现出来算是挺快了。缺点是部分游戏流程进行的太快,还没明白是什么就过去了(自动推演的部分);影响玩家选择的支付和结算部分,非常容易误操作选择对玩家不利的选择;至于最后碰到的那个 bug ,可以充分理解。第一次玩家试玩有一两个 bug 是再正常不过了。

我记录了一下玩家反馈,回家调整了对应部分:在底层增加了鼠标长按确认的防呆操作(其中图形底层实现了环形进度条的显示,同时发掘了底层图元装箱的一个小问题:图元拼接在整张贴图上时,需要空出一像素的边界,否则会相互影响),顺便重构了鼠标消息的底层管理 。另外,丰富了不少自动推演的流程的视觉表现,一开始设想尽量快速自动结算方便玩家恐怕不太合适。玩家并不需要过于加快游戏节奏,通过视觉上的推演过程让玩家理解游戏更重要。这些工作做了几个晚上(白天需要做游戏评审工作)。


接下来的两周发生了意外,我的开发工作几乎停滞。

租的房子到期,原计划在 9 月底搬家。给 indieplay 做评委的最后一天,接到母亲电话,在小区门口被顺丰快递员骑的电瓶车撞到,胫骨粉碎性骨折住院。处理医院的事情花了一整个晚上,心情大受影响。

调整心情后,我还需要面对另一个问题:原本计划是和母亲一起收纳搬家的东西,时间上非常充裕,每天只需要规划出小块时间即可。现在虽然父亲可以负责医院住院的事情,但搬家的工作几乎得我一个人来做了。关键是意外让日程安排突然变得紧张起来。把开发从日程重去掉是必然的。

最终如期搬完家,非常疲惫不堪。万幸母亲手术很顺利,只是未来半年行动受限,需要人照顾。


这段时间,我已经把游戏代码仓库开放。由于在 twitter 上的传播,已经有少量程序员玩家了。其实游戏并未完成,网友 Xhacker 率先赢得了(除我本人的)第一场游戏胜利…… 只是代码上并无胜利判定,所以他补完了这部分代码。由于对游戏规则不那么熟悉,所以实现是有 bug 的,后来也被我重构掉了。但接受这种 gameplay 的 PR 让我感受到了玩家共同创作的热情。

Xhacker 同学还依照本地化格式,提供了英文版本的文本。这也是我计划中想做而没精力顾及的部分。帮我节省了大量的时间。后来我只花了两天时间就将后续开发中的新词条双语同步。

网友 Hanchin Hsieh 对多平台支持表现出热情。先后实现了 soluna 的 MacOS 和 Linux 版本 。中间我也花了 1-2 天时间解决多平台的技术问题。还给 soluna 提交了 CI 以及 luamake 的构建脚本。

如果开源项目可以拆分出更独立的子任务(例如跨平台支持、本地化等),多人合作的确能大大缩短开发进程。


搬家结束后,我重拾开发。恢复开发状态用了一两天的时间。后续工作主要是以下几点:

  1. 重构胜利结算流程
  2. 完善游戏存档
  3. 实现文明卡和奇迹
  4. 制作主界面,增加多游戏文件支持和语言切换的交互(之前只提供命令行切换)
  5. 卡片随机命名
  6. 实现输入控件以及玩家自定义卡片名称
  7. 将玩家游戏过程组织成文本供回顾游戏历史

这部分花了两周时间,可以说是按部就班。但实际开发工作比字面上的需求多许多。

在重构胜利结算流程中,我顺手把控制游戏流程的状态机模块修改了不少。因为无论是胜利结算还是失败判定,以及持久化支持,都会引入更复杂的状态切换。需要保证这些切换过程中数据和表现一致不能出错。

胜利结算中,为了增加游戏的仪式感,底层支持了镜头控制:可以聚焦放大桌面,将镜头拉近和恢复。

游戏存档被分离到独立服务中,同时承担数据一致性校验。在过去一个月的开发中,我发现存档对最终 bug 非常有效。依赖出错前的存档恢复出错环境比查看 log 要方便得多。但这需要更细致的存档备份,方便玩家从文件系统中提取历史存档。同期还解决了一个底层在 windows 上处理 utf-8 文件名转换的 bug 。

文明卡和奇迹都是游戏后期内容,开发起来并不容易。对于文明卡,规则书上有不少含糊其辞的地方,专门去 bgg 论坛和原作者核对细节。文明卡有一半的每个效果是特殊的,需要单独实现。但这些单独实现的部分和之前的 advancement effect 又有部分共同之处。本着让日后修改更容易的原则,再次重构了部分 advancement 处理的代码,让它们可以共用相同的部分;而奇迹的实现使得星图的管理模块又需要扩展,同样需要扩展的是 EXPAND 行动流程。这部分的开发持续了好几天。

主界面功能涉及到多层界面布局。之前游戏只使用了单层 HUD 结构外加一个说明文字的附加层,没打算实现多层界面(即多窗口)。而按钮模块也是临时凑上去的。待到实现主界面时,其结构的复杂度已经不允许我继续凑合了。

所以我对此进行的重新设计:原则上还是将行为了表现以及交互分离。在同一个代码文件里实现了所有界面按钮对应的功能,用一个简单的 table 描述界面按钮的视觉结构,通过这个视觉结构表来显示界面。这还是一个贴近这个游戏的设计,不太有普适性。可能换个游戏的交互风格就需要再重构一次。不够我觉得现阶段不用太考虑以后再开发新游戏的需求。遇到重写就好了。多做几次才好提取出通用性来。

界面的防呆设计没有继续沿用长按转圈的方法,而使用了两次确认的方式。即危险操作(例如删除存档)的按钮在点击后,再展开一个二级菜单,需要玩家再点击新按钮才生效。我觉得这种方式实现简单,也可以充分防呆。

我原本只想做卡片随机命名,不想做玩家输入自定义卡片名称的。一是做了一个多月有点疲倦了,想早点告一段落;二是考虑到我自己玩了不少策略游戏,几乎不会修改系统随机起好的名字,即使游戏提供了玩家修改名字的功能。很快的,我就从网上搜集了中国和世界大城市名称列表,用来随机给星区和星球卡命名。但当我在做科技卡命名时却犯了难。在原本桌游规则里,依照三条随机组合的 advancement 效果给科技卡起一个恰当的名字,是玩家玩这个游戏的一大乐趣(也是一项对玩家想象力的挑战)。程序化命名无非是在前缀、后缀、核心词的列表中按规则组合,必然失去韵味。我花了一天时间做了一班并不满意。尤其是想同时照顾中文和英文的命名风格太不容易。

Paradox 在群星的最近版本中一只致力于生成更好的随机组合名称。我在汉化时也学到了不少,这或许是很好的一个课题,值得专门研究实现。但在当下,我只想早点发布游戏。所以,我选择实现键盘输入模块。

soluna 原本并未实现键盘输入的相关功能。这主要涉及文本块排版模块的改进。因为一旦需要实现输入,就必须控制输入光标的位置,这个信息只要文本排版模块内部才有。我原计划是在日后增加文本超链接功能时再大改排版模块的,这次增加输入光标支持只能先应付一下了。有了底层支持,增加用户自定义卡片名称倒很容易。

至此,我已经完成了绝大部分预想的游戏功能。除了 7 ,暂时还未实现。

最后,还差一个 credits 列表。之前在做网游,只有在大话西游中我按当时的游戏软件管理加上了制作人员名单。那还是我在客户端压(光)盘前一晚执意加上的。为此我熬了一个通宵。后来的网游我便不再坚持,这似乎开了一个坏头,整个中国的网游产品都不再加入 Credits 了。再后来,我只在杭州开发的一个并不成功的卡牌游戏(卡牌对决)中再加过一次 credits。

正如《程序员修炼之道》第二版所言:

提示 97 :在作品上签名

“保持匿名会滋生粗心、错误、懒惰和糟糕的代码,特别是在大型项目中——很容易把自己看成只是大齿轮上的一个小齿,在无休止的工作汇报中制造蹩脚的借口,而不是写出好的代码……我们想看到你对所有权引以为豪——这是我写的,我与我的作品同在。你的签名应该被认为是质量的标志。人们应该在一段代码上看到你的名字,并对它是可靠的、编写良好的、经过测试的、文档化的充满期许。这是一件非常专业的工作,出自专业人士之手”。

我在 gameplay 的开发中充满着仓促、粗糙的设计,在游戏中展示我的名字会让我心存愧疚,以后或许会完善它或在新作品中做得更好。


数据统计

开发这个项目,我经历了接近两个月,从 2025 年 7 月底到 2025 年 9 月底,除去中间被打断的两周,一共 7 周时间。

游戏项目一共增加了 25152 行,删除了 7912 行文本,合计 17240 行。其中包含了 1000 多行的本地化文本和 3000 行左右的界面布局、测试数据、规则表格等。实际代码在 13000 行左右。

引擎 soluna 因这个游戏增加了 7756 行,删除了 2,084 行代码,合计 5672 行代码。

虽然游戏中美术量不大,但我还是大约花了 3-4 个工作日制作所用到的美术资源。时间花在学习 GIMP 和其它一些美术制作工作使用上为主。图标是在 fontawesome 上进行的二次创作,卡片是自己绘制的。星图则直接复用了桌游的原始资源。

版面设计不算复杂,yoga 提供的 flexbox 方案很好用。算上学习 flexbox 排版的时间,前后大约花了 2 个工作日。

虽然游戏规则很繁杂,但 bug 比我预想的少。debug 时间不算太多,通常随着开发就一起完成了。后来在 github 上玩家提到的 bug 也都可以马上解决。预计后续的游戏测试过程会是一个长尾,持续很长时间,但需要的精力并不多。不过能做到这一点,得益于桌游规则经历了近十年的修订,非常稳定。而我在动手实现数字版前,已经花了一个月的时间充分玩了实体,经历了无数的游戏规则错误。动手写代码时,游戏规则细节已经清晰的刻画在大脑中了。这和写底层代码很像:需求已经被反复提炼,只需要用代码表达出来。开发过程解决的都是程序结构问题,而不是应对多变的需求。

经验积累

经历这么一次,我想我可以部分回答项目开始之初的疑问。

我在开发过程中的情绪波动告诉我,最重要的是保持开发热情。不同情绪状态下的效率、质量差异很很大。这可以部分解释为什么行百里路半九十。并不是最后 10% 真的有一半工作量,而是开发热情下降后,开发效率变低了。伴随着潜在的质量下降,花在重构、debug 上的时间也会增加。

所以明确拆分任务真的很重要。每完成一步就解决了一个小问题。开发精力就能回复一点。但这样也容易陷入到开发细节中。多人协作可以一定程度的避免这一点,分工让人更专心。一人做多个层次不同门类的工作需要承担思维切换的成本,但能减少沟通,利弊还说不好。

对于游戏来说,视觉反馈是激励开发热情的重要途径。所以需要做一点玩一点。让自己觉得游戏又丰富了。但是追求快速的视觉反馈很容易对质量妥协:我先对付一下让游戏跑起来,不惜使用冗长重复的实现方式,硬编码游戏规则…… 事后一定需要额外精力去拆这些脚手架的。所以,会有很大部分的功能需要实现两遍。这或许是预估开发时间时需要将时间乘 2 的根源。

虽然重构很花时间,有时候还很累。但过去的经验告诉我,越早做,越频繁,越省事。这也是独立开发的优势之一:你不必顾及重构对合作者的冲击。所有东西都在一个人的脑子里,只要对自己负责就够了。

对于独立开发,代码量又变成了一个对项目进度很好的衡量标准。因为你知道自己不会故意堆砌低效代码,那么每 100 行代码就真的代表着大致相同的工作进展。整个游戏的核心代码放在 20000 行之内是非常恰当的篇幅,其实这个数字对非游戏项目也适用。因为这意味着你可以在一到两个月完成项目的基础工作。这样的周期不至于让热情消磨殆尽。后续的长期维护则是另一项工作了。

要把代码量控制在这个规模,需要尽可能的把数据分离出去。不然游戏很容易膨胀到几十万行代码。识别出哪些部分的代码可以数据化只能靠经验积累。而经验来源于多做游戏。所以,我今后还需要多写。

同时,分离引擎也是控制游戏代码规模的要点。不用刻意做游戏引擎,只需要做游戏就够了。识别出通用部分,集成到引擎中。给游戏项目也留一个底层模块,把不确定是否应该放在引擎中的代码先放在那里。它们可能跨不同游戏类型通用,但只是还没想到更好的抽象接口而已。

“优化”工作对我很有吸引力。但考虑到游戏开发进度,可以先把优化点记录下来放一放。保持着写好代码的决心,晚一点做优化不迟。这里的优化不仅仅指性能优化,也包括更好的代码结构和更紧凑的实现方式(更短的代码)。老实说,目前这版实现中,还是有大量冗长可以改进的代码,我相信有机会再做一次的话,我只需要一半的代码就能实现相同的功能。当然我不需要再实现一次,开始下一个项目更好。

开源依然有很大的优势。虽然很少有游戏业务代码开源,《大教堂与集市》的 4.10 探讨了“何时开放,何时关闭”,游戏业务本身开源能获得经济收益非常少。我一开始也考虑过闭源开发。这并不是一个经济上的决定,而是我知道,这个项目注定不会有很高的代码质量,低质量代码不具备传播因素,它无法作为学习参考,也没什么复用性,反而有一点点“面子”问题,毕竟写出低质量代码“面子上”不太好看。

但我发现这个项目开源后依然获得了额外收益。

吸引了程序员的参与,多交了几个朋友。在发现 bug 时,有一个更好的交流基础,对着代码看更清晰。即便只是自己读,阅读公开代码比阅读私人代码会更仔细。而且更有动力用文字解释。在写作过程中,思路得以迅速理清。

btw, github 的公开仓库比私有仓库有更多的免费特性。

Comments

虽然不做游戏开发,但还是把主要内容看完了,2 个月完成游戏开发👍,这种细致的总结和反思也值得学习。

Post a comment

非这个主题相关的留言请到:留言本