Skip to content

游戏制作技巧

制作 LibGDX 游戏的小贴士

以下是我在游戏制作领域短暂涉足后学到的一些东西。

其中有些对你来说显而易见,有些则未必。

使用 Kotlin

Unciv 最初是 C# 的 Unity 项目,后来转向 Java 与 LibGDX,最终迁移到 Kotlin。

我后悔在 Java 中编写事件所花的每一分钟,这可能是你的应用能做出的最重要改变。

使用 Scene2d

除非你打算动态生成图片,否则你会使用预渲染资源。

手动摆放它们就像手动定位 HTML 标签,而不是利用 HTML 层级结构和 CSS 来引导布局。

Scene2d 也是如此——它是一个布局框架,相对容易理解,尤其是当……

忽略 Horizontal 和 Vertical group —— 使用 Table

我个人发现 Table 拥有以上两者的全部功能,甚至更多。

每个类都有不同的语法,所以我发现全都用 Table 反而更简单。

Table 几乎能做所有事情!它简直太棒了!

游戏变慢时,使用 Android Studio 的 Android profiler

自上而下的 CPU 图表是我见过最好的代码分析器,善加利用!

缓存一切

缓存是纯净、无状态代码与更高性能之间的权衡。 作为 PC 背景出身的人,我本能地认为任何低于 O(n^2) 的操作都不到一毫秒,因此不值得缓存。 但在移动开发中并非如此。

当你需要保存和加载包含大量关联部分的游戏数据时,这一点尤其重要——你必须避免循环引用、最小化存档体积,同时还要在加载时重建缺失的链接。

最小化字符串操作

你听过的所有关于最小化字符串操作的建议?用起来!

字符串常量应该是 const,使用 StringBuilder(或者用字符串的 ArrayList,最后 .joinToString())。

处处使用 Sequences!

我没想到的一个大问题是排序和映射时的中间列表。

显然,这些任务的内存分配是件大事。

所以尽可能在列表操作前调用 .asSequence()——这能节省大量时间和内存!

唯一不该这么做的情况是:你想缓存特定值以备将来使用——sequence 每次迭代都会重新走一遍完整流程,所以拿到最终结果后记得 .toList()

制作开源游戏的一般建议

降低门槛——对程序员和玩家都是

我认为大多数开源游戏都受此困扰——圈内的人深入其中,而圈外想加入的人却要学习整套生态。

文档是个大问题,详细的指引也是——我指的是"手把手喂到嘴边"。

把新开发者当作从未用过 Git 的人来对待——他们可能真的没用过!

解释如何下载源代码、工具,如何让游戏在本地跑起来,如何修改以及如何提交。

对新玩家也一样——让游戏能跑起来应该尽可能简单——你想让人们玩你的游戏,不是吗?

包括:

  • 源码到可执行文件的自动化——我用 Travis
  • 应用商店等渠道
  • 游戏内教程——玩家永远不会对最后这一点满意,但至少尽力去做

社区,社区,社区!

我个人在发布后大约一年里都低估了这一点。

我通过 Google Play 商店和 GitHub issues 与玩家交流,这似乎就够了。

直到玩家反复催促,我才开了 Discord 服务器——而这逐渐带来了巨大的改变!

你看,关键不在于程序员与玩家之间的互动。相对于庞大的玩家群体,核心开发者永远只是少数。

社区的关键是玩家与玩家之间的互动。解释、提问、点子、玩家之间互相碰撞的想法, 不仅让松散的社区变得更好,实际上还让游戏变得更好!

另外要记住,你周围还有更大的社区——开源社区、Linux 社区等等。

有很多人仅仅因为你的游戏是开源的就会去玩它,这也意味着他们没有太多其他选择。

例如……

  • 成为最好的 4X 游戏意味着与最大的那些名字竞争
  • 成为最好的 Linux 4X 游戏意味着竞争对手少得多,但如今"酷孩子们"都在跨平台,所以你仍然不占优
  • 成为最好的开源 4X 游戏意味着大约 5 个竞争对手,而且没有金钱参与,所以平均水准没那么精良
  • 成为最好的安卓开源 4X 游戏……意味着竞争对手少到完全可行

一切都是营销。

你的游戏名、图标、截图——玩家看到的关于你游戏的一切都是营销。

图标和标语尤其重要,因为它们是玩家最先看到的东西。

在几次实验后(Google Play 让你很容易做这些实验),我仅仅通过更换图标就看到了近 50%(!)的变化。

翻译是你源代码的一部分

这可能有点争议,容我解释。

在到达当前格式之前,我们在如何保存翻译上经历了好几轮迭代。

要点如下:

  • 游戏翻译文件应该自动生成。这样你可以毫无顾虑地往游戏里添加新对象, 因为相应的词条会被自动加入翻译。

  • 每种语言的翻译应分开存储——这样多个语言可以并行修改,互不冲突

  • 翻译应该通过 PR 合入!这样其他语言使用者可以质疑或修改提出的翻译,你也可以对翻译运行测试。 如果你要求特定格式,这一点价值连城——坏翻译在门口就会被拒之门外。

开源问题需要开放的解决方案

简而言之,考虑使用免费(即使不是开源)的 API。

多人游戏需要在客户端之间同步游戏文件,即使其中一个玩家当前不在线。

'正确'的解决方式大概是有一个在线数据库和一个处理用户请求的服务。

由于这是开源游戏,我的预算是 0 美元,所以我们就简单地把所有文件存在 Dropbox 里,在那里上传/下载。

这安全吗?不安全,但需要吗?你需要权衡成本与价值。

模组也是一样。Steam 大而安全,所以它自己管理模组。

我们小而开放,所以只允许从 GitHub 下载,这让我们免费使用 GitHub 的所有内置功能(用户管理、readme、star、版本管理……)。

与基本算是滥用的 Dropbox 用法不同,GitHub 天生就是干这个的! 这正是他们当初设想的使用场景!

算总账的时刻

每个项目都会迎来这样一个时刻:酷炫的部分做完了。所有前沿的惊艳和算法的橡皮泥都玩完了,现在(哈)需要的只是打磨。

你知道谁喜欢打磨吗?玩家!当然,有些人会说"好游戏即使朴素也是好游戏",但他们心中对"朴素游戏"该有什么也是有标准的。

数字不会说谎。打磨好的游戏卖得更好,玩得人也更多。

你知道谁喜欢打磨吗?开发者

游戏相对简单时,打磨的选项有限,但游戏越复杂,可打磨的地方就越多。

而且这可能是个绝对的苦差事。又一个奇怪的使用场景、又一个游戏内选项、"更好的性能"(我肯定在各类性能相关的事情上花了几十个小时)。

最糟糕的是,所有人都注意到它缺席,却没人注意它存在。字面意义上的一百个打磨版本,而普通玩家可能只注意到一丝丝变化。

然后你会问自己:何必呢?我们到底在干什么?

对我来说,答案如下:

A. 要做出真正伟大的东西,你必须在它不再有趣之后继续坚持很久。

B. 有一群喜欢你正在做的事的人,他们希望有更多这样的东西 😃

C. 你知道自己想继续写代码,而且——怎么,你以为再开一个项目就能一样顺利?你已经试过好几次了,说实话,除非你投入和现在一样多的时间,否则做出第二个同样成功的游戏的几率真的很小,然后嘛,你又回到了这个位置。

这就是我过去一百来个版本所处的循环!解 bug、修边界情况、改进 AI、接收 PR。大量模组相关改动——既要阻止玩家在模组里做不该做的事导致游戏崩溃,又要给他们更多制作自由。

我不认为我真的会去把 G&K 做完,我绝对不打算实现 BNW 的机制,坦率说我觉得那些……不怎么样。

这就是我现在的状态。算是做完了这个游戏,但考虑到半年前我就这么想了,而发布仍然大约每周一次——所以也还算没做完。