2011-08-24 55 views
3

我正在研究多玩家fps,我正在考虑如何在游戏状态对象上执行增量压缩。使用协议缓冲区的增量压缩

在阅读有关Q3如何做联网,我认为增量压缩可以通过序列化对象的二进制状态,然后只发送最后已知接收的对象和当前对象之间的二进制差异来实现。这是处理增量压缩的正确方法吗?

+0

总有几种方式和一些不那么重要的方面...但基本上你描述了我会怎么做 - 所以是的:-) – Yahia

回答

1

那么你有两个选择。

  • 您可以序列化状态A和状态B并运行结果上的差异。 (如你所描述的)。

  • 您可以使用结构的知识发现A国和B国之间的差异,序列化的结构差异。

下面是这个问题 - 数据的结构是这样定义的,即采取增量比运行通用差异更快?

我相信它通常是。让我们举一个简单的例子。我们的游戏世界在游戏状态被定义为P1(x,y,z)和P2(x,y,z)的任何时间点定义了P1和P2两个项目(它们在世界各地奔跑)。因此,结构增量是6个变量(两个玩家的x,y,z)之间的差异。计算这个很快 - 它是3个数学运算。然而,谁知道这些将如何序列化 - 然后diff例程将不得不做很多工作(至少一个循环)来查找结果的增量。

但它比这更好。既然你的游戏引擎知道你关心随着事物的改变而发生的变化,它可以把变化存储在一个列表中,并且准备好发送变化而不需要任何计算(例如每当P移动时它就会保存变化)。

+1

我认为,虽然第二个例子可能会更快,但它也会更多复杂。我认为Q3为什么在整个对象上做三角洲的原因之一是他们的游戏状态很复杂。当我从复杂的数据结构的角度思考事物时,有许多属性其中一些是复杂的结构本身,看起来简单易行,只是选择A –

+1

我认为缺少的部分是如何通过Protobuf序列化空(或默认值)字段和一个未定义的字段。一旦压缩增量,一个没有改变的字段不应该被序列化。 'ShouldSerialize ...'序列化与默认值相同(没有任何内容)。这意味着反序列化不能轻易区别于将值更改为null或应保持不变。 – Wernight