如何在networking游戏中以强大的方式分配实体ID?

我正在为一个networking游戏的实体系统工作,我正在分配每个实体一个唯一的32位整数ID,我可以用它来序列化实体和实体本身的引用。

目前我只是增加一个计数器,每次创建一个实体。 我猜这个ID最终会用完,但我真的不希望有40亿个实体。 如果实体#5被销毁,并且我们得到5的标识,这也避免了这个问题。它是指新的#5还是旧的删除#5?

问题是我不知道如何处理/避免碰撞。 目前,如果客户端接收到一个id高于当前“免费id”的实体的更新,那么它就会自由地使用id。 但是这似乎不是很强大。

我考虑过为每个客户端分配范围,以便他们可以在没有冲突的情况下分配实体(比如前n位是玩家号码),但是我担心如果范围开始随着时间的推移会发生什么情况。

有没有更好的方法来处理这个问题? 我是否应该关心id溢出或超过允许的范围? 我可以添加代码来检测这些情况,但如果它们发生崩溃,它会怎么做。

另一个select是使用一个像128位GUID那样独一无二的机会,但是这对于尝试最小化networkingstream量的游戏似乎确实很重。 另外,实际上,我永远不需要更多的实体,那么一次可以适应32位甚至24位整数。

谢谢!

Solutions Collecting From Web of "如何在networking游戏中以强大的方式分配实体ID?"

我所做的就是让服务器做好一切 。 客户只能要求服务器做一些事情,而不能自己做任何事情。 在这种情况下,服务器将始终是分配ID和解决问题的人。

在等待服务器批准如下操作时,我没有处理客户端预测:“射击火箭”或“在这里建立太阳能站”。 这些操作将要创建实体,而实体具有ID。 到目前为止,我只是坐在我的拇指等待服务器,但我相信需要做的是创建一个临时的实体,当你等待服务器批准。 当您收到服务器批准时,服务器将分配一个ID,您可以更新或覆盖该临时对象。

我也没有处理ID溢出,但是如果服务器处于完全控制状态,并检测到溢出,它可以做任何你认为必要的处理(从0开始,从一个空闲堆栈中select,崩溃等),以及所有客户甚至不会知道或关心。 客户端只会接受服务器发出的ID。

当我为商业多人游戏做这个时,我完全按照你的建议做了:使用一个32位的GUID整数,前八位是玩家号码,最后二十四位包含一个本地唯一号码。

如果/当本地号码溢出时(在我的情况下,几乎不会发生;在正常使用情况下,在单个networking会话中需要连续播放4到5天才会发生),则所有者将发送“重置所有对象”消息,并重新编号从零开始的所有仍然存在的对象。 该消息告诉所有同行放弃他们收到的对象,并再次查询。

一个更奇特的方法将是一个“带GUID的对象'n'现在是每个现有对象都带有GUID'm''消息的对象。 但就我而言,这是不太可能真的发生的事情,我不认为人们会介意在一个networking会话中不间断地玩了五天之后,半秒钟内从世界上消失的远程物体。 ;)

如果你的客户可以产生自己的实体,我猜你有一个点对点的多人游戏。

如果是这样的话,你可能没有太多的客户。 当然不会超过256.而且你的实体ID保证适合24位(对于每个人来说,有16000000+实体是足够的!)。 所以,只要使你的ID的最高字节等于客户端的ID:

entityId = clientId<<24 + (maxEntityIn++) 

或者其他的东西。

如果我错了,你有一个权威的服务器, 不要在客户端上创建新的实体。

我在永久性多人游戏中使用了“最天真”的方法(只为每个新ID增加一个整数),并且它工作正常,因为我不让客户端创建新的ID:s。

如果你让客户决定(通过使用一种解释的GUID技术),客户端也可以通过给一个新的项目分配一个旧ID来引入各种错误(这正是我想到的在我头顶上想着5秒,可能会有其他的漏洞)。

像往常一样, 为了防止作弊 ,服务器应该做所有的创建和validation