Asynchronous multiplayer
With the ysdk.multiplayer
module, you can create a competitive mode similar to online multiplayer. This means you don't need to:
- write and maintain your own server solution;
- have a critical mass of players necessary for fast opponent matching.
Examples of genres whose core mechanics can be implemented via the SDK:
- Puzzles: asynchronous sessions can be played on adjacent game boards, and you can add competition based on time or scores. Examples of suitable games: Solitaire Online! (by KosmosGames), Match Arena - Match 3! (by PecPoc Piggy).
- Runners and races: opponents' sessions can be displayed as "ghosts" moving along the level simultaneously with the player (ghost driver mechanic). Examples of suitable games: Wild Racing 2 (by JL studio) in "Fast Race" mode, Wild Bikes (by haoda games).
- Strategy and auto-battlers: you can create battles against other players' tactics. Examples of suitable games: Ludus (by Positron Dynamics), Like a King (by Vladimir Saponenko), TOYS: Crash Arena (by Mad Pixel).
Concept
- User A plays, SDK records key events (key presses, state changes) and timestamps them.
- These events are stored on the server as a timeline (a list of transactions).
- When User B starts the game, opponents from the already saved timelines are loaded into their session.
- The SDK reproduces the opponents' actions in real time, creating the impression of simultaneous play.
Initialization and Session Loading
To start working with asynchronous multiplayer, call the ysdk.multiplayer.sessions.init()
method. This handles initial initialization and loading of the opponents' game sessions.
The method returns an array of loaded sessions.
The count
parameter determines the number of sessions to load. The maximum number of sessions in the response is 10.
The parameters meta1
, meta2
, meta3
are used for selection. They are objects in the form { min: %number%, max: %number% }
and are set when saving a session. For example, if meta1
stores the game score and meta2
stores the player's level, you can load saved sessions that are close to these parameters of the current user.
Warning
To load sessions, you need to set at least one of the three meta
parameters and ensure the count
value is greater than zero. Otherwise, multiplayer will be initialized only for recording.
ysdk.multiplayer.sessions.init({
count: 2, // Number of opponent sessions to load (up to 10).
isEventBased: true, // Flag to initialize work through events.
maxOpponentTurnTime: 200, // Opponent's turn time limit (ms).
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, // Number of opponent sessions to load (up to 10).
isEventBased: true, // Flag to initialize work through events.
maxOpponentTurnTime: 200, // Opponent's turn time limit (ms).
meta: {
meta1: {
min: 0,
max: 6000,
},
meta2: {
min: 2,
max: 10,
},
},
});
console.log(opponents);
}
work();
Response format
[
{
id: string;
meta: {
meta1: number;
meta2: number;
meta3: number;
};
player: {
avatar: string;
name: string;
};
timeline: [
{
id: string;
payload: object | string | undefined;
time: number;
},
...
];
},
...
]
Parameter |
Type |
Description |
|
string |
Session identifier. |
|
object |
Custom parameters |
|
object |
Information about the opponent player:
|
|
array |
Array of events with timing information describing the game session:
|
Recording Game Session
Alert
The maximum size of a single recorded session is 200 KB.
Use the SDK to record user game sessions (a sequence of events with timestamps). Events can include moving pieces on a board in puzzles or pressing keyboard or mouse buttons in runners.
In games where user input is continuous, such as runners, events may be artificially generated at set time intervals, capturing character state metrics — coordinates, energy levels, etc. They may also include random events in the game, such as rewards or earthquakes.
Events occurring in the game are saved as transactions. Each transaction includes:
id
— a unique event identifier;payload
— event data: information reflecting the essence or reason for changes in the game world (e.g., new character coordinates or a mouse button press);time
— time elapsed since the start of the game, adjusted for pauses.
During the game, save the payload
using the commit() method. This will form a list of transactions—a timeline of the game session (timeline
).
At the end of the game, save the session on a server using the push() method. Once saved, the session can be loaded and replayed in a subsequent game.
ysdk.multiplayer.sessions.commit()
The commit()
method finalizes transactions of the current game session. It takes event data (payload) as an argument.
Warning
Other transaction parameters — identifier (id
) and time since the start of the game (time
) — are computed in the SDK, so it's important to send the payload
in a timely manner.
Usage example
// The first transaction.
ysdk.multiplayer.sessions.commit({ x: 1, y: 2, z: 3, health: 67 });
// .......
// The next transaction.
ysdk.multiplayer.sessions.commit({ x: 4, y: -2, z: 19, health: 15 });
// .......
ysdk.multiplayer.sessions.push()
The push()
method is used to save the timeline on a remote server. It is called at the end of the game.
The values for meta1
, meta2
, meta3
are set when saving the session. At least one of the meta-parameters must be defined.
Usage example
ysdk.multiplayer.sessions.push({ meta1: 12, meta2: -2 });
Working with Sessions
To choose how to work with loaded opponent sessions, pass the desired value of the isEventBased
flag to the init() method:
true
— event-based operation;false
— manual processing.
The client subscribes to the multiplayer-sessions-transaction
and multiplayer-sessions-finish
events using ysdk.on()
, and the SDK independently loads the general session and issues events at the time stamps indicated in it:
-
During the game, opponent transactions arrive at the
multiplayer-sessions-transaction
handler at the recorded moment from the start of the session, considering the opponent's turn time limit (maxOpponentTurnTime
, a parameter of the init() method). -
When the session ends, the
multiplayer-sessions-finish
handler is called with the identifier of the opponent whose game has finished.
ysdk.multiplayer.sessions.init({
count: 2, // Number of opponent sessions to load (up to 10).
isEventBased: true, // Flag to initialize work through events.
maxOpponentTurnTime: 200, // Opponent's turn time limit (ms).
meta: {
meta1: {
min: 0,
max: 6000,
},
meta2: {
min: 2,
max: 10,
},
},
});
// Here's an array of transactions to be executed at the current time:
// the current transaction, as well as transactions delayed due to possible game freezes.
ysdk.on('multiplayer-sessions-transaction', ({ opponentId, transactions }) = > {
console.log(opponentId, transactions);
// Applying transaction.payload data to the game field.
});
ysdk.on('multiplayer-sessions-finish', (opponentId) => console.log(opponentId));
The start and pause of multiplayer are controlled by gameplay markup methods:
// Start multiplayer.
ysdk.features.GameplayAPI.start();
// Pause multiplayer.
ysdk.features.GameplayAPI.stop();
The multiplayer initialization method init() returns an array of loaded opponent sessions that contain timelines with transactions.
Retrieve the data and process it yourself:
const start = (opponent) => {
console.log('player', opponent.player);
console.log('timeline', opponent.timeline);
// Implementation of the mechanism for using timeline and player data.
}
const work = async () => {
const opponents = await ysdk.multiplayer.sessions.init({
count: 2, // Number of opponent sessions to load (up to 10).
isEventBased: false, // Flag to initialize work through events.
maxOpponentTurnTime: 200, // Opponent's turn time limit (ms).
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();
Note
Our support team can help publish finished games on Yandex Games. If you have any questions about development or testing, ask them in the Discord channel.
If you are facing an issue or have a question regarding the use of Yandex Games SDK, please contact support:
Session identifier.
Custom parameters meta1
, meta2
, meta3
, set when saving the session. For example, the game score or player level.
Information about the opposing player:
avatar: string
— URL of the user's avatar;name: string
— the player's name.
Array of timed events describing the game session:
id: string
— unique event identifier;payload
— event data: information reflecting the essence, reason for changes in the game world (e.g., new character coordinates or mouse button press);time: number
— time from the beginning of the game adjusted for pauses (ms).
Unique event identifier.
Event data: information reflecting the essence, reason for changes in the game world (e.g., new character coordinates or mouse button press).
Time from the beginning of the game adjusted for pauses.