目前我的游戏服务器很小(只有一个区域和约50个人工智能),每次发送状态更新数据包(UDP)时,都会向每个客户端发送完整的状态。这会创建一个大约1100字节的数据包大小。它所发送的几乎所有信息都是为所有实体提供以下信息:
int uid
int avatarImage
float xPos
float yPos
int direction
int attackState
24 bytes
编辑:更高效的结构
int uid
byte avatarImage
float xPos
float yPos
byte direction & attackState
14 bytes
但是我最终需要为实体发送更多的信息。例如,我正在添加以下内容:
float targetXPos
float targetYPos
float speed
随着每个实体需要发送更多的数据,我很快就接近并很可能已经超过了数据包的最大大小。因此,我正在尝试想出一些可能的解决方法:
1)将状态更新数据包累加直到没有空间为止,然后剩余部分不发送。这会给客户端带来非常糟糕的视觉效果,不是真正的选择。
2)仅向客户端发送N个最近的实体的数据。这要求在每次状态更新时计算每个客户端的最近N个实体。这可能非常耗时。
3)以某种方式设计数据包,使得可以发送同一更新的多个数据包。目前,客户端假定数据包的结构如下:
int currentMessageIndex
int numberOfPCs
N * PC Entity data
int numberOfNPCs
N * NPS Entity data
客户端然后接受到这个新数据并完全覆盖其状态的副本。由于数据包是完全自我包含的,即使客户端错过一个数据包,也不会有问题。我不确定如何实现同一更新的多个数据包的想法,因为如果我错过其中一个,那么怎么办?我无法使用更新的部分状态覆盖完整但已过时的状态。
4)仅发送实际更改的变量。例如,对于每个实体,我添加一个整数,用于每个字段的位掩码。诸如速度、目标、方向和头像图像之类的内容在每次更新时都不需要被发送。我仍然遇到了客户端错过必须更新其中一个值的数据包的问题。我不确定这有多重要。这还需要在客户端和服务器端上进行更多的计算来创建/读取数据包,但不会太多。
是否有更好的想法呢?