Асинхронный мультиплеер

С помощью модуля 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).

Концепция

  1. Пользователь А играет, SDK записывает ключевые события (нажатия клавиш, изменения состояния) и фиксирует их время.
  2. Эти события сохраняются на сервере как таймлайн (список транзакций).
  3. Когда пользователь Б запускает игру, в его сессию загружаются соперники из уже сохраненных таймлайнов.
  4. SDK воспроизводит действия соперников в реальном времени, создавая ощущение одновременной игры.

Инициализация и загрузка сессий

Чтобы начать работу с асинхронным мультиплеером, вызовите метод ysdk.multiplayer.sessions.init(). В нем происходят стартовая инициализация и загрузка игровых сессий оппонентов.

Метод возвращает массив загруженных сессий.

Принимает параметры:

Параметр

Тип

Описание

count

number

Определяет количество сессий для загрузки. Максимальное количество сессий в ответе — 10 шт.

isEventBased

boolean

Флаг для инициализации работы через события.

maxOpponentTurnTime

number

Ограничивает время хода оппонента и задает максимальный интервал между отправками событий multiplayer-sessions-transaction в миллисекундах. Если он указан, то каждый ход противника, длившийся больше maxOpponentTurnTime, сократится до указанного значения. По умолчанию время хода оппонента не ограничено.

Пример работы maxOpponentTurnTime

Оппонент в записанной сессии совершал ходы с интервалом в 2–10 секунд, значение параметра maxOpponentTurnTime — 5000 мс. В этом случае все действия этого оппонента, независимо от изначальной длительности хода, произойдут не позднее, чем через 5 секунд.

meta

object

Пользовательские параметры meta1, meta2, meta3, которые используются для выборки. Они имеют форму объектов { min: %number%, max: %number% } и задаются при сохранении сессии. К примеру, если в meta1 хранится счет в игре, а в meta2 — уровень игрока, вы можете загрузить сохраненные сессии, близкие по этим параметрам текущему пользователю.

Важно

Для загрузки сессий необходимо задать как минимум один из трех 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]

Параметр

Тип

Описание

id

string

Идентификатор сессии.

meta

object

Пользовательские параметры meta1, meta2, meta3. Например, счет в игре или уровень игрока.

player

object

Информация об игроке-сопернике:

  • avatar: string — URL аватара пользователя;
  • name: string — имя игрока.

timeline

array

Массив событий с таймингом, описывающий игровую сессию:

  • id: string — уникальный идентификатор события;
  • payload — данные события: информация, отражающая суть, причину изменений в игровом мире (например, новые координаты персонажа или нажатие кнопки мыши);
  • time: number — время от начала игры с поправкой на паузы (мс).

Запись игровой сессии

Внимание

Максимальный размер одной записанной сессии — 200 КБ.

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

В играх, где пользовательский ввод непрерывный, например в раннерах, события могут формироваться искусственно в заданный интервал времени, фиксируя показатели состояния персонажа — координаты, уровень энергии и т. д. Также это могут быть случайные события в игре — вознаграждения, землетрясения.

События, происходящие в игре, сохраняются в виде транзакций. У каждой транзакции есть:

Параметр

Тип

Описание

id

number

Уникальный идентификатор события.

payload

object

Данные события: информация, отражающая суть, причину изменений в игровом мире (например, новые координаты персонажа или нажатие кнопки мыши). Объект с парами «ключ — значение».

time

number

Время от начала игры с поправкой на паузы.

В течение игры сохраняйте 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:

Значение

Описание

isEventBased: true

Работа через события.

isEventBased: 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 Яндекс Игр вы столкнулись с проблемой или у вас появился вопрос, обратитесь в службу поддержки:

Написать в чат Написать в MAX

Идентификатор сессии.

Пользовательские параметры meta1, meta2, meta3, которые задаются при сохранении сессии. Например, счет в игре или уровень игрока.

Информация об игроке-сопернике:

  • avatar: string — URL аватара пользователя;
  • name: string — имя игрока.

Массив событий с таймингом, описывающий игровую сессию:

  • id: string — уникальный идентификатор события;
  • payload — данные события: информация, отражающая суть, причину изменений в игровом мире (например, новые координаты персонажа или нажатие кнопки мыши);
  • time: number — время от начала игры с поправкой на паузы (мс).

Уникальный идентификатор события.

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

Время от начала игры с поправкой на паузы.

Предыдущая
Следующая