今天在Reddit上看到一个帖子,直接把我看乐了。有个老哥在游戏开发社区r/gamedev里问了一个特别实在的问题:“那些殖民地模拟游戏到底是怎么做到同时处理500多个角色还不掉帧的?”结果评论区涌进来一堆正经做游戏的程序员,回答的画风跟他想象的完全不一样。

帖子是用户Link_AJ发的,他拿Steam上评价不错的《Songs of Syx》举例子。这游戏里几百号居民在城里走来走去,搞物流的生产的忙个不停,他就很好奇这种规模的模拟到底用了什么黑科技。然后,真正的技术大佬们开始下场了。

打开网易新闻 查看精彩图片

先上来的是《Mewgenics》的程序员Tyler Glaiel,这游戏今年2月刚发售,是个肉鸽模拟类。他的原话翻译过来大概就是:500个角色而已,基础设计别作死,根本不用搞什么特殊优化。什么叫别作死?就是别干那种“每个角色每帧算好几次寻路”的蠢事,也别过度依赖那种管理起来费劲的插件系统。他还特意补了一句,真正需要上猛药的阶段,是几千个角色起步。到了那个量级,评论区其他人提到的各种优化手法才会变得有意义。

《Dota 2》热门自定义地图“Crumbling Island Arena”的作者DoctorGester也给了差不多的判断。他说你要是搞5万个NPC,那确实得另说,但500个真不用那么紧张。有意思的是,当有人聊到把数据按类型集中管理能提速时,他还泼了盆冷水,说这不一定是万能解,具体怎么排布数据得看实际要做什么计算,有时候哪怕数据结构看起来乱一点,性能照样能打。

最让我觉得有收获的,是《Dwarf Fortress》的程序员Putnam3145出来说的话。这游戏什么分量不用多介绍,影响了《我的世界》和《RimWorld》的作品。他开口就很直白:“电脑其实比你们想的快得多。”

然后他开始聊《Dwarf Fortress》自己的情况。游戏里400个角色互相做视野判定、算寻路,大面上能跑到50帧左右。他们试过把处理任务分摊到多个CPU核心上跑,速度确实快了大概20%,但稳定性开始出问题,有些不好控制的苗头。真正让性能质变的操作,是把游戏里散落在内存各处的角色数据重新整理,让它们挨在一起。就这么一个改动,性能直接提升了40%到50%。

Putnam3145的观点很明确:数据到底是怎么摆在内存里的,这个事太关键了。优化之前,CPU得反复跑去内存里不同的地方抓数据,累得要死;把数据紧凑排列之后,存取效率完全不一样。他给的建议是,先盯着数据结构和内存布局做文章,比什么都靠谱。

帖子里其他人也贡献了不少实操经验。比如处理那500个角色时,别傻乎乎地把每个都当成独立数据完整跑一遍,屏幕外的那些可以简化处理,或者降低更新频率。还有,尽量别让复杂的寻路计算到处跑,画面的渲染负担也得压住。显然,到了几千个角色这个量级,这些东西就变成必修课了。

我觉得这次讨论最好玩的地方在于,它跟我之前的直觉完全是反着来的。以前看到那些几百号人同屏的游戏,总觉得背后一定有什么逆天的优化手段,结果一群现役开发者摊手说:真没有,500个在现代硬件上就是正常跑。这背后可能有玩家电脑整体性能在往上走的因素,也可能只是外行对“性能”这两个字的想象过于夸张了。

当然,这不代表优化这件事不存在。你看《Dwarf Fortress》那个案例,数据挪个位置就能提40%以上的性能,说明真正起作用的往往不是玩家能直接看到的那些炫酷画面,而是底下那些看不见的计算逻辑、内存排布、还有对屏幕外内容的取舍。帖子里反复出现的一个思路就是,别在玩家根本注意不到的地方浪费算力,这可能是最朴素也最有效的原则。

说到这种“看不见的优化”,这个品类其实有不少老故事。以前《RimWorld》的开发者聊过寻路算法怎么做减法,《Songs of Syx》的开发者也分享过类似的经验。还有一个例子这次帖子里没细说但我知道的,《They Are Billions》,就是那个要挡几万只僵尸的RTS。他们最开始用Unity做原型,结果400只僵尸就跑不动了,后来干脆自己撸了个定制引擎,一路优化到能处理3万个僵尸同时在场。

但像这次这样,一堆开发者集体说“几百个角色根本不是事儿”,确实挺刷新认知的。不过他们也把话说明白了,好玩的部分在几千个开始。到那个阶段,数据怎么塞进内存、哪些计算可以偷懒、怎么把活儿分给多个核心但又别把稳定性搞崩,这些东西就开始分出高下了。

说到底,玩家平时在屏幕上看到的那些流畅又好看的场景,底下全是这种琐碎的、没有什么视觉冲击力但极其耗头发的活儿。几百个角色能丝滑跑,靠的可能只是电脑够快;几千个角色还能丝滑跑,那才是真正拼内功的时候。