> For the complete documentation index, see [llms.txt](https://docs.edgegap.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.edgegap.com/ru/learn/podbor-igrokov/matchmaker-in-depth.md).

# Подробный обзор

Узнайте подробнее о концепциях no-code матчермейкера Edgegap и настройте их под свои нужды.

{% hint style="info" %}
Если вам нужна помощь, [свяжитесь с нами через Discord](https://discord.gg/MmJf8fWjnt). Для поддержки по играм в реальном времени см. нашу [систему тикетов](https://edgegap.atlassian.net/servicedesk/customer/portal/3).
{% endhint %}

## ✔️ Введение

Матчмейкинг в играх, основанных на матчах, как правило, стремится к следующему:

* **найти других игроков** на основе таких критериев, как регион, задержка, навыки или параметры игры;
* **найти серверы** чтобы подключиться к ним в зависимости от доступной вместимости \[или пинга, региона, навыков, карты, режима];
* **запустить новый сервер** если существующие серверы заполнены или не соответствуют критериям игрока.

Опыт игрока стоит на первом месте, определяя наши основные цели:

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

{% hint style="success" %}
В качестве альтернативы, позвольте игрокам **выбрать постоянный (всегда онлайн) сервер** из списка с [Server Browser](/ru/learn/server-browser.md).
{% endhint %}

**Начните всего за 5 минут и бесплатно протестируйте все функции, кредитная карта не требуется.**

Обновите тариф, когда будете готовы к более мощному, приватному (выделенному) кластеру. Нативная интеграция с Edgegap [Развертывания](/ru/learn/orkestraciya/deployments.md) обеспечивает лучшую в классе задержку пинга независимо от того, где находятся ваши игроки.

{% hint style="info" %}
Бесплатный тариф позволяет 3 часа работы после каждого перезапуска. Ваш матчмейкер будет работать на общей инфраструктуре с ограниченными ресурсами, что подходит для тестирования. **После публичного релиза ваш матчмейкер должен работать 24/7.**
{% endhint %}

Есть три основных концепции для каждого матчмейкера:

* [#hosting-cluster](#hosting-cluster "mention") - базовая серверная инфраструктура, полностью управляемая и обслуживаемая Edgegap.
* [#configuration](#configuration "mention") - набор правил и настроек, определяющих, как работает матчмейкер.
* 🌐 Экземпляр сервиса **-** работающий 24/7 сервис подбора матчей на Кластере, использующий Конфигурацию для объединения игроков и назначения развертываний (серверов).

{% hint style="success" %}
[Часто обновляйте версию своего матчмейкера](#changelog) на **чтобы пользоваться новыми функциями и исправлениями ошибок.**
{% endhint %}

## ▶️ Начать подбор матча

**Начните быстро — добавьте наш стартовый SDK-пример в свою игру**:

* Unreal Engine [Инструменты разработчика](/ru/unreal-engine/developer-tools.md#integration-kit):
  * [прочитать документацию](https://egik.betide.studio/) от Betide Studios,
  * [установить из Fab Marketplace](https://www.fab.com/listings/ff17ad88-12a1-49cf-9a41-31695ed11e16) (бесплатно для личного использования),
  * [импортировать простой пример blueprint](https://blueprintue.com/blueprint/m33u1okj/) (сопоставление игроков) и настроить под свои нужды.
* Unity [Инструменты разработчика](/ru/unity/developer-tools.md#software-development-kit):
  * [установите пакет бесплатно с помощью Unity Package Manager](https://github.com/edgegap/edgegap-unity-sdk),
  * [изучите наше руководство для начала работы и полные примеры](/ru/unity/podbor-igrokov.md).

Изучите процесс подбора матчей, чтобы настраивать, устранять неполадки и оптимизировать интеграцию вашей игры:

<figure><img src="/files/de8d63bab346f3b338118bf18ccbe1eebd021d87" alt=""><figcaption><p>Последовательность подбора матча</p></figcaption></figure>

1. [Аутентифицировать игрока](#authenticate) - не позволяет пиратским копиям играть онлайн,
2. [Создать лобби](#create-group) - объединиться с друзьями и поделиться предпочтениями игрока/матча,
3. [**Сформировать группу**](#group-up) **- зарегистрировать ваше Лобби как Группу подбора матча,**
4. [**Найти матч**](#find-match) **- приготовиться и начать поиск матча (нового или существующего),**
   1. Назначить сервер и внедрить билеты — сервер автоматически назначается через несколько секунд,
5. [**Подключиться и аутентифицироваться**](#connect-to-server) **- попытаться установить защищённое соединение с игровым сервером,**
   1. Подтвердить личность — сервер проверяет личность игрового клиента с помощью токенов сторонних сервисов,
   2. Принять игрока или исключить игрока — сервер решает, может ли игрок присоединиться.

### Аутентификация

Все запросы должны отправлять `Authorization`  HTTP-заголовок с вашим секретом **Токен аутентификации:**

<pre><code>Авторизация: <a data-footnote-ref href="#user-content-fn-1">xxxxxxxx-e458-4592-b607-c2c28afd8b62</a>
</code></pre>

{% hint style="warning" %}
**Храните ваши токены в секрете и в безопасности! Сотрудники Edgegap никогда не будут просить у вас ваши токены.**
{% endhint %}

{% hint style="info" %}
Токен Matchmaker и токены Server Browser являются отдельными от токенов Edgegap API.
{% endhint %}

{% hint style="success" %}
**Этот токен можно безопасно включить в ваш игровой клиент, так как он не даёт доступ к API Edgegap.**
{% endhint %}

Отдельные игроки могут быть идентифицированы по ID своего билета, доступному на клиентах и сервере. При желании добавьте собственную аутентификацию или ограничения с помощью пользовательского прокси через [#server-to-server-api](#server-to-server-api "mention") API.

### Сформировать группу

Создание группы (пати) гарантирует, что игроки вместе со своими друзьями попадут в одну и ту же команду и на один сервер.

{% hint style="success" %}
Создать группу, отмеченную как готовую [#find-match](#find-match "mention") быстро как **игрок-одиночка без членов группы**.
{% endhint %}

<figure><img src="/files/a7d88fc4e7173bede5ae8a8fb24d8cb577d4f854" alt=""><figcaption><p>Диаграмма жизненного цикла группы</p></figcaption></figure>

#### Лобби и группа

Используйте сервис Лобби, если дизайн вашей игры требует задания предпочтений подбора матча под управлением игрока (например, выбор персонажа, сложность, карта и т. д.). По мере того как игроки присоединяются к Лобби и покидают его, они также обновляют Группу подбора матча, чтобы подготовиться к поиску матча позже.

{% hint style="success" %}
**Нет времени на сервис Лобби?** Предложите игрокам делиться ID группы через Discord или личные сообщения.
{% endhint %}

<table><thead><tr><th width="390">Дизайн игры — функция / требование</th><th>Лобби перед матчем</th><th>Группа матчмейкера</th></tr></thead><tbody><tr><td><a data-footnote-ref href="#user-content-fn-2">приглашать друзей играть со мной</a></td><td>✅</td><td>✅</td></tr><tr><td>изменять мои предпочтения игрока/матча</td><td>✅</td><td>❌</td></tr><tr><td>просматривать предпочтения других участников лобби</td><td>✅</td><td>❌</td></tr><tr><td>хранить и управлять пользовательскими данными ключ-значение</td><td>✅</td><td>❌</td></tr><tr><td>уведомлять участников группы о том, что я готов играть</td><td>❌</td><td>✅</td></tr><tr><td>показывать прогресс подбора матча и находить матч</td><td>❌</td><td>✅</td></tr><tr><td>получать назначение команды для игрока/группы</td><td>❌</td><td>✅</td></tr><tr><td>получать данные подключения к игровому серверу</td><td>❌</td><td>✅</td></tr></tbody></table>

Наш кроссплатформенный матчмейкер поддерживает все коммерческие и пользовательские сервисы Лобби:

<table><thead><tr><th>Сервис Лобби (сторонний)</th><th width="120" data-type="checkbox">Unreal Engine</th><th width="75" data-type="checkbox">Unity</th><th width="50" data-type="checkbox">ПК</th><th width="90" data-type="checkbox">Консоли</th><th width="65" data-type="checkbox">VR/XR</th><th width="100" data-type="checkbox">Мобильные устройства</th></tr></thead><tbody><tr><td><a href="https://dev.epicgames.com/docs/game-services/lobbies-and-sessions/lobbies/lobbies-intro">Лобби Epic Online Services</a><br>(Epic Games)</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://partner.steamgames.com/doc/features/multiplayer/matchmaking#friends">Лобби Steamworks</a><br>(Valve Corporation)</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://heroiclabs.com/docs/nakama/concepts/groups/">Группа Nakama</a><br>(Heroic Labs)</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://learn.microsoft.com/en-us/gaming/playfab/community/associations/groups/quickstart">Лобби Playfab</a><br>(Microsoft)</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://docs.braincloudservers.com/learn/key-concepts/multiplayer/lobbies/#lobby-experience">Лобби brainCloud</a><br>(bitHeads)</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://developer.apple.com/documentation/gamekit/connecting-players-with-their-friends-in-your-game">Gamekit Friends</a><br>(Apple)</td><td>true</td><td>true</td><td>false</td><td>false</td><td>false</td><td>true</td></tr><tr><td>Пользовательское лобби<br>(ваша компания)</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td><td>true</td></tr></tbody></table>

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

**Сохраните ID вашей группы в общих данных лобби**, чтобы другие участники лобби могли легко найти и присоединиться к группе подбора матча, связанной со сторонним лобби. Игроки, приглашённые в группу, используют ID группы, чтобы **создать свои членства (присоединиться)**, и чтобы **безопасно хранить свои** [**атрибуты подбора матча**](#matchmaking-rules)**.**

{% hint style="warning" %}
**Как только группа начинает подбор матча, к ней нельзя присоединиться.** [#abandon-queue](#abandon-queue "mention") и создать новую.
{% endhint %}

#### Оптимизация пинга

Если [#configuration](#configuration "mention") включает [`задержки` правило](#rule-example-elo_rating) все участники группы отправляют свои [Маяки Ping](/ru/learn/orkestraciya/ping-beacons.md) измерения в **чтобы не подбирать игроков из удалённых регионов** или с гораздо более высоким/низким пингом (задержкой).

{% code title="Пример измерений пинга игрового клиента в миллисекундах" %}

```json
{
  "Chicago": 224.4,
  "Frankfurt": 23.2,
  "Tokyo": 167.4
}
```

{% endcode %}

#### **Покинуть очередь**

Владелец группы может удалить группу, автоматически удаляя все членства группы. Удаление группы после начала подбора матча отменит все членства и удалит их вскоре после этого.

Участники группы (кроме владельца) могут удалить свои членства (покинуть группу) в любое время до [#find-match](#find-match "mention"). Удаление членства после этого отменит подбор матча для всей группы.

{% hint style="info" %}
Как только подбор матча отменён, участники [автоматически удаляются из подбора матча](#matchmaking-profiles) и уведомляются через статус членства `status:CANCELLED`  в своём следующем ответе опроса статуса.
{% endhint %}

После отмены, если группа хочет перезапустить подбор матча, владелец группы должен заново создать группу, поделиться новым ID группы с участниками и заставить их заново создать свои членства.

**После того как матч найден, группу нельзя удалить** (`409 Conflict`), и будет [удалён автоматически](#connect-to-server). Ваш сервер должен дать игрокам немного времени (например, 60 секунд), чтобы подключиться, прежде чем считать игрока покинувшим игру.

Если ваш сервер помечает игрока как покинувшего игру, вы можете:

* заменить покинувшего игрока ИИ-персонажем, чтобы немедленно начать матч,
* или создать [backfill](#backfill-match) чтобы найти нового игрока на замену покинувшему,
* или продолжить без замены покинувшего игрока, если дизайн вашей игры допускает переменное количество игроков.

### Найти матч

Чтобы начать поиск матча, все участники и владелец должны отметить себя готовыми.

{% hint style="success" %}
Чтобы позволить владельцу группы **немедленно начать подбор матча, отмечайте членства как готовые при создании**. Как только владелец отметит себя готовым, подбор матча начнётся, так как все готовы.
{% endhint %}

{% hint style="info" %}
Для наилучшего опыта, **предоставляйте игрокам обновления статуса через внутриигровой интерфейс**.
{% endhint %}

**Все игроки должны опрашивать своё членство через регулярные интервалы** (рекомендуется 3-5 с), чтобы определить, когда начинается подбор матча, и сообщать о прогрессе подбора через внутриигровой интерфейс.

Игрокам следует **сохранять свои ID членства и группы постоянно**, чтобы они могли перезапустить игру и продолжить без потери прогресса подбора матча в случае сбоя клиента игры.

Как только мы найдём достаточно игроков, чтобы собрать их в одну команду с соблюдением вашего [#matchmaking-rules](#matchmaking-rules "mention"), игроки будут уведомлены в ответе своего членства с `status:TEAM_FOUND`.

Удаление членства на этом этапе приведёт к отмене всех членств группы, а все другие группы, назначенные в ту же команду, вернутся в `status:SEARCHING` .

Команды продолжают подбор матча с другими командами, используя пересекающиеся значения в своих группах (или среднее значение в случае `number_difference` ), пока не будет собрано достаточно команд. Членства обозначают это ответом  `status:MATCH_FOUND` , что означает, что ваше [развёртывание запускается](https://docs.edgegap.com/ru/learn/podbor-igrokov/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-1.-start-a-deployment).

**Матчмейкер стремится максимизировать заполненность матча и не перейдёт к `MATCH_FOUND` пока не наступит одно из следующих условий:**

1. достаточно команд сопоставлены с настроенным максимальным размером команды,
2. или если [#rule-expansion](#rule-expansion "mention") задано И достигнуто время расширения, И достаточно команд сопоставлены с настроенным минимальным размером команды,
3. или истёк настроенный срок действия билета, И достаточно команд сопоставлены с настроенным минимальным размером команды.

Если ни один из сценариев не сработает до истечения срока действия билета, группа и билеты будут отменены.

{% hint style="info" %}
Столкнулись с долгим временем ожидания в очереди во время тестирования или с игроками в менее популярных регионах? Установите меньший срок действия билета (например, 30 с) и заново создавайте группу (или билеты) на стороне клиента по истечении срока.
{% endhint %}

Срок действия билета автоматически сбрасывается, когда группа (или игрок) сопоставляется с командой.

{% hint style="success" %}
Сохранить `team_id`  и `match_id` в вашем бэкенде игры, чтобы отображать информацию об участниках команды внутри игры.
{% endhint %}

{% hint style="info" %}
Каждый игрок получает **уникальный ID билета, который можно использовать для** [#authenticate](#authenticate "mention") **с игровыми серверами.**
{% endhint %}

Если игрок был сопоставлен и назначен на игровой сервер, его билет удаляется автоматически. Игроки, которые покидают очередь после `status:HOST_ASSIGNED`  могут быть заменены [backfill](#backfill-match).

Как только игроки получают `status:HOST_ASSIGNED`  они переходят к [#connect-to-server](#connect-to-server "mention").

### Подключиться к серверу

Через несколько секунд после нахождения совпадения участники переходят к `status:HOST_ASSIGNED`  что означает, что ваш [развертывание уже готово, а ваш игровой сервер инициализируется](https://docs.edgegap.com/ru/learn/podbor-igrokov/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-3.-deployment-ready).

Каждый игрок читает свой `ticket_id`  и  `назначение`  и пытаются подключиться, используя [**FQDN**](#user-content-fn-3)[^3] **(URL развертывания)** и **внешний порт**. В этот момент ваш игровой сервер может все еще инициализироваться, поэтому **игрокам нужно повторять попытку подключения несколько раз**, пока не будет превышено обычное время инициализации сервера:

{% tabs %}
{% tab title="Unreal Engine" %}
Чтобы **подключение из PIE (редактора)** во время разработки и тестирования нажмите клавишу тильды `~`  и введите `open {URL}:{port}`  и дождитесь, пока редактор загрузит карту.

Чтобы **подключение из сборки игрового клиента** (и в рабочей production-среде) попробуйте

* Unreal Engine [⚡ Integration Kit](https://docs.edgegap.com/learn/unreal-engine-games/developer-tools#integration-kit):
  * [установить из Fab Marketplace](https://www.fab.com/listings/ff17ad88-12a1-49cf-9a41-31695ed11e16) (бесплатно для личного использования),
  * [импортировать простой пример blueprint](https://blueprintue.com/blueprint/m33u1okj/) и настроить под свои нужды.

{% hint style="success" %}
В случае неудачного подключения или черного экрана обратитесь к нашему [руководству по устранению неполадок](/ru/unreal-engine.md#troubleshooting-and-faq).
{% endhint %}
{% endtab %}

{% tab title="Unity" %}
Чтобы **подключите ваш Unity Editor** или **игровой клиент** к вашему облачному развертыванию, укажите:

* **Развертывание** **URL** указывающий на IP-адрес сервера, обычно в `NetworkManager` компоненте.
* **внешний порт** сопоставленный с [внутренним портом прослушивания сервера](/ru/learn/orkestraciya/application-and-versions.md#port-mapping), обычно в компоненте Transport.

{% hint style="success" %}
В случае тайм-аута подключения или других проблем обратитесь к нашему [руководству по устранению неполадок](/ru/unity.md#troubleshooting-and-faq-4).
{% endhint %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Мы не просим игроков подтверждать матч, поскольку стремимся обеспечить как можно более короткое время до начала игры, высокий процент заполнения матчей и минимизировать уклонение от очереди и отмены матчей.
{% endhint %}

Игровые клиенты должны **сохранять свой ID назначения в постоянном хранилище между перезапусками игры**, чтобы в случае сбоя игрового клиента они могли получить данные подключения и попытаться переподключиться.

### Матч Backfill

При необходимости у некоторых игр могут быть особые требования к подбору игроков, например:

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

Backfill — это **серверный тикет, представляющий игроков, которые сейчас подключены к серверу.** Это гарантирует, что вновь добавленные игроки будут соблюдать ваши правила подбора при сопоставлении с текущими игроками.

{% hint style="warning" %}
[Подробный обзор](/ru/learn/podbor-igrokov/matchmaker-in-depth.md#backfill-match) для замены сессий Seat/Match. Matchmaker поддерживает только сессию Default.
{% endhint %}

<figure><img src="/files/39d6a1014be11c05325f3f774ba8a221dd36281b" alt=""><figcaption><p>Визуализация сценариев Backfill</p></figcaption></figure>

{% hint style="success" %}
**Backfill игнорируют** `player_count`  **правило и всегда сопоставляют ровно одну группу**. `backfill_group_size`  управляет вместимостью команды по стратегии round-robin, равномерно заполняя команды контролируемым образом.
{% endhint %}

**Чтобы успешно выполнить backfill, нужно:**

1. Сервер создаёт один Backfill для каждой команды, которой не хватает игроков, используя значения из:
   * Реальные `назначение`  данные, полученные из [Развертывания](/ru/learn/orkestraciya/deployments.md#injected-environment-variables) (развёртывания).
   * Текущих подключённых игроков' `тикеты`:
     * из [Подробный обзор](/ru/learn/podbor-igrokov/matchmaker-in-depth.md#injected-variables) (matchmaker), предыдущих backfill' `assigned_ticket` ответа или тестовых данных, изменённых для соответствия конкретным игрокам,
     * замените `backfill_group_size`  значения на возможные размеры групп [до доступной вместимости](#user-content-fn-4)[^4],
2. Игровые клиенты создают новые тикеты (участия) и включают `backfill_group_size`  значения:
   * `"1"`  если игрок подбирается в матч в одиночку.
   * [`"2"`  если игрок является частью группы подбора с 2x участниками всего](#user-content-fn-5)[^5].
   * `"new"`  если игроки разрешили запуск новых игр в дополнение к присоединению к уже идущим играм.
3. Игровые клиенты переходят к [Подробный обзор](/ru/learn/podbor-igrokov/matchmaker-in-depth.md#find-match) и сопоставляют игроков с соответствующим backfill.
4. Если группа, пополненная через backfill, не полностью заполнила команду, сервер может повторить этот процесс с тикетами новых игроков, добавленных через backfill, чтобы добавить ещё игроков и достичь нужного размера команды.

{% hint style="success" %}
Backfill игнорируют правила размера команды и всегда сопоставляют 1× backfill с 1× группой. **Чтобы сопоставлять только с backfill и отключить подбор с другими игроками в очереди, установите `min_team_size: 999999` .**
{% endhint %}

<details>

<summary>🥛 Пример Backfill (демонстрация Backfill)</summary>

```json
{
  "profile": "backfill-example",
  "attributes": {
    "assignment": {
      "request_id": "cd28e6c66554",
      "fqdn": "cd28e6c66554.pr.edgegap.net",
      "public_ip": "192.168.2.14",
      "ports": {
        "game": {
          "internal": 7777,
          "external": 56890,
          "link": "cd28e6c66554.pr.edgegap.net:56890",
          "protocol": "UDP"
        },
        "web": {
          "internal": 22,
          "external": 57440,
          "link": "cd28e6c66554.pr.edgegap.net:57440",
          "protocol": "TCP"
        },
        "server": {
          "internal": 80,
          "external": 50110,
          "link": "cd28e6c66554.pr.edgegap.net:50110",
          "protocol": "TCP"
        }
      },
      "location": {
        "city": "Монреаль",
        "country": "Канада",
        "continent": "Северная Америка",
        "administrative_division": "Квебек",
        "timezone": "America/Toronto"
      }
    }
  },
  "tickets": {
    "c3d057h5h6f7j889fk43": {
      "player_ip": "174.25.48.238",
      "attributes": {
        "beacons": {
          "Нью-Йорк": 12.2,
          "Лос-Анджелес": 45.3,
          "Париж": 78.3
        },
        "backfill_group_size": [
          "2",
          "1"
        ]
      },
      "group_id": "192bb97e-7fd6-4d86-8ce4-61c53c9fef16",
      "id": "c3d057h5h6f7j889fk43",
      "created_at": "2024-08-20T13:38:05.251393+00:00"
    },
    "cqg0bg9583s738h9dkf6": {
      "player_ip": "217.34.85.142",
      "attributes": {
        "beacons": {
          "Нью-Йорк": 21.0,
          "Лос-Анджелес": 30.2,
          "Париж": 101.1
        },
        "backfill_group_size": [
          "2",
          "1"
        ]
      },
      "group_id": "aea7df3c-d391-4ea3-a3ec-dded422fe7c8",
      "id": "cqg0bg9583s738h9dkf6",
      "created_at": "2024-08-20T13:38:05.251393+00:00"
    }
  },
  "assigned_ticket": null
}
```

</details>

<details>

<summary>🥛 Пример назначения Backfill (демонстрация Backfill)</summary>

```json
{
  "profile": "backfill-example",
  "attributes": {
    "assignment": {
      "request_id": "cd28e6c66554",
      "fqdn": "cd28e6c66554.pr.edgegap.net",
      "public_ip": "192.168.2.14",
      "ports": {
        "game": {
          "internal": 7777,
          "external": 56890,
          "link": "cd28e6c66554.pr.edgegap.net:56890",
          "protocol": "UDP"
        },
        "web": {
          "internal": 22,
          "external": 57440,
          "link": "cd28e6c66554.pr.edgegap.net:57440",
          "protocol": "TCP"
        },
        "server": {
          "internal": 80,
          "external": 50110,
          "link": "cd28e6c66554.pr.edgegap.net:50110",
          "protocol": "TCP"
        }
      },
      "location": {
        "city": "Монреаль",
        "country": "Канада",
        "continent": "Северная Америка",
        "administrative_division": "Квебек",
        "timezone": "America/Toronto"
      }
    }
  },
  "tickets": {
    "c3d057h5h6f7j889fk43": {
      "player_ip": "174.25.48.238",
      "attributes": {
        "beacons": {
          "Нью-Йорк": 12.2,
          "Лос-Анджелес": 45.3,
          "Париж": 78.3
        },
        "backfill_group_size": [
          "2",
          "1"
        ]
      },
      "group_id": "192bb97e-7fd6-4d86-8ce4-61c53c9fef16",
      "id": "c3d057h5h6f7j889fk43",
      "created_at": "2024-08-20T13:38:05.251393+00:00"
    },
    "cqg0bg9583s738h9dkf6": {
      "player_ip": "217.34.85.142",
      "attributes": {
        "beacons": {
          "Нью-Йорк": 21.0,
          "Лос-Анджелес": 30.2,
          "Париж": 101.1
        },
        "backfill_group_size": [
          "2",
          "1"
        ]
      },
      "group_id": "aea7df3c-d391-4ea3-a3ec-dded422fe7c8",
      "id": "cqg0bg9583s738h9dkf6",
      "created_at": "2024-08-20T13:38:05.251393+00:00"
    }
  },
  "assigned_ticket": {
    "profile": "backfill-example",
    "player_ip": "244.13.201.244",
    "attributes": {
      "beacons": {
        "Нью-Йорк": 30.2,
        "Лос-Анджелес": 10.5,
        "Париж": 123.9
      },
      "backfill_group_size": [
        "new",
        "1"
      ]
    },
    "id": "cqg0bg550h7uujd77khg",
    "group_id": "e0cf41c0-f88f-456e-a032-03b1d6821a9a",
    "created_at": "2024-08-20T13:38:08.251393+00:00",
    "status": "HOST_ASSIGNED"
  }
}
```

</details>

{% hint style="info" %}
См. [Управление местами Mirror Seat](https://docs.edgegap.com/docs/sample-projects/mirror-on-edgegap#bonus-seat-sessions-management) и [Управление местами FishNet Seat](https://docs.edgegap.com/docs/sample-projects/fishnet-on-edgegap#bonus-seat-sessions-management) для **мониторинг подключений игроков**.
{% endhint %}

После завершения инициализации игрового сервера, **ваш сервер должен**:

* **запустить таймер покидания для каждого нового игрока.** Мы рекомендуем показывать подключённым игрокам прогресс загрузки с помощью сцены/уровня загрузки — будь то полноценная 3D-сцена, социальный UI в стиле лобби или экран загрузки с индикатором прогресса.
* **Следите за новыми подключениями игроков или уходом существующих игроков со временем**:
  1. Новые игроки должны сообщить серверу ID билета для аутентификации и чтобы сопоставить своё подключение с матчмейкером [#injected-variables](#injected-variables "mention") или `assigned_ticket` (если был выполнен backfill).
  2. Создавайте новые Backfill для неиспользуемой ёмкости игроков (покинувших игру) на протяжении всего срока жизни сервера.
  3. Продлевайте просроченные Backfill, которые удаляются после `ticket_expiration_period`.
* **Очищайте (удаляйте) все оставшиеся Backfill** как только [/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-5.-deployment-stopped](https://docs.edgegap.com/ru/learn/podbor-igrokov/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-5.-deployment-stopped "mention"):
  * Unity - [`OnApplicationQuit`](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/MonoBehaviour.OnApplicationQuit.html) callback или пользовательский callback завершения игры,
  * Unreal Engine - [`OnWorldDestroyed`](https://forums.unrealengine.com/t/call-function-before-quit-game/344954/2) , [`PreExit`](https://forums.unrealengine.com/t/event-on-close/298087/2) , или пользовательский callback завершения игры.

{% hint style="info" %}
Используйте [GetEnvironmentVariable в C#](https://learn.microsoft.com/en-us/dotnet/api/system.environment.getenvironmentvariable?view=net-8.0) или [GetEnvironmentVariable в C++](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/GenericPlatform/FGenericPlatformMisc/GetEnvironmentVariable) чтобы получить значения переменных.
{% endhint %}

Для Backfill можно использовать любой профиль, если указано корректное назначение сервера и предоставлен хотя бы один билет. См. [Подбор игроков](/ru/learn/podbor-igrokov.md#backfill-showcase) для минимального примера.

## ⚙️ Конфигурация

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

{% hint style="success" %}
См. [Подбор игроков](/ru/learn/podbor-igrokov.md) для наших SDK и подробных примеров сценариев.
{% endhint %}

<details>

<summary>🍀 Простой пример (минимальная рекомендуемая конфигурация)</summary>

<pre class="language-json"><code class="lang-json">{
  "version": "3.2.5",
  "inspect": true,
  "max_deployment_retry_count": 3,
  "profiles": {
    "simple-example": {
      "ticket_expiration_period": "5m",
      "ticket_removal_period": "1m",
      "group_inactivity_removal_period": "5m",
      "application": {
        "name": "<a data-footnote-ref href="#user-content-fn-6">my-game-server</a>",
        "version": "<a data-footnote-ref href="#user-content-fn-7">2024.01.30-16.23.00-UTC</a>"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 1,
              "min_team_size": 2,
              "max_team_size": 2
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 100,
              "max_latency": 200
            }
          }
        },
        "expansions": {}
      }
    }
  }
}
</code></pre>

</details>

<details>

<summary>🏁 Расширенный пример (полная конфигурация примера)</summary>

```json
{
  "version": "3.2.5",
  "inspect": true,
  "max_deployment_retry_count": 3,
  "allowed_cors_origins": [
    "https://*.my-game-server.com"
  ],
  "profiles": {
    "advanced-example": {
      "ticket_expiration_period": "5m",
      "ticket_removal_period": "1m",
      "group_inactivity_removal_period": "5m"
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 1,
              "min_team_size": 4,
              "max_team_size": 4
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 125,
              "max_latency": 125
            }
          },
          "elo_rating": {
            "type": "number_difference",
            "attributes": {
              "max_difference": 50
            }
          },
          "selected_game_mode": {
            "type": "string_equality"
          },
          "selected_map": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "backfill_group_size": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {
          "30": {
            "elo_rating": {
              "max_difference": 150
            },
            "beacons": {
              "difference": 125,
              "max_latency": 250
            }
          },
          "60": {
            "elo_rating": {
              "max_difference": 200
            }
          },
          "180": {
            "match_size": {
              "team_count": 1,
              "min_team_size": 1,
              "max_team_size": 4
            },
            "beacons": {
              "difference": 99999,
              "max_latency": 99999
            }
          }
        }
      }
    }
  }
}
```

</details>

<details>

<summary><span data-gb-custom-inline data-tag="emoji" data-code="1f95b">🥛</span> Пример конфигурации Backfill</summary>

```json
{
  "version": "3.2.5",
  "inspect": true,
  "max_deployment_retry_count": 3,
  "profiles": {
    "backfill-example": {
      "ticket_expiration_period": "30s",
      "ticket_removal_period": "1m",
      "group_inactivity_removal_period": "5m",
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 1,
              "min_team_size": 4,
              "max_team_size": 4
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 100,
              "max_latency": 200
            }
          },
          "backfill_group_size": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {}
      }
    }
  }
}
```

</details>

<details>

<summary>⚔️ Пример соревновательной игры</summary>

```json
{
  "version": "3.2.5",
  "inspect": true,
  "max_deployment_retry_count": 3,
  "profiles": {
    "casual-example": {
      "ticket_expiration_period": "5m",
      "ticket_removal_period": "1m",
      "group_inactivity_removal_period": "5m",
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 2,
              "min_team_size": 5,
              "max_team_size": 5
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 125,
              "max_latency": 150
            }
          },
          "selected_maps": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "backfill_group_size": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {
          "30": {
            "beacons": {
              "difference": 125,
              "max_latency": 250
            }
          },
          "180": {
            "beacons": {
              "difference": 99999,
              "max_latency": 99999
            }
          }
        }
      }
    },
    "competitive-example": {
      "ticket_expiration_period": "5m",
      "ticket_removal_period": "1m",
      "group_inactivity_removal_period": "5m"
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 2,
              "min_team_size": 5,
              "max_team_size": 5
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 125,
              "max_latency": 150
            }
          },
          "versus_ranks": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {
          "120": {
            "beacons": {
              "difference": 125,
              "max_latency": 250
            }
          }
        }
      }
    },
    "challenger-example": {
      "ticket_expiration_period": "5m",
      "ticket_removal_period": "1m",
      "group_inactivity_removal_period": "5m"
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 2,
              "min_team_size": 5,
              "max_team_size": 5
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 125,
              "max_latency": 150
            }
          },
          "elo_rating": {
            "type": "number_difference",
            "attributes": {
              "max_difference": 50
            }
          }
        },
        "expansions": {
          "120": {
            "beacons": {
              "difference": 125,
              "max_latency": 250
            }
          }
        }
      }
    }
  }
}
```

</details>

<details>

<summary>🤝 Пример кооперативной игры</summary>

```json
{
  "version": "3.2.5",
  "inspect": true,
  "max_deployment_retry_count": 3,
  "profiles": {
    "cooperative-example": {
      "ticket_expiration_period": "3m",
      "ticket_removal_period": "1m",
      "group_inactivity_removal_period": "5m",
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 1,
              "min_team_size": 4,
              "max_team_size": 4
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 125,
              "max_latency": 150
            }
          },
          "selected_difficulty": {
            "type": "string_equality"
          },
          "selected_map": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "player_level": {
            "type": "number_difference",
            "attributes": {
              "max_difference": 10
            }
          },
          "backfill_group_size": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "moderation_flags": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {
          "30": {
            "beacons": {
              "difference": 125,
              "max_latency": 250
            },
            "player_level": {
              "max_difference": 20
            }
          },
          "60": {
            "match_size": {
              "team_count": 1,
              "min_team_size": 2,
              "max_team_size": 4
            }
          },
          "150": {
            "match_size": {
              "team_count": 1,
              "min_team_size": 1,
              "max_team_size": 4
            }
          }
        }
      }
    }
  }
}
```

</details>

<details>

<summary>🎈 Пример социальной игры</summary>

```json
{
  "version": "3.2.5",
  "inspect": true,
  "max_deployment_retry_count": 3,
  "profiles": {
    "social-example": {
      "ticket_expiration_period": "3m",
      "ticket_removal_period": "1m",
      "group_inactivity_removal_period": "5m",
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "attributes": {
              "team_count": 1,
              "min_team_size": 50,
              "max_team_size": 50
            },
            "type": "player_count"
          },
          "beacons": {
            "attributes": {
              "difference": 125,
              "max_latency": 150
            },
            "type": "latencies"
          },
          "selected_mode": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "backfill_group_size": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "moderation_flags": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {
          "15": {
            "beacons": {
              "difference": 125,
              "max_latency": 250
            },
            "match_size": {
              "team_count": 1,
              "min_team_size": 20,
              "max_team_size": 50
            }
          },
          "30": {
            "match_size": {
              "team_count": 1,
              "min_team_size": 10,
              "max_team_size": 50
            }
          },
          "150": {
            "match_size": {
              "team_count": 1,
              "min_team_size": 1,
              "max_team_size": 50
            }
          }
        }
      }
    }
  }
}
```

</details>

{% hint style="warning" %}
Редактирование запущенного матчмейкера **вызовет быстрое перезагружение**, удалит все билеты и вызовет кратковременный простой.
{% endhint %}

<details>

<summary><code>Конфигурация приложения недействительна для профиля XYZ.</code></summary>

* Мы не смогли найти ваш [Приложения и версии](/ru/learn/orkestraciya/application-and-versions.md), пожалуйста, проверьте `приложение`  значения.

</details>

<details>

<summary><code>Docker-образ для '2024.01.30-16.23.00-UTC' не кэширован.</code></summary>

[**🌟 Обновитесь до тарифа Pay as You Go**](https://app.edgegap.com/user-settings?tab=memberships) **чтобы разблокировать** [**мгновенные развёртывания с кэшированием**](https://docs.edgegap.com/ru/learn/podbor-igrokov/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-1.-start-a-deployment)**.**

* Некэшированные образы размером 4 ГБ и более могут дольше развёртываться, что приведёт к [/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-4.-deployment-error](https://docs.edgegap.com/ru/learn/podbor-igrokov/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-4.-deployment-error "mention"). Рассмотрите возможность оптимизации размера образа сервера ([Unreal Engine](/ru/unreal-engine.md#optimize-server-build-size) / [Unity](/ru/unity.md#optimize-server-build-size)).
* Вы всё равно можете продолжить, хотя мы рекомендуем протестировать время развёртывания.

</details>

### Профили (очереди) <a href="#matchmaking-profiles" id="matchmaking-profiles"></a>

Профили представляют собой полностью отдельные очереди подбора матча, использующие одну и ту же версию матчмейкера. Вы можете **настроить любое количество профилей для каждого матчмейкера.** Разделение вашей базы игроков на несколько профилей может привести к более длительному ожиданию в очереди для ваших игроков.

Каждый профиль матчмейкера использует [Версия приложения](/ru/learn/orkestraciya/application-and-versions.md) как шаблон для запуска новых развёртываний (серверов).

{% hint style="success" %}
Некоторые игровые режимы могут требовать больше vCPU / RAM, особенно если они поддерживают большее количество игроков. Каждый **матчмейкер может включать несколько профилей**, каждый привязан к версии приложения с настроенными ресурсами.
{% endhint %}

### Правила <a href="#matchmaking-rules" id="matchmaking-rules"></a>

Каждый игрок и группа входят в очередь подбора матча и находят матчи, используя  `начальные` правила в первую очередь.

Каждая запись в профиле по пути `.rules.initial` представляет правило, где:

* **key** — это строковое значение, чтобы назвать правило как угодно; например, `match_size` , а
* **value** — это объект, определяющий тип и атрибуты правила в соответствии с нашим стандартным набором правил.

{% hint style="info" %}
Все правила должны выполняться одновременно, чтобы инициировать назначение хоста и запустить или найти развёртывание.
{% endhint %}

**Операторы (тип правила)**

**`player_count`** — это специальное правило, определяющее, сколько игроков должно совпасть, чтобы инициировать назначение.

{% hint style="warning" %}
Правило `player_count`  **обязательно и может быть определено только один раз** в ваших начальных правилах конфигурации.
{% endhint %}

Матчмейкер всегда стремится максимизировать заполненность матча, вплоть до указанного `max_team_size` :

1. если достигнут максимальный размер команды, матч создаётся немедленно,
2. иначе игроки ждут в очереди, чтобы заполнить матч, пока [расширение](#rule-expansion) (или срок действия) вот-вот не истечёт,
3. незадолго до [расширения](#rule-expansion) (или истечения), если возможен частичный матч (≥ min и < max size команды), этот матч будет создан со всеми игроками на одной стадии расширения (при условии прохождения остальных правил).

{% hint style="success" %}
Для кооперативных, free-for-all или асимметричных режимов с разным размером команды установите `"team_count": 1` .
{% endhint %}

Количество команд можно настроить так, чтобы собирать несколько сбалансированных команд для соревновательных игр:

* **атрибуты группы вычисляются как среднее/пересечение** атрибутов игроков **группы,**
* **атрибуты команды вычисляются как среднее/пересечение** атрибутов группы **.**

Предполагая фиксированный размер команды из 4 игроков:

<figure><img src="/files/e5d57871dc252856b075a22e9725c5690d66f797" alt=""><figcaption><p>Примеры сценариев матча</p></figcaption></figure>

{% hint style="info" %}
**Группы сопоставляются в команды без переполнения,** только если в команде достаточно места, чтобы вместить всю группу.
{% endhint %}

**`string_equality`** сопоставляет игроков с абсолютно одинаковым строковым значением.

<details>

<summary>Пример правила: <code>selected_game_mode</code></summary>

`selected_game_mode`  правило будет сопоставлять игроков с учётом регистра:

:white\_check\_mark: Alice + Bob + Dave могут совпасть,

:x: Alice + Erin, или Charlie + Frank никогда не совпадут.

| "Free For All" | "Capture The Flag" | "capture the flag" |
| -------------- | ------------------ | ------------------ |
| Alice          | Erin               | Frank              |
| Bob            | Charlie            |                    |
| Dave           |                    |                    |

</details>

**`number_difference`** сопоставляет игроков, если абсолютная числовая разница между ними находится в пределах.

<details>

<summary>Пример правила: <code>elo_rating</code></summary>

`elo_rating`  правило выше с `"max_difference": 50` сначала:

:white\_check\_mark: Alice + Bob могут совпасть, или Bob + Charlie могут совпасть,

:x: Alice + Bob + Charlie никогда не совпадут.

<figure><img src="/files/81d958edea12e340b96198f11c556ca754587237" alt=""><figcaption></figcaption></figure>

</details>

**`задержки`** — это специальное правило, оптимизирующее пинг матчей игроков:

* уменьшить задержку между клиентом и сервером, удаляя регионы с высокой задержкой (выше порога),
* повысить справедливость матчей, группируя игроков с похожей задержкой (ниже разницы).

<details>

<summary>Пример правила: <code>маяки</code></summary>

`маяки` правило, настроенное с `"difference": 100, "max_latency": 200`  будет сопоставлять:

:white\_check\_mark: Алиса и Боб могут быть сопоставлены:

* Токио отбрасывается (>200 мс),
* задержка для Чикаго в пределах абсолютной разницы 100 мс.

<table><thead><tr><th width="180">Город маяка</th><th width="80">Матч</th><th width="132">abs(A - B) [мс]</th><th width="164">Алиса [мс]</th><th width="164">Боб [мс]</th></tr></thead><tbody><tr><td>Чикаго</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td>75.0</td><td>12.3</td><td>87.3</td></tr><tr><td>Лос-Анджелес</td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><a data-footnote-ref href="#user-content-fn-8">113.2</a> <span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td>145.6</td><td>32.4</td></tr><tr><td><del>Токио</del></td><td>н/д</td><td>н/д</td><td><a data-footnote-ref href="#user-content-fn-9"><del>233.2</del></a> <span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td><a data-footnote-ref href="#user-content-fn-9"><del>253.2</del></a> <span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr></tbody></table>

:x: Алиса и Чарли никогда не будут сопоставлены:

* нет маяков с задержкой < 200 мс для обоих игроков,
* Алиса живет в Северной Америке — Иллинойс,
* Чарли живет в Азии — Япония.

<table><thead><tr><th width="180">Город маяка</th><th width="80">Матч</th><th width="132">abs(A - B) [мс]</th><th width="164">Алиса [мс]</th><th width="164">Чарли [мс]</th></tr></thead><tbody><tr><td><del>Чикаго</del></td><td>н/д</td><td>н/д</td><td>12.3</td><td><a data-footnote-ref href="#user-content-fn-9"><del>215.6</del></a> <span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr><tr><td><del>Лос-Анджелес</del></td><td>н/д</td><td>н/д</td><td>145.6</td><td><a data-footnote-ref href="#user-content-fn-9"><del>238.3</del></a> <span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr><tr><td><del>Токио</del></td><td>н/д</td><td>н/д</td><td><a data-footnote-ref href="#user-content-fn-9"><del>233.2</del></a> <span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td><td>24.2</td></tr></tbody></table>

</details>

{% hint style="warning" %}
Правило `задержки`  — это **является необязательным и может быть определено только один раз в вашей начальной конфигурации** правила.
{% endhint %}

Некоторые игроки с высоким пингом ко всем маякам из-за провайдера[^10] проблем или медленного соединения (например, беспроводного/мобильного) могут вызывать лаги и ухудшать игровой опыт других. Чтобы смягчить эту проблему:

* Постепенно расширяйте максимально допустимую задержку и разницу (см. [Пример расширенной конфигурации](/ru/learn/podbor-igrokov.md#advanced-example)),
  * игрокам с высоким пингом, возможно, придется ждать дольше обычного, чтобы найти матч.
* В качестве альтернативы разрешите игрокам переопределять измерение вручную, выбирая регион, и отправляйте поддельные значения пинга только для выбранных игроком регионов (например, 25 мс для быстрого матча),
  * это может отрицательно повлиять на опыт игры товарищей по команде и соперников.

{% hint style="info" %}
**Высокий пинг до маяка не всегда приводит к высокому пингу до сервера**. Развертывания доступны в большем количестве локаций, чем маяки. Маяки оркеструются в реальном времени для приоритизации глобального покрытия и надежности.
{% endhint %}

{% hint style="success" %}
См. [Подбор игроков](/ru/learn/podbor-igrokov.md) для **автоматизированное измерение пинга с помощью наших SDK**.
{% endhint %}

{% hint style="danger" %}
Маяки автоматически масштабируются в реальном времени — добавляются/удаляются/заменяются существующие маяки. Ваши клиенты и бэкенд должны учитывать это и **перезагружать список маяков перед каждым раундом подбора игроков**.
{% endhint %}

**`intersection`** сопоставляет игроков с одним или несколькими совпадающими строковыми значениями с учётом регистра.

<details>

<summary>Пример правила: <code>selected_map</code></summary>

`selected_map` правило выше с `"overlap": 1`  будет сопоставлять:

:white\_check\_mark: Alice + Bob + Charlie могут совпасть, или Alice + Bob + Dave могут совпасть,

:x: Alice + Bob + Charlie + Dave никогда не совпадут.

<figure><img src="/files/583a8d57c0bcaf33a76b960c00485e98a69c6acd" alt=""><figcaption></figcaption></figure>

</details>

#### Расширение правила

При желании, **`расширения`**  изменяют атрибуты правила после некоторого времени, проведённого в очереди, чтобы ослабить ограничения и расширить пул игроков, которых можно сопоставить, **что приводит к более быстрым матчам**.

<details>

<summary>Пример сценария: расширения</summary>

[Сначала нам требуется 1 команда, состоящая ровно из 4 игроков (возможно, разделённых по группам)](/ru/learn/podbor-igrokov.md#advanced-example) с:

* максимум 125 мс задержки против одного и того же (любого одного) маяка,
* разница задержки 125 мс или меньше между минимальным/максимальным значением для одного и того же маяка,
* разница рейтинга навыка 50 очков или меньше между игроком с самым низким и самым высоким рейтингом,
* точно тот же (с учётом регистра) выбранный игровой режим,
* как минимум одно совпадающее значение карты (с учётом регистра) среди игроков,
* как минимум одно совпадающее [размер backfill-группы](#backfill-match) значение среди игроков.

В примере выше мы **расширяем поиск, изменяя атрибуты** после:

<table data-view="cards"><thead><tr><th></th><th></th></tr></thead><tbody><tr><td>30 секунд:</td><td><ul><li>4 игроков</li><li><strong>диапазон рейтинга навыка 150</strong></li><li><strong>макс. задержка 250 мс</strong></li></ul></td></tr><tr><td>60 секунд:</td><td><ul><li>4 игроков</li><li><strong>диапазон рейтинга навыка 200</strong></li><li>макс. задержка 250 мс</li></ul></td></tr><tr><td>3 минуты (180 с):</td><td><ul><li><strong>1–4 игрока</strong></li><li>диапазон рейтинга навыка 200</li><li><strong>любая задержка</strong></li></ul></td></tr></tbody></table>

</details>

{% hint style="info" %}
Расширения любого атрибута правила **перезапишут предыдущие значения** этого атрибута.
{% endhint %}

{% hint style="success" %}
[**Узнайте о распространённых подводных камнях матчмейкинга**](https://edgegap.com/blog/how-session-fill-rate-affects-your-multiplayer-hosting-costs)**, а** [**оптимизируйте скорость заполнения матчей с помощью нашего руководства**](https://edgegap.com/blog/how-to-optimize-session-fill-rate-in-your-matchmaker)**.**
{% endhint %}

## 📌 Внедрённые переменные

Вашему серверу могут понадобиться сведения о его игроках. Атрибуты игроков, вычисленные значения матча и другие значения внедряются в ваше развёртывание вместе с обычными [Приложения и версии](/ru/learn/orkestraciya/application-and-versions.md#injected-variables).

Предпросмотр без форматирования **🏁 Переменные расширенного примера:**

```
MM_MATCH_PROFILE=advanced-example
MM_EXPANSION=initial
MM_TICKET_IDS=["cusfn10msflc73beiik0","cusfn18msflc73beiil0"]
MM_TICKET_cusfn10msflc73beiik0={"id":"cusfn10msflc73beiik0","created_at":"2025-02-21T22:17:42.3886970Z","player_ip":"174.93.233.25","group_id":"b2080c27-19c9-4fb0-8fe7-4bf1e5d285d1","team_id":"cusfn1gmsflc73beiim0","attributes":{"beacons":{"Chicago":12.3,"LosAngeles":145.6,"Tokyo":233.2},"elo_rating":1337,"selected_game_mode":"quickplay","selected_map":["DustII","Airport","BankVault"],"backfill_group_size":["new","1"]}}
MM_TICKET_cusfn18msflc73beiil0={"id":"cusfn18msflc73beiil0","created_at":"2025-02-21T22:17:42.2548390Z","player_ip":"174.93.233.23","group_id":"015d4dc8-6c79-4b5c-bbc6-f309b9787c8f","team_id":"cusfn1gmsflc73beiim0","attributes":{"beacons":{"Chicago":87.3,"LosAngeles":32.4,"Tokyo":253.2},"elo_rating":1339,"selected_game_mode":"quickplay","selected_map":["Island","Airport"],"backfill_group_size":["new","1"]}}
MM_GROUPS={"b2080c27-19c9-4fb0-8fe7-4bf1e5d285d1":["cusfn10msflc73beiik0"],"015d4dc8-6c79-4b5c-bbc6-f309b9787c8f":["cusfn18msflc73beiil0"]}
MM_TEAMS={"cusfn1gmsflc73beiim0":["b2080c27-19c9-4fb0-8fe7-4bf1e5d285d1","015d4dc8-6c79-4b5c-bbc6-f309b9787c8f"]}
MM_MATCH_ID=advanced-example_initial-2025-02-21T22:17:43.3886970Z
MM_INTERSECTION={"selected_map":["Airport"],"backfill_group_size":["new","1"]}
MM_EQUALITY={"selected_game_mode":"quickplay"}
```

{% hint style="info" %}
Переменные среды **хранятся как JSON в строковом виде**, анализируйте их с помощью наших SDK или пользовательского метода.
{% endhint %}

{% hint style="success" %}
**Серверы могут сопоставлять подключения игроков с группами и атрибутами** после того, как игрок отправит свой ID билета на сервер.
{% endhint %}

## 🧵 Трассировка игроков

Если у ваших игроков возникают какие-либо проблемы, отслеживание их пути до серверных логов может быть полезным. Каждый Matchmaker **развёртывание** **будет помечено назначенными ID билетов игроков** чтобы вы могли легко [Развертывания](/ru/learn/orkestraciya/deployments.md#filter-deployments) и найти [Развертывания](/ru/learn/orkestraciya/deployments.md#container-logs) чтобы помочь вам устранить неполадки.

{% hint style="success" %}
**Отображайте ID билетов и ID развёртывания в интерфейсе истории матчей клиента** для отслеживания игроков при устранении неполадок.
{% endhint %}

{% hint style="info" %}
См. [Развертывания](/ru/learn/orkestraciya/deployments.md#connection-quality) чтобы узнать об устранении неполадок развёртывания.
{% endhint %}

## 👀 Аналитика

Получайте сведения о нагрузке и производительности вашего матчмейкера без необходимости в коде или настройке.

🌟 [**Обновите Matchmaker до Enterprise-уровня**](https://app.edgegap.com/matchmaker-management-v2/matchmakers/list) **чтобы разблокировать метрики и аналитические сведения о матчмейкинге:**

<figure><img src="/files/d0579318cba10674d2d4bcecc12bf9c7d765961a" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/fb7a0a3397679b51db8b60350f98af02e0318914" alt=""><figcaption></figcaption></figure>

## ☁️ Кластер хостинга

Matchmaker удобно размещается и управляется Edgegap круглосуточно 24/7.

Выберите вариант хостинга, наиболее подходящий для вашей цели:

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

#### Тарифы частного кластера

В настоящее время мы предлагаем [3 уровня частных кластеров](https://edgegap.com/resources/pricing#managed-infrastructure) чтобы удовлетворить потребности каждого:

<table><thead><tr><th width="160">Уровень</th><th align="right">Уровень для любителей</th><th align="right">Студийный уровень</th><th align="right">Корпоративный уровень</th></tr></thead><tbody><tr><td>Лучше всего подходит для</td><td align="right">энтузиастов,<br>разработчиков-одиночек</td><td align="right">коммерческих релизов</td><td align="right">запусков с высоким трафиком</td></tr><tr><td>Ресурсы</td><td align="right">1 vCPU + 2 ГБ ОЗУ</td><td align="right">6 vCPU + 12 ГБ ОЗУ</td><td align="right">18 vCPU + 48 ГБ ОЗУ</td></tr><tr><td>Отказоустойчивость</td><td align="right">1 виртуальный узел</td><td align="right">3 виртуальных узла</td><td align="right">3 виртуальных узла</td></tr><tr><td>Ограничение скорости (запросов/с)</td><td align="right">200</td><td align="right">750</td><td align="right">2,000</td></tr><tr><td>Цена, в час</td><td align="right">$0.0312</td><td align="right"> $0.146</td><td align="right">$0.548</td></tr><tr><td><strong>Цена, за 30 дней</strong><br>(непрерывное использование)</td><td align="right"><strong>$22.464</strong></td><td align="right"><strong>$105.12</strong></td><td align="right"><strong>$394.56</strong></td></tr></tbody></table>

Обновление до частного кластера в один клик. После запуска также возможно изменение тарифов частного кластера без простоя для игроков с [#rolling-updates-and-ab-tests](#rolling-updates-and-ab-tests "mention"). Управляемые кластеры обеспечивают высокодоступный хостинг сервисов, поддерживаемый Edgegap, с круглосуточной живой поддержкой для публично выпущенных игр.

Требования к ресурсам для вашего экземпляра будут зависеть от факторов:

* **количество игроков** - больше игроков приводят к большему количеству билетов и API-запросов,
* **количество запросов на игрока** - более частые повторы увеличивают нагрузку на сервис и расходуют ресурсы,
* **сложность конфигурации** - правила пересечения и расширения особенно требовательны,
* **средняя длительность матча** - более короткие сессии заставляют игроков чаще возвращаться в матчмейкинг,
* **периоды истечения и удаления** - устаревшие билеты накапливаются со временем и расходуют ресурсы,
* **логика резервного повторного запроса клиента** - повторные попытки с экспоненциальным backoff и джиттером помогают распределить всплески трафика.

{% hint style="warning" %}
**Подготовьтесь к успеху и оптимизируйте после запуска, чтобы не блокировать игроков в день релиза.** Используйте [Инструменты разработчика](/ru/unity/developer-tools.md#matchmaking-sdk) или **внедрите экспоненциальный backoff с джиттером** чтобы восстановиться после высокой нагрузки.
{% endhint %}

{% hint style="info" %}
Наши кластеры используют облачные машины с процессорами AMD/Intel с тактовой частотой 2,4 - 3,2 ГГц.
{% endhint %}

## ⏩ Поэтапные обновления <a href="#rolling-updates-and-ab-tests" id="rolling-updates-and-ab-tests"></a>

Отслеживать совместимость между версиями сервера и клиента может быть сложно. Следуйте нашим советам для надёжных релизов, обновлений и предотвращения простоя или проблем совместимости.

**Ваш URL Matchmaker и токен аутентификации всегда останутся теми же после перезапуска.**

{% hint style="danger" %}
**Создайте отдельные матчмейкеры для сред разработки и производства** чтобы безопасно экспериментировать.
{% endhint %}

#### ⚠️ **Перед запуском**

Мы рекомендуем заранее создать несколько копий вашего матчмейкера: `зелёный`, `синий` и `оранжевый`. Вы можете переключать используемый матчмейкер по мере выпуска обновлений ([сине-зелёная стратегия](https://en.wikipedia.org/wiki/Blue%E2%80%93green_deployment)).

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

<figure><img src="/files/d133d707f5f79ffc15ab4244a9d943c30aa3f0b2" alt=""><figcaption><p>Пример среды DevOps с сине-зелёным развёртыванием</p></figcaption></figure>

#### **🔃 Обновление клиента и сервера**

**Предварительные требования:** В этом разделе предполагается, что вы завершили [#before-going-live](#before-going-live "mention").

Чтобы **выпустить обновления игрового клиента и сервера**, вы можете:

1. Подготовьте новую версию серверного приложения `v1.2.0-rc` в Edgegap:
   1. отправьте новый тег образа в ваш реестр контейнеров `t1.2.0`,
   2. создайте новую версию приложения `v1.2.0-rc`,
2. Выполните любые dev-тесты,  [разворачивая новую версию приложения](https://app.edgegap.com/deployment-management/deployments/list) `v1.2.0-rc`:
   1. подключите редактор вашего игрового движка к предоставленному URL + внешнему порту,
3. Обновите неиспользуемый матчмейкер `синий` чтобы привязать его к новому тегу образа `t1.2.0`,
   1. включите кэширование для новой версии приложения `v1.2.0-rc` , включение кэша для этой версии обеспечит, что образ также будет кэширован для версии `v-blue`  поскольку они ссылаются на один и тот же тег,
   2. дождитесь, пока индикатор кэширования в версии `v1.2.0-rc`  достигнет :green\_circle: зелёного,
4. Обновите ваш новый игровой клиент `c2` чтобы использовать новую версию `v-blue` при создании билетов:
   1. обновите базовый URL и токен авторизации в игровом клиенте,
5. Выполните QA-тесты и финальные проверки вашего нового игрового клиента `c2`:
   1. если вы обнаружите и устраните какие-либо проблемы, повторите процесс с самого начала,
   2. подождите 3–7 дней, чтобы изменения DNS матчмейкера распространились среди провайдеров по всему миру после остановки матчмейкера (быстрый перезапуск не требует обновления DNS или периода ожидания),
6. Выпустите обновление вашего нового игрового клиента `c2` на платформах распространения игр,
7. Дайте время новому игровому клиенту `c2` распространиться на устройства игроков (обычно до 3–7 дней):
   1. отслеживайте устаревшие игровые клиенты `c1`  с использованием развёртывания [Развертывания](/ru/learn/orkestraciya/deployments.md#analytics),
8. Очистите неиспользуемые ресурсы в вашей учётной записи Edgegap:
   1. удалите тег образа `t1.0.0` чтобы освободить место в Container Registry,
   2. удалите тег образа `t1.1.0` чтобы освободить место в Container Registry,
   3. выключите ваш `зелёный`  матчмейкер, чтобы приостановить выставление счетов до вашего следующего обновления.

{% hint style="success" %}
**Для вашего следующего обновления**, увеличьте номера версий и замените `зелёный` и `синий` ключевые слова в руководстве.
{% endhint %}

#### **⚡ Горячее исправление сервера**

**Предварительные требования:** В этом разделе предполагается, что вы завершили [#before-going-live](#before-going-live "mention").

Чтобы **выпустить патч сервера без необходимости обновления игрового клиента**, вы можете:

1. Подготовьте новую версию серверного приложения `v1.2.0-rc` в Edgegap:
   1. отправьте новый тег образа в ваш реестр контейнеров `t1.2.0`,
   2. создайте новую версию приложения `v1.2.0-rc`,
2. Выполните тесты и проверки,  [разворачивая новую версию приложения](https://app.edgegap.com/deployment-management/deployments/list) `v1.2.0-rc`:
   1. подключите редактор вашего игрового движка к предоставленному URL + внешнему порту,
   2. если вы обнаружите и устраните какие-либо проблемы, повторите процесс с самого начала,
   3. включите кэширование для новой версии приложения `v1.2.0-rc` , включение кэша для этой версии обеспечит, что образ также будет кэширован для версии `v-green`  позже, поскольку они будут ссылаться на один и тот же тег,
   4. дождитесь, пока индикатор кэширования в версии `v1.2.0-rc`  достигнет :green\_circle: зелёного,
3. Обновить версию `v-green`  чтобы привязать его к новому тегу образа `t1.2.0`,
   1. новые матчи будут автоматически начинать назначение с обновлённым тегом `t1.2.0`,
   2. отслеживайте устаревшие игровые клиенты `c1`  с использованием развёртывания [Развертывания](/ru/learn/orkestraciya/deployments.md#analytics),
4. Очистка неиспользуемых ресурсов в вашей учётной записи Edgegap:
   1. удалите тег образа `t1.1.0` чтобы освободить место в Container Registry.

## 📗 API <a href="#matchmaking-api" id="matchmaking-api"></a>

Клиенты и серверы могут вызывать API напрямую или с помощью SDK игрового движка, см. также [Подбор игроков](/ru/learn/podbor-igrokov.md).

{% hint style="info" %}
Unity/Android — рассмотрите возможность [использования подстановки в сырой строке](https://www.c-sharpcorner.com/article/convert-string-to-json-in-c-sharp/) чтобы предотвратить удаление кода жестко заданных JSON-файлов.
{% endhint %}

{% hint style="success" %}
**Веб-интерфейс Swagger**: при развертывании вашего управляемого сервиса генерируется спецификация OpenAPI и удобный веб-интерфейс, полезный для тестирования крайних случаев или проверки структуры полезных данных.
{% endhint %}

{% tabs fullWidth="false" %}
{% tab title="🍀 Простой пример" %}
{% file src="/files/7d0f90dc43c3b7d145adac1ad73250ee407bb816" %}
{% endtab %}

{% tab title="🏁 Продвинутый пример" %}
{% file src="/files/174cc4ac8b555f73c277175e8e15173e226b8ed9" %}
{% endtab %}

{% tab title="🎾 Пользовательский лобби" %}
{% file src="/files/11e2695177f3949632a909a5baf2c4d45c2ebfdc" %}
{% endtab %}

{% tab title="🥛 Демонстрация подбора игроков" %}
{% file src="/files/db149be8a4616a601a799ce1f015caace9ee1e03" %}
{% endtab %}

{% tab title="⚔️ Соревновательные игры" %}
{% file src="/files/4438d60914c9c7a4b475bb5bc172ebe487125bbd" %}
{% endtab %}

{% tab title="🤝 Кооперативные игры" %}
{% file src="/files/5794324ea05f7587619d5cc384394d352fb718d8" %}
{% endtab %}

{% tab title="🎈 Социальные игры" %}
{% file src="/files/17d42dcf1fc9846bdbb74a6d6303005d408f851e" %}
{% endtab %}
{% endtabs %}

Импортировать спецификацию API в [Веб-клиент Scalar API](https://client.scalar.com/workspace/default/request/default) или [Swagger Editor](https://editor.swagger.io/) для изучения деталей.

### Ограничения по скорости

Чтобы защитить ваш кластер от превышения его всплескной ёмкости и падения, мы ограничиваем число запросов в секунду на основе наших внутренних нагрузочных тестов с использованием [Подбор игроков](/ru/learn/podbor-igrokov.md#advanced-example) конфигурации.

<table><thead><tr><th>конечная точка API</th><th width="130">Бесплатный тариф</th><th width="130">Любительский тариф</th><th width="130">Тариф Studio</th><th width="130">Тариф Enterprise</th></tr></thead><tbody><tr><td><strong>Общий лимит</strong></td><td><strong>100</strong></td><td><strong>200</strong></td><td><strong>750</strong></td><td><strong>2,000</strong></td></tr><tr><td>Создать развёртывание</td><td>5</td><td>10</td><td>30</td><td>30</td></tr><tr><td>Список маяков</td><td>10</td><td>20</td><td>75</td><td>200</td></tr><tr><td>Создать группу<br>+ Создать билет<br>+ Создать групповой билет</td><td>10</td><td>20</td><td>75</td><td>200</td></tr><tr><td>Читать членство<br>+ Читать группу<br>+ Читать билет</td><td>10</td><td>120</td><td>450</td><td>1,300</td></tr><tr><td>Создать Backfill</td><td>5</td><td>10</td><td>37</td><td>100</td></tr></tbody></table>

Ограничения по скорости выражаются в **суммарных запросах в секунду к указанному набору конечных точек API**.

{% hint style="warning" %}
Если ваши игровые клиенты не повторяют запросы после получения ответа `429 Слишком много запросов` **в ваших развёртываниях могут отсутствовать игроки** во время коротких всплесков и пиковых периодов трафика.
{% endhint %}

#### Нагрузочное тестирование

Нагрузочное тестирование в среде, похожей на производственную, связано со стоимостью хостинга развертывания. См. ресурсы и цены, связанные с каждым уровнем, на [нашей странице с тарифами](https://edgegap.com/resources/pricing#matchmaker).

{% hint style="warning" %}
**Используйте** [**частные кластеры**](#private-cluster-tiers) **для стресс-тестирования.** Бесплатные экземпляры строго ограничены и предназначены только для тестирования в разработке.
{% endhint %}

При проектировании нагрузочного теста, **пожалуйста, учитывайте реалистичные модели поведения игроков**:

| Реалистичный сценарий                                                                                      | Нереалистичный шаблон трафика                                                                   |
| ---------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| ✅ Игроки постепенно присоединяются к игре, увеличивая число запросов в секунду в течение нескольких часов. | ❌ Все игроки скоординированно обращаются к API в одну и ту же секунду.                          |
| ✅ Игроки ждут всё больше времени между повторными попытками (например, 1 с – 5 с – 10 с – 10 с).           | ❌ Все игроки повторяют попытку немедленно при получении `429 Слишком много запросов`  ответа.   |
| ✅ Большинство игроков получат свои назначения в течение короткого времени (10–60 с) и прекратят опрос.     | ❌ Все игроки продолжают опрашивать в течение заданного времени даже после получения назначения. |
| ✅ Большинство игроков завершают свою игру (это занимает время), прежде чем начать новую сессию.            | ❌ Все игроки немедленно перезапускают свою сессию сразу после получения назначения сервера.     |
| ✅ Пиковый трафик сохраняется примерно 6 часов в день, после чего часть часовых поясов отключается.         | ❌ Пиковый трафик сохраняется 24 часа в сутки, и все игроки играют и днём и ночью.               |

#### Поведение под нагрузкой

Если матчмейкер испытывает высокую нагрузку:

* если CPU троттлит, матчмейкинг может замедлиться,
* если у матчмейкера закончится память, он перезапустится без потери информации о билетах, надеясь, что клиенты реализуют экспоненциальный backoff и всплеск растянется на более длительный период времени.

#### Совместное использование ресурсов между источниками (CORS)

Для WebGL-игр, размещённых на сторонних платформах распространения (например, [itch.io](http://itch.io/)), отправка любых запросов к Matchmaker из игрового клиента может привести к [совместному использованию ресурсов между источниками](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) нарушениям политики. Большинство современных веб-браузеров отправляют [предварительный запрос](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request) чтобы проверить, понимает ли backend-сервис (Matchmaker) и принимает ли он связь от вашего игрового клиента.

Неудачная предварительная проверка (по умолчанию по соображениям безопасности) может привести к [одной из нескольких возможных ошибок, связанных с CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSMissingAllowOrigin), чаще всего `отсутствует заголовок CORS 'Access-Control-Allow-Origin'` .

Чтобы устранить эту ошибку, добавьте **`allowed_cors_origin`** параметр в вашу конфигурацию, чтобы либо:

* внести в белый список точные домены, на которых размещён ваш клиент:

<details>

<summary>🍀 Простой пример (пример с конкретными доменами)</summary>

<pre class="language-json"><code class="lang-json">{
  "version": "3.2.3",
  "allowed_cors_origins": [
    "https://dev.my-game-server.com",
    "https://prod.my-game-server.com"
  ],
  "profiles": {
      <a data-footnote-ref href="#user-content-fn-11">...</a>
  }
}
</code></pre>

</details>

* или внести в белый список домен с подстановочным знаком (включая все поддомены):

<details>

<summary>🍀 Простой пример (пример с доменом-подстановкой)</summary>

<pre class="language-json"><code class="lang-json">{
  "version": "3.2.3",
  "allowed_cors_origins": ["https://*.my-game-server.com"],
  "profiles": {
      <a data-footnote-ref href="#user-content-fn-11">...</a>
  }
}
</code></pre>

</details>

{% hint style="info" %}
**Для предварительных запросов Matchmaker не требуются учётные данные**, если домены настроены правильно.
{% endhint %}

### Сервер к серверу <a href="#server-to-server-api" id="server-to-server-api"></a>

Добавьте расширенные или настраиваемые элементы управления потоком матчмейкинга — реализуйте пользовательский прокси с помощью нашего [Управляемых кластеров](/ru/learn/advanced-features/managed-clusters.md) или любого облачного FaaS[^12] вычислительного платформенного сервиса, чтобы достичь любого из:

* прикреплять чувствительные атрибуты игроков — такие как флаги читерства, рейтинги навыков или подобное,
* предоставлять контекст команды и матча в игре — перечислять моих союзников и противников во время загрузки,
* ограничивать определённые крайние случаи — например, разрешать только 1 группу на игрока в любой момент времени,
* добавлять кэширование или ограничение частоты API — уменьшать число запросов и нагрузку на матчмейкер,
* настраивать интеграцию лобби и группы — создавать асимметричные/ролевые лобби перед матчмейкингом.

{% hint style="success" %}
**Включите параметр `player_ip`  с публичным IP-адресом участника** чтобы обеспечить минимально возможную задержку для игрока и воспользоваться [/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-1.-server-score-strategy-best-practice](https://docs.edgegap.com/ru/learn/podbor-igrokov/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-1.-server-score-strategy-best-practice "mention").
{% endhint %}

{% hint style="info" %}
Игровые клиенты могут использовать [ipify.org](http://ipify.org/) бесплатный сервис ipify.org для определения своих публичных IP-адресов. VPN могут скрывать публичный IP-адрес.
{% endhint %}

<figure><img src="/files/93040a08d96eb0a657bc04834091d9667fff7716" alt=""><figcaption><p>Диаграмма активности матчмейкинга сервер-сервер</p></figcaption></figure>

## 🚨 Устранение неполадок

**Ваш успех — наш приоритет.** Если вы хотите отправить пользовательские запросы, попросить о недостающих критически важных функциях или высказать любые мысли, [пожалуйста, свяжитесь с нами в нашем Discord-сообществе](https://discord.gg/MmJf8fWjnt).

<details>

<summary><code>Конфигурация приложения недействительна для профиля XYZ.</code></summary>

* Мы не смогли найти ваш [Приложения и версии](/ru/learn/orkestraciya/application-and-versions.md), пожалуйста, проверьте `приложение`  значения.

</details>

<details>

<summary><code>Docker-образ для '2024.01.30-16.23.00-UTC' не кэширован.</code></summary>

[**🌟 Обновитесь до тарифа Pay as You Go**](https://app.edgegap.com/user-settings?tab=memberships) **чтобы разблокировать** [**мгновенные развёртывания с кэшированием**](https://docs.edgegap.com/ru/learn/podbor-igrokov/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-1.-start-a-deployment)**.**

* Некэшированные образы размером 4 ГБ и более могут дольше развёртываться, что приведёт к [/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-4.-deployment-error](https://docs.edgegap.com/ru/learn/podbor-igrokov/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-4.-deployment-error "mention"). Рассмотрите возможность оптимизации размера образа сервера ([Unreal Engine](/ru/unreal-engine.md#optimize-server-build-size) / [Unity](/ru/unity.md#optimize-server-build-size)).
* Вы всё равно можете продолжить, хотя мы рекомендуем протестировать время развёртывания.

</details>

<details>

<summary>Почему я получаю ошибки при попытке создать новый матчмейкер?</summary>

* Пожалуйста, прочитайте сообщение об ошибке: возможно, вы неправильно написали идентификатор, правило или оператор. - Используйте [JSONLint](https://jsonlint.com/) для проверки форматирования JSON; возможно, вы пропустили запятую или скобку. - Обратитесь через [наш Discord-сообщество](https://discord.gg/MmJf8fWjnt) за помощью, мы будем рады помочь. 🙏

</details>

<details>

<summary>Почему мой матчмейкер автоматически отключился через 3 часа?</summary>

* Матчмейкеры на бесплатном тарифе предназначены для начальных тестов и автоматически отключаются через 3 часа. Чтобы продолжить тестирование, вы можете [перезапустить ваш матчмейкер](https://app.edgegap.com/matchmaker-management-v2/matchmakers/list).
* Рассмотрите возможность обновления до платного тарифа для неограниченного времени работы.

</details>

<details>

<summary>Почему я не могу запустить второе развёртывание в своей учётной записи?</summary>

* В бесплатном тарифе вы можете запускать только 1 одновременное развёртывание.
* Пожалуйста, рассмотрите возможность обновления до платного тарифа для неограниченного числа развёртываний.

</details>

<details>

<summary>Почему я получаю назначение/развёртывание в случайные моменты, игнорируя <code>player_count</code>?</summary>

* Вы или другой член команды могли создать билеты во время предыдущей тестовой сессии, которые не были назначены. Пожалуйста [перезапустить ваш матчмейкер](https://app.edgegap.com/matchmaker-management-v2/matchmakers/list).

</details>

<details>

<summary>Мой билет застрял в <code>ПОИСКЕ</code> .</summary>

* Пожалуйста, проверьте, что вы создали достаточное количество подходящих билетов, соответствующих вашей конфигурации.

</details>

<details>

<summary>Мой билет застрял, переключаясь между <code>MATCH_FOUND</code> и <code>КОМАНДА НАЙДЕНА</code> многократно.</summary>

* Учётные записи на бесплатном тарифе ограничены 1 развёртыванием одновременно.
* Пожалуйста, рассмотрите возможность обновления или остановите текущее развёртывание, чтобы запустить новое.

</details>

<details>

<summary>Мой билет сразу переходит в <code>ОТМЕНЕНО</code>.</summary>

* Срок действия вашего билета истёк. Создайте новый билет или увеличьте период истечения в своей конфигурации для тестирования.

</details>

<details>

<summary>Я получаю <code>HTTP 404 Not Found</code> при проверке моего билета.</summary>

* Ваш билет был удалён либо запросом DELETE, либо по достижении периода удаления (начинается после истечения срока действия билета, определённого в вашей конфигурации). Создайте новый билет заново или увеличьте периоды истечения/удаления в своей конфигурации для тестирования.

</details>

<details>

<summary>Мой матчмейкер показывает ошибку, что мне делать?</summary>

* Если это экземпляр для разработки или тестирования, сначала попробуйте перезапустить ваш матчмейкер. - Сообщайте о любых проблемах через [наш Discord-сообщество](https://discord.gg/MmJf8fWjnt).
* Если эта проблема влияет на живую игру, создайте [срочный запрос в поддержку](https://edgegap.atlassian.net/servicedesk/customer/portal/3).

</details>

## 🔖 Журнал изменений

#### Семантическое версионирование

Наши инструменты для разработчиков и управляемые сервисы используют официальное [Семантическое версионирование](https://semver.org/), что указывает, какие обновления ✅ безопасны (minor, patch), а какие могут содержать ⚠️ несовместимые изменения (major).

**После выпуска версия никогда не будет изменена**.

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

{% hint style="info" %}
**Последняя версия матчмейкера — `3.2.5`**. Все примеры на этой странице актуальны.

Следите за [обновлениями и объявлениями](/ru/docs/release-notes.md). См. также [#rolling-updates-and-ab-tests](#rolling-updates-and-ab-tests "mention").
{% endhint %}

{% hint style="warning" %}
**Чтобы обновить версию вашего матчмейкера — остановите, измените, перезапустите.** Быстрый перезапуск не применит изменения версии.
{% endhint %}

[^1]: пример значения

[^2]: игровые клиенты присоединяются к Лобби, чтобы получить ID группы подбора матча и присоединиться к группе

[^3]: Fully Qualified Domain Name

[^4]: например, для 3 свободных слотов = \["3", "2", "1"]

[^5]: замените "2" на число фактических участников группы

[^6]: замените на собственное имя приложения

[^7]: замените на собственную версию приложения

[^8]: превышена максимальная разница

[^9]: превышена максимальная задержка

[^10]: поставщик интернет-услуг

[^11]: см. другие примеры

[^12]: [Функция как услуга](https://www.ibm.com/think/topics/faas)
