如何制作MMO(服务器端)?

use*_*694 8 mmo

我试图搜索如何制作一个MMO并总是找到相同的回复,这是不可能的或需要很多钱,但从来没有给出如何制作一个指南.

我想构建一个非常可扩展的东西,我目前关于如何构建MMO的想法如下:


组件:

  • 登录服务器:客户端向此服务器发送用户名和密码,如果成功,则向客户端提供要连接的游戏服务器.
  • 游戏服务器[1..N]:所有游戏逻辑都在这里,客户端连接到这个.
  • 位置数据库:存储当前登录用户和活动怪物的数据,其中包括游戏服务器,他们在地图上的位置以及他们采取的行动(移动,攻击等).
  • 帐户数据DB:存储有关用户的所有数据(用户名,密码,字符,项目,任务等)
  • 聊天服务器:由于位于同一个地方的用户可以在不同的服务器上,因此需要额外添加一个服务器,以便玩家可以在他们之间进行通信.
  • Monster DB:一个包含所有怪物的属性,基本位置和AI脚本的数据库.
  • 怪物服务器[1..N]:服务器中所有活动的怪物
  • 日志数据库:存储所有采取的操作和聊天文本.

操作:

  • 登录:
    1. 客户端将用户名和密码发送到登录服务器.
    2. 登录服务器使用帐户数据DB验证数据并检查当前未记录的数据(位置数据库),如果成功则转到3,否则返回不成功的登录消息.
    3. 登录服务器更新位置数据库,将新连接的用户添加到他将连接的服务器(最低人数/最近)
    4. 位置DB通知相应的游戏服务器用户已连接.
    5. 登录服务器向游戏服务器发送连接的客户端.
  • 主循环(客户端):
    1. 客户在位置DB中检查他当前的位置和动作以及他附近的人(玩家和怪物),在所接收的数据中还包括玩家的最后更新时间(档位或等级).
    2. 客户将收到的玩家的日期与保存在内存中的当前玩家进行比较,如果玩家不在记忆中或日期不同,则客户要求账户数据DB获取lvl,齿轮等.
    3. 客户端呈现玩家
    4. 一段时间后转到1.
  • 聊天:
    1. 客户端向聊天服务器发送消息(pm/normal/all)
    2. 如果是pm,聊天服务器将消息发送给目标
    3. 如果正常,聊天服务器会与位置服务器一起检查区域内的玩家(与主循环(客户端).1相同,当检查附近的玩家时)并将消息发送给那些人.
    4. 如果全部,聊天服务器广播给所有玩家
    5. 确认发件人和收件人收到了邮件
  • 行动:
    1. 客户端向Game Server发送动作(制作,移动,攻击等).
    2. 游戏服务器处理动作并使用动作的效果更新位置数据库(客户端将知道主循环动作发生了什么).
    3. 在制作或抢劫的情况下,游戏服务器将获得的项目返回给客户.
  • 主循环(游戏服务器):
    1. 检查从客户端收到的所有数据并处理它们.
    2. 向客户发送过程结果(损坏,xp,获得的项目等),并更新位置DB及其效果(新位置等).
    3. 一段时间后转到1.
  • 主循环(怪物服务器):
    1. 检查一个活跃的怪物是否有一个玩家在附近,如果没有将它从Monster Server和Position DB中删除.
    2. 如果附近有任何怪物(来自怪物数据库)并且未激活并激活它(更新位置服务器和怪物服务器),请检查位置数据库中的所有玩家.
    3. Monster根据存储在怪物DB上的脚本采取行动(攻击,移动,不做任何事情等).
    4. 一段时间后转到1.

以及我的问题:

  1. 这种实施方式会起作用吗?(考虑一个有很多怪物和玩家的大地图)
  2. 我觉得如果事情成长,职位数据库将会非常紧张.会更好,如果:
    • 制作多个位置数据库
    • 制作链接的数据库(玩家/怪物,游戏服务器,位置数据库)
    • 创建一个链接的DB(位置DB,区域)
    • 因此,位置DB基于一个区域(或多个区域),当玩家移动到另一个区域时,他的数据被移动到另一个位置DB; 最后一个DB(位置数据库,区域)将是如果一个区域有太多的玩家,很少位置DB可以共享相同的区域(如果区域没有很多人,位置DB可以容纳一些区域)
  3. 关于使用的技术,我正在思考以下内容:
    • 登录服务器:scala/django
    • 游戏服务器:C++中的原始编程?
    • 位置DB:用于通信的scala/django和用SQL的DB
    • 帐户数据DB:用于通信的scala/django和DB不确定是使用像mongoDB这样的NoSQL还是使用保存在文件上的帐户(哪个会更好?)
    • 聊天服务器:使用C++进行原始编程,还是应该尝试调整IRC服务器?
    • 怪物DB:SQL
    • 怪物服务器:像游戏服务器
    • 日志数据库:SQL
  4. 客户端 - 服务器之间的通信应该是UDP以便更快地通信?和TCP登录?或者应该始终在客户端和服务器之间保持一个开放的TCP套接字?还有,聊天,TCP还是UDP?
  5. 主循环应该运行多长时间以便游戏流畅?每0.5秒,0.1,接近60fps的东西?还要使计时器最好每次循环抛出一个线程?(控制线程数量,所以如果循环花费的时间比它应该的长)

而且我不认为我现在忘记任何事情要求并抱歉这个大帖子......

小智 5

我认为您的解决方案不会扩展。问题是您的位置DB需要针对每个玩家动作进行更新。您可能使用此方法来允许游戏服务器共享数据,这是一个坏主意,因为数据库并不旨在启用系统分发。将数据库视为真正的脱机存储,仅在激活播放器或对象时才加载状态。

您需要摆脱位置数据库,并存储分布在游戏服务器之间的玩家状态。

还可以考虑使前端服务器始终保持与客户端的一种连接,将消息中继到正确的游戏服务器等。通过这种方式,您可以避免客户端不得不连接到“正确的”游戏服务器以及所有的问题。带有这种信任度。

分布式编程相当困难,但是Erlang编程语言比Python / C ++等使您更容易。