如何在C#中实现对象的delta压缩?

时间:2013-08-20 17:58:08

标签: c# networking multiplayer compression serialization

我正在研究用C#编写的基于服务器的多人游戏。服务器和客户端共享代码,每个对象具有相同的int ID。我想通过仅发送更改的数据使网络尽可能轻。

游戏中有类,其中包含许多字段/属性,并且它们经常发生变化。 我正在寻找一种方法来检测这些值何时发生变化并将这些值发送给客户端。

基本上,这个算法:

  1. 更改时标记对象
  2. 使用网络Tick中更改的对象:
    1. 将每个属性与之前的状态进行比较
    2. 仅发送更改后的值
    3. 存储旧值
  3. 在客户端接收
  4. 实例化相同类型的对象,或按ID
  5. 查找
  6. 设置新值
  7. 当然,.NET Reflection可以解决这个问题,但是在每个Tick中迭代1000个对象及其属性将是性能瓶颈。

    我可以发送基本类型(int,float,vector),并保持连接。我的问题是这些:

    发送对象Class并实例化它的最佳方法是什么?

    我应该如何检测属性更改以及如何序列化属性,以便我可以在接收时在客户端上找到它们的“对”。

1 个答案:

答案 0 :(得分:3)

您可以创建以下内容:

class Mob {
private int _health;
public int Health
{
   get { return _health; }
   set { _health = value; DirtyFlags |= MobDirtyFlags.Health
}
}

这意味着每个属性的代码很多

或者您可以拥有一些自定义词典,并且会跟踪该词典中的每个更改,所以

mob.Properties [“Health”] = 10;会跟踪你改变了什么。

Mooege(暗黑破坏神3模拟器)就是这样做的。

第一种方法可以用方面重写(可能是一些自定义代码,它们将生成在运行时通过Reflection.Emit或类似方法在上面编写的所有代码)。 或者,如果您知道所有实体的外观,您可以从某些模板为它们生成类(使用T4之类的东西)

至于序列化,这已经足够了: (key:int,value:object) 其中key是一些枚举,如ActorProperties {Health,Strength,...}