Расширенная версия Little Bee в настоящее время извлекает логику синхронизации кадров в SDK. См. проект https://github.com/dudu502/littlebee_libs. Это пример игры с синхронизацией кадров, синхронизирующий сотни объектов и тысячи состояний в игре. . Предыстория игры — стрельба по планетарной системе. Ниже приводится ссылка на видео.
[Смотреть воспроизводимое видео (Youtube)]
[Смотреть повтор видео (Youtube)]
[Смотреть воспроизводимое видео(bilibili)]
[Смотреть повтор видео(bilibili)]
Синхронизация кадров | Государственная синхронизация | |
---|---|---|
последовательность | Уровень проектирования определяет неизбежную последовательность | Может гарантировать последовательность |
Количество игроков | Ограниченная поддержка многопользовательской игры | Несколько игроков имеют преимущества |
Кросс-платформенный | Необходимо учитывать согласованность операций с плавающей запятой. | Поскольку основные вычисления выполняются на сервере, проблем с кроссплатформенностью нет. |
Античитерство | Легко обмануть, но можно оптимизировать | Может быть очень хорошим средством предотвращения мошенничества |
Отключите и снова подключите | Это сложно реализовать, но не невозможно | Вам нужно отправить сообщение только один раз, это легко реализовать. |
Требования к воспроизведению | может быть реализовано идеально | Невозможно достичь |
пауза в игре | Легко реализовать | Не легко реализовать |
Объем сетевой передачи | относительно небольшой | относительно большой |
Сложность разработки | относительно сложный | относительно простой |
РТС-игры | Подходящий | Не подходит |
файтинги | Подходящий | Не подходит |
МОБА-игры | Подходящий | Не подходит |
ММО игры | Не подходит | Подходящий |
После понимания трудностей, которые необходимо преодолеть в процессе разработки синхронизации кадров, мы рассмотрим выбор лучшего метода реализации или среды разработки. Поскольку разработка кадровой синхронизации требует разделения данных и производительности, в какой степени ее следует разделять? Часть расчета данных можно даже разместить в отдельном потоке. Преимущество написания логики таким способом заключается в том, что он также позволяет серверу выполнять функцию быстрого повтора игры. Я думаю, что только ECS может достичь такого уровня разделения. Синхронизация кадров плюс ECS — абсолютно идеальный партнер.
Во-первых, нам необходимо представить ECS — это не совершенно новая технология, и Unity ее не предложила впервые. Этот термин появился очень рано и внезапно стал популярным в последние годы из-за «Overwatch» от Blizzard. Серверная и клиентская части «Overwatch» полностью построены на базе ECS и имеют отличную производительность в игровой механике, сети и рендеринге. Честно говоря, ECS не похож на шаблон проектирования. Все шаблоны проектирования, которые мы использовали ранее, обсуждались в рамках объектно-ориентированного проектирования, а ECS не является объектно-ориентированным. В Unity тоже есть ECS. Фактически, собственные компоненты Unity тоже являются своего рода ECS, но они недостаточно чисты. ECS особенно подходит для игрового процесса. Существует множество вариантов ECS, и вот ECS с некоторыми небольшими модификациями.
Это особенность игр с кадровой синхронизацией. Если в игре есть система повторов, то игра должна быть реализована через кадровую синхронизацию. Воспроизведение также можно назвать видеозаписью, но оно сильно отличается от воспроизведения видео с использованием видеофайлов, поскольку носитель обычно занимает огромный файл, и в процессе воспроизведения невозможно переключить окно. Видео легко украсть, злоупотребить, злонамеренно. изменяется, сжимается и ухудшается качество, поэтому воспроизведение видео имеет большой недостаток. При воспроизведении с синхронизацией кадров файл может стать очень маленьким, и его невозможно будет изменить. Пользователи могут переключать окна по своему желанию во время процесса воспроизведения. Можно сказать, что необходимой системой для игр с синхронизацией кадров является система повторов.
Здесь рекомендуется RevenantX/LiteNetLib. Эта библиотека очень мощная и простая в использовании. Она обеспечивает надежную передачу UDP, а это именно то, что мне нужно. Существует множество протоколов данных на выбор для сетевой связи. Я использую самодельный протокол двоичного потока. Основные функции — сериализация и десериализация. Поля в структуре являются необязательными. Как эта структура PtRoom:
//Template auto generator:[AutoGenPt] v1.0
//Creation time:2021/1/28 16:43:48
using System ;
using System . Collections ;
using System . Collections . Generic ;
namespace Net . Pt
{
public class PtRoom
{
public byte __tag__ { get ; private set ; }
public uint RoomId { get ; private set ; }
public byte Status { get ; private set ; }
public uint MapId { get ; private set ; }
public string RoomOwnerUserId { get ; private set ; }
public byte MaxPlayerCount { get ; private set ; }
public List < PtRoomPlayer > Players { get ; private set ; }
public PtRoom SetRoomId ( uint value ) { RoomId = value ; __tag__ |= 1 ; return this ; }
public PtRoom SetStatus ( byte value ) { Status = value ; __tag__ |= 2 ; return this ; }
public PtRoom SetMapId ( uint value ) { MapId = value ; __tag__ |= 4 ; return this ; }
public PtRoom SetRoomOwnerUserId ( string value ) { RoomOwnerUserId = value ; __tag__ |= 8 ; return this ; }
public PtRoom SetMaxPlayerCount ( byte value ) { MaxPlayerCount = value ; __tag__ |= 16 ; return this ; }
public PtRoom SetPlayers ( List < PtRoomPlayer > value ) { Players = value ; __tag__ |= 32 ; return this ; }
public bool HasRoomId ( ) { return ( __tag__ & 1 ) == 1 ; }
public bool HasStatus ( ) { return ( __tag__ & 2 ) == 2 ; }
public bool HasMapId ( ) { return ( __tag__ & 4 ) == 4 ; }
public bool HasRoomOwnerUserId ( ) { return ( __tag__ & 8 ) == 8 ; }
public bool HasMaxPlayerCount ( ) { return ( __tag__ & 16 ) == 16 ; }
public bool HasPlayers ( ) { return ( __tag__ & 32 ) == 32 ; }
public static byte [ ] Write ( PtRoom data )
{
using ( ByteBuffer buffer = new ByteBuffer ( ) )
{
buffer . WriteByte ( data . __tag__ ) ;
if ( data . HasRoomId ( ) ) buffer . WriteUInt32 ( data . RoomId ) ;
if ( data . HasStatus ( ) ) buffer . WriteByte ( data . Status ) ;
if ( data . HasMapId ( ) ) buffer . WriteUInt32 ( data . MapId ) ;
if ( data . HasRoomOwnerUserId ( ) ) buffer . WriteString ( data . RoomOwnerUserId ) ;
if ( data . HasMaxPlayerCount ( ) ) buffer . WriteByte ( data . MaxPlayerCount ) ;
if ( data . HasPlayers ( ) ) buffer . WriteCollection ( data . Players , ( element ) => PtRoomPlayer . Write ( element ) ) ;
return buffer . Getbuffer ( ) ;
}
}
public static PtRoom Read ( byte [ ] bytes )
{
using ( ByteBuffer buffer = new ByteBuffer ( bytes ) )
{
PtRoom data = new PtRoom ( ) ;
data . __tag__ = buffer . ReadByte ( ) ;
if ( data . HasRoomId ( ) ) data . RoomId = buffer . ReadUInt32 ( ) ;
if ( data . HasStatus ( ) ) data . Status = buffer . ReadByte ( ) ;
if ( data . HasMapId ( ) ) data . MapId = buffer . ReadUInt32 ( ) ;
if ( data . HasRoomOwnerUserId ( ) ) data . RoomOwnerUserId = buffer . ReadString ( ) ;
if ( data . HasMaxPlayerCount ( ) ) data . MaxPlayerCount = buffer . ReadByte ( ) ;
if ( data . HasPlayers ( ) ) data . Players = buffer . ReadCollection ( ( rBytes ) => PtRoomPlayer . Read ( rBytes ) ) ;
return data ;
}
}
}
}
Это проект Unity, основанный на синхронизации кадров.
Некоторые инструменты: инструмент генерации структуры Pt, инструмент генерации Excel2Json, проект общей библиотеки, проект библиотеки ServerDll.
Проектная документация: эскизная документация, проектная документация прототипа, конфигурационные таблицы.
Следующие три рисунка описывают использование симулятора синхронизации кадров в трех различных сценариях.
На рисунке ниже показано общее поведение клиента и сервера одновременно, и логика воспроизведения также соответствует такому же поведению.
На этом рисунке показана логика выполнения клиента и сервера в каждом логическом TICK. Верхняя часть — это клиент. Логика, которую должен выполнять клиент, включает часть ECSR, а нижняя часть — серверную часть.
Последняя картинка описывает каждый логический кадр воспроизведения.
С помощью этих изображений и конкретных типов игр мы можем настроить собственную систему и компонент для обработки связанной логики.
Это проект сбора сервисов, включая WebServer, GateServer, RoomServer и т. д.