---
metadata:
  - name: generator
    content: Diplodoc Platform v5.66.0
alternate:
  - https://yandex.com/dev/games/doc/en/sdk/sdk-multiplayer-sessions.md
  - https://yandex.com/dev/games/doc/hi/sdk/sdk-multiplayer-sessions.md
  - https://yandex.com/dev/games/doc/ko/sdk/sdk-multiplayer-sessions.md
  - https://yandex.com/dev/games/doc/ru/sdk/sdk-multiplayer-sessions.md
  - https://yandex.com/dev/games/doc/tr/sdk/sdk-multiplayer-sessions.md
  - https://yandex.com/dev/games/doc/vi/sdk/sdk-multiplayer-sessions.md
  - https://yandex.com/dev/games/doc/zh/sdk/sdk-multiplayer-sessions.md
  - href: https://yandex.com/dev/games/doc/en/sdk/sdk-multiplayer-sessions.md
    type: text/markdown
    title: Markdown version
  - href: https://yandex.com/dev/games/doc/en/llms.txt?revision=r21993288
    rel: describedby
---
> **Documentation Index:** Fetch the complete configuration index at https://yandex.com/dev/games/doc/en/llms.txt?revision=r21993288

# Asynchronous multiplayer

<!-- source: en/_includes/script-common.md -->
<!-- source: en/_includes/script/index-js.md -->

<!-- endsource: en/_includes/script/index-js.md -->

<!-- source: en/_includes/script/requirements-js.md -->

<!-- endsource: en/_includes/script/requirements-js.md -->

<!-- source: en/_includes/script/image-modal-js.md -->

<!-- endsource: en/_includes/script/image-modal-js.md -->
<!-- endsource: en/_includes/script-common.md -->

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!](https://yandex.com/games/app/211144){.external} (by KosmosGames), [Match Arena - Match 3!](https://yandex.com/games/app/96787){.external} (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](https://yandex.com/games/app/374739){.external} (by JL studio) in "Fast Race" mode, [Wild Bikes](https://yandex.com/games/app/233231){.external} (by haoda games).
- **Strategy and auto-battlers**: you can create battles against other players' tactics. Examples of suitable games: [Ludus](https://yandex.com/games/app/376147){.external} (by Positron Dynamics), [Like a King](https://yandex.com/games/app/140656){.external} (by Vladimir Saponenko), [TOYS: Crash Arena](https://yandex.com/games/app/291515){.external} (by Mad Pixel).



## Concept {#concept}

1. User A plays, SDK records key events (key presses, state changes) and timestamps them.
2. These events are stored on the server as a timeline (a list of transactions).
3. When User B starts the game, opponents from the already saved timelines are loaded into their session.
4. The SDK reproduces the opponents' actions in real time, creating the impression of simultaneous play.



## Initialization and Session Loading {#init}

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](#response-format).

Accepts parameters:

#|
|| **Parameter** | **Type** | **Description** ||
|| `count` | `number` | Determines the number of sessions to load. The maximum number of sessions in the response is 10. ||
|| `isEventBased` | `boolean` | Flag for [initializing](#use) via events. ||
|| `maxOpponentTurnTime` | `number` | Limits the opponent's turn time and sets the maximum interval between sending `multiplayer-sessions-transaction` events in milliseconds. If specified, each opponent's turn that lasts longer than `maxOpponentTurnTime` will be shortened to the specified value. By default, the opponent's turn time is unlimited.

{% cut "Example of `maxOpponentTurnTime` in action" %}

The opponent in the recorded session made moves at intervals of 2–10 seconds, and the value of the `maxOpponentTurnTime` parameter is 5000 ms. In this case, all actions of this opponent, regardless of the initial move duration, will occur no later than 5 seconds.

{% endcut %} ||
|| `meta` | `object` | The custom 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](#push). 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. ||
|#

{% note 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.

{% endnote %}

{% list tabs %}

- Request example

  ```javascript showLineNumbers
  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](*meta): {
          meta1: {
              min: 0,
              max: 6000
          },
          meta2: {
              min: 2,
              max: 10
          }
      }
  }).then((opponents) => console.log(opponents));
  ```

- Request example using ES2017 async/await

  ```javascript showLineNumbers
  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](*meta): {
              meta1: {
                  min: 0,
                  max: 6000
              },
              meta2: {
                  min: 2,
                  max: 10
              }
          }
      });

      console.log(opponents);
  };

  work();
  ```

{% endlist %}

#### Response format {#response-format}

```javascript showLineNumbers
[
    {
        [id](*id): string;
        [meta](*meta): {
            meta1: number;
            meta2: number;
            meta3: number;
        };
        [player](*player): {
            avatar: string;
            name: string;
        };
        [timeline](*timeline): [
            {
                [id](*timeline_id): string;
                [payload](*payload): object | string | undefined;
                [time](*time): number;
            },
            ...
        ];
    },
    ...
]
```

#|
|| **Parameter** | **Type** | **Description** ||
|| `id` | `string` | Session identifier. ||
|| `meta` | `object` | Custom parameters `meta1`, `meta2`, `meta3`. For example, game score or player level. ||
|| `player` | `object` | Information about the opponent player:
- `avatar: string` — URL of the user's avatar;
- `name: string` — player's name.
||
|| `timeline` | `array` | Array of events with timing information describing the game session:
- `id: string` — unique event identifier;
- `payload` — event data: information that reflects the essence or cause of changes in the game world (e.g., new character coordinates or mouse click);
- `time: number` — time from the start of the game adjusted for pauses (ms).
||
|#



## Recording Game Session {#record}

{% note alert %}

The maximum size of a single recorded session is 200 KB.

{% endnote %}

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 with continuous user input, such as runners, events can be generated artificially at a set time interval, recording character state indicators — coordinates, energy level, etc. These can also be random in-game events — rewards, earthquakes.

Events occurring in the game are saved as transactions. Each transaction includes:

#|
|| **Parameter** | **Type** | **Description** ||
|| `id` | `number` | A unique event identifier. ||
|| `payload` | `object` | Event data: information reflecting the essence or reason for changes in the game world (e.g., new character coordinates or a mouse button press). An object with key-value pairs. ||
|| `time` | `number` | Time elapsed since the start of the game, adjusted for pauses. ||
|#

During the game, save the `payload` using the [commit()](#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()](#push) method. Once saved, the session can be loaded and replayed in a subsequent game.


### ysdk.multiplayer.sessions.commit() {#commit}

The method finalizes transactions of the current game session. It takes event data ([payload](*payload)) as an argument.

{% note 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.

{% endnote %}

#### Example {#commit-ex}

```javascript showLineNumbers
// 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() {#push}

The 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](*meta) must be defined.

#### Usage example {#push-ex}

```javascript
ysdk.multiplayer.sessions.push({ meta1: 12, meta2: -2 });
```


## Working with Sessions {#use}

To choose how to work with loaded opponent sessions, pass the desired value of the `isEventBased` flag to the [init()](#init) method:

#|
|| **Value** | **Description** ||
|| `isEventBased: true` | Event-based operation. ||
|| `isEventBased: false` | Manual processing. ||
|#

{% list tabs %}

- Event-based

  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()](#init) method).

  - When the session ends, the `multiplayer-sessions-finish` handler is called with the identifier of the opponent whose game has finished.

  ```javascript showLineNumbers
  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](*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](https://yandex.com/dev/games/doc/en/sdk/sdk-game-events.md#gameplay) methods:

  ```javascript showLineNumbers
  // Start multiplayer.
  ysdk.features.GameplayAPI.start();

  // Pause multiplayer.
  ysdk.features.GameplayAPI.stop();
  ```

- Your own solution

  The multiplayer initialization method [init()](#init) returns an array of loaded opponent sessions that contain timelines with transactions.

  Retrieve the data and process it yourself:

  ```javascript showLineNumbers
  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](*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();
  ```

{% endlist %}


---

<!-- source: en/_includes/sdk/sdk-support.md -->
{% note info %}

Support staff help you publish a ready-made game on the Yandex Games platform. For applied questions about development and testing, other developers will answer in the [Discord community](https://discord.com/invite/wU4p3whr4T){.external}.

{% endnote %}

If you encounter a problem or have a question while using the Yandex Games SDK, contact support:

<!-- source: en/_includes/button-chat.md -->
<a href="https://yandex.com/chat/#/user/a4fa5c06-75db-9b38-6eea-b1673785f7d5">
  <span class="button">Write to chat</span>
</a>
<!-- endsource: en/_includes/button-chat.md -->
<!-- endsource: en/_includes/sdk/sdk-support.md -->

[*id]: Session identifier.

[*meta]: Custom parameters `meta1`, `meta2`, `meta3`, set when saving the session. For example, the game score or player level.

[*player]: Information about the opposing player:
- `avatar: string` — URL of the user's avatar;
- `name: string` — the player's name.

[*timeline]: 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).

[*timeline_id]: 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]: Time from the beginning of the game adjusted for pauses.