Асинхронный мультиплеер
С помощью модуля 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()
. В нем происходят стартовая инициализация и загрузка игровых сессий оппонентов.
Метод возвращает массив загруженных сессий.
Параметр count
определяет количество сессий для загрузки. Максимальное количество сессий в ответе — 10 шт.
Для выборки используются параметры meta1
, meta2
, meta3
. Они имеют форму объектов { min: %number%, max: %number% }
и задаются при сохранении сессии. К примеру, если в meta1
хранится счет в игре, а в meta2
— уровень игрока, вы можете загрузить сохраненные сессии, близкие по этим параметрам текущему пользователю.
Важно
Для загрузки сессий необходимо задать как минимум один из трех meta
-параметров, а также значение параметра count
больше нуля. В ином случае мультиплеер будет проинициализирован только на запись.
ysdk.multiplayer.sessions.init({
count: 2, // Количество сессий оппонентов для загрузки (до 10).
isEventBased: true, // Флаг для инициализации работы через события.
maxOpponentTurnTime: 200, // Ограничение времени хода оппонента (мс).
meta: {
meta1: {
min: 0,
max: 6000,
},
meta2: {
min: 2,
max: 10,
},
},
}).then(opponents => console.log(opponents));
const work = async () => {
const opponents = await ysdk.multiplayer.sessions.init({
count: 2, // Количество сессий оппонентов для загрузки (до 10).
isEventBased: true, // Флаг для инициализации работы через события.
maxOpponentTurnTime: 200, // Ограничение времени хода оппонента (мс).
meta: {
meta1: {
min: 0,
max: 6000,
},
meta2: {
min: 2,
max: 10,
},
},
});
console.log(opponents);
}
work();
Формат ответа
[
{
id: string;
meta: {
meta1: number;
meta2: number;
meta3: number;
};
player: {
avatar: string;
name: string;
};
timeline: [
{
id: string;
payload: object | string | undefined;
time: number;
},
...
];
},
...
]
Параметр |
Тип |
Описание |
|
string |
Идентификатор сессии. |
|
object |
Пользовательские параметры |
|
object |
Информация об игроке-сопернике:
|
|
array |
Массив событий с таймингом, описывающий игровую сессию:
|
Запись игровой сессии
Внимание
Максимальный размер одной записанной сессии — 200 КБ.
Используйте SDK, чтобы записать игровые сессии пользователей (последовательность событий с метками времени). Событиями могут быть перемещения фигур на доске в головоломках или нажатие клавиш клавиатуры или мыши в раннерах.
В играх, где пользовательский ввод непрерывный, например в раннерах, события могут формироваться искусственно в заданный интервал времени, фиксируя показатели состояния персонажа — координаты, уровень энергии и т. д. Также это могут быть случайные события в игре — вознаграждения, землетрясения.
События, происходящие в игре, сохраняются в виде транзакций. У каждой транзакции есть:
id
— уникальный идентификатор события;payload
— данные события: информация, отражающая суть, причину изменений в игровом мире (например, новые координаты персонажа или нажатие кнопки мыши);time
— время от начала игры с поправкой на паузы.
В течение игры сохраняйте payload
с помощью метода commit(). Так сформируется список транзакций — таймлайн игровой сессии (timeline
).
В конце игры сохраните сессию на сервере с помощью метода push(). После сохранения сессия может быть загружена и воспроизведена в следующей игре.
ysdk.multiplayer.sessions.commit()
Метод commit()
фиксирует транзакции текущей игровой сессии. В него передаются данные события (payload).
Важно
Другие параметры транзакции — идентификатор (id
) и время от начала игры (time
) — рассчитываются в SDK, поэтому важно отправлять payload
своевременно.
Пример использования
// Первая транзакция.
ysdk.multiplayer.sessions.commit({ x: 1, y: 2, z: 3, health: 67 });
// .......
// Следующая транзакция.
ysdk.multiplayer.sessions.commit({ x: 4, y: -2, z: 19, health: 15 });
// .......
ysdk.multiplayer.sessions.push()
Метод 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
с идентификатором соперника, чья игра закончилась.
ysdk.multiplayer.sessions.init({
count: 2, // Количество сессий оппонентов для загрузки (до 10).
isEventBased: true, // Флаг для инициализации работы через события.
maxOpponentTurnTime: 200, // Ограничение времени хода оппонента (мс).
meta: {
meta1: {
min: 0,
max: 6000,
},
meta2: {
min: 2,
max: 10,
},
},
});
// Здесь приходит массив транзакций для выполнения в данный момент времени:
// текущая транзакция, а также транзакции, отставшие из-за возможных фризов игры.
ysdk.on('multiplayer-sessions-transaction', ({ opponentId, transactions }) = > {
console.log(opponentId, transactions);
// Применение данных transaction.payload на игровом поле.
});
ysdk.on('multiplayer-sessions-finish', (opponentId) => console.log(opponentId));
Старт и пауза мультиплеера управляются методами разметки геймплея:
// Старт мультиплеера.
ysdk.features.GameplayAPI.start();
// Пауза мультиплеера.
ysdk.features.GameplayAPI.stop();
Метод инициализации мультиплеера init() возвращает массив загруженных сессий оппонентов, содержащих в себе таймлайны с транзакциями.
Получите данные и обработайте их самостоятельно:
const start = (opponent) => {
console.log('player', opponent.player);
console.log('timeline', opponent.timeline);
// Реализация механизма использования данных timeline и player.
}
const work = async () => {
const opponents = await ysdk.multiplayer.sessions.init({
count: 2, // Количество сессий оппонентов для загрузки (до 10).
isEventBased: false, // Флаг для инициализации работы через события.
maxOpponentTurnTime: 200, // Ограничение времени хода оппонента (мс).
meta: {
meta1: {
min: 0,
max: 6000,
},
meta2: {
min: 2,
max: 10,
},
},
});
console.log('opponents', opponents);
for (let i = 0; i < opponents.length; i++) {
start(opponents[i]);
}
}
work();
Примечание
Сотрудники службы поддержки помогают разместить готовую игру на платформе Яндекс Игр. На прикладные вопросы о разработке и тестировании предметно ответят другие разработчики в Сообществе в Телеграме.
Если при использовании SDK Яндекс Игр вы столкнулись с проблемой или у вас появился вопрос, обратитесь в службу поддержки:
Идентификатор сессии.
Пользовательские параметры meta1
, meta2
, meta3
, которые задаются при сохранении сессии. Например, счет в игре или уровень игрока.
Информация об игроке-сопернике:
avatar: string
— URL аватара пользователя;name: string
— имя игрока.
Массив событий с таймингом, описывающий игровую сессию:
id: string
— уникальный идентификатор события;payload
— данные события: информация, отражающая суть, причину изменений в игровом мире (например, новые координаты персонажа или нажатие кнопки мыши);time: number
— время от начала игры с поправкой на паузы (мс).
Уникальный идентификатор события.
Данные события: информация, отражающая суть, причину изменений в игровом мире (например, новые координаты персонажа или нажатие кнопки мыши).
Время от начала игры с поправкой на паузы.