Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MMORPG开发和服务器端逻辑,是否更新所有游戏对象?_C#_.net - Fatal编程技术网

C# MMORPG开发和服务器端逻辑,是否更新所有游戏对象?

C# MMORPG开发和服务器端逻辑,是否更新所有游戏对象?,c#,.net,C#,.net,我以前设计过多人游戏,但现在我想创建一个用于学习/挑战目的的MMORPG架构。我想在一台服务器上模拟数百(或数千)个并发播放器 到目前为止一切都很好,只是现在我面临着一个问题,那就是如何找到一个好方法,尽可能经常、尽可能快地更新服务器上的所有游戏对象 我所说的游戏对象是指所有玩家、暴徒和子弹 问题是,所有玩家、暴徒、子弹都存储在服务器端内存的集合中,以便更快地处理,并遍历所有玩家、暴徒、子弹以检查冲突、更新运行状况、更新移动等。。。时间太长了 假设我有1000名玩家,全世界有10000名暴徒,所

我以前设计过多人游戏,但现在我想创建一个用于学习/挑战目的的MMORPG架构。我想在一台服务器上模拟数百(或数千)个并发播放器

到目前为止一切都很好,只是现在我面临着一个问题,那就是如何找到一个好方法,尽可能经常、尽可能快地更新服务器上的所有游戏对象

我所说的游戏对象是指所有玩家、暴徒和子弹

问题是,所有玩家、暴徒、子弹都存储在服务器端内存的集合中,以便更快地处理,并遍历所有玩家、暴徒、子弹以检查冲突、更新运行状况、更新移动等。。。时间太长了

假设我有1000名玩家,全世界有10000名暴徒,所有玩家和生物都负责创建5个其他游戏对象(不多也不少),比如子弹

这将在一个集合中提供(1000+10000)*5=55000个游戏对象

在具有4gb RAM的双核HTI5上,迭代所有对象以更新它们需要很长时间(几分钟)。这是错误的

迭代时,代码如下所示(伪):

for(inti=0;i
作为一种优化,我正在考虑将我的游戏对象划分为不同的区域和集合,但这并不能解决我需要每秒更新所有对象几次的问题

我应该如何继续更新服务器端的所有游戏对象?我做了大量的搜索来寻找有趣的游戏设计模式,但到目前为止没有结果(


提前感谢!

在55000个对象上循环应该不会太慢。显然,你在这些对象上做了太多太多的事情,可能做了不应该总是做的事情

例如,如果一个暴徒周围没有玩家,那么它真的应该被计算吗? (如果一棵树倒在森林里,周围没有人,它真的发出声音吗?)

此外,很多对象可能不需要在每次循环中更新。例如,玩家可以由客户端计算,只需“验证”每1-2秒一次。将所有玩家的冲突转储到客户端将使服务器工作负载更易于处理。玩家的子弹或光线投射也是如此。反过来,它也会使玩家的游戏更加流畅

跟随路径时的MOB是否需要进行碰撞测试,或者路径的节点是否足够

测试每一个物体和其他物体是很糟糕的。是否所有的怪物都必须和其他所有的怪物进行测试,或者只需要测试特定的类型或派别?你能把你的世界分成更小的区域,只测试里面的怪物和里面的物体吗


MMO服务器的代码需要做大量的工作才能正常工作。所做的优化有时是疯狂的,但只要它能正常工作。

您的代码运行得那么慢,不仅仅是因为它检查了所有N个对象,而是因为它检查了对象之间所有可能的交互,并且需要在您的内存中进行N^2次计算=3 025 000 000次样品

减少检查次数的一种方法是将游戏世界中的对象放入网格中,以便不在相同或对齐单元格中的对象无法相互交互

此外,您当前的代码会对每个交互进行两次检查,您可以通过在内部循环中从i开始循环来轻松解决此问题:

for(int i = 0; i < gameobjects.Count; i++) 
  for(int j = i; j < gameobjects.Count; j++) 
for(inti=0;i
我会完全改变设计并实施事件库设计。这有很多好处,显而易见的是,您只需要更新实际与之交互的对象。因为MMO游戏中的大多数游戏对象都是空闲的,或者根本看不到

您没有理由计算在任何玩家屏幕上都看不到的对象。这太疯狂了,需要一个您很可能负担不起的服务器场。相反,您可以尝试预测移动。或者存储一个当前未与之交互的所有对象的列表,并不太频繁地更新这些对象

如果玩家看不到某个物体,你可以远距离传送该单位,而不是让它平稳移动。基本上是在允许该物体移动的受限区域内移动该单位,使其看起来像是该物体在自由移动,即使玩家看不到该物体。通常这会导致当新玩家进入或离开一个区域时触发事件


你可以通过简单地计算上次更新后的时间来实现这一点,并预测对象的移动距离,就好像它对玩家可见一样。这对于有固定路线的对象或NPC特别有用,因为它使计算变得更加简单。

我将采用基于事件的设计,它只需要一个对象来移动在需要时进行更新。对于范围检查代码,您应该使用四叉树()(或类似工具)结构。这将防止它总是N^2。请注意,即使方法不正确,我想指出的是,您在该循环中没有使用2个内核,没有涉及多线程,您正在浪费50%的处理器能力。当然@Fire Dragon DoL,但这不会解决核心问题,最多需要4-5分钟,而不是广告8。@eandersson:是的,这很明显。我只是想指出,如果你的代码不关心CPU的使用,你就不能期望CPU的使用率。你很聪明,我知道有人会谈论“森林中的倒下的树”的事情。重点是,我仍然在考虑暴徒,即使不在任何玩家的视觉范围内,是否仍然是mo四处游荡,建造
for(int i = 0; i < gameobjects.Count; i++) 
  for(int j = i; j < gameobjects.Count; j++)