Это правильная архитектура для нашей мобильной игры MMORPG?

В эти дни я пытаюсь разработать архитектуру новой мобильной игры MMORPG для моей компании. Эта игра похожа на Mafia Wars, iMobsters или RISK. Основная идея состоит в том, чтобы подготовить армию для сражения с вашими противниками (онлайн-пользователями).

Хотя я ранее работал над несколькими мобильными приложениями, но это что-то новое для меня. После долгой борьбы я придумал архитектуру, которая проиллюстрирована с помощью блок-схемы высокого уровня:

Поток высокого уровня

Мы решили перейти на клиент-серверную модель. На сервере будет централизованная база данных. Каждый клиент будет иметь свою собственную локальную базу данных, которая будет синхронизирована с сервером. Эта база данных действует как кеш для хранения вещей, которые не меняются часто, например. карты, продукты, инвентарь и т. д.

С этой моделью я не уверен, как решить следующие проблемы:

  • Каков наилучший способ синхронизации серверных и клиентских баз данных?
  • Должно ли событие сохраняться в локальной БД перед его обновлением на сервере? Что делать, если приложение по какой-то причине завершает работу до сохранения изменений в централизованной БД?
  • Будут ли простые HTTP-запросы служить цели синхронизации?
  • Как узнать, какие пользователи в данный момент вошли в систему? (Один из способов может заключаться в том, чтобы клиент продолжал отправлять запрос на сервер каждые x минут, чтобы уведомить, что он активен. В противном случае клиент считается неактивным).
  • Достаточно ли проверок на стороне клиента? Если нет, как отменить действие, если сервер что-то не проверяет?

Я не уверен, является ли это эффективным решением и как оно будет масштабироваться. Я был бы очень признателен, если бы люди, которые уже работали над такими приложениями, поделились своим опытом, который мог бы помочь мне придумать что-то лучшее. Заранее спасибо.

Дополнительная информация:

Клиентская часть реализована на игровом движке C++ под названием marmalade. Это кроссплатформенный игровой движок, что означает, что вы можете запускать свое приложение на всех основных мобильных ОС. Мы, безусловно, можем добиться многопоточности, что также показано на моей блок-схеме. Я планирую использовать MySQL для сервера и SQLite для клиента.

Это не пошаговая игра, поэтому взаимодействия с другими игроками не так много. Сервер предоставит список онлайн-игроков, и вы можете сразиться с ними, нажав кнопку битвы, и после некоторой анимации будет объявлен результат.

Для синхронизации базы данных у меня есть два решения:

  1. Хранить временную метку для каждой записи. Также следите за тем, когда в последний раз обновлялась локальная БД. При синхронизации выбирайте только те строки, которые имеют большую временную метку и отправляйте в локальную БД. Сохраняйте флаг isDeleted для удаленных строк, чтобы каждое удаление просто вело себя как обновление. Но у меня есть серьезные сомнения по поводу производительности, так как для каждого запроса на синхронизацию нам придется сканировать всю БД и искать обновленные строки.

  2. Другой метод может состоять в том, чтобы вести журнал каждой вставки или обновления, которые происходят в отношении пользователя. Когда клиентское приложение запрашивает синхронизацию, перейдите к этой таблице и узнайте, какие строки какой таблицы были обновлены или вставлены. Как только эти строки будут успешно переданы клиенту, удалите этот журнал. Но затем я думаю о том, что произойдет, если пользователь использует другое устройство. Согласно таблице журналов все обновления были переданы для этого пользователя, но на самом деле это было сделано на другом устройстве. Таким образом, нам, возможно, придется также отслеживать устройство. Реализация этого метода требует больше времени, но не уверен, что он работает лучше первого.


person umair    schedule 05.10.2011    source источник


Ответы (4)


Я вижу две потенциальные проблемы, скрытые в том, что вы сохраняете все состояние на клиенте, а затем обновляете состояние на сервере с помощью фонового потока.

  • Как сервер может проверить публикуемые данные? Если кто-то взломал ваше приложение, он может изменить код, чтобы всякий раз, когда он размахивал своим мечом (или что бы он ни делал в вашей игре), это всегда был удар. Делать это в одиночной игре не так уж и сложно, но в MMORPG это может испортить впечатление всем остальным. Таким образом, сервер должен проверять каждое обновление данных или, что еще лучше, сервер должен отвечать за каждое бизнес-правило. Поэтому, когда вы замахиваетесь мечом против противника, это должен быть вызов сервера, и сервер возвращает ответ, был ли это удар или нет, и сколько очков жизни потерял противник.

  • Как насчет взаимодействия с другими игроками (раз уж вы говорите, что это MMORP, то взаимодействие с другими игроками будет)? Поскольку вы говорите, что обновляете сервер и получаете обновления в фоновом потоке, взаимодействие будет вялым. Когда вы общаетесь с другим персонажем, вам сначала нужно дождаться, пока ваш фоновый поток синхронизирует данные, но вам также придется подождать, пока фоновый поток другого игрока синхронизирует данные.

person Pete    schedule 05.10.2011
comment
Да, вы правы насчет проверки. Но разве это не приведет к задержке, если каждое действие должно быть проверено сервером, прежде чем оно действительно повлияет на игру. Это не пошаговая игра, поэтому взаимодействия с другими игроками не так много. Сервер предоставит список онлайн-игроков, и вы можете сразиться с ними, нажав кнопку битвы, и после некоторой анимации будет объявлен результат. - person umair; 05.10.2011

На самом деле я работал над некоторыми из названий, которые вы упомянули. Я не рекомендую использовать mysql, он не масштабируется правильно, даже если вы шардируете. Если вы это сделаете, вы потеряете все преимущества, которые могли бы быть у вас при использовании реляционной базы данных. Вероятно, вам лучше использовать базу данных без sql. Его быстрее разрабатывать, легко масштабировать и легко изменять структуру документа, заданную для игры. Если ваши игровые данные просты, вы можете попробовать CouchDB, если вам нужны расширенные запросы, вам, вероятно, лучше подойдет MongoDB. Позаботьтесь о безопасности на старте. Они наверняка попытаются взломать игру, и если у вас есть несколько выпущенных клиентов, трудно сделать изменения безопасности обратно совместимыми. SSL мало что даст, поскольку проблема заключается в конечном пользователе, а не в перехватчике. Подписание или шифрование ваших данных затруднит добавление пользователями предметов и золота в свои учетные записи. Вы также должны определить свою архитектуру для поддержки нескольких клиентов без набора операторов if и case. Прочитайте версию клиента и отправьте этот клиент в соответствующую кодовую базу. Имейте режим обслуживания с флагами для обновления, обслуживания и т. д. Это позволит вам немного расслабиться, если вам нужно повторно разбить вашу БД или любое другое изменение, которое может потребовать простоя. Проверки на стороне клиента недостаточно, особенно при использовании в покупках приложений. Я согласен с сообщением выше. Сервер должен контролировать игровую логику. Что касается синхронизации с БД, лучше всего кэшировать данные только для чтения. Типичными примерами являются покупаемые предметы, карты, новости и т. д. Пользовательские данные сложнее, так как вы не можете позволить себе потерять какие-либо измененные данные. Самая простая настройка — кешировать пользовательские данные на пару часов и каждый раз записывать напрямую в БД. Если вы используете no-sql, он, вероятно, выдержит высокую нагрузку без необходимости использования постоянной очереди.

person Eddie    schedule 03.05.2013

Выглядит хорошо. Но из чего состоит клиентская часть? Интернет? Можете ли вы использовать потоки для синхронизации обеих БД? Я должен сделать игру таким образом, чтобы она сразу взаимодействовала с локальной БД, и позволить некоторому фоновому механизму выполнять синхронизацию (что-то вроде моментального снимка). Это заставляет меня задуматься о репликации MySQL. Я думаю, стоит попробовать, но я никогда этого не делал. Это также дает вам ответы на другие вопросы. Но как насчет платы (сколько клиентов подключено вместе)?

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

person Louis    schedule 05.10.2011
comment
Клиентская часть реализована на игровом движке C++ под названием marmalade. Это кроссплатформенный игровой движок, что означает, что вы можете запускать свое приложение на всех основных мобильных ОС. Мы, конечно, можем добиться многопоточности, и это также показано на моей блок-схеме. - person umair; 05.10.2011

Заставьте ваш клиент выдавать команды серверу («ударил игрока»), а сервер отправляет (соответствующие) события клиенту («игрок был убит»). Я бы не советовал синхронизировать данные. Сервер должен нести ответственность за все важные игровые решения.

person driushkin    schedule 05.10.2011