矮人要塞如何跟踪这么多实体而又不损失性能?


79

在“矮人要塞”中,您一次可以在游戏中拥有成百上千的矮人,动物,妖精等,每种都有各自复杂的AI和寻路例程。我的问题是,这怎么不会导致明显的放缓?每个矮人都在自己的线程中运行吗?


6
有趣的问题。尽管我不喜欢它的措词方式,因为只是猜测有人会回答这个问题。无论如何,您可能已经看到本文与Tarn Adams交谈。他们简要介绍了寻路的地方。
MichaelHouse

25
一旦拥有复杂的隧道拓扑和100多个矮人,它绝对会产生明显的减速。
罗素·博罗戈夫

3
是的,根据您的描述,根据我的经验,DF非常慢。
agentage

4
摧毁一个主要的楼梯间,看着你的帧速率像一块岩石一样下降一会儿,而每个小矮人都在同一时间突然转向。
Mooing Duck 2012年

2
我要插话并同意DF不是最好的例子。实际上,众所周知DF会遇到性能问题。
罗伯特S.13年

Answers:


110

任何一个拥有如此多字符的线程的系统都会很快耗尽资源。线程可以使您访问额外的处理器内核,但它们并不能使任何事情本质上都更加高效,并且它们会带来开销。

简单的答案只是要有效处理游戏中的每个实体。

  • 不要在每个框架中处理每个实体。
  • 将处理分为需要经常执行的工作和不需要经常执行的工作。
  • 将长时间运行的算法分布在多个帧上,以免它们阻塞其他系统中的处理。
  • 确保使用有效的算法和数据结构。
  • 如果可能会再次使用昂贵的计算结果,则将其缓存。

2
为此,+ 1,用于实际解释正在发生的事情,而不是对像我这样的图形感到费解。:)
Matt Kemp

4
公平地说,我也给了您+1,因为我忘记了这方面,这的确是事实-将gfx排除在等式之外,这就像使计算机立即快2倍或3倍。
Kylotan

我听说DF现在是多线程的,但至少直到最近,它都是在单个线程中完成的。(可能仍然不确定)
Mooing Duck 2012年

@MooingDuck仍然不是。
塔文

63

“矮人要塞”不是开放源代码,尽管有很多推测和逆向工程可以说明其全部工作原理,但我将重点介绍一些基本技术,以优化3D渲染的3D(而非3D图形,3D世界)。相同的类型。

与所有电子游戏一样,大量的烟雾和镜子从简单的规则和系统中营造出复杂的错觉。这些范围从使用简单的随机数一直无目标地移动到预烘焙高级节点网格以进行寻路。

运动

说到寻路,通常对于大空间来说这是一个很难解决的问题,例如DF映射可以(多达768x768x64 IIRC),但是可以通过以下方式简化和加快问题的解决:

  • 预烘焙节点网络:创建地图时,世界可以分为多个块,每个块可以映射其出口和入口。在更新块时(例如在建造墙时),仅需要更新该块的网络。
  • 分段寻路:在整个地图上逐个路径运行路径会花费很多时间,相反,您会在较大的区块网络上寻路,该网络会映射各个区块之间的所有连接,然后仅在以下情况下运行区块内部路径:逐块移动。这为您做两件事。通过将其分解成许多较小的部分,它可以加快寻路速度,并且还可以使单元在更新块时沿路径的一部分改变方向。如果需要交叉更新的任何节点,它将在大型网络上重新路径化。
  • 随机转向:当不移动至目标时,装置仅需漫无目的地行走。许多流氓只是将装置沿随机方向移动,这感觉很不自然。可以使用各种转向技术,简单的转向技术倾向于沿直线移动,并且在向后辐射的方向上移动的机会越来越少,而这种机会只有大约1%的机会。因此,该单元有时会完全反转方向,但很少。

我不会介绍寻路的基础知识。大多数无赖猫使用A *,但是还有其他方法可以为猫皮。Mmmmm猫皮革..

个人任务

使DF部队流行并充满活力的主要因素之一是他们的个人目标清单。实际上,许多无赖类游戏都具有基本水平。本质上,每个单位都有一份愿望清单(对于您的小伙子来说,他们可能会承担您要完成的任务),并且他们会根据自己的个性(统计数据)从中选择。

有些任务有要求。制作皮裙要求多夫在某家拥有X件商品的商店中。因此,所有这些都将被检查并作为任务添加到其列表中。就那么简单。

由于大部分时间单位会在运输过程中,因此对单位运行情况的检查可能非常快,在任何给定的时刻只有少数单位会做出选择,因此总体而言,即使是数百个或数百个单位也不会降低速度数千个单位。记住,在DF中,从蜜蜂到穴居人再到树木的一切都是单位。


在进行一些其他研究时,很显然,DF通常在做寻路方面做得很糟糕。并不是将地图分解成块,而是将地图分解成已连接的段或区域(这肯定比没有结果要好),因此我的上述评估甚至比DF想象的还要少。:)这并不是说DF由于其他百万种原因而令人惊讶。

它表明游戏中重要的是游戏。没有图形,没有出色的程序设计,没有出色的写作,没有出色的音乐,甚至没有界面;没有什么比游戏本身重要的多1%了。


1
1024X1024X32?我相信垂直是128或256。它远远大于
劳顿

@Lawton我相信最大大小我是错误的,但是高度并不是那么错误。我正在纠正。我加载了游戏,登船时的高度只有大约45级。可能会“模拟”更多,但我无权进行挖掘或建造。
DampeS8N 2012年

@ DampeS8N我刚刚加载了未修改的中型地图,并且能够在180级别从+16到-156进行查看。40个级别的地图是例外,而不是规则。即使由于被含水层或熔岩阻塞而只能挖掘其中的40个,这也不重要,因为下面的区域仍然充满了模拟乐趣。
劳顿

@Lawton,我的地图只允许我翻阅45个级别。它们是绝对可变的,但我很难找到每张地图可访问的数量。这也可能取决于我们使用的游戏版本。最后,对于我的回答来说,并不是那么重要。
DampeS8N 2012年

这是一个古老的哨所,但矮人堡垒的深度取决于沉积层。就像某些地方的地壳更厚。DF并不是完全正确的地质学,但是他们像pro的:D一样对它进行研究。
Madmenyo 2015年

50

从此页面

从我的角度来看,[寻路]看起来很棒,因为有成千上万的字符同时完成。

TA:矮人本身大多以A *来回走动,并使用常规的旧街道距离试探法。棘手的部分是,如果他们不知道自己可以提前到达那里,就无法真正调用A *,否则最终将淹没地图并杀死处理器。

我不知道这是否绝对是他如何防止“淹没地图”,但是在游戏中这样做的通常方法是使用对A *的更改,称为“ 层次路径查找A * ”或HPA *。这个想法是将网格分成更少但更大的块,然后使用A *查找从每个块到其相邻块的最佳路径。您可以使用它来构建一个更小的图形,在该图形上为每个单元运行A *。

分层寻路

您还可以将这些块分组为更大的块,这就是“分层”的来源。

该算法只能找到接近最佳的路径,但是对于矮人要塞这样的游戏来说通常是可以的。如果存在,仍然可以保证找到路径。当没有路径时,它只会淹没较小的图形,从而节省大量时间。

HPA *还有一个抽象概念,即可以穿越某些地形但不能越过其他地形的单位(例如悬崖,空中单位可以越过而地面单位则不能越过)。这就是所谓的HAA *,并且有一个很接近的文章,解释它在这里

您可以在此处阅读有关各种寻路算法的更多信息。


3
我发现RimWorld开发人员的这段视频很有启发性。这是一个类似的游戏,但只有2D模式。他解释了寻路背后的基础知识以及将地图分成多个区域的好处。youtube.com/watch?v=RMBQn_sg7DA
2014年

18

如果有的话,它是相反的-整个事情都在一个线程上运行,现在达到了成为阻塞因素的地步(我上次检查!)

快速的原因是没有精美的图形。这具有欺骗性,但最主要的是减慢绘图速度(在AAA标题中,请考虑超过三分之二的帧)。由于矮人堡垒是非常基本的,所以它将剩下的时间用于做有趣的事情。


8
支持这一点的一个数据点是前不久的OpenGL重写,我记得它带来了巨大的帧速率提高。因此,即使执行简单的Sprite图形,DF也会有效地产生影响。
millimoose 2012年

3
+1条图形=大量的业余时间用于游戏计算
Laurent Couvidou 2012年

2
值得注意的是,DF的图形要求与任何现代独立2D游戏一样高。有许多纹理,即使它们很小又很简单,它们可以分布在全高清全高清监视器上。没有任何浮华的粒子效果或您拥有什么,但是原始的“绘制所有这些像素”作品仍然存在,并且由于需要小瓷砖尺寸的绘制调用次数,实际上对于提高性能来说是一个很大的挑战。
DampeS8N 2014年

乍一看似乎是一个愚蠢的答案,但这是正确的,想象一下如果不需要绘制复杂的基元,展开,纹理,将3D向量转换为像素,着色器等二维数组
Felype '18

10

我不知道DF是如何编码的,但是人工智能的数量并没有给我真正的印象,因为人们经常监督人工智能不需要精度。每隔几秒钟执行大多数工作是完全可行的。使用不精确的计算也是可行的。不完美会节省很多性能。您可以每100毫秒运行100个单位的决策例程,或者每秒运行1000个单位的决策例程,这将花费相同的CPU时间,但是...您有10倍的单位。

这是一个简单的示例,说明如何处理很多单位:

int curUnit;
Array<Unit> units;
[...]
while([...]) // Game Loop
{
  [...game logic...]
  // process 10 AIs per Frame
  for(int i=0; i++; i<10)
  {
    curUnit++
    if(curUnit == units.length()) curUnit=0;
    if(curUnit < units.length())
      units[curUnit].processAI();
  }

  // Update the position of all units, this should be as optimized as possible
  foreach(Unit& unit in units){ unit.move(); };

  [...graphics...]
}

越多,AI的响应就会越来越少,但玩家可能只会在极端情况下才会注意到它。


要逐步完成并非帧级精确的任务栈,要说很多。AAA游戏通常会以帧的百分比明确地对每个部门设置时间限制,以使一个部门无法踩到其他部门的脚步。如果基于风速和风向的树木摇摆动画方法很慢,那么将处理更少的树木,而不是消耗其他团队的预算。
DampeS8N 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.