Технические риски разработки MMOG
“Умножайте все на 5000 пользователей”
Эту фразу я первый раз услышал от Андрея Плахова. Идея проста: если у вас в оффлайн-игре была небольшая проблема, то в онлайн-игре она будет в 5000 раз сложнее.
Для запуска серверов требуется огромное количество ресурсов.
По косвенным данным известно, что один рилм WoW перезагружается порядка 10-15 минут. Сервер LA2 требует от 4 Гб оперативной памяти. Сейчас на основном сервере ARENA Online стоит 12 Гб оперативной памяти.
Почему так много? В отличие от оффлайн-игр, серверу необходимо держать в памяти весь мир, так как люди могут появиться где угодно. Можно попробовать подгружать только те локации, где есть хотя бы один человек, но если игра хорошо сбалансирована (а она должна быть такой), то игроки также будут равномерно распределены по всему миру. И придется все равно загрузить мир полностью.
Очевидно, что “простой смертный разработчик” не сможет у себя запустить такой сервер. Поэтому надо:
- Создать серверную ферму для возможности запуска полнофункционального сервера. В проекте ARENA Online, кроме основного сервера, где играют игроки, стоят еще четыре таких же мощных сервера, где разработчики могут запускать свои версии, чтобы в них копаться.
- Создать light-weight версию базы данных, в которой описан не весь мир, а лишь маленький его кусочек – чтобы была возможность быстро проверить какую-нибудь небольшую фичу.
- Разрабатывать сервер под 64-битную платформу. 32 бита позволяют использовать только 4 Гб памяти (вернее 3 Гб, так как последний гигабайт обычно резервирует для себя ОС).
Количество утечек памяти будет в 5000 раз больше
Представьте, что у вашей игры течет память в некоторых сложных ситуациях. Течет она со скоростью 1 мегабайт/час. В общем, это несерьезная проблема. Чтобы игрок это заметил, ему надо играть несколько дней напролет. А теперь умножим это на 5000. Получим 5 гигабайт/час. За пару часов сервер займет всю возможную память и благополучно умрет.
Из предыдущего пункта мы знаем, что запуск сервера требует больших ресурсов. И перезапускаться он будет достаточно долго. Из-за этого игроки будут еще больше недовольны. Если после каждого часа сервер недоступен 15 минут, то никто в такую игру играть не будет.
Пример: в старом сервере ARENA Online не освобождалась часть памяти при убийстве монстра. Допустим, у нас из 5000 человек онлайн 2500 человек активно дерутся с монстрами (остальные болтают и торгуют). Они убивают одного монстра за 30 секунд. При убийстве монстра не освобождается 1Кб памяти. Получим:
2500 человек * 1/30 монстров/сек * 3600 сек/час * 1Кб/монстр = 300 Мб/час
За 10 часов утечки в сервере займут 3 Гб памяти. Для 32-битных приложений это максимум. Примерно так происходило со старым сервером ARENA Online. Он был написан под 32 бита и раз в день перезагружался.
Решение этой проблемы еще больше затруднялось тем, что профилировать сервер было очень затруднительно: memory profiler ест еще больше ресурсов. Пустой сервер ARENA Online под профайлером valgrind запускался более часа и безбожно тормозил уже при 10 онлайн. В конце концов, на решение этой проблемы потребовалось несколько недель.
- Проводить плановые перезагрузки сервера. В Eve Online каждый день проводится часовая профилактика, в течение которой перезапускают серверный кластер. WoW, LA2, RO имеют еженедельную профилактику, во время которой сервер перезагружается. В ARENA Online сервер перезагружается 2-3 раза в неделю. Обычно перезагрузки происходят утром, когда онлайн на серверах небольшой.
- Разрабатывать сервер под 64-битную платформу. Как минимум, это позволит оттянуть момент перезагрузки сервера. Конечно, если утечка памяти порядка 5 Гб/час, то 64 бита не помогут. Но если утечка на уровне 300 Мб/час, то можно временно решить проблему, нарастив память у сервера.
- Кроме обычных путей использования smart pointers и правильного менеджмента памяти (этому стоит учиться у консольщиков), есть еще интересный вариант – использовать языки программирования со сборщиками мусора: С#, Java, Python (это будет подробнее описано ниже).
Неиспользуемые данные об игроках занимают ресурсы
Пример : Более точная статистика по ARENA Online. Зарегистрировано более 600 000 персонажей. Из них более 20 000 активных (заходивших хотя бы раз за последний месяц). Из них онлайн порядка 1500.
Если загружать в сервер все данные об игроках, то серверу потребуется в несколько раз больше ресурсов. Этого сервер уже не выдержит. Возникает идея удалять всех, кто не входит месяц. Но, как мы видим по статистике Арены, и это тоже не поможет – онлайн находится менее 10% активных пользователей. К этому можно добавить, что если загружать всех активных персонажей, то сервер может подвергнуться DoS-атаке: злоумышленник быстро зарегистрирует кучу персонажей и сервер исчерпает лимит памяти.
Тут выход один – загружать только тех, кто заходит в игру. И по этой причине придется отказаться от xml. Если у вас 600 000 персонажей и вам надо загрузить одного из них, то в случае xml вам необходимо будет пройтись по всему файлу. А это потребует кучу ресурсов. Также при изменении данных о пользователях в случае xml приходится полностью перезаписывать его.
Использовать реляционные базы данных и правильно их индексировать, чтобы время выполнения запроса не зависело линейно от количества записей. В ARENA Online была сделана система, которая запрещала писать запросы к БД без необходимых индексов.
Рассчитывайте на пинг 200 мс
Если на вашем сервере будет играть 5000 человек, то они будут находиться в разных краях России или даже мира. Если для Москвы пинг 200 мс может показаться чересчур большим, то за ее пределами такое качество канала встречается часто.
Какие проблемы могут возникнуть при этом? В Spectrum Worlds (ныне замороженный проект GDTeam) в одном из обновлений при открытии каждого интерфейсного окна клиент запрашивал подтверждение сервера. Это было не заметно при тестировании в локальной сети. Однако очень сильно раздражало при проверке в Интернете. Задержка в открытии окна на 100 мс уже заметна.
В ARENA Online онлайн резко повысился, когда интерфейс “отвязали” от подтверждений сервера. То есть игрок мог локально делать все, что угодно, и ему позже сообщалось, что реально произошло на сервере.
Платформа разработки Этот пункт обычно вызывает самые большие холивары. Я постараюсь их обойти и объяснить плюсы и минусы различных решений. Linux vs Windows Для оффлайн-игр такого вопроса не стоит. Разрабатывать надо под то, что стоит у пользователя – Windows. В недавнем прошлом для серверов такого вопроса тоже не стояло. Была только одна высокоэффективная серверная ОС – Linux. Однако с недавнего времени Windows 2003 зарекомендовал себя как альтернативная серверная платформа. Противоборство “Linux vs Windows” строится на куче мифов. И менеджеры часто выбирают платформу исходя из того мифа, который они услышали последним. Я постараюсь показать, что разница между ними по сути мизерная. И все зависит от программистов – на чем они умеют программировать, то и надо брать. Миф 1. У Linux намного лучше безопасность. Да, так оно и было с Windows 2000, который пережил уже 5-ый service pack. Windows 2003 очень сильно поменялся в лучшую сторону. В интернете можно найти кучу ссылок со сравнением безопасности Linux и Windows 2003. В большинстве случаев Linux побеждает. Однако win2k3 держится на уровне. А опытный администратор сможет настроить и ту, и другую ОС для обеспечения хорошей безопасности. Миф 2. Linux экономит на стоимости серверов. И вправду, win2k3 надо покупать, и лицензия стоит от $1000. Однако его также можно арендовать за $50 в месяц. Добавим, что аренда хорошего сервера в дата-центре стоит порядка $500 в месяц. То есть на Linux мы экономим около 10% стоимости сервера. Сюда можно еще добавить, что если один сервер держит хотя бы 1000 человек и каждый человек платит $10 в месяц, то с каждого сервера доход будет $10000 в месяц (расчет очень занижен, реально доход намного больше). Поэтому вместо холиваров стоит потратить время на сохранение оставшихся $9950 с сервера – это будет намного эффективнее. Миф 3. Под Linux очень сложно разрабатывать. Да, Visual Studio под Linux нет. Однако вполне приличные IDE есть. Плюс можно разрабатывать под MSVS и после этого портировать на Linux. Если делать это с самого начала разработки, то ресурсов уйдет минимум – порядка 1 человеко-месяца. Это небольшое время по сравнению с общим временем разработки, которое может достигать сотни человеко-месяцев. Миф 4. Под Linux сложно найти разработчиков. Да, квалифицированных программистов под Linux мало. Но их много и не надо. Большая часть кода пишется платформонезависимой. Разница в компиляторах небольшая и выучить ее несложно. Примеры. ARENA Online изначально разрабатывалась под Linux. Позже была перенесена на Windows, где и живет по сей день. Shelter Online разрабатывается на Windows и портируется на FreeBSD. CrimeCraft изначально предполагался на Linux, сейчас разработка идет на Windows. [/su_box]
Что делать? Не спорить по этому поводу. Есть намного более важные проблемы. Пусть серверную платформу выберут те, кому под нее работать так, чтобы им было удобно. [/su_box]
C# vs C++ Если вам сильно не нравится Windows, то можно заменить “C#” на “Java” и вычеркнуть первый пункт. Второй пункт может быть легко решен закупкой более мощных серверов. Сервера стоят дешевле программистов. И рисков, связанных с ними, меньше. Как я показывал выше, стоимость аренды сервера составляет менее 5% от дохода. Третий пункт не проблема, так как нам требуется его установка на сервер и пользовательские компьютеры трогать не надо. Таким образом, первые три пункта хоть и являются минусами, но в случае разработки MMOG они почти не заметны. А последние два пункта дают большой плюс в скорости и качестве разработки. Примеры. Сервера ARENA Online и CrimeCraft сейчас разрабатываются на C#. Основная логика сервера EvE Online написана на Python – он обладает теми же плюсами и минусами. Что делать? Присмотреться к вариантам использования C#/Java/Python. Перейти на C# после C++ достаточно просто, а выигрыш в разработке существенен. Все, что может быть неправильно использовано, будет Это один из законов дизайна онлайн-миров. Я расскажу, как можно минимизировать возможность использования сервера неправильно. Возможность копирования вещей В общем, эта проблема касается любых ресурсов, которые можно передавать. Если в какой-нибудь игре можно будет передавать опыт и уровни другим игрокам, то такая проблема встанет и с ними. Если же, наоборот, в игре нельзя передавать вещи между игроками, то и проблемы не возникнет. Здесь и далее под “вещами” я буду понимать ценности внутри игры, которые могут быть переданы другим игрокам. Пример 1. В WoW была возможность копирования вещи при входе в незагруженный сервер инстансов. Как это происходило: два человека подходили к входу в инстанс. Первый передавал второму вещь, которую надо скопировать, и заходил в подземелье. Так как сервер еще не загрузился до конца, он не мог туда войти. Происходила ошибка, и его выкидывало. Но когда он возвращался в мир, загружались данные пятиминутной давности. А пять минут назад у него эта вещь еще была. Получалось копирование – одна и та же вещь была и у первого, и у второго игрока. Пример 2. В RO есть два типа торговли: На одном из пиратских серверов была ошибка: если деньги одновременно передавать через оба типа торговли, то они копировались. Пример 3. Сохранение данных игроков в RO происходило отдельно для игроков в случаях: На одном из серверов был обнаружен баг: при перезагрузке сервера данные не сохранялись принудительно. Поэтому при объявлении о перезагрузке сервера через 5 минут игроки проделывали следующие действия: Результатом этого стал выброс на рынок большого количества улучшенных вещей. Что прямо повлияло на экономику и игровой баланс.
Источник: dif.ru
Для оффлайн-игр этот вопрос иногда поднимается. В большинстве случаев выбирают C++. Но иногда случается увидеть игры на C#. В чем плюсы и минусы C#?
У игроков это называется “дюп” (от английского dupe – копировать). Основная идея: с помощью ошибки в коде создается дубликат вещи. Обычно вещи являются одной из основных ценностей в MMOG. Их можно передавать, а значит, устранить последствия такой ошибки будет проблематично: игрок может создать кучу крутых вещей и раздать их остальным игрокам. Если заблокировать только этого игрока, то вещи останутся в мире и будут нарушать баланс. Если забрать все вещи этого рода у всех игроков, то они будут недовольны и могут уйти из игры.