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

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

  • Happstack для связи клиент-сервер
  • Ямпа/Реактив для игрового движка

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

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

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

Architecture

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

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

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

Ответы

Ответ 1

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

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

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

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

Ответ 3

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

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