存在哪些应用程序/游戏状态“增量压缩”技术/算法?

罗密欧

我对探索实时多人客户端服务器游戏开发和相关算法感兴趣。许多著名的多人游戏,例如Quake 3Half-Life 2,都使用增量压缩技术来节省带宽。

服务器必须不断将最新的游戏状态快照发送给所有客户端。始终发送完整的快照非常昂贵,因此服务器仅发送最后一个快照与当前快照之间的差异。

...容易,对吗?好吧,我觉得很难思考的部分是如何实际计算两个游戏状态之间的差异。

游戏状态可能非常复杂,并且具有通过指针相互引用在堆上分配的实体,可以具有其表示形式随体系结构而变化的数字值等等。

我很难相信每个游戏对象类型都有手写的序列化/反序列化/差异计算功能。


让我们回到基础。假设我有两种状态,用位表示,我想计算它们之间的差异:

state0:  00001000100    // state at time=0
state1:  10000000101    // state at time=1
         -----------
added:   10000000001    // bits that were 0 in state0 and are 1 in state1
removed: 00001000000    // bits that were 1 in state0 and are 1 in state1

太好了,我现在有了addedremoved diff位集-但是...

...差异的大小仍然与州的大小完全相同实际上,我必须通过网络发送两个差异!

一个有效的策略实际上是根据那些差异位集构建某种稀疏数据结构吗?例子:

// (bit index, added/removed)
// added = 0
// removed 1
(0,0)(4,1)(10,0)

// ^
// bit 0 was added, bit 4 was removed, bit 10 was added

这可能是有效的方法吗?


假设我设法为JSON中的所有游戏对象类型编写了序列化/反序列化函数

我能否以某种方式拥有两个JSON值,就位自动地计算它们之间的差异

例子:

// state0
{
    "hp": 10,
    "atk": 5
}

// state1
{
    "hp": 4,
    "atk": 5
}

// diff
{
    "hp": -6
}

// state0 as bits (example, random bits)
010001000110001

// state1 as bits (example, random bits)
000001011110000

// desired diff bits (example, random bits)
100101

如果有这种可能,那么避免与体系结构有关的问题和手写差异计算功能将相当容易。

给定两个串彼此相似,是可以计算的字符串Ç其在尺寸上大于较小,即表示之间的差可以和施加得到在结果?

SlugFiller

由于您已经以Quake3为例,所以我将重点介绍那里的工作方式。您需要了解的第一件事是,与客户端-服务器游戏相关的“游戏状态”并不涉及对象的整个内部状态,包括AI的当前状态,碰撞功能,计时器等。游戏的服务器实际上减少了客户很多。只是对象的位置,方向,模型,模型的动画,速度和物理类型中的框架。后两个用于通过允许客户模拟弹道运动来使运动更平滑,但仅此而已。

每个游戏帧大约每秒发生10次,服务器为游戏中的所有对象运行物理,逻辑和计时器。然后,每个对象调用API函数以更新其新位置,框架等,并更新是否在此框架中添加或删除了该对象(例如,由于击中墙壁而被删除的镜头)。实际上,《雷神之锤3》在这方面有一个有趣的错误-如果镜头在物理阶段发生移动并撞到墙壁上,它将被删除,并且客户端接收到的唯一更新也将被删除,而不是之前朝向墙壁的飞行,因此,客户看到镜头在实际撞墙之前会在空中1/10秒内消失。

有了很少的每个对象的信息,就很容易区分新信息与旧信息。另外,只有实际更改的对象才调用更新API,因此保持不变的对象(例如Walls或不活动的平台)甚至不需要执行这种差异。另外,服务器可以通过不向客户端发送直到客户端看不到的对象才能进一步节省发送的信息。例如,在Quake2中,一个关卡被划分为多个视图区域,并且如果一个区域(及其内部的所有对象)都被关闭,则该区域被视为“不可见”。

请记住,服务器不需要客户端具有完整的游戏状态,仅需要一个场景图,并且需要更简单的序列化,并且绝对不需要指针(在Quake中,它实际上保存在一个静态大小的数组中,该数组也限制游戏中对象的最大数量)。

除此之外,还有用于玩家健康状况,弹药等内容的UI数据。同样,每个玩家只会获得自己的健康状况和弹药,而不是服务器上每个人的健康状况。服务器没有理由共享该数据。

更新:为确保获得最准确的信息,我仔细检查了代码。这基于Quake3,而不是Quake Live,因此某些情况可能有所不同。发送给客户端的信息基本上封装在称为的单个结构中snapshot_t它包含playerState_t当前玩家的单个entityState_t可见游戏实体的256个数组以及一些额外的整数,以及代表“可见区域”的位掩码的字节数组。

entityState_t依次由22个整数,4个向量和2个轨迹组成。“轨迹”是一种数据结构,用于表示物体未发生任何变化时在空间中的运动,例如弹道运动或直线飞行。它是2个整数,2个向量和一个枚举,在概念上可以存储为一个小整数。

playerState_t是一个更大的数组,包含大约34个整数,大约8个整数数组,每个数组的大小范围从2到16,以及4个向量。它包含从武器的当前动画帧到玩家的清单到玩家发出的声音的所有内容。

由于所使用的结构具有预设的大小以及结构,因此制作一个简单的手动“ diff”功能,将每个成员进行比较非常简单。然而,据我所知道的,entityState_t并且playerState_t仅在全部发送,而不是在部分。唯一被“增量”处理的是作为实体数组的一部分发送的实体snapshot_t

快照最多可以包含256个实体,而游戏本身最多可以包含1024个实体。从客户端的角度来看,这意味着只能在单个帧中更新25%的对象(任何其他对象都会导致臭名昭著的“数据包溢出”错误)。服务器仅跟踪哪些对象进行了有意义的移动,然后将其发送。它比执行实际的差异要快得多-只需发送任何本身称为“更新”的对象,并且该对象位于播放器的可见区域位掩码中即可。但是从理论上讲,手写的每个结构的差异不会变得那么难。

为了团队健康,虽然Quake3似乎没有做到这一点,所以我只能推测在Quake Live中是如何完成的。有两种选择:要么发送所有playerState_t结构(因为最多64个结构),要么添加另一个数组playerState_t以保持团队HP(因为它只有64个整数)。后者的可能性更大。

为了使对象数组在客户端和服务器之间保持同步,每个实体都有一个从0到1023的实体索引,并将其作为消息的一部分从服务器发送到客户端。当客户端接收到一个由256个实体组成的数组时,它将遍历该数组,从每个实体中读取索引字段,并在其本地存储的实体数组中的读取索引处更新该实体。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

我的应用程序如何识别用户的iOS设备上存在哪些社交应用程序?

来自分类Dev

Web + 移动应用程序使用哪些技术

来自分类Dev

什么技术使用此树形游戏应用程序?

来自分类Dev

有没有办法知道您的应用程序中是否存在信号以及存在哪些信号?

来自分类Dev

需要解压缩文件,在哪里可以将其保存在JSF Web应用程序中?

来自分类Dev

压缩技术有哪些?

来自分类Dev

哪些技术可用于在iOS应用程序中以编程方式转换HTML / DOM?

来自分类Dev

Twitter / Facebook如何知道可以在哪些应用程序上共享tweet / status / images?

来自分类Dev

我们可以在哪些版本的 Windows 上运行 dot net 应用程序?

来自分类Dev

这些绘图应用程序背后的技术

来自分类Dev

Pacman AI-Minimax应用程序-避免重复的游戏树状状态

来自分类Dev

我可以使用状态设计模式解决此纸牌游戏应用程序吗?

来自分类Dev

非游戏应用程序的Facebook应用程序请求

来自分类Dev

我应该从我的应用程序将哪些数据保存在Sqlite数据库中?

来自分类Dev

React / Redux:我应该在哪里创建+放置“主”应用程序状态?

来自分类Dev

应用程序使用哪些端口

来自分类Dev

压缩Sencha Touch应用程序

来自分类Dev

在iOS 7.1中使用“ iBeacon”检测附近的设备存在哪些技术限制?

来自分类Dev

在iOS 7.1中使用“ iBeacon”检测附近的设备存在哪些技术限制?

来自分类Dev

跨平台多人游戏(应用程序)

来自分类Dev

玩游戏以外的应用程序

来自分类Dev

检测UWP应用中存在哪些API

来自分类Dev

android phonegap应用程序数据保存在哪里?

来自分类Dev

在Flask应用程序中将js文件保存在哪里?

来自分类Dev

VB.NET中存在的C#中的Winforms“应用程序框架”在哪里?

来自分类Dev

在哪里将ORM保存在分布式应用程序中?

来自分类Dev

.NET 5 WinForms应用程序中的设置保存在哪里?

来自分类Dev

用户应用程序用户项目文件应在Mac OS X上保存在哪里?

来自分类Dev

Wire Messenger应用程序的配置文件保存在哪里?

Related 相关文章

  1. 1

    我的应用程序如何识别用户的iOS设备上存在哪些社交应用程序?

  2. 2

    Web + 移动应用程序使用哪些技术

  3. 3

    什么技术使用此树形游戏应用程序?

  4. 4

    有没有办法知道您的应用程序中是否存在信号以及存在哪些信号?

  5. 5

    需要解压缩文件,在哪里可以将其保存在JSF Web应用程序中?

  6. 6

    压缩技术有哪些?

  7. 7

    哪些技术可用于在iOS应用程序中以编程方式转换HTML / DOM?

  8. 8

    Twitter / Facebook如何知道可以在哪些应用程序上共享tweet / status / images?

  9. 9

    我们可以在哪些版本的 Windows 上运行 dot net 应用程序?

  10. 10

    这些绘图应用程序背后的技术

  11. 11

    Pacman AI-Minimax应用程序-避免重复的游戏树状状态

  12. 12

    我可以使用状态设计模式解决此纸牌游戏应用程序吗?

  13. 13

    非游戏应用程序的Facebook应用程序请求

  14. 14

    我应该从我的应用程序将哪些数据保存在Sqlite数据库中?

  15. 15

    React / Redux:我应该在哪里创建+放置“主”应用程序状态?

  16. 16

    应用程序使用哪些端口

  17. 17

    压缩Sencha Touch应用程序

  18. 18

    在iOS 7.1中使用“ iBeacon”检测附近的设备存在哪些技术限制?

  19. 19

    在iOS 7.1中使用“ iBeacon”检测附近的设备存在哪些技术限制?

  20. 20

    跨平台多人游戏(应用程序)

  21. 21

    玩游戏以外的应用程序

  22. 22

    检测UWP应用中存在哪些API

  23. 23

    android phonegap应用程序数据保存在哪里?

  24. 24

    在Flask应用程序中将js文件保存在哪里?

  25. 25

    VB.NET中存在的C#中的Winforms“应用程序框架”在哪里?

  26. 26

    在哪里将ORM保存在分布式应用程序中?

  27. 27

    .NET 5 WinForms应用程序中的设置保存在哪里?

  28. 28

    用户应用程序用户项目文件应在Mac OS X上保存在哪里?

  29. 29

    Wire Messenger应用程序的配置文件保存在哪里?

热门标签

归档