Структура клиент-сервера асинхронной многопользовательской игры для UnityC#

Место общения программистов C#
Anonymous
Структура клиент-сервера асинхронной многопользовательской игры для Unity

Сообщение Anonymous »

Мой проект выходит из стадии прототипа, и я пытаюсь определить надежную архитектуру для своей игры. По своей концепции это похоже на Битвы в рюкзаках, Суперавтопитомцы или Базар: игроки сражаются асинхронно с «призраками» других игроков. Я также хочу добавить систему лобби, чтобы друзья могли сражаться друг с другом, возможно, используя одноранговую сеть (пока не решено).
Игра похожа на настольную: все полностью пошаговое, и у каждого игрока есть своя карта. Между игроками нет взаимодействия в реальном времени, нет проверок столкновений и нет синхронизации действий между ходами.
Чтобы удовлетворить мои требования к детерминированности и простоте разработки, на данный момент я структурировал проект следующим образом:

Код: Выделить всё

Project Root
├─ Client (Unity project)
├─ Shared (pure C# classes, no Unity or server-specific dependencies)
└─ Server (ASP.NET)
Папка Shared содержит всю игровую логику, включая ActionExecutionChains для проверки того, что клиент не жульничает. И клиент, и сервер независимо друг от друга оценивают действия игрока без сохранения состояния и детерминированно. Если есть несоответствие, сервер перезаписывает результаты клиента, чтобы обеспечить справедливость. Я «импортировал» папку Shared в Unity через символическую ссылку, и пока это работает хорошо.
После исследования я составил краткий список технических требований:
  • Все структуры данных должны быть на чистом C# и полностью сериализуемы в JSON — никаких специфичных для Unity типов, никаких атрибутов [Serializable].
  • Общие файлы — единственный источник достоверной информации: ActionExecutionChain, GameEntityDatabase, ModifierDatabase и т. д.
  • Сервер является авторитетным: он проверяет ActionExecutionChain, обеспечивает соблюдение правил и не обрабатывает логику пользовательского интерфейса.
  • Дескрипторы клиента Пользовательский интерфейс и моделирование; он генерирует ActionExecutionChain для проверки сервера.
  • Модификаторы и игровая логика существуют в виде чистых данных в общих файлах; логика времени выполнения (подсказки, расчеты) выполняется только на стороне клиента.
  • Все расчеты должны воспроизводиться как на сервере, так и на клиенте без зависимостей Unity.
  • Нет дублирования: все игровые правила, объекты и модификаторы определяются только один раз на общем уровне.
  • Все объекты и игровая логика должны сохраняться и исполняемый на как сервере, так и на клиенте Unity.
Мои вопросы:
  • Хороший ли это подход для пошагового детерминированного автобитвы? Существуют ли существующие проекты, шаблоны или примеры, на которых я мог бы поучиться? Сделали бы вы что-нибудь по-другому в моем конкретном сценарии?
  • Прав ли я, предполагая, что я не могу использовать [Serializable] для общих классов? Нужно ли мне избегать динамической типизации, использования определенных словарей и типов, специфичных для Unity, чтобы поддерживать полностью разделяемое состояние между Unity и сервером?
Я хотел бы добавить, что я опытный веб-разработчик, но никогда раньше не работал над ASP.NET сервером или сервером C#. Одна из основных причин, по которой я прошу совета, — перепроверить свои предположения о том, что сервер может и не может обрабатывать в отношении общих игровых данных и детерминированной логики.
Кроме того, на сервере в конечном итоге потребуется разместить базу данных, содержащую все данные игроков, включая:
  • рейтинги ELO
  • Бой история
  • Сами данные боя (для реконструкции и представления противников-призраков)
Сервер также должен иметь возможность предоставлять клиентам действительные данные боя, чтобы сражения были воспроизводимыми и достоверными.
Спасибо всем за то, что прочитали все это, хорошего дня!

Вернуться в «C#»