Асинхронный мультиплеер
С помощью модуля ysdk.multiplayer вы можете создать соревновательный режим, похожий на онлайн-мультиплеер. При этом вам не нужно:
- писать и поддерживать собственное серверное решение;
- иметь критическую массу игроков, необходимую для быстрого поиска соперников.
Примеры жанров, кор-механику которых можно реализовать через SDK:
- Головоломки: асинхронные сессии могут воспроизводиться на соседних игровых полях, можно добавить соперничество по времени или по очкам. Примеры подходящих игр: Косынка Онлайн! (от KosmosGames), Match Arena - Три в Ряд! (от PecPoc Piggy).
- Раннеры и гонки: сессии соперников могут отрисовываться в виде «теней», перемещающихся по уровню одновременно с игроком (механика ghost driver). Примеры подходящих игр: Дикие Тачки 2 (от JL studio) в режиме «Скоростная Гонка», Дикие мотоциклы (от haoda games).
- Стратегии и автобаттлеры: можно реализовать бои против тактик других игроков. Примеры подходящих игр: Ludus (от Positron Dynamics), Like a King (от Vladimir Saponenko), TOYS: Crash Arena (от Mad Pixel).
Концепция
- Пользователь А играет, SDK записывает ключевые события (нажатия клавиш, изменения состояния) и фиксирует их время.
- Эти события сохраняются на сервере как таймлайн (список транзакций).
- Когда пользователь Б запускает игру, в его сессию загружаются соперники из уже сохраненных таймлайнов.
- SDK воспроизводит действия соперников в реальном времени, создавая ощущение одновременной игры.
Инициализация и загрузка сессий
Чтобы начать работу с асинхронным мультиплеером, вызовите метод ysdk.multiplayer.sessions.init(). В нем происходят стартовая инициализация и загрузка игровых сессий оппонентов.
Метод возвращает массив загруженных сессий.
Принимает параметры:
|
Параметр |
Тип |
Описание |
|
|
|
Определяет количество сессий для загрузки. Максимальное количество сессий в ответе — 10 шт. |
|
|
|
Флаг для инициализации работы через события. |
|
|
|
Ограничивает время хода оппонента и задает максимальный интервал между отправками событий Пример работы |
|
|
|
Пользовательские параметры |
Важно
Для загрузки сессий необходимо задать как минимум один из трех meta-параметров, а также значение параметра count больше нуля. В ином случае мультиплеер будет проинициализирован только на запись.
1ysdk.multiplayer.sessions.init({
2 count: 2, // Количество сессий оппонентов для загрузки (до 10).
3 isEventBased: true, // Флаг для инициализации работы через события.
4 maxOpponentTurnTime: 200, // Ограничение времени хода оппонента (мс).
5 meta: {
6 meta1: {
7 min: 0,
8 max: 6000,
9 },
10 meta2: {
11 min: 2,
12 max: 10,
13 },
14 },
15}).then(opponents => console.log(opponents));
1const work = async () => {
2 const opponents = await ysdk.multiplayer.sessions.init({
3 count: 2, // Количество сессий оппонентов для загрузки (до 10).
4 isEventBased: true, // Флаг для инициализации работы через события.
5 maxOpponentTurnTime: 200, // Ограничение времени хода оппонента (мс).
6 meta: {
7 meta1: {
8 min: 0,
9 max: 6000,
10 },
11 meta2: {
12 min: 2,
13 max: 10,
14 },
15 },
16 });
17
18 console.log(opponents);
19}
20
21work();
Формат ответа
1[
2 {
3 id: string;
4 meta: {
5 meta1: number;
6 meta2: number;
7 meta3: number;
8 };
9 player: {
10 avatar: string;
11 name: string;
12 };
13 timeline: [
14 {
15 id: string;
16 payload: object | string | undefined;
17 time: number;
18 },
19 ...
20 ];
21 },
22 ...
23]
|
Параметр |
Тип |
Описание |
|
|
|
Идентификатор сессии. |
|
|
|
Пользовательские параметры |
|
|
|
Информация об игроке-сопернике:
|
|
|
|
Массив событий с таймингом, описывающий игровую сессию:
|
Запись игровой сессии
Внимание
Максимальный размер одной записанной сессии — 200 КБ.
Используйте SDK, чтобы записать игровые сессии пользователей (последовательность событий с метками времени). Событиями могут быть перемещения фигур на доске в головоломках или нажатие клавиш клавиатуры или мыши в раннерах.
В играх, где пользовательский ввод непрерывный, например в раннерах, события могут формироваться искусственно в заданный интервал времени, фиксируя показатели состояния персонажа — координаты, уровень энергии и т. д. Также это могут быть случайные события в игре — вознаграждения, землетрясения.
События, происходящие в игре, сохраняются в виде транзакций. У каждой транзакции есть:
|
Параметр |
Тип |
Описание |
|
|
|
Уникальный идентификатор события. |
|
|
|
Данные события: информация, отражающая суть, причину изменений в игровом мире (например, новые координаты персонажа или нажатие кнопки мыши). Объект с парами «ключ — значение». |
|
|
|
Время от начала игры с поправкой на паузы. |
В течение игры сохраняйте payload с помощью метода commit(). Так сформируется список транзакций — таймлайн игровой сессии (timeline).
В конце игры сохраните сессию на сервере с помощью метода push(). После сохранения сессия может быть загружена и воспроизведена в следующей игре.
ysdk.multiplayer.sessions.commit()
Метод фиксирует транзакции текущей игровой сессии. В него передаются данные события (payload).
Важно
Другие параметры транзакции — идентификатор (id) и время от начала игры (time) — рассчитываются в SDK, поэтому важно отправлять payload своевременно.
Пример
1// Первая транзакция.
2ysdk.multiplayer.sessions.commit({ x: 1, y: 2, z: 3, health: 67 });
3
4// .......
5
6// Следующая транзакция.
7ysdk.multiplayer.sessions.commit({ x: 4, y: -2, z: 19, health: 15 });
8
9// .......
ysdk.multiplayer.sessions.push()
Метод используется для сохранения таймлайна на удаленном сервере. Вызывается по завершению игры.
Значения meta1, meta2, meta3 задаются при сохранении сессии. Как минимум один из meta-параметров должен быть определен.
Пример
ysdk.multiplayer.sessions.push({ meta1: 12, meta2: -2 });
Работа с сессиями
Чтобы выбрать, как работать с загруженными сессиями оппонентов, в метод init() передайте нужное значение флага isEventBased:
true— работа через события;false— самостоятельная обработка.
Клиент подписывается на события multiplayer-sessions-transaction и multiplayer-sessions-finish через ysdk.on(), а SDK сам загружает общую сессию и выдает события по указанным в ней временным меткам:
-
Во время игры транзакции соперников приходят в обработчик
multiplayer-sessions-transactionв записанный момент от начала сессии, но с учетом ограничения времени хода оппонента (maxOpponentTurnTime, параметр метода init()). -
Когда сессия заканчивается, вызывается обработчик
multiplayer-sessions-finishс идентификатором соперника, чья игра закончилась.
1ysdk.multiplayer.sessions.init({
2 count: 2, // Количество сессий оппонентов для загрузки (до 10).
3 isEventBased: true, // Флаг для инициализации работы через события.
4 maxOpponentTurnTime: 200, // Ограничение времени хода оппонента (мс).
5 meta: {
6 meta1: {
7 min: 0,
8 max: 6000,
9 },
10 meta2: {
11 min: 2,
12 max: 10,
13 },
14 },
15});
16
17// Здесь приходит массив транзакций для выполнения в данный момент времени:
18// текущая транзакция, а также транзакции, отставшие из-за возможных фризов игры.
19ysdk.on('multiplayer-sessions-transaction', ({ opponentId, transactions }) = > {
20 console.log(opponentId, transactions);
21 // Применение данных transaction.payload на игровом поле.
22});
23
24ysdk.on('multiplayer-sessions-finish', (opponentId) => console.log(opponentId));
Старт и пауза мультиплеера управляются методами разметки геймплея:
1// Старт мультиплеера.
2ysdk.features.GameplayAPI.start();
3
4// Пауза мультиплеера.
5ysdk.features.GameplayAPI.stop();
Метод инициализации мультиплеера init() возвращает массив загруженных сессий оппонентов, содержащих в себе таймлайны с транзакциями.
Получите данные и обработайте их самостоятельно:
1const start = (opponent) => {
2 console.log('player', opponent.player);
3 console.log('timeline', opponent.timeline);
4
5 // Реализация механизма использования данных timeline и player.
6}
7
8const work = async () => {
9 const opponents = await ysdk.multiplayer.sessions.init({
10 count: 2, // Количество сессий оппонентов для загрузки (до 10).
11 isEventBased: false, // Флаг для инициализации работы через события.
12 maxOpponentTurnTime: 200, // Ограничение времени хода оппонента (мс).
13 meta: {
14 meta1: {
15 min: 0,
16 max: 6000,
17 },
18 meta2: {
19 min: 2,
20 max: 10,
21 },
22 },
23 });
24
25 console.log('opponents', opponents);
26
27 for (let i = 0; i < opponents.length; i++) {
28 start(opponents[i]);
29 }
30}
31
32work();
Примечание
Сотрудники службы поддержки помогают разместить готовую игру на платформе Яндекс Игр. На прикладные вопросы о разработке и тестировании предметно ответят другие разработчики в Сообществе в Телеграме.
Если при использовании SDK Яндекс Игр вы столкнулись с проблемой или у вас появился вопрос, обратитесь в службу поддержки:
Идентификатор сессии.
Пользовательские параметры meta1, meta2, meta3, которые задаются при сохранении сессии. Например, счет в игре или уровень игрока.
Информация об игроке-сопернике:
avatar: string— URL аватара пользователя;name: string— имя игрока.
Массив событий с таймингом, описывающий игровую сессию:
id: string— уникальный идентификатор события;payload— данные события: информация, отражающая суть, причину изменений в игровом мире (например, новые координаты персонажа или нажатие кнопки мыши);time: number— время от начала игры с поправкой на паузы (мс).
Уникальный идентификатор события.
Данные события: информация, отражающая суть, причину изменений в игровом мире (например, новые координаты персонажа или нажатие кнопки мыши).
Время от начала игры с поправкой на паузы.