首先,您需要知道如何以协议兼容的方式表示您的相关数据。这取决于与游戏相关的数据。我将以RTS游戏为例。
出于联网目的,列举了游戏中的所有实体(例如,皮卡,单位,建筑物,自然资源,破坏性物品)。
玩家需要拥有与其相关的数据(例如所有可见的单位):
- 他们活着还是死了?
- 他们是什么类型的?
- 他们还剩下多少健康?
- 当前位置,旋转,速度(速度+方向),不久的将来的路径...
- 活动:进攻,散步,建筑,固定,复原等。
- 增益/减益状态效果
- 以及其他属性,例如法力,盾牌,还有什么不可以?
首先,玩家必须先进入完整状态,然后才能进入游戏(或选择与该玩家相关的所有信息)。
每个单元都有一个整数ID。属性是枚举的,因此也具有整数标识符。单元ID不必长32位(如果我们不节俭,则可能是32位)。它很可能是20位(为属性保留10位)。单位的ID必须是唯一的,当实例化和/或添加到游戏世界时,它很可能由计数器分配(建筑物和资源被认为是不可移动的单位,在地图上可以为资源分配ID)已加载)。
服务器存储当前的全局状态。每个玩家最近的更新状态由指向a list
的最近更改的指针表示(指针尚未发送到该玩家之后的所有更改)。更改会list
在发生时添加到。一旦服务器完成发送最后一个更新,它就可以开始遍历列表:服务器将玩家的指针沿列表移至其尾部,一路收集所有更改并将其放置在缓冲区中,然后发送给播放器(即协议的格式可以是这样的:unit_id; attr_id; new_value)新单元也被视为更改,并将其所有属性值发送给接收播放器。
如果您不使用带有垃圾收集器的语言,则需要设置一个滞后指针,该指针将滞后,然后追上列表中最陈旧的播放器指针,从而释放对象。您可以记住哪个玩家是优先堆中最陈旧的玩家,或者只是简单地进行迭代和释放,直到惰性指针等于(即与玩家指针之一指向同一项目)。
您没有提出的一些问题,我认为很有趣:
- 客户是否应该首先接收所有数据的快照?视野之外的物品呢?RTS游戏中的战争迷雾怎么样?如果发送所有数据,则客户端可能会被黑客入侵,以显示播放器不可用的数据(取决于您采取的其他安全措施)。如果仅发送相关数据,则此问题已解决。
- 什么时候发送变更而不是发送所有信息至关重要?考虑到现代机器上的可用带宽,如果发送“增量”而不是发送所有信息,我们是否有任何收获?