Как лучше всего синхронизировать игровой движок и сетевой сервер в Haskell?

Я разрабатываю небольшую футбольную игру, в которой игровой движок (который вычисляет движения игроков и т. д.) работает на сервере, а рендеринг и обработка клавиатуры/мыши выполняются клиентом. Для сервера (Haskell) я хочу использовать

  • Happstack для связи клиент-сервер
  • Yampa/Reactimate для движка игры

Примерно каждые 20 мс клиент должен отправлять события клавиатуры и мыши на сервер через HTTP GET, получать текущий статус игры (мяч и позиции игрока в формате JSON) и отображать его. Я думаю об использовании инфраструктуры SDL для игрового цикла, обработки ввода и рендеринга.

Сервер в основном выполняет два потока: сервер happstack получает HTTP GET, помещает команды клавиатуры/мыши в очередь, считывает текущий статус игры из второй очереди и отвечает на запрос HTTP GET.

Второй поток запускает игровой движок Yampa, как описано в Yampa новый раунд как можно быстрее (без тиков) и помещает результат в очередь рендеринга.

Архитектура

Общий вопрос: похоже ли это на выполнимую архитектуру?

Конкретный вопрос: как можно спроектировать очередь рендеринга на стороне сервера: можно ли использовать для этого Чан? Если игровой движок в среднем быстрее, чем «тикает» на стороне клиента, очередь будет становиться все длиннее и длиннее. Как это могло быть улажено с Чаном?

Ваши комментарии очень приветствуются!


person martingw    schedule 11.02.2011    source источник


Ответы (3)


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

Я также не понимаю, почему вы хотите использовать HTTP для такой игры (любой игры в этом отношении), почти все игры используют UDP, и я, вероятно, пойду по этому пути для вашего типа игры. Это руководство отлично подходит для изучения подобных вещей.

Я бы также поставил под сомнение ваш выбор формата сетевых данных, зачем вам нужен формат, который потребует нетривиального разбора/форматирования при получении/отправке? Я полагаю, что отправка большого количества данных и часто это потребует значительного времени. Если бы я собирался использовать строки, я бы попытался использовать самый простой формат, требующий минимального синтаксического анализа. В связанной системе, над которой я работал, была многопроцессорная система реального времени, использующая сокеты для связи, и изначально она использовала строки xml в качестве формата сетевых данных, и это было ужасно неэффективно, и все процессы находились на одной машине.

Что касается Yampa и рендеринга на стороне сервера, то, если мы думаем о FRP в контексте игр как о средстве реализации игровой логики и объектов, я считаю, что в большинстве сетевых игр есть серверные и клиентские объекты. Обычно визуализируемые объекты являются клиентскими объектами, а невизуализируемые — серверными объектами, и я предполагаю, что некоторые объекты имеют представление в обоих случаях. Так что в этом случае вы, вероятно, захотите, чтобы Yampa работала как на стороне сервера, так и на стороне клиента, и я бы постарался избежать всего, что связано с рендерингом на стороне сервера. Я считаю, что визуализируемые объекты должны преимущественно придерживаться клиентской стороны. Есть ли конкретная причина, по которой вы хотите, чтобы команды рендеринга поступали с сервера?

person snk_kid    schedule 12.02.2011
comment
Большое спасибо, как раз то, что я искал! Что касается рендеринга на стороне сервера: я хотел, чтобы игровой движок вычислял позиции игрока и мяча (только координаты X, Y, Z) и отправлял их (через очередь рендеринга и HTTP) клиенту. Мне еще предстоит пройти весь путь по вашей ссылке, но мне уже кажется, что это уже пройденный тупик... - person martingw; 12.02.2011

Если вы хотите получить только последнее состояние игры, не используйте чан или очередь, используйте пример: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Concurrent-SampleVar.html

person sclv    schedule 12.02.2011

Если вам интересно, я также однажды написал похожую футбольную игру на основе сервер-клиент на Haskell. Вы можете найти исходный код на github (сервер, client). Поскольку в то время я был новичком в Haskell, я столкнулся с некоторыми проблемами, связанными с многопоточностью (и записал о них в блоге) и так и не закончил проект, но вы, по крайней мере, видите из кода, как этого делать не надо. (В конце концов я отказался от архитектуры сервер-клиент и написал freekick2.) Я действительно думаю, что архитектура хотя само по себе осуществимо.

Однако, как пишет snk_kid, я не знаю, зачем вам использовать HTTP. Чтобы он работал в сети без (заметной) задержки, вам, вероятно, придется использовать UDP, а также предсказание на стороне клиента (вот немного информативного материала).

person Antti    schedule 14.02.2011
comment
Спасибо, Анти! Я посмотрю ваш код! Я думаю, что пропущу часть CS, эта возня с UDP кажется довольно сложной... - person martingw; 21.02.2011