现实世界模拟是如何设计的?

12
我对"过山车大亨"、"模拟人生"和FPS游戏等应用程序的性能深感着迷。我想了解更多关于基本应用程序架构的信息。(我不太关心UI - 我假设MVC/MVP原则在这里适用。我也不关心数学和物理学方面的问题。)
我的主要问题涉及到模拟中数以十计或数百计的单独对象(人员、车辆、物品等),它们都在同时移动、做出决策并引发事件,我想知道它们是如何为如此良好的性能而设计的。 问:主要来说,这些对象是在一个巨大的循环中逐个进行处理还是每个对象都在其自己的线程中进行处理?在这样的模拟中实际上有多少个线程是可行的?(当然只是个大概的数字,比如10、100、1000)
我不想写游戏,我只是想了解设计理论,因为我想知道这种设计是否可以应用于其他需要同时做出几项决策的应用程序。
5个回答

8
有两种基本的方法可以做这种仿真基于代理的系统动力学。在基于代理的仿真中,游戏中的每个实体都将由一个具有属性和行为的类实例来表示,所有实体之间的交互必须明确定义,并且当您想让这些实体相互作用时,会调用函数更改交互实体的属性。
系统动力学完全不同,它只处理总和,没有对系统中单个实体的表示。最简单的例子是捕食者和猎物模型。
这两种方法都有优缺点,系统动力学方法可以扩展到大量实体,并保持运行时间短。虽然有多个公式需要计算,但计算时间与公式中的值无关。但是这种方法无法查看单个实体。基于代理的方法可以让您将实体放置在特定位置,并与模拟中的特定实体进行交互。

有限状态机(FSMs)和元胞自动机是模拟游戏系统的其他方式。例如,在基于代理的方法中,您可以使用FSM对一个代理的行为进行建模。模拟城市使用元胞自动机来完成部分模拟工作。

通常情况下,您可能不会有一个大型的模型来完成所有任务,而是多个执行特定任务的系统。其中一些系统可能不需要经常更新,例如确定天气的系统,而其他系统可能需要不断更新。即使将它们放在单独的线程中,您也需要在需要时暂停或启动它们。您可能希望将工作拆分成多个帧,例如仅计算特定数量代理的更新。


4

原版模拟城市的源代码已经开源,成为了Micropolis。这可能是一个有趣的研究。


1

直到最近,游戏的逻辑和管理都在一个大有限状态机中的单个线程中。现在,您会看到游戏的不同部分(音频、图形、物理、“模拟”逻辑等)被拆分为自己的FSM线程。

编辑:顺便说一句,线程是让模拟中的事情“同时发生”的非常糟糕的方式--它会导致竞态条件。当您想要让事情“同时发生”时,通常只需在迭代数据时确定需要发生的内容并将其单独存储,然后在处理完所有数据后应用它。反复执行。


每个对象能否在自己的线程中“同时”设置其状态(属性),然后由主进程处理结果。没有事件或竞争。但循环不必等待每个对象处理的时间那么长...? - Doug L.
1
你可以通过线程池或类似的方式相当高效地完成这个任务,但我发现最好将数据分成块,然后为此线程处理程序,构建像我描述的更改集。 - Serafina Brocious
完全不同意你的答案。如果只是“一个胖 FSM,把位放在不同的线程上”,那么每个人都会发布像这样的游戏。这比这个过于简化的回答复杂得多。你以前做过严肃的游戏吗? - OJ.

0

@Cody Brocious

这个 CodeProject 使用 Linq 来演示这种实践。(Linq 至生命)


我之前加了一条评论,说这种方法不够可扩展之类的,后来意识到这只是它的一种实现方式——可恶,我的 LINQ 理解不够好 ;) 不错的链接。 - Serafina Brocious

0
除了已发布的建议之外,我建议浏览sourceforge上的模拟标签。那里有各种复杂程度的模拟项目。
此外,我推荐以下书籍作为基本概述,虽然它主要关注物理学,但也涉及模拟问题。 Sourceforge Physics for Game Developers

谢谢!我会查看这两个来源。 - Doug L.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接