【发布时间】:2012-08-24 08:02:11
【问题描述】:
我目前正在尝试为少数玩家(我认为少于 20 )。我将 TCP 套接字用于需要保证交付的数据包(即:聊天消息、登录和注销请求、ping 数据包等),将 UDP 用于不一定需要交付的所有内容,因为只有最后一个通过的数据包是重要(即:用户输入、游戏世界和对象更新等)。
我应该在这里提一下,我的游戏世界是什么样子的。每个对象服务器端都有其 id、角色和所有者成员。 Id 基本上是客户端的标识符,因此,一旦我向他们发送对象更新,他们就知道要更新哪个对象。 Owner是关于对象所有者的信息,即:控制actor的玩家。一旦玩家失去连接/注销,我用它来删除孤立的对象。然而,大多数对象都将此值设置为 Server。最后角色决定对象对客户是否重要。这可以设置为 ServerSide(对于不需要复制到客户端的对象,因为它们仅用于服务器端游戏状态计算),RelevantToOwner(此对象仅复制到其所有者,即:玩家私人库存不需要复制给所有人)、RelevantToList(对象被复制给列表中的所有玩家,即:我有对象可见的玩家列表,我只复制给他们)和 RelevantToAll(复制给所有人)。
当用户发送登录数据包时,我检查我是否有空闲插槽,如果有,那么我将世界复制给他(发送当前世界状态 - 每个没有将角色设置为 ServerSide 或 RelevantToList 的对象 - 当然除非客户端是在该对象的列表中)。
然后在服务器游戏状态更新循环的每次迭代之后,我发送完全相同的东西 - 整个世界状态。
当用户发送注销数据包时,我将他从登录的客户端中删除,释放插槽,并从游戏世界中删除所有孤立对象(以该用户为所有者的对象)。
这是我的问题:
- 这个模型适合实时多人游戏还是我做错了?
- 有没有办法减少初始世界复制后发送的数据包数量(即:仅更新自上次迭代以来状态发生变化的对象。我已经考虑过了,到目前为止我遇到了一个大问题使用这种方法 - 如果来自先前迭代的 UDP 数据包丢失并且对象的状态在后续迭代中没有改变,则对象将不会在播放器端更新。)
- 如何将多个对象更新打包到一个数据包中(我目前正在发送一个效率低下且可能非常错误的对象/数据包。
- 谁能给我指出一些简单客户端/服务器游戏的工作示例(来源会很好),以便我了解专业人士是如何做到的? C++ 或 C 会很好,但 Java / C# / Python 也很好。
【问题讨论】:
-
顺便说一句,如果这是一个作业,你真的应该添加作业标签
标签: c++ replication real-time multiplayer