这是适合我们的 MMORPG 手机游戏的架构吗?

发布于 2024-12-08 09:31:02 字数 1388 浏览 0 评论 0原文

这些天我正在尝试为我的公司设计一款新的MMORPG手机游戏的架构。该游戏类似于 Mafia Wars、iMobsters 或 RISK。基本思想是准备一支军队来对抗你的对手(在线用户)。

虽然我之前曾开发过多个移动应用程序,但这对我来说是新鲜事。经过一番努力,我想出了一个架构,并在高级流程图的帮助下进行了说明:

High -level flow

我们决定采用客户端-服务器模型。服务器上将有一个集中数据库。每个客户端都有自己的本地数据库,该数据库将与服务器保持同步。该数据库充当缓存,用于存储不经常更改的内容,例如地图、产品、库存等。

有了这个模型,我不确定如何解决以下问题:

  • 同步服务器和客户端数据库的最佳方法是什么?
  • 在将事件更新到服务器之前是否应该将其保存到本地数据库?如果应用程序在将更改保存到集中式数据库之前由于某种原因终止怎么办?
  • 简单的 HTTP 请求是否可以达到同步的目的?
  • 如何知道当前有哪些用户登录? (一种方法可能是让客户端在每 x 分钟后继续向服务器发送请求,以通知它处于活动状态。否则认为客户端处于非活动状态)。
  • 客户端验证是否足够?如果不是,如果服务器未验证某些内容,如何恢复操作?

我不确定这是否是一个有效的解决方案以及它将如何扩展。如果已经开发过此类应用程序的人能够分享他们的经验,这可能会帮助我想出更好的东西,我将非常感激。提前致谢。

其他信息:

客户端是在名为 marmalade 的 C++ 游戏引擎中实现的。这是一个跨平台游戏引擎,这意味着您可以在所有主要移动操作系统上运行您的应用程序。我们当然可以实现线程化,这也在我的流程图中进行了说明。我计划使用 MySQL 作为服务器,使用 SQLite 作为客户端。

这不是回合制游戏,因此与其他玩家的互动不多。服务器会提供在线玩家列表,你可以通过点击战斗按钮来与他们战斗,在一些动画之后,结果将被公布。

对于数据库同步,我有两个解决方案:

  1. 为每条记录存储时间戳。还要跟踪本地数据库何时 是最后更新的。同步时,仅选择那些 有更大的时间戳并发送到本地数据库。保留 isDeleted 标志 对于已删除的行,因此每次删除都只是作为更新。但 我对我们的每个同步请求的性能抱有严重怀疑 必须扫描整个数据库并查找更新的行。

  2. 另一种技术可能是保留每次插入或更新的日志 针对用户发生的情况。当客户端应用程序请求同步时, 转到该表并找出该表的哪些行已被 更新或插入。一旦这些行成功转移到 客户端删除此日志。但后来我想到如果用户 使用另一台设备。根据日志表,所有更新均已 为该用户转移,但实际上是在另一个用户上完成的 设备。所以我们可能还必须跟踪设备。实施 这种技术比较耗时,但不确定是否可行 执行第一个。

These days I am trying to design architecture of a new MMORPG mobile game for my company. This game is similar to Mafia Wars, iMobsters, or RISK. Basic idea is to prepare an army to battle your opponents (online users).

Although I have previously worked on multiple mobile apps but this is something new to me. After a lot of struggle, I have come up with an architecture which is illustrated with the help of a high-level flow diagram:

High-level flow

We have decided to go with client-server model. There will be a centralized database on server. Each client will have its own local database which will remain in sync with server. This database acts as a cache for storing things that do not change frequently e.g. maps, products, inventory etc.

With this model in place, I am not sure how to tackle following issues:

  • What would be the best way of synchronizing server and client databases?
  • Should an event get saved to local DB before updating it to server? What if app terminates for some reason before saving changes to centralized DB?
  • Will simple HTTP requests serve the purpose of synchronization?
  • How to know which users are currently logged in? (One way could be to have client keep on sending a request to server after every x minutes to notify that it is active. Otherwise consider a client inactive).
  • Are client side validations enough? If not, how to revert an action if server does not validate something?

I am not sure if this is an efficient solution and how it will scale. I would really appreciate if people who have already worked on such apps can share their experiences which might help me to come up with something better. Thanks in advance.

Additional Info:

Client-side is implemented in C++ game engine called marmalade. This is a cross platform game engine which means you can run your app on all major mobile OS. We certainly can achieve threading and which is also illustrated in my flow diagram. I am planning to use MySQL for server and SQLite for client.

This is not a turn based game so there is not much interaction with other players. Server will provide a list of online players and you can battle them by clicking battle button and after some animation, result will be announced.

For database synchronization I have two solutions in mind:

  1. Store timestamp for each record. Also keep track of when local DB
    was last updated. When synchronizing, only select those rows that
    have a greater timestamp and send to local DB. Keep a isDeleted flag
    for deleted rows so every deletion simply behaves as an update. But
    I have serious doubts about performance as for every sync request we
    would have to scan the complete DB and look for updated rows.

  2. Another technique might be to keep a log of each insertion or update
    that takes place against a user. When the client app asks for sync,
    go to this table and find out which rows of which table have been
    updated or inserted. Once these rows are successfully transferred to
    client remove this log. But then I think of what happens if a user
    uses another device. According to logs table all updates have been
    transferred for that user but actually that was done on another
    device. So we might have to keep track of device also. Implementing
    this technique is more time consuming but not sure if it out
    performs the first one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

妄司 2024-12-15 09:31:03

我实际上已经开发过你提到的一些游戏。
我不建议使用 mysql,即使你进行分片,它也无法正确扩展。如果这样做,您将失去使用关系数据库可能带来的任何好处。
使用 no-sql 数据库可能会更好。它的开发速度更快,易于扩展,并且可以轻松更改游戏指定的文档结构。
如果您的游戏数据很简单,您可能想尝试 couchDB,如果您需要高级查询,您可能更适合使用 MongoDB。
一开始就注意安全。他们肯定会尝试破解游戏,如果您发布了多个客户端,则很难使安全更改向后兼容。 SSL 不会起多大作用,因为问题在于最终用户而不是窃听者。对您的数据进行签名或加密将使用户更难向其帐户添加物品和金币。
您还应该定义您的架构来支持多个客户端,而无需使用大量 if 和 case 语句。读取客户端版本并将该客户端分派到适当的代码库。
有一个带有升级、维护等标志的维护模式。如果您需要重新分片数据库或任何其他可能需要停机的更改,它会让您轻松一些。
客户端验证还不够,特别是在应用程序内购买时。我同意上面的帖子。服务器应该控制游戏逻辑。
至于DB同步,最好memcache只读数据。典型的例子是可购买的物品、地图、新闻等。用户数据更难,因为您可能无法承担丢失任何修改数据的后果。最简单的设置是将用户数据缓存几个小时,然后每次都直接写入数据库。如果您使用 no-sql,它可能会承受高负载,而无需使用持久性队列。

I've actually worked on some of the titles you mentioned.
I do not recommend using mysql, it doesn't scale up correctly, even if you shard. If you do you are loosing any benefits you might have in using a relational database.
You are probably better off using a no-sql database. Its is faster to develop, easy to scale and it is simple to change the document structure which is a given for a game.
If your game data is simple you might want to try couchDB, if you need advanced querying you are probably better of with MongoDB.
Take care of security at the start. They will try to hack the game for sure and if you have a number of clients released it is hard to make security changes backward compatible. SSL won't do much as the end user is the problem not an eavesdropper. Signing or encrypting your data will make it harder for a user to add items and gold to their accounts.
You should also define your architecture to support multiple clients without having a bunch of ifs and case statements. Read the client version and dispatch that client to the appropriate codebase.
Have a maintenance mode with flags for upgrading, maintenance, etc. It will cut you some slack if you need to re-shard your DB or any other change that might require downtime.
Client side validations are not enough, specially if using in app purchases. I agree with the above post. Server should control game logic.
As for DB sync, its best to memcache read only data. Typical examples are buyable items, maps, news, etc. User data is harder as you might not be able to afford loosing any modified data. The easiest setup is to cache user data for a couple of hours and write directly to the DB every time. If you are using no-sql it will probably withstand a high load without the need of using a persistence queue.

夜吻♂芭芘 2024-12-15 09:31:03

我发现两个潜在的问题隐藏在以下事实中:您将所有状态存储在客户端上,然后使用后台线程更新服务器上的状态。

  • 服务器如何验证正在发布的数据?如果有人入侵了您的应用程序,他们可以修改代码,因此每当他们挥舞剑(或在您的游戏中执行任何操作)时,总是会受到攻击。在单人游戏中这样做没什么大不了的,但在大型多人在线角色扮演游戏中这样做可能会破坏其他人的体验。因此服务器应该验证每一次数据更新——或者更好的是,服务器应该负责每一个业务规则。所以当你向对手挥剑时,这应该是一个服务器调用,服务器返回是否击中,以及对手损失了多少生命值。

  • 和其他玩家的互动呢(既然你说是MMORP,那就会有和其他玩家的互动)?既然你说你更新服务器,并在后台线程中获取更新,交互就会很缓慢。当你与另一个角色通信时,你首先要等待你的后台线程同步数据,但你也必须等待其他玩家的后台线程同步数据。

I see two potential problem hidden in the fact that you store all the state on the client, and then update the state on the server using a background thread.

  • How can the server validate the data being posted? If someone hacked your application, they could modify the code so whenever they swing their sword (or whatever they do in your game), it is always a hit. Doing that in a single player game is not that big a deal, but doing that in an MMORPG can ruin the experience for everyone else. So the server should validate every update of data - or even better, the server should be in charge of every business rule. So when you swing your sword against an opponent, that should be a server call, and the server returns whether or not it is a hit, and how many hit points the opponent lost.

  • What about interaction with other players (since you say it is an MMORP, there will be interaction with other players)? Since you say that you update the server, and get updates in a background thread, interaction will be sluggish. When you communicate with another character you have first wait for you background thread to sync data, but you also have to wait on the background thread of the other player to sync data.

好倦 2024-12-15 09:31:03

看起来不错。但客户端是由什么组成的呢?网络?您可以使用线程来同步两个数据库吗?我应该以立即与本地数据库交互的方式制作游戏,并让某些后台机制进行同步(类似于快照)。这让我想到了mysql复制。我认为值得尝试,但我从未尝试过。它还为您带来其他问题的答案。但是费用如何(有多少客户连接在一起)?

http://dev.mysql.com/doc/refman/5.0/en /replication.html

Looks nice. But what is the client-side made of ? Web ? Can you use threading to synchronize both DB ? I should make the game in that way that it interacts immediately with the local DB, and let some background mechanism do the sync (something like a snapshot). This leads me to think about mysql replication. I think it is worth to be tried, but I never did. It also brings you answers to other questions. But what about the charge (how many customers are connected together) ?

http://dev.mysql.com/doc/refman/5.0/en/replication.html

你的他你的她 2024-12-15 09:31:03

让您的客户端向服务器发出命令(“击中玩家”),然后服务器向客户端发送(相关)事件(“玩家被杀死”)。我不建议进行数据同步。服务器应该负责所有重要的游戏决策。

Make your client issue commands to the server ("hit player"), and server send (relevant) events to client ("player was killed"). I wouldn't advice going with data synchronization. Server should be responsible for all important game decisions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文