Как написать реал-тайм онлайн игру? Методология, паттерны, статьи?

Доброго времени суток, уважаемые,

Писать буду серверную часть на c++ (решение может изменится в сторону nodejs в силу наименьшего порога синтаксиса), но меня больше интересует не столько тонкости самого языка как способы и приемы.

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

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

1. Как лучше открыть сокет?
2. Какие данные лучше всего передавать по сокету и в каком виде? (наименьший размер, перфоманс)
3. Что хранить в оперативной памяти сервера, что хранить в базе данных?
4. Какая база данных лучше подойдет? SQL / noSQL / Реляционная / Объектно-реляционная?
5. Имеет ли смысл использовать кеширование? Или сойдет оперативная память + БД.

С уважением, искатель приключений.
  • Вопрос задан
  • 10384 просмотра
Решения вопроса 2
@kazmiruk
Вы задаете более-менее правильные вопросы, но на них нет правильных ответов. Каждый случай очень индивидуальный и кратким ответом тут не обойтись, тут нужны лекции с тоннами теории. Я в свое время писал игры: php (api) + flash (клиент) + C++ (сервер) + mysql (база данных) + memcache (кеш), php (api) + python gevent (сервер) + mongodb (база данных) + redis (кеш) + html5 (клиент), nodejs (сервер) + html5 (клиент) + redis (кеш) + postgresql (база данных). Все они были довольно проивзодительными. Такое разнообразие технологий отчасти обуславливалось моим любопытством (проект на nodejs писал для себя).
В целом пытаясь ответить на Ваши вопросы:
1. Не совсем понятно что Вы имеете ввиду. Уточните вопрос.
2. Лучше всего передавать на сервер все действия клиента и обсчет производить на сервере для невозможности подделывания результатов действий, но это приводит к возрастанию нагрузки на сервер. Протокол - мне нравится bson с готовыми библиотеками, понятным форматом и небольшим размером. Но опять же его я использовал только во втором проекте, в остальных местах я создавал свои велосипеды, которые для конкретных случаев были наиболее эффективны (в моем представлении)
3. В базе хранить все, что не должно пропадать между играми (условно говоря после выключения сервера ;)), в оперативной памяти дублировать все в идеале (для избавления от операций чтения с диска).
4. Зависит от потребностей. Postgresql\mysql - более традиционны. Mongodb - модная ) Если Вы понимаете, что в Вашей игре вы можете пережить ограничения mongodb (к примеру отсутствие транзакций) - юзайте его, очень удобен для хранения игровых состояний. Если не уверены - используйте традиционные реляционки.
5. Кеширование по сути и есть перемещение данных из БД в оперативную память. Причем перемещается таким образом, что скорость выборки из оперативной памяти не зависит от количества данных. Это так называемые хэш-таблицы.

В общем, без обид, но судя по Вашим вопросам Вам надо очень серьезно подтянуть теорию, прежде чем браться за серьезную игру. Писать серверную часть на С++ - круто, если Вы его знаете на отлично. В целом большого профита Вы не получите, так как скорость С++ проявляется в числодробилках. А игровой сервер - в основном операции чтения\записи, которые будут одинаково выполняться на практически любом современном языке и их скорость больше зависит от построенной архитектуры.
Мои рекомендации: читать про блокирующие\неблокирующие сокеты, многопточность, структуры данных, паттерны проектирования, оптимизация запросов (включая нормализацию и денормализацию данных), кеширование. Параллельно с этим можно делать простенький чатик постепенно улучшая и оптимизируя его. Таким образом Вы приобретете и теорию, и практику. После этого можно сделать какую-нибудь простенькую игру.
Ответ написан
lexxpavlov
@lexxpavlov
Программист, преподаватель
По части вопросов и общих моментов - присоединяюсь к @kazmiruk и @dplsoft, они всё правильно сказали. Их советы на самом деле хороши.

Добавлю только несколько ссылок, которые вам могут пригодиться:
0fps.net - ресурс по созданию реалтаймовых сетевых движков (на англ.)

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

Две статьи от Маилру по созданию сервера: Базы данных в онлайн-играх. От Аллодов Онлайн до S... и
Архитектура сервера онлайн-игры на примере Skyforge. Подробно и качественно рассматривают создание сервера игры.

Сетевое программирование для разработчиков игр:
Часть 1: UDP vs. TCP
Часть 2: прием и передача пакетов данных
Часть 3: виртуальные соединения поверх UDP

Ещё полезные статьи с хабра:
Высоконагруженные системы: решение основных проблем
Создание многопользовательской realtime игры на node.js
Как не нужно писать большие сервера - на java
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
@TroyashkA
Самый лучший ответ для топикстартера - просто начни. С теорией у тебя всё плохо, зато с фантазией все хорошо и это отлично на самом деле. Как сказал @Kazmiruk, у него тоже в начале были велосипеды, вот с этого надо и начать. Однако, здесь не совсем явно был выделен один момент. Онлайн игра - это МНОГО графики. Если её качество будет плохим, то мало кто будет играть, за редким исключением, типа того же minecraft, но там автор сильно подумал, как компенсировать этот недостаток и превратил его в фичу.
А если смотреть на вещи реально, то в данный момент, создавать рабочую реализацию тебе пока рановато, теорию и практику ой как подтянуть надо. Я бы на твоем месте сделал так: сделай первую версию и постепенно улучшай. Не сделаешь - значит еще не время для таких вещей.
Ответ написан
Комментировать
@dplsoft
Сильно мне кажется, что вам в первую очредь надо понять/рассказатьНам что именно вы собираетесь писать, а уже потом - вам могут предлагать те или иные варинты решения.

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

И что вы вкладываете в понятие "реалтаймовый"?
вы понимаете, что если 2-х шахматистов ограничить регламентом - мол далайте ход раз в минуту и строго черезх минуту всегда - то это тоже будет _реалтаймовая игра_? "реалтаймовые шахматы с периодом 1 минута". Вас устроит такое?

с другой стороны вот скажем - сервер для кваки - должен жить совершенно по другим принципам.

с третьей стороны - при обилии игроков - кваковский сервер начнет лагать, а вот EVE-онлайн, как где-то уже писали - ... замедлит время.

Что идеально в одном случае - никак не подходит в другом. Постройте сначала логическую модель вашей игры, сущности, объекты, принципы их взаимодействия между друг другом, определите требования в быстродействию, потом начинайте представлять как клиенты и сервер будут взаимодейтсвовать и какую картину миру будут поддерживать?

например, если у вас платформер - то поймите - как будет ваш персонах взаимодействовать и что на него будет влиять. Например - если он во всех стреляет - это одно. А если его может сдувать ветром, причем таким который генерирует другой персонаж - это уже другое. А что делать если от одного из клиентов данные пришли позднее чем требуется? как будут решщаться проблемы рассинхронизации? что делать если один игрок стреляет по месту, где его клиент показывает что стоит другой игрок, а сервер считает что игрок давно уже убежал?

и потом уже выстраивайте из этого и того что вы знаете те или иные архитектурные механизмы и выбирайте паттерны.

Вообще задача сильно глобальная - в том виде как задан вопрос.
Может стоит попробовать начать с чего-то более простого? потому что если вы задаете вопрос про то "как открывать сокет" (технологический инструментарный вопрос) - но плохо представляете что делать если начнется "рассинхронизация" (это концепции логики работы распределнной системы сервер-клиенты) - то может стоит начать с чего-то попроще?

например, сделать сервер для какой пошаговой игры?
Ответ написан
vipuhoff
@vipuhoff
Сколько "правильно" не планируй все равно сломается:) Поэтому если проект интересный можно говнокодить пока не сделаешь демо версию с минимальным функционалом а дальше на кикстартер или Steam ранний доступ и допиливаешь продукт руками профессионалов:) (на собранные деньги)
а по поводу вопросов прежде чем их задать нужно знать минимум то о чем говорит @dplsoft, без этих так сказать фундаментальных знаний за такую затею лучше не браться.
Ответ написан
Комментировать
@Levhav
Возьмусь за разработку проектов любой сложности.
Я писал комет сервер на C++ это не игра но серверная часть имела бы общие черты.

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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы