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

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

  • 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 — время от начала игры с поправкой на паузы (мс).

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

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

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

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