从概念上讲,重播如何在游戏中发挥作用?

Ste*_*ers 145 design-patterns

我对如何在游戏中实现重播感到好奇.

最初,我认为只会有一个游戏中所有玩家/动作的命令列表,然后它"重新玩"游戏并让引擎像往常一样渲染.但是,我已经看过FPS/RTS游戏中的重放,经过仔细检查,即使粒子和图形/听觉故障等内容也是一致的(这些故障通常一致的).

那么这是怎么发生的呢.在固定摄像机角度游戏中,我可能只是将整个场景的每一帧写入存储的流然后只是重放流回来,但这对于允许您暂停和移动摄像机的游戏来说似乎不够周围.您必须在所有时间点存储场景中所有内容的位置(否?).因此对于像粒子这样的东西来说,这是推送的大量数据,这似乎是对游戏性能的重要影响.

Pet*_*man 61

我认为你最初的想法是正确的.要创建重播,您可以存储从用户收到的所有输入(以及接收它的帧编号)以及任何随机数生成器的初始种子.要重放游戏,您可以使用保存的种子重置PRNG,并为游戏引擎提供相同的输入序列(与帧编号同步).由于许多游戏将根据帧之间传递的时间量更新游戏状态,因此您可能还需要存储每个帧的长度.

  • 图形框架和引擎"框架"(或迭代)不一定相同.在许多较旧的游戏中,引擎在一个主循环中以与图形相同的速率更新.使用现代引擎,图形通常可以像GPU允许的那样快速更新,引擎在游戏动态(通常是物理引擎)的良好,一致的分辨率所需的水平上滴答作响. (14认同)
  • @Ben:帧率没有区别,因为帧数仍然是相同的.这是正确的答案. (5认同)
  • @iamgopal:如果你知道伪随机数生成器的状态,那么问题就已经解决了.另一种方法可以是将随机数作为另一种形式的输入处理,并将那些随机数保存在按键等之外. (3认同)

Bob*_*ise 28

星际争霸和星际争霸:母巢之战有重播功能.匹配完成后,您可以选择保存重播以便稍后查看.在重放时,您可以滚动地图并单击单位和建筑物,但不能更改其行为.

我记得曾经观看过在原版游戏中播放的一场比赛的重播,但重播正在母巢之战中被观看.对于那些不熟悉的人来说,母巢之战包含了所有原始单位和建筑物,以及各种新单元和建筑物.在原始游戏中,玩家通过创建计算机无法轻易抵抗的单位来击败计算机.当我在母巢之战中播放重播时,计算机可以访问不同的单位,它创建并用来击败玩家.因此,完全相同的重播文件会产生不同的赢家,具体取决于星际争霸的哪个版本正在播放该文件.

我总觉得这个概念引人入胜.似乎重播功能通过记录播放器的所有输入来工作,并假设计算机每次都以完全相同的方式响应这些刺激.当玩家输入被送入原始的星际争霸者重播时,游戏就像在原始比赛中一样.当相同的确切输入被输入Brood War重播器时,计算机反应不同,创建了更强大的单位,并赢得了游戏.

如果您正在编写重播引擎,请记住一些事情.

  • +1:非常有趣.我从来没有听说过这个.提供他们如何开发它的一些很好的见解. (6认同)

lio*_*ori 18

有两种主要方法:

  1. 存储事件(例如播放器/ ai操作) - 就像你说的那样.
  2. 存储状态(完整游戏状态,对象的fe位置,连续时刻).

这取决于你想做什么.有时存储事件更好,因为这通常会占用更少的内存.另一方面,如果您想提供可以不同速度和不同起点播放的重放,最好存储状态.存储状态时,您还可以决定是在每次事件后存储它们还是每秒仅存储12或25次 - 这可能会减少重放的大小并使其更容易快退/快进.

请注意,"状态"并不意味着图形状态.更像是单位,资源状况等等.像图形,粒子系统等东西通常是确定性的,可以存储为"动画X,时间Y:Z".

有时重放被用作反加热方案.然后存储事件可能是最好的.


Tim*_*dge 10

从技术上讲,你应该把你的引擎写成确定性的,这不是随机的.假设游戏中的角色瞄准对手的手臂并射击武器,则在所有情况下都应对对手施加相同数量的伤害.

假设炸弹在位置X引爆,爆炸产生的粒子应始终产生相同的视觉效果.如果您需要随机性,请创建一组随机数,在游戏播放时选择种子值,并将该种子值保存在重播中.

通常,在游戏中具有随机性是个坏主意.即使是像多人游戏这样的东西,你也不能让一半的玩家能够看到爆炸,而其他玩家不能仅仅因为他们没有得到正确的随机值.

让一切都变得确定,你应该没事.

  • 那真的没必要.对所有随机事件使用种子伪随机数,并将种子保存在重播文件中.这样,在重放期间将生成相同的"随机"数字. (18认同)
  • -1清楚地误解了"随机性"在计算机中的工作原理 (13认同)
  • 嗯....不....我完全清楚,没有"真正的"随机性这样的东西.然而,大多数人试图通过将随机种子设置为类似系统时间来解决这个问题.然而,我所说的是不应该做这样的事情.我不在乎他是否使用系统API或预定义的随机数表.我原来说的是对的.他的引擎中的每个函数都应根据其输入生成相同的结果.时间永远不应成为一个因素. (10认同)
  • 如果粒子没有以任何有意义的方式与游戏机制相互作用,那么RNG对它们是不同的并不重要.这将有助于网络同步模拟(大多数RTS游戏和许多其他游戏类型的情况),因为模拟必须同步每一帧(粒子效果刚刚获得)单独更新). (2认同)

Ben*_*n S 10

给定初始状态一系列带有时间戳的动作,只需记录序列,因为记录的动作应该发生重放.

为了使随机事件重新发生完全相同,使用种子伪随机数并将种子保存在重放文件中.

只要您使用相同的算法从种子生成随机数,您就可以像在实时游戏中一样重新创建所有事件,而无需完整的游戏状态快照.

这将需要按顺序观看重放,但这对于游戏重放来说非常正常(参见星际争霸2).如果您想允许随机访问时间线,您可以按设定的时间间隔(比如每分钟)拍摄完整的状态快照,以设定的粒度跳过时间线.


Dan*_*ant 7

NVidia PhysX(一种常用于游戏的物理模拟引擎)能够随时间记录物理场景的完整状态.这包含来自游戏引擎的任何驱动输入,这意味着您不需要像其他人建议的那样跟踪随机数种子.如果您进行此场景转储,您可以在外部工具(由NVidia提供)中重放它,这对于跟踪物理模型的问题非常方便.但是,您也可以使用相同的物理流来驱动图形引擎,这样您就可以进行普通的摄像机控制,因为只记录了驱动图形的物理场景.在许多游戏中,这包括粒子效果(PhysX包括一些非常复杂的粒子系统.)至于声音,我猜测它是逐字记录的(作为声音流),但是我