> 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/fr/learn/matchmaking/matchmaker-in-depth.md).

# Analyse approfondie

Découvrez en détail les concepts de matchmaking sans code d’Edgegap et personnalisez-les selon vos besoins.

{% hint style="info" %}
Si vous avez besoin d’aide, [veuillez nous contacter sur Discord](https://discord.gg/MmJf8fWjnt). Pour l’assistance aux jeux en direct, consultez notre [système de tickets](https://edgegap.atlassian.net/servicedesk/customer/portal/3).
{% endhint %}

## ✔️ Introduction

Le matchmaking dans les jeux basés sur des matchs vise généralement à :

* **trouver d'autres joueurs** en fonction de critères tels que la région, la latence, le niveau, ou les paramètres du jeu ;
* **rechercher des serveurs** pour rejoindre en fonction de la capacité disponible \[ou du ping, de la région, du niveau, de la carte, du mode] ;
* **démarrer un nouveau serveur** si les serveurs existants sont pleins ou ne répondent pas aux critères des joueurs.

L'expérience du joueur passe avant tout, définissant nos objectifs principaux :

* taux de remplissage des matchs élevé et intégration des fonctionnalités sociales (jouer avec des amis en groupe),
* matchs rapides avec qualité de match contrôlée (faible latence, préférences partagées),
* processus de matchmaking fiable et prévisible avec une disponibilité mondiale.

{% hint style="success" %}
Alternativement, laissez les joueurs **choisir un serveur persistant (toujours en ligne)** d'une liste avec [Navigateur de serveurs](/fr/learn/navigateur-de-serveurs.md).
{% endhint %}

**Commencez en moins de 5 minutes et testez toutes les fonctionnalités gratuitement, sans carte de crédit requise.**

Passez à la version supérieure lorsque vous êtes prêt pour un cluster privé (dédié) plus puissant. Intégration native avec Edgegap [Déploiements](/fr/learn/orchestration/deployments.md) offre un ping de premier ordre, quel que soit l'endroit où se trouvent vos joueurs.

{% hint style="info" %}
Le forfait gratuit permet 3 heures d'exécution après chaque redémarrage. Votre matchmaker fonctionnera sur une infrastructure partagée aux ressources limitées, adaptée aux tests. **Après votre lancement public, le matchmaker doit fonctionner 24 h/24 et 7 j/7.**
{% endhint %}

Chaque Matchmaker repose sur trois concepts essentiels :

* [#hosting-cluster](#hosting-cluster "mention") - infrastructure serveur sous-jacente, entièrement gérée et exploitée par Edgegap.
* [#configuration](#configuration "mention") - ensemble de règles et de paramètres qui définissent le fonctionnement du matchmaker.
* 🌐 Instance de service **-** service de matchmaking en direct fonctionnant 24 h/24 et 7 j/7 sur le cluster, utilisant la configuration pour regrouper les joueurs et produire des affectations de déploiement (serveur).

{% hint style="success" %}
[Mettez fréquemment à jour la version de votre matchmaker](#changelog) à **pour profiter des nouvelles fonctionnalités et corrections de bugs.**
{% endhint %}

## ▶️ Démarrer le matchmaking

**Démarrez rapidement - ajoutez notre SDK à votre jeu**:

* Unreal Engine [Outils pour développeurs](/fr/unreal-engine/developer-tools.md#integration-kit):
  * [lisez la documentation](https://egik.betide.studio/) par Betide Studios,
  * [installez depuis Fab Marketplace](https://www.fab.com/listings/ff17ad88-12a1-49cf-9a41-31695ed11e16) (gratuit pour un usage personnel).
* Unity [Outils pour développeurs](/fr/unity/developer-tools.md#software-development-kit):
  * [installer le package gratuitement via Unity Package Manager](https://github.com/edgegap/edgegap-unity-sdk),
  * [explorez notre guide de démarrage et des exemples complets](/fr/unity/matchmaking.md).

Découvrez le processus de matchmaking afin de personnaliser, dépanner et optimiser l'intégration de votre jeu :

<figure><img src="https://3008966946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fm4U4bgwucX6iGEieMISU%2Fimage.png?alt=media&amp;token=39b97619-700b-4062-9dd9-73fa08fb96c2" alt=""><figcaption><p>Séquence de matchmaking</p></figcaption></figure>

1. [Authentifier le joueur](#authenticate) - empêche les copies piratées de jouer en ligne,
2. [Créer le lobby](#create-group) - rejoignez vos amis et partagez les préférences de joueur/match,
3. [**Former un groupe**](#group-up) **- enregistrez votre lobby comme groupe de matchmaking,**
4. [**Trouver une partie**](#find-match) **- préparez-vous et commencez à chercher une partie (nouvelle ou existante),**
   1. Attribuer le serveur et injecter les tickets - le serveur est automatiquement attribué après quelques secondes,
5. [**Se connecter et s'authentifier**](#connect-to-server) **- tenter une connexion sécurisée au serveur de jeu,**
   1. Confirmer l'identité - le serveur vérifie l'identité du client de jeu à l'aide de jetons tiers,
   2. Accepter le joueur ou le renvoyer - le serveur décide si le joueur est autorisé à rejoindre.

### Authentifier

Toutes les requêtes doivent envoyer un `Authorization`  en-tête HTTP avec votre secret **Jeton d'authentification :**

<pre><code>Autorisation : <a data-footnote-ref href="#user-content-fn-1">xxxxxxxx-e458-4592-b607-c2c28afd8b62</a>
</code></pre>

{% hint style="warning" %}
**Gardez vos jetons secrets et en sécurité ! Le personnel d'Edgegap ne vous demandera jamais vos jetons.**
{% endhint %}

{% hint style="info" %}
Le jeton Matchmaker et les jetons Server Browser sont distincts des jetons API d'Edgegap.
{% endhint %}

{% hint style="success" %}
**Ce jeton peut être inclus en toute sécurité dans votre client de jeu, car il ne donne pas accès à l'API Edgegap.**
{% endhint %}

Les joueurs individuels peuvent être identifiés à l'aide de leur ID de ticket, disponible côté client et serveur. En option, ajoutez une authentification ou des limites personnalisées avec un proxy personnalisé à l'aide de [#server-to-server-api](#server-to-server-api "mention") l'API.

### Former un groupe

Créer un groupe garantit que les joueurs rejoignent la même équipe et le même serveur que leurs amis.

{% hint style="success" %}
Créez un groupe marqué comme prêt pour [#find-match](#find-match "mention") rapidement en tant que **joueur solo sans membres de groupe**.
{% endhint %}

<figure><img src="https://3008966946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2FO79XVv9r9uZQ7ZI1kbFv%2FUntitled-2024-12-04-1155.png?alt=media&amp;token=9cf9caab-236d-4127-bb0f-4d50e1915f47" alt=""><figcaption><p>Diagramme d'activité du cycle de vie du groupe</p></figcaption></figure>

#### Lobby et groupe

Lobby et groupe sont des termes similaires mais légèrement différents, liés à [Sessions de joueur](/fr/learn/orchestration/sessions-de-joueur.md).

Utilisez un service de lobby si la conception de votre jeu exige de définir des préférences de matchmaking contrôlées par le joueur (p. ex. choix du personnage, difficulté, carte, etc.). À mesure que les joueurs rejoignent et quittent le lobby, ils mettent également à jour le groupe de matchmaking afin de se préparer à trouver une partie plus tard.

{% hint style="success" %}
**Vous n'avez pas le temps de mettre en place un service de lobby ?** Indiquez aux joueurs de partager les ID de groupe via Discord ou par message privé.
{% endhint %}

<table data-search="false"><thead><tr><th width="390">Conception du jeu - Fonctionnalité / Exigence</th><th>Lobby avant partie</th><th>Groupe de matchmaking</th></tr></thead><tbody><tr><td><a data-footnote-ref href="#user-content-fn-2">inviter des amis à jouer avec moi</a></td><td>✅</td><td>✅</td></tr><tr><td>modifier mes préférences de joueur/de match</td><td>✅</td><td>❌</td></tr><tr><td>voir les préférences des autres membres du lobby</td><td>✅</td><td>❌</td></tr><tr><td>stocker et gérer des données personnalisées clé-valeur</td><td>✅</td><td>❌</td></tr><tr><td>notifier aux membres du groupe que je suis prêt à jouer</td><td>❌</td><td>✅</td></tr><tr><td>afficher la progression du matchmaking et trouver une partie</td><td>❌</td><td>✅</td></tr><tr><td>obtenir l'affectation d'équipe pour un joueur/groupe</td><td>❌</td><td>✅</td></tr><tr><td>récupérer les détails de connexion au serveur de jeu</td><td>❌</td><td>✅</td></tr></tbody></table>

Notre matchmaker multiplateforme prend en charge tous les services de lobby commerciaux et personnalisés :

<table data-search="false"><thead><tr><th width="414">Back-end de jeu (y compris service de lobby tiers)</th><th width="120" data-type="checkbox">Unreal Engine</th><th width="75" data-type="checkbox">Unity</th><th data-type="checkbox">Godot</th></tr></thead><tbody><tr><td><a href="https://dev.epicgames.com/docs/game-services/lobbies-and-sessions/lobbies/lobbies-intro">Lobby Epic Online Services</a><br>(Epic Games)</td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://partner.steamgames.com/doc/features/multiplayer/matchmaking#friends">Lobby Steamworks</a><br>(Valve Corporation)</td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://heroiclabs.com/docs/nakama/concepts/groups/">Groupe Nakama</a><br>(Heroic Labs)</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">Lobby PlayFab</a><br>(Microsoft)</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">Lobby brainCloud</a><br>(bitHeads)</td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://github.com/foxssake/noray">noray</a><br>(Netfox)</td><td>false</td><td>false</td><td>true</td></tr><tr><td><a href="https://developer.apple.com/documentation/gamekit/connecting-players-with-their-friends-in-your-game">Amis Gamekit</a><br>(Apple)</td><td>true</td><td>true</td><td>false</td></tr><tr><td>Lobby personnalisé<br>(votre entreprise)</td><td>true</td><td>true</td><td>true</td></tr></tbody></table>

Le propriétaire du lobby (le joueur qui envoie les invitations) doit également créer le groupe de matchmaking.

**Stockez l'ID de votre groupe dans vos données de lobby partagées**, afin que les autres membres du lobby puissent facilement trouver et rejoindre un groupe de matchmaking associé au lobby tiers. Les joueurs invités au groupe utilisent l'ID de groupe pour **créer leur adhésion (rejoindre)**, et pour **stocker en toute sécurité leurs** [**attributs de matchmaking**](#matchmaking-rules)**.**

{% hint style="warning" %}
**Une fois qu'un groupe a commencé le matchmaking, il n'est plus possible de le rejoindre.** [#abandon-queue](#abandon-queue "mention") et en créer un nouveau.
{% endhint %}

#### Optimisation du ping

Si [#configuration](#configuration "mention") inclut [`latences` règle](#rule-example-elo_rating) tous les membres du groupe envoient leurs [Balises de ping](/fr/learn/orchestration/ping-beacons.md) mesures à **empêcher d'associer des joueurs de régions éloignées** ou avec un ping (latence) beaucoup plus élevé/plus faible.

{% code title="Exemple de mesures de ping du client de jeu en millisecondes" %}

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

{% endcode %}

#### **Abandonner la file**

Le propriétaire du groupe peut supprimer le groupe, ce qui supprime automatiquement toutes les adhésions au groupe. Supprimer le groupe après le début du matchmaking annulera toutes les adhésions et les supprimera peu après.

Les membres du groupe (à l'exception du propriétaire) peuvent supprimer leur adhésion (quitter le groupe) à tout moment avant [#find-match](#find-match "mention"). Supprimer une adhésion après cela annulera le matchmaking pour tout le groupe.

{% hint style="info" %}
Une fois le matchmaking annulé, les membres sont [retirés automatiquement du matchmaking](#matchmaking-profiles) et informés via l'adhésion `status:CANCELLED`  dans leur prochaine réponse d'interrogation de statut.
{% endhint %}

Une fois annulé, si le groupe souhaite relancer le matchmaking, le propriétaire du groupe doit recréer le groupe, partager le nouvel ID de groupe aux membres et leur faire recréer leurs adhésions.

**Une fois une partie trouvée, le groupe ne peut pas être supprimé** (`409 Conflict`), et sera [supprimé automatiquement](#connect-to-server)Votre serveur doit laisser un certain temps (p. ex. 60 s) aux joueurs pour se connecter avant de considérer qu'un joueur a abandonné.

Si votre serveur signale qu'un joueur a abandonné, vous pouvez :

* remplacer le joueur parti par un personnage IA pour lancer immédiatement la partie,
* ou créer un [backfill](#backfill-match) pour trouver un nouveau joueur afin de remplacer le joueur parti,
* ou continuer sans remplacer le joueur parti, si la conception de votre jeu permet un nombre de joueurs variable.

### Trouver une partie

Pour commencer à chercher une partie, tous les membres et le propriétaire doivent se marquer comme prêts.

{% hint style="success" %}
Pour permettre au propriétaire du groupe de **démarrer le matchmaking immédiatement, marquez les adhésions comme prêtes à la création**. Une fois que le propriétaire se marque comme prêt, le matchmaking démarrera, puisque tout le monde est prêt.
{% endhint %}

{% hint style="info" %}
Pour une meilleure expérience, **fournissez aux joueurs des mises à jour de statut via l'interface en jeu**.
{% endhint %}

**Tous les joueurs doivent interroger leur adhésion à intervalles réguliers** (3 à 5 s recommandés) pour détecter le début du matchmaking et communiquer la progression du matchmaking via l'interface en jeu.

Les joueurs doivent **enregistrer de manière persistante leur adhésion et les ID de groupe**, ce qui leur permet de redémarrer le jeu et de reprendre sans perdre la progression du matchmaking en cas de plantage du client de jeu.

Supprimer une adhésion à ce stade annulera toutes les adhésions du groupe et toutes les autres affectations des groupes à la même équipe reviendront à `status:SEARCHING` .

Les joueurs recherchent des parties en utilisant les valeurs communes entre leurs groupes (ou la moyenne dans le cas de `number_difference` ) jusqu'à ce que suffisamment de joueurs et d'équipes soient réunis. Les adhésions l'indiquent avec la réponse  `status:MATCH_FOUND` , ce qui signifie que votre [déploiement est en cours de démarrage](https://docs.edgegap.com/fr/learn/matchmaking/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-1.-start-a-deployment).

Les joueurs peuvent revenir de `status:MATCH_FOUND`  à `status:SEARCHING`  dans le cas où toutes les nouvelles tentatives de déploiement (telles que configurées) sont épuisées sans succès.

#### Correspondances partielles

Si la configuration de votre matchmaker autorise une taille d'équipe dynamique (paramètres min et max différents), certains joueurs peuvent se retrouver dans une correspondance partielle - avec moins de joueurs que le maximum défini.&#x20;

**Le matchmaker ne produira pas de parties avec moins que le minimum défini pour la taille de l'équipe.**

Les seuls scénarios dans lesquels les correspondances partielles sont autorisées sont :

1. un ou plusieurs joueurs dans la file atteignent un [#rule-expansion](#rule-expansion "mention") (si défini),
2. un ou plusieurs joueurs dans la file atteignent le délai d'expiration du ticket.

Une correspondance partielle est tentée une seule fois. Les joueurs non appariés reçoivent `status:CANCELLED`.

{% hint style="info" %}
Vous rencontrez de longs temps d'attente dans la file lors des tests, ou avec des joueurs dans des régions moins populaires ? Définissez une période d'expiration de ticket plus courte (p. ex. 30 s) et recréez le groupe (ou les tickets) côté client à l'expiration.
{% endhint %}

{% hint style="success" %}
Stocker `team_id`  et `match_id` dans votre backend de jeu pour afficher les informations des membres de l'équipe en jeu.
{% endhint %}

Chaque joueur reçoit un **ID de ticket unique, qui peut être utilisé pour** [#authenticate](#authenticate "mention") **avec les serveurs de jeu.**

Si le joueur a été apparié et attribué à un serveur de jeu, son ticket est supprimé automatiquement. Les joueurs qui quittent la file après `status:HOST_ASSIGNED`  peuvent être remplacés par [backfill](#backfill-match).

Une fois que les joueurs reçoivent `status:HOST_ASSIGNED`  ils passent à [#connect-to-server](#connect-to-server "mention").

### Se connecter au serveur

Quelques secondes après avoir trouvé une correspondance, les adhésions passent à `status:HOST_ASSIGNED`  indiquant que votre [le déploiement est maintenant prêt et votre serveur de jeu est en cours d'initialisation](https://docs.edgegap.com/fr/learn/matchmaking/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-3.-deployment-ready).

Chaque joueur lit son `ticket_id`  et  `attribution`  et tente une connexion en utilisant le [**FQDN**](#user-content-fn-3)[^3] **(URL du déploiement)** et le **port externe**. Votre serveur de jeu est peut-être encore en cours d'initialisation à ce moment-là, donc **les joueurs doivent réessayer la connexion plusieurs fois**, jusqu’à dépasser votre temps d'initialisation habituel du serveur :

{% tabs %}
{% tab title="Unreal Engine" %}
Pour **se connecter depuis PIE (éditeur)** pendant le développement et les tests, appuyez sur la touche tilde `~`  et tapez `open {URL}:{port}`  et attendez que votre éditeur charge la carte.

Pour **se connecter depuis une compilation du client de jeu** (et dans un environnement de production réel) essayez

* Unreal Engine [⚡ Kit d'intégration](https://docs.edgegap.com/learn/unreal-engine-games/developer-tools#integration-kit):
  * [installer depuis le Fab Marketplace](https://www.fab.com/listings/ff17ad88-12a1-49cf-9a41-31695ed11e16) (gratuit pour un usage personnel),
  * [importer un blueprint d'exemple simple](https://blueprintue.com/blueprint/m33u1okj/) et l'adapter à vos besoins.

{% hint style="success" %}
En cas d'échec de connexion ou d'écran noir, consultez notre [guide de dépannage](/fr/unreal-engine.md#troubleshooting-and-faq).
{% endhint %}
{% endtab %}

{% tab title="Unity" %}
Pour **connecter votre éditeur Unity** ou **client de jeu** à votre déploiement cloud, saisissez :

* **Déploiement** **URL** pointant vers l'adresse IP du serveur, généralement dans `NetworkManager` composant.
* **Port externe** correspondant au [port d'écoute interne du serveur](/fr/learn/orchestration/application-and-versions.md#port-mapping), généralement dans un composant Transport.

{% hint style="success" %}
En cas de délai d'attente de connexion ou d'autres problèmes, consultez notre [guide de dépannage](/fr/unity.md#troubleshooting-and-faq-4).
{% endhint %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Nous ne demandons pas aux joueurs de confirmer la partie, car nous visons à fournir le temps d'accès au gameplay le plus court possible, un taux de remplissage des parties élevé, et à minimiser l'évitement de file d'attente et les annulations de partie.
{% endhint %}

Les clients de jeu doivent **enregistrer de façon persistante leur identifiant d’attribution entre les redémarrages du jeu**, afin qu’en cas de plantage du client de jeu, ils puissent récupérer les détails de connexion et tenter de se reconnecter.

### Correspondance de backfill

En option, certains jeux peuvent avoir des besoins particuliers en matière de matchmaking, tels que :

* permettre aux nouveaux joueurs de rejoindre des parties en cours (amis ou « aléatoires »),
* remplacer les joueurs qui quittent la partie (quitteurs) après le démarrage du serveur afin d’éviter de relancer la partie,
* permettre aux spectateurs de rejoindre et d’observer des tournois ou les matchs d’amis (e-sport),
* centraliser les joueurs sur des serveurs plus grands pour offrir davantage d’interactions sociales (MMO).

Le backfill est un **ticket détenu par le serveur représentant les joueurs actuellement connectés au serveur.** Cela garantit que les joueurs ajoutés respecteront vos règles de matchmaking lorsqu’ils seront appariés avec les joueurs actuels.

{% hint style="warning" %}
[Analyse approfondie](/fr/learn/matchmaking/matchmaker-in-depth.md#backfill-match) pour remplacer les sessions Seat/Match. Matchmaker ne prend en charge que la session par défaut.
{% endhint %}

<figure><img src="https://3008966946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2FJhdLAJYga4z2sjxLj6LM%2FUntitled-2024-10-29-1018.png?alt=media&amp;token=279136ba-a15e-46b0-a119-8419b8aca044" alt=""><figcaption><p>Scénarios de backfill visualisés</p></figcaption></figure>

{% hint style="success" %}
**Les backfills ignorent** `player_count`  **la règle, et correspondent toujours exactement à un seul groupe**. `backfill_group_size`  contrôle la capacité des équipes avec une stratégie en round-robin, en remplissant les équipes de manière uniforme et contrôlée.
{% endhint %}

**Les étapes pour réaliser un backfill réussi sont :**

1. Le serveur doit créer un Backfill par équipe manquant de joueurs, en utilisant les valeurs provenant de :
   * Réel `affectation`  données récupérées depuis [Déploiements](/fr/learn/orchestration/deployments.md#injected-environment-variables) (déploiement).
   * des joueurs actuellement connectés `tickets`:
     * depuis [Analyse approfondie](/fr/learn/matchmaking/matchmaker-in-depth.md#injected-variables) (matchmaker), des backfills précédents' `assigned_ticket` réponse, ou des données simulées manipulées pour correspondre à des joueurs spécifiques,
     * remplacer `backfill_group_size`  les valeurs par des tailles de groupe possibles [jusqu’à la capacité disponible](#user-content-fn-4)[^4],
2. Les clients de jeu créent de nouveaux tickets (adhésions) et incluent `backfill_group_size`  valeurs :
   * `"1"`  si le joueur effectue le matchmaking seul.
   * [`"2"`  si le joueur fait partie d’un groupe de matchmaking comptant 2x membres au total](#user-content-fn-5)[^5].
   * `"nouveau"`  si les joueurs ont activé le démarrage de nouvelles parties en plus de rejoindre des parties en cours.
3. Les clients de jeu procèdent à [Analyse approfondie](/fr/learn/matchmaking/matchmaker-in-depth.md#find-match) et associent les joueurs au backfill correspondant.
4. Si le groupe complété ne remplit pas entièrement l’équipe, le serveur peut répéter ce processus avec les tickets des joueurs nouvellement ajoutés via backfill, afin d’ajouter davantage de joueurs et d’atteindre les tailles d’équipe souhaitées.

{% hint style="success" %}
Les backfills ignorent les règles de taille d’équipe et associent toujours 1 backfill à 1 groupe. **Pour n’apparier qu’avec des backfills et désactiver l’appariement avec les autres joueurs dans la file d’attente, définissez `min_team_size: 999999` .**
{% endhint %}

<details>

<summary>🥛 Exemple de backfill (vitrine de backfill)</summary>

```json
{
  "profile": "backfill-example",
  "attributs": {
    "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": "Montréal",
        "country": "Canada",
        "continent": "Amérique du Nord",
        "administrative_division": "Québec",
        "timezone": "America/Toronto"
      }
    }
  },
  "tickets": {
    "c3d057h5h6f7j889fk43": {
      "player_ip": "174.25.48.238",
      "attributs": {
        "balises": {
          "New York": 12.2,
          "Los Angeles": 45.3,
          "Paris": 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",
      "attributs": {
        "balises": {
          "New York": 21.0,
          "Los Angeles": 30.2,
          "Paris": 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>🥛 Exemple d’affectation de backfill (vitrine de backfill)</summary>

```json
{
  "profile": "backfill-example",
  "attributs": {
    "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": "Montréal",
        "country": "Canada",
        "continent": "Amérique du Nord",
        "administrative_division": "Québec",
        "timezone": "America/Toronto"
      }
    }
  },
  "tickets": {
    "c3d057h5h6f7j889fk43": {
      "player_ip": "174.25.48.238",
      "attributs": {
        "balises": {
          "New York": 12.2,
          "Los Angeles": 45.3,
          "Paris": 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",
      "attributs": {
        "balises": {
          "New York": 21.0,
          "Los Angeles": 30.2,
          "Paris": 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",
    "attributs": {
      "balises": {
        "New York": 30.2,
        "Los Angeles": 10.5,
        "Paris": 123.9
      },
      "backfill_group_size": [
        "nouveau",
        "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" %}
Voir [Gestion des sièges en miroir](https://docs.edgegap.com/docs/sample-projects/mirror-on-edgegap#bonus-seat-sessions-management) et [Gestion des sièges FishNet](https://docs.edgegap.com/docs/sample-projects/fishnet-on-edgegap#bonus-seat-sessions-management) pour **la surveillance des connexions des joueurs**.
{% endhint %}

Une fois l'initialisation du serveur de jeu terminée, **votre serveur doit**:

* **Démarrer le minuteur d'abandon pour chaque nouveau joueur.** Nous recommandons d'indiquer la progression du chargement aux joueurs connectés avec une scène/un niveau de chargement - soit une scène 3D complète, une interface sociale de type lobby, soit un écran de chargement avec une barre de progression.
* **Suivez les nouvelles connexions de joueurs ou les départs de joueurs existants au fil du temps**:
  1. Les nouveaux joueurs doivent annoncer l'ID de ticket au serveur pour l'authentification et pour associer leur connexion au matchmaker [#injected-variables](#injected-variables "mention") ou `assigned_ticket` (si backfill).
  2. Créez de nouveaux backfills pour la capacité de joueurs inutilisée (joueurs partis) tout au long de la durée de vie du serveur.
  3. Renouvelez les backfills expirés, qui sont supprimés après `ticket_expiration_period`.
* **Nettoyez (supprimez) tout backfill restant** une fois que le [/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-5.-deployment-stopped](https://docs.edgegap.com/fr/learn/matchmaking/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-5.-deployment-stopped "mention"):
  * Unity - [`OnApplicationQuit`](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/MonoBehaviour.OnApplicationQuit.html) appel de rappel ou rappel de fin de partie personnalisé,
  * 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) , ou un rappel de fin de partie personnalisé.

{% hint style="info" %}
Utilisez [GetEnvironmentVariable en C#](https://learn.microsoft.com/en-us/dotnet/api/system.environment.getenvironmentvariable?view=net-8.0) ou [GetEnvironmentVariable en C++](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/GenericPlatform/FGenericPlatformMisc/GetEnvironmentVariable) pour obtenir les valeurs des variables.
{% endhint %}

N'importe quel profil peut être utilisé pour le backfill tant qu'une affectation de serveur valide et au moins un ticket sont fournis. Voir [Matchmaking](/fr/learn/matchmaking.md#backfill-showcase) pour un exemple minimal.

## ⚙️ Configuration

L'API du matchmaker est générée à partir d'une configuration JSON spécifiée lorsque vous créez un nouveau Matchmaker (ou un redémarrage rapide). Vous pouvez définir n'importe quel nombre de profils avec des règles et des expansions différentes :

{% hint style="success" %}
Voir [Matchmaking](/fr/learn/matchmaking.md) pour nos SDK et des scénarios d'exemple détaillés.
{% endhint %}

<details>

<summary>🍀 Exemple simple (configuration minimale recommandée)</summary>

<pre class="language-json"><code class="lang-json">{
  "version": "3.3.3",
  "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>🏁 Exemple avancé (configuration d'exemple complète)</summary>

```json
{
  "version": "3.3.3",
  "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> Exemple de configuration de backfill</summary>

```json
{
  "version": "3.3.3",
  "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>⚔️ Exemple de jeu compétitif</summary>

```json
{
  "version": "3.3.3",
  "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>🤝 Exemple de jeu coopératif</summary>

```json
{
  "version": "3.3.3",
  "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>🎈 Exemple de jeu social</summary>

```json
{
  "version": "3.3.3",
  "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" %}
Modifier un matchmaker en cours d'exécution **déclenchera un rechargement rapide**, supprimant tous les tickets et provoquant une courte interruption.
{% endhint %}

<details>

<summary><code>La configuration de l'application n'est pas valide pour le profil XYZ.</code></summary>

* Nous n'avons pas trouvé votre [Applications et versions](/fr/learn/orchestration/application-and-versions.md), veuillez vérifier `application`  valeurs.

</details>

<details>

<summary><code>L'image Docker pour '2024.01.30-16.23.00-UTC' n'est pas mise en cache.</code></summary>

[**🌟 Passez au niveau Pay as You Go**](https://app.edgegap.com/user-settings?tab=memberships) **pour débloquer** [**déploiements instantanés avec mise en cache**](https://docs.edgegap.com/fr/learn/matchmaking/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-1.-start-a-deployment)**.**

* Les images non mises en cache de plus de 4 Go peuvent prendre plus de temps à se déployer, entraînant [/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-4.-deployment-error](https://docs.edgegap.com/fr/learn/matchmaking/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-4.-deployment-error "mention"). Envisagez d'optimiser la taille de votre image serveur ([Unreal Engine](/fr/unreal-engine.md#optimize-server-build-size) / [Unity](/fr/unity.md#optimize-server-build-size)).
* Vous pouvez procéder malgré tout, bien que nous recommandions de tester le temps de déploiement.

</details>

### Profils (files) <a href="#matchmaking-profiles" id="matchmaking-profiles"></a>

Les profils représentent des files de matchmaking entièrement séparées, partageant la même version du matchmaker. Vous pouvez **configurer autant de profils que vous le souhaitez pour chaque matchmaker.** Répartir votre base de joueurs en plusieurs profils peut entraîner des temps d'attente plus longs pour vos joueurs.

Chaque profil de matchmaker utilise un [Version d'application](/fr/learn/orchestration/application-and-versions.md) comme modèle pour lancer de nouveaux déploiements (serveurs).

{% hint style="success" %}
Certains modes de jeu peuvent nécessiter davantage de vCPU / RAM, surtout s'ils prennent en charge un plus grand nombre de joueurs. Chaque **matchmaker peut inclure plusieurs profils**, chacun lié à une version d'application avec des ressources ajustées.
{% endhint %}

### Règles <a href="#matchmaking-rules" id="matchmaking-rules"></a>

Chaque joueur et groupe rejoint la file de matchmaking et trouve des parties en utilisant  `initial` règles au début.

Chaque entrée du profil au chemin `.rules.initial` représente une règle, où :

* **clé** est une valeur de chaîne pour nommer la règle comme vous le souhaitez ; p. ex. `match_size` , et
* **valeur** est un objet définissant le type et les attributs de la règle, conformément à notre ensemble de règles standard.

{% hint style="info" %}
Toutes les règles doivent être satisfaites simultanément pour lancer l'attribution d'hôte et démarrer ou trouver un déploiement.
{% endhint %}

**Opérateurs (type de règle)**

**`player_count`** est une règle spéciale définissant combien de joueurs doivent correspondre pour lancer l'attribution.

{% hint style="warning" %}
Règle `player_count`  **est obligatoire et ne peut être définie qu'une seule fois** dans vos règles de configuration initiales.
{% endhint %}

Le matchmaker s'efforce toujours de maximiser le taux de remplissage des parties, jusqu'aux `max_team_size` :

1. si la taille maximale de l'équipe est atteinte, la partie est créée immédiatement,
2. sinon, les joueurs attendent dans la file pour remplir la partie jusqu'à [expansion](#rule-expansion) (ou l'expiration) est sur le point de se produire,
3. peu avant [l'expansion](#rule-expansion) (ou l'expiration), si une correspondance partielle est possible (≥ min et < taille max de l'équipe), cette partie sera créée avec tous les joueurs au même stade d'expansion (à condition que les autres règles soient respectées).

{% hint style="success" %}
Pour les modes de jeu coopératifs, chacun pour soi ou à taille d'équipe asymétrique, définissez votre `"team_count": 1` .
{% endhint %}

Le nombre d'équipes peut être configuré pour composer plusieurs équipes équilibrées pour les jeux compétitifs :

* **les attributs du groupe sont calculés comme la moyenne/le chevauchement** des **attributs des joueurs du groupe,**
* **les attributs de l'équipe sont calculés comme la moyenne/le chevauchement** des **attributs du groupe.**

En supposant une taille d'équipe fixe de 4 joueurs :

<figure><img src="https://3008966946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2FSFEzBayk3XNEUTIynjNd%2Fimage.png?alt=media&amp;token=11a43fdf-3a99-4caa-8d2b-639e0f3cc06f" alt=""><figcaption><p>Exemples de scénarios de match</p></figcaption></figure>

{% hint style="info" %}
**Les groupes s'associent en équipes sans surcharge,** uniquement si une équipe dispose d'une capacité suffisante pour accueillir l'ensemble du groupe.
{% endhint %}

**`string_equality`** associe des joueurs avec exactement la même valeur de chaîne.

<details>

<summary>Exemple de règle : <code>selected_game_mode</code></summary>

`selected_game_mode`  associera les joueurs en tenant compte de la casse :

:white\_check\_mark: Alice + Bob + Dave peuvent correspondre,

:x: Alice + Erin, ou Charlie + Frank ne correspondront jamais.

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

</details>

**`number_difference`** associe des joueurs dont la différence numérique absolue entre eux respecte la limite.

<details>

<summary>Exemple de règle : <code>elo_rating</code></summary>

`elo_rating`  la règle ci-dessus avec `"max_difference": 50` au départ :

:white\_check\_mark: Alice + Bob peuvent correspondre, ou Bob + Charlie peuvent correspondre,

:x: Alice + Bob + Charlie ne correspondront jamais.

<figure><img src="https://3008966946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2FxtTxZ7TPSa8a8WtnGNAE%2Fimage.png?alt=media&amp;token=c48b843b-c4e5-47bf-9154-07254a788067" alt=""><figcaption></figcaption></figure>

</details>

**`latences`** est une règle spéciale optimisant le ping des matchs de joueurs :

* réduire la latence client-serveur en supprimant les régions à forte latence (au-dessus du seuil),
* améliorer l’équité des matchs en regroupant les joueurs ayant une latence similaire (en dessous de la différence).

<details>

<summary>Exemple de règle : <code>balises</code></summary>

`balises` règle configurée avec `"difference": 100, "max_latency": 200`  correspondra à :

:white\_check\_mark: Alice et Bob peuvent correspondre :

* Tokyo est écarté (>200 ms),
* la latence pour Chicago se situe dans une différence absolue de 100 ms.

<table><thead><tr><th width="180">Ville de la balise</th><th width="80">Correspondance</th><th width="132">abs(A - B) [ms]</th><th width="164">Alice [ms]</th><th width="164">Bob [ms]</th></tr></thead><tbody><tr><td>Chicago</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>Los Angeles</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>Tokyo</del></td><td>n/a</td><td>n/a</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: Alice et Charlie ne correspondront jamais :

* aucune balise n'a une latence < 200 ms pour les deux joueurs,
* Alice vit en Amérique du Nord - Illinois,
* Charlie vit en Asie - Japon.

<table><thead><tr><th width="180">Ville de la balise</th><th width="80">Correspondance</th><th width="132">abs(A - B) [ms]</th><th width="164">Alice [ms]</th><th width="164">Charlie [ms]</th></tr></thead><tbody><tr><td><del>Chicago</del></td><td>n/a</td><td>n/a</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>Los Angeles</del></td><td>n/a</td><td>n/a</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>Tokyo</del></td><td>n/a</td><td>n/a</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" %}
Règle `latences`  est **facultative et ne peut être définie qu’une seule fois dans votre configuration initiale** règles.
{% endhint %}

Certains joueurs ayant un ping élevé vers tous les balises en raison de [Fournisseur d'accès](#user-content-fn-10)[^10] des problèmes ou d'une connexion lente (par ex. sans fil/mobile) peuvent provoquer des lags et dégrader l'expérience de jeu des autres. Pour atténuer ce problème :

* Élargir progressivement la latence maximale et l'écart autorisés (voir [Exemple de configuration avancée](/fr/learn/matchmaking.md#advanced-example)),
  * les joueurs avec un ping élevé peuvent devoir attendre plus longtemps que d'habitude pour trouver une partie.
* Alternativement, permettre aux joueurs de remplacer la mesure par une sélection manuelle de région, n'envoyant des valeurs de ping factices que pour les régions sélectionnées par le joueur uniquement (par ex. 25 ms pour une correspondance rapide),
  * cela peut avoir un impact négatif sur l'expérience des coéquipiers et des adversaires du joueur.

{% hint style="info" %}
**Un ping élevé vers les balises n'entraîne pas toujours un ping élevé vers le serveur**. Les déploiements sont disponibles dans plus d'emplacements que les balises. Les balises sont orchestrées en temps réel pour privilégier la couverture mondiale et la fiabilité.
{% endhint %}

{% hint style="success" %}
Voir [Matchmaking](/fr/learn/matchmaking.md) pour **mesure de ping automatisée utilisant nos SDK**.
{% endhint %}

{% hint style="danger" %}
Les balises sont automatiquement redimensionnées en temps réel - ajout, suppression ou remplacement des balises existantes. Vos clients et votre backend doivent en tenir compte et **recharger la liste des balises avant chaque manche de matchmaking**.
{% endhint %}

**`intersection`** associe des joueurs partageant une ou plusieurs valeurs de chaîne communes, en tenant compte de la casse.

<details>

<summary>Exemple de règle : <code>selected_map</code></summary>

`selected_map` la règle ci-dessus avec `"overlap": 1`  correspondra :

:white\_check\_mark: Alice + Bob + Charlie peuvent correspondre, ou Alice + Bob + Dave peuvent correspondre,

:x: Alice + Bob + Charlie + Dave ne correspondront jamais.

<figure><img src="https://3008966946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2FcQSUAnRkZKVyuGjFWSYL%2Fimage.png?alt=media&amp;token=bf1a4e28-230a-4c9a-9ef6-a0dea4dbecdb" alt=""><figcaption></figcaption></figure>

</details>

#### Expansion de règle

Facultativement, **`les expansions`**  modifient les attributs de règle après un certain temps passé dans la file afin d'assouplir les limitations et d'élargir le pool de joueurs pouvant être appariés, **ce qui permet des parties plus rapides**.

Dans la configuration, les expansions sont indexées en secondes par rapport à la création du ticket de chaque joueur. Chaque expansion doit être inférieure à l'expiration du ticket pour s'activer.

<details>

<summary>Exemple de scénario : expansions</summary>

[Au départ, nous exigeons 1 équipe composée exactement de 4 joueurs (éventuellement répartis en groupes)](/fr/learn/matchmaking.md#advanced-example) avec :

* un maximum de 125 ms de latence par rapport au même beacon (quel qu'il soit),
* une différence de latence de 125 ms ou moins entre la valeur la plus basse et la plus haute pour le même beacon,
* une différence de niveau de 50 points ou moins entre le joueur le moins bien classé et le mieux classé,
* exactement le même mode de jeu sélectionné (sensible à la casse),
* au moins une sélection de carte correspondante (sensible à la casse) parmi les joueurs,
* au moins une [taille de groupe de backfill](#backfill-match) valeur parmi les joueurs.

Dans l'exemple ci-dessus, nous **élargissons la recherche en modifiant les attributs** après :

<table data-view="cards"><thead><tr><th></th><th></th></tr></thead><tbody><tr><td>30 secondes :</td><td><ul><li>4 joueurs</li><li><strong>plage de niveau de 150 points</strong></li><li><strong>latence max 250 ms</strong></li></ul></td></tr><tr><td>60 secondes :</td><td><ul><li>4 joueurs</li><li><strong>plage de niveau de 200 points</strong></li><li>latence max 250 ms</li></ul></td></tr><tr><td>3 minutes (180 s) :</td><td><ul><li><strong>1 à 4 joueurs</strong></li><li>plage de niveau de 200 points</li><li><strong>toute latence</strong></li></ul></td></tr></tbody></table>

</details>

{% hint style="warning" %}
Les expansions de n'importe quel attribut de règle **écraseront les valeurs précédentes** de cet attribut.
{% endhint %}

{% hint style="success" %}
[**Découvrez les erreurs courantes**](https://edgegap.com/blog/how-session-fill-rate-affects-your-multiplayer-hosting-costs)**, et** [**optimisez votre taux de remplissage des parties grâce à notre guide**](https://edgegap.com/blog/how-to-optimize-session-fill-rate-in-your-matchmaker)**.**
{% endhint %}

## 📌 Variables injectées

Votre serveur peut avoir besoin de connaître des détails sur ses joueurs. Les attributs des joueurs, les valeurs de match résolues et d'autres valeurs sont injectées dans votre déploiement en même temps que les [Applications et versions](/fr/learn/orchestration/application-and-versions.md#injected-variables).

Aperçu non formaté **🏁 Variables d'exemple avancées :**

```
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" %}
Les variables d'environnement sont **stockés sous forme de JSON sérialisés en chaîne**, analysez-les à l’aide de nos SDKs ou d’une méthode personnalisée.
{% endhint %}

{% hint style="success" %}
**Les serveurs peuvent associer les connexions des joueurs à des groupes et des attributs** après que le joueur a envoyé son identifiant de ticket au serveur.
{% endhint %}

## 🧵 Suivi des joueurs

Si vos joueurs rencontrent des problèmes, tracer leur chemin jusqu’aux journaux du serveur peut être utile. Chaque Matchmaker **déploiement** **sera étiqueté avec les identifiants de tickets des joueurs attribués** afin que vous puissiez facilement [Déploiements](/fr/learn/orchestration/deployments.md#filter-deployments) et trouver [Déploiements](/fr/learn/orchestration/deployments.md#container-logs) pour vous aider à résoudre les problèmes.

{% hint style="success" %}
**Afficher les identifiants de ticket et les identifiants de déploiement dans l’interface d’historique des matchs du client** pour suivre les joueurs lors du dépannage.
{% endhint %}

{% hint style="info" %}
Voir [Déploiements](/fr/learn/orchestration/deployments.md#connection-quality) pour en savoir plus sur le dépannage des déploiements.
{% endhint %}

## 👀 Analytique

Obtenez des informations sur la charge et les performances de votre Matchmaker, sans code ni configuration requis.

🌟 [**Passez Matchmaker au niveau Entreprise**](https://app.edgegap.com/matchmaker-management-v2/matchmakers/list) **pour débloquer les métriques et les analyses de matchmaking :**

<figure><img src="https://3008966946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fhb8NmB4ELuG7ayGLTeHs%2Fimage.png?alt=media&amp;token=e3e0371e-c33f-48c8-bd15-5c11448dc633" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3008966946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fl0zTNccJASUTkJfTYxss%2Fimage.png?alt=media&amp;token=0d061320-9524-4b12-83e6-ea9112ef1409" alt=""><figcaption></figcaption></figure>

## ☁️ Cluster d’hébergement

Matchmaker est hébergé et géré de manière pratique 24h/24 et 7j/7 par Edgegap.

Choisissez l’option d’hébergement la mieux adaptée à votre objectif :

* **Cluster gratuit (partagé)** pour tester toutes les fonctionnalités et explorer les synergies avec votre conception,
  * s'éteint automatiquement après 3 heures, nécessitant un redémarrage pour continuer les tests.
* **Cluster privé** **(dé dédié)** pour garantir un environnement stable pour vos besoins de production,
  * choisissez votre région et obtenez un support 24/7 pour les jeux en direct afin de publier en toute confiance.

#### Niveaux de cluster privé

Nous proposons actuellement [3 niveaux de cluster privé](https://edgegap.com/resources/pricing#managed-infrastructure) pour répondre aux besoins de chacun :

<table><thead><tr><th width="160">Niveau</th><th align="right">Niveau Hobbyiste</th><th align="right">Niveau Studio</th><th align="right">Niveau Entreprise</th></tr></thead><tbody><tr><td>Mieux adapté pour</td><td align="right">passionnés,<br>développeurs indépendants</td><td align="right">versions commerciales</td><td align="right">lancements à fort trafic</td></tr><tr><td>Limite de débit (req/s)</td><td align="right">200</td><td align="right">750</td><td align="right">2,000</td></tr><tr><td>Ressources</td><td align="right">1 vCPU + 2 Go de RAM</td><td align="right">6 vCPU + 12 Go de RAM</td><td align="right">18 vCPU + 48 Go de RAM</td></tr><tr><td>Redondance</td><td align="right">1 nœud virtuel</td><td align="right">3 nœuds virtuels</td><td align="right">3 nœuds virtuels</td></tr><tr><td>Prix, à l’heure</td><td align="right">$0.0312</td><td align="right"> $0.146</td><td align="right">$0.548</td></tr><tr><td><strong>Prix, 30 jours</strong><br>(utilisation continue)</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>

Passez à un cluster privé en un clic. Il est également possible de modifier les niveaux de cluster privé après le lancement, sans interruption pour les joueurs, avec [#rolling-updates-and-ab-tests](#rolling-updates-and-ab-tests "mention"). Les clusters gérés fournissent un hébergement de service à haute disponibilité assuré par Edgegap avec une assistance en direct 24h/24 et 7j/7 pour les jeux publiés au public.

Les besoins en ressources de votre instance dépendront des facteurs suivants :

* **nombre de joueurs** - plus de joueurs entraînent davantage de tickets et de requêtes API,
* **nombre de requêtes par joueur** - des tentatives plus rapides augmentent la charge du service et consomment des ressources,
* **complexité de la configuration** - les règles d’intersection et les expansions sont particulièrement exigeantes,
* **durée moyenne des matchs** - des sessions plus courtes amènent les joueurs à rejoindre plus souvent le matchmaking,
* **périodes d’expiration et de suppression** - les tickets obsolètes s’accumulent au fil du temps et consomment des ressources,
* **logique de secours des tentatives de réessai du client** - réessayer avec un backoff à délai aléatoire permet d’étaler les pics de trafic.

{% hint style="warning" %}
**Préparez-vous au succès et optimisez après le lancement, afin de ne pas bloquer vos joueurs le jour de la sortie.** Utilisez [Outils pour développeurs](/fr/unity/developer-tools.md#matchmaking-sdk) ou **mettre en œuvre un backoff exponentiel avec délai aléatoire** pour se remettre d’une charge élevée.
{% endhint %}

{% hint style="info" %}
Nos clusters utilisent des machines cloud équipées de processeurs AMD/Intel avec une vitesse d’horloge allant jusqu’à 3,7 GHz.
{% endhint %}

## ⏩ Mises à jour progressives <a href="#rolling-updates-and-ab-tests" id="rolling-updates-and-ab-tests"></a>

Garder une trace de la compatibilité entre les versions serveur et client peut vite devenir compliqué. Suivez nos conseils pour des sorties et des mises à jour fiables, et pour éviter les interruptions ou les problèmes de compatibilité.

**L’URL de votre Matchmaker et votre jeton d’authentification resteront toujours les mêmes après un redémarrage.**

{% hint style="danger" %}
**Créez des Matchmakers distincts pour les environnements de développement et de production** afin d’expérimenter en toute sécurité.
{% endhint %}

#### ⚠️ **Avant la mise en ligne**

Nous recommandons de créer à l’avance plusieurs copies de votre Matchmaker : `vert`, `bleu` et `orange`. Vous pouvez faire tourner le Matchmaker utilisé au fur et à mesure que vous publiez des mises à jour ([stratégie bleu/vert](https://en.wikipedia.org/wiki/Blue%E2%80%93green_deployment)).

**Choisissez différentes régions pour chaque instance afin d’éviter les interruptions** lors de pannes localisées.

<figure><img src="https://3008966946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Flzy4elHYDPBMpjSMG1HS%2Fimage.png?alt=media&amp;token=7da795fc-ae6c-490f-b65c-5f8dda635503" alt=""><figcaption><p>Exemple d’environnement DevOps bleu/vert</p></figcaption></figure>

#### **🔃 Mise à jour client + serveur**

**Prérequis :** Cette section suppose que vous avez terminé [#before-going-live](#before-going-live "mention").

Afin de **publier les mises à jour du client de jeu + du serveur**, vous pouvez :

1. Préparer une nouvelle version de l’application serveur `v1.2.0-rc` sur Edgegap :
   1. pousser une nouvelle balise d’image vers votre registre de conteneurs `t1.2.0`,
   2. créer une nouvelle version de l’application `v1.2.0-rc`,
2. Effectuer tous les tests de développement en [déployant votre nouvelle version de l’application](https://app.edgegap.com/deployment-management/deployments/list) `v1.2.0-rc`:
   1. connecter l’éditeur de votre moteur de jeu à l’URL fournie + au port externe,
3. Mettre à jour le Matchmaker inutilisé `bleu` pour le lier à votre nouvelle balise d’image `t1.2.0`,
   1. activer la mise en cache pour la nouvelle version de l’application `v1.2.0-rc` , l’activation du cache pour cette version garantira que l’image est également mise en cache pour la version `v-vert`  puisqu’elles font référence à la même balise,
   2. attendre que l’indicateur de mise en cache dans la version `v1.2.0-rc`  atteigne :green\_circle: vert,
4. Mettre à jour votre nouveau client de jeu `c2` pour utiliser la nouvelle version `v-vert` lors de la création de tickets :
   1. mettez à jour l’URL de base et le jeton d’autorisation dans le client de jeu,
5. Effectuer les tests QA et les vérifications finales de votre nouveau client de jeu `c2`:
   1. si vous trouvez et résolvez des problèmes, recommencez le processus depuis le début,
   2. attendre 3 à 7 jours pour que les changements DNS du Matchmaker se propagent aux FAI à l’échelle mondiale, après l’arrêt du Matchmaker (un redémarrage rapide ne nécessite pas de mises à jour DNS ni de période d’attente),
6. Publiez la mise à jour de votre nouveau client de jeu `c2` sur les plateformes de distribution de jeux,
7. Laissez le temps au nouveau client de jeu `c2` de se distribuer sur les appareils des joueurs (généralement jusqu’à 3 à 7 jours) :
   1. surveiller les clients de jeu obsolètes `c1`  en utilisant le déploiement [Déploiements](/fr/learn/orchestration/deployments.md#analytics),
8. Nettoyez les ressources inutilisées dans votre compte Edgegap :
   1. supprimer la balise d’image `t1.0.0` pour libérer de la capacité dans le registre de conteneurs,
   2. supprimer la balise d’image `t1.1.0` pour libérer de la capacité dans le registre de conteneurs,
   3. désactivez votre `vert`  Matchmaker pour suspendre la facturation jusqu’à votre prochaine mise à jour.

{% hint style="success" %}
**Pour votre prochaine mise à jour**, augmentez les numéros de version et échangez `vert` et `bleu` les mots-clés dans le guide.
{% endhint %}

#### **⚡ Correctif serveur**

**Prérequis :** Cette section suppose que vous avez terminé [#before-going-live](#before-going-live "mention").

Pour **publier un correctif serveur sans nécessiter de mise à jour du client de jeu**, vous pouvez :

1. Préparer une nouvelle version de l’application serveur `v1.2.0-rc` sur Edgegap :
   1. pousser une nouvelle balise d’image vers votre registre de conteneurs `t1.2.0`,
   2. créer une nouvelle version de l’application `v1.2.0-rc`,
2. Effectuer les tests et les vérifications en [déployant votre nouvelle version de l’application](https://app.edgegap.com/deployment-management/deployments/list) `v1.2.0-rc`:
   1. connecter l’éditeur de votre moteur de jeu à l’URL fournie + au port externe,
   2. si vous trouvez et résolvez des problèmes, recommencez le processus depuis le début,
   3. activer la mise en cache pour la nouvelle version de l’application `v1.2.0-rc` , l’activation du cache pour cette version garantira que l’image est également mise en cache pour la version `v-vert`  plus tard puisqu’elles feront référence à la même balise,
   4. attendre que l’indicateur de mise en cache dans la version `v1.2.0-rc`  atteigne :green\_circle: vert,
3. Mettre à jour la version `v-vert`  pour le lier à votre nouvelle balise d’image `t1.2.0`,
   1. les nouveaux matchs lanceront automatiquement l’attribution avec la balise mise à jour `t1.2.0`,
   2. surveiller les clients de jeu obsolètes `c1`  en utilisant le déploiement [Déploiements](/fr/learn/orchestration/deployments.md#analytics),
4. Nettoyage des ressources inutilisées dans votre compte Edgegap :
   1. supprimer la balise d’image `t1.1.0` pour libérer de la capacité dans le registre de conteneurs.

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

Les clients et les serveurs peuvent appeler l’API directement ou avec les SDKs du moteur de jeu, voir aussi [Matchmaking](/fr/learn/matchmaking.md).

{% hint style="info" %}
Unity/Android - envisager [d'utiliser l'interpolation de chaîne brute](https://www.c-sharpcorner.com/article/convert-string-to-json-in-c-sharp/) pour empêcher la suppression de code des JSON codés en dur.
{% endhint %}

{% hint style="success" %}
**Interface Web Swagger**: le déploiement de votre service géré génère une spécification OpenAPI et une interface Web pratique, utile pour tester des cas limites ou valider la structure des charges utiles.
{% endhint %}

{% tabs fullWidth="false" %}
{% tab title="🍀 Exemple simple" %}
{% file src="/files/c776940067ab24f54a0b268cc95579eada4a9ab8" %}
{% endtab %}

{% tab title="🏁 Exemple avancé" %}
{% file src="/files/43a41be367fb0ab7ac7fe32c25db07d1022d3652" %}
{% endtab %}

{% tab title="🎾 Salon personnalisé" %}
{% file src="/files/5f68d3a239309e71119084a21efbae380261d3a4" %}
{% endtab %}

{% tab title="🥛 Présentation du remplissage arrière" %}
{% file src="/files/e9d3c906be28faebd6eed9111e2ad013c21b8429" %}
{% endtab %}

{% tab title="⚔️ Jeux compétitifs" %}
{% file src="/files/9255b1fccca0102825e4be46ee077114e5d6bdf6" %}
{% endtab %}

{% tab title="🤝 Jeux coopératifs" %}
{% file src="/files/5d31c1ca46c0df8f2b109eef58ceeff55b93cadf" %}
{% endtab %}

{% tab title="🎈 Jeux sociaux" %}
{% file src="/files/43de6f310a0549e5fd3d21d8240e53b89420af62" %}
{% endtab %}
{% endtabs %}

Importer la spécification de l'API vers [Client Web de l'API Scalar](https://client.scalar.com/workspace/default/request/default) ou [Éditeur Swagger](https://editor.swagger.io/) pour inspecter les détails.

### Limites de débit

Pour protéger votre cluster contre le dépassement de sa capacité de pic et éviter un plantage, nous limitons le nombre de requêtes par seconde en nous basant sur nos tests de charge internes utilisant [Matchmaking](/fr/learn/matchmaking.md#advanced-example) la configuration.

<table><thead><tr><th>point de terminaison API</th><th width="130">Niveau Gratuit</th><th width="130">Niveau Hobbyiste</th><th width="130">Niveau Studio</th><th width="130">Niveau Entreprise</th></tr></thead><tbody><tr><td><strong>Limite globale</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>Créer un déploiement</td><td>5</td><td>10</td><td>30</td><td>30</td></tr><tr><td>Lister les balises</td><td>10</td><td>20</td><td>75</td><td>200</td></tr><tr><td>Créer un groupe\n+ Créer un ticket\n+ Créer un ticket de groupe</td><td>10</td><td>20</td><td>75</td><td>200</td></tr><tr><td>Lire l’appartenance\n+ Lire le groupe\n+ Lire le ticket</td><td>10</td><td>120</td><td>450</td><td>1,300</td></tr><tr><td>Créer un backfill</td><td>5</td><td>10</td><td>37</td><td>100</td></tr></tbody></table>

Les limites de débit sont exprimées en **requêtes combinées par seconde pour l’ensemble spécifié de points de terminaison API**.

{% hint style="warning" %}
Si vos clients de jeu ne réessaient pas les requêtes lorsqu’ils reçoivent la réponse `429 Trop de requêtes` **vos déploiements peuvent manquer des joueurs** lors de courtes rafales et de périodes de trafic de pointe.
{% endhint %}

#### Tests de charge

Les tests de charge dans un environnement similaire à la production entraînent un coût d’hébergement du déploiement. Consultez les ressources et les prix associés à chaque niveau sur [notre page de tarification](https://edgegap.com/resources/pricing#matchmaker).

{% hint style="warning" %}
**Utilisez** [**des clusters privés**](#private-cluster-tiers) **pour les tests de stress.** Les instances gratuites sont strictement limitées aux tests de développement uniquement.
{% endhint %}

Lors de la conception de votre test de charge, **veuillez prendre en compte des comportements de joueurs réalistes**:

| Scénario réaliste                                                                                                           | Schéma de trafic irréaliste                                                                                                |
| --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| ✅ Les joueurs rejoignent la partie progressivement, augmentant les requêtes/s sur plusieurs heures.                         | ❌ Tous les joueurs se coordonnent et sollicitent l’API exactement à la même seconde.                                       |
| ✅ Les joueurs attendent un temps croissant entre leurs nouvelles tentatives (p. ex. 1 s - 5 s - 10 s - 10 s).               | ❌ Tous les joueurs réessaient immédiatement après avoir reçu `429 Trop de requêtes`  la réponse.                           |
| ✅ La plupart des joueurs recevront leur affectation en peu de temps (10 à 60 s) et cesseront d’interroger le serveur.       | ❌ Tous les joueurs continuent d’interroger le serveur pendant une durée déterminée même après avoir reçu leur affectation. |
| ✅ La plupart des joueurs terminent leur partie (en prenant du temps) avant de redémarrer une nouvelle session.              | ❌ Tous les joueurs redémarrent immédiatement leur session dès qu’ils reçoivent l’affectation du serveur.                   |
| ✅ Le trafic de pointe est maintenu pendant environ 6 heures par jour, après quoi certains fuseaux horaires se déconnectent. | ❌ Le trafic de pointe est maintenu 24 heures sur 24, avec tous les joueurs jouant jour et nuit.                            |

#### Comportement sous charge

Si un Matchmaker subit une charge élevée :

* si le CPU est bridé, le matchmaking pourrait être ralenti,
* si le Matchmaker manque de mémoire, il redémarrera sans perdre les informations des tickets, en espérant que les clients implémentent un backoff exponentiel et que la rafale soit étalée sur une période plus longue.

#### Partage de ressources entre origines croisées (CORS)

Pour les jeux WebGL hébergés sur des plateformes de distribution tierces (par ex. [itch.io](http://itch.io/)), l’envoi de requêtes au Matchmaker depuis le client du jeu peut entraîner [des violations de la politique de partage de ressources entre origines croisées](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) . La plupart des navigateurs web modernes envoient une [requête de pré-validation](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request) pour vérifier qu’un service backend (le Matchmaker) comprend et accepte la communication provenant de votre client de jeu.

L’échec de la vérification de pré-validation (comportement par défaut pour des raisons de sécurité) peut entraîner [l’une de plusieurs erreurs possibles liées à CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSMissingAllowOrigin), le plus souvent `en-tête CORS « Access-Control-Allow-Origin » manquant` .

Pour résoudre cette erreur, ajoutez **`allowed_cors_origin`** paramètre à votre configuration pour soit :

* mettre sur liste blanche vos domaines d’hébergement client exacts :

<details>

<summary>🍀 Exemple simple (exemple de domaines spécifiques)</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>

* ou mettre sur liste blanche un domaine générique (incluant tous les sous-domaines) :

<details>

<summary>🍀 Exemple simple (exemple de domaine générique)</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" %}
**Aucun identifiant n’est requis pour les requêtes de pré-validation du Matchmaker**, si les domaines sont correctement configurés.
{% endhint %}

### Serveur à serveur <a href="#server-to-server-api" id="server-to-server-api"></a>

Ajoutez des contrôles améliorés ou personnalisés sur le flux de matchmaking - implémentez un proxy personnalisé en utilisant notre [Managed Clusters](/fr/learn/advanced-features/managed-clusters.md) ou tout cloud FaaS[^12] plateforme de calcul, pour réaliser l’un des objectifs suivants :

* associer des attributs sensibles du joueur - comme des indicateurs de triche, des classements de compétence ou similaires,
* fournir le contexte de l’équipe et du match en jeu - afficher mes coéquipiers et mes adversaires pendant le chargement,
* restreindre des cas particuliers spécifiques - par ex. n’autoriser qu’un seul groupe par joueur à la fois,
* ajouter de la mise en cache ou une limitation du débit API - réduire le nombre de requêtes et la charge sur le Matchmaker,
* personnaliser l’intégration lobby-groupe - créer des lobbies asymétriques/basés sur les rôles avant le matchmaking.

{% hint style="success" %}
**Inclure le paramètre `player_ip`  avec l’adresse IP publique du membre** afin d’assurer la latence joueur la plus faible possible et de tirer parti de [/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-1.-server-score-strategy-best-practice](https://docs.edgegap.com/fr/learn/matchmaking/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-1.-server-score-strategy-best-practice "mention").
{% endhint %}

{% hint style="info" %}
Les clients de jeu peuvent utiliser [ipify.org](http://ipify.org/) service gratuit pour trouver leurs IP publiques. Les VPN peuvent masquer l’adresse IP publique.
{% endhint %}

<figure><img src="https://3008966946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2FzLfA3fEBgwaziGtp2yMO%2Fimage.png?alt=media&amp;token=3d551e74-4a60-47a6-9d79-a506f961663d" alt=""><figcaption><p>Diagramme d’activité du matchmaking serveur à serveur</p></figcaption></figure>

## 🚨 Dépannage

**Votre réussite est notre priorité.** Si vous souhaitez envoyer des requêtes personnalisées, demander des fonctionnalités critiques manquantes ou partager vos idées, [veuillez nous contacter sur notre Discord communautaire](https://discord.gg/MmJf8fWjnt).

<details>

<summary><code>La configuration de l'application n'est pas valide pour le profil XYZ.</code></summary>

* Nous n'avons pas trouvé votre [Applications et versions](/fr/learn/orchestration/application-and-versions.md), veuillez vérifier `application`  valeurs.

</details>

<details>

<summary><code>L'image Docker pour '2024.01.30-16.23.00-UTC' n'est pas mise en cache.</code></summary>

[**🌟 Passez au niveau Pay as You Go**](https://app.edgegap.com/user-settings?tab=memberships) **pour débloquer** [**déploiements instantanés avec mise en cache**](https://docs.edgegap.com/fr/learn/matchmaking/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-1.-start-a-deployment)**.**

* Les images non mises en cache de plus de 4 Go peuvent prendre plus de temps à se déployer, entraînant [/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-4.-deployment-error](https://docs.edgegap.com/fr/learn/matchmaking/pages/5d7a2f9e0583a99d78071f1c4b8a7892a518534a#id-4.-deployment-error "mention"). Envisagez d'optimiser la taille de votre image serveur ([Unreal Engine](/fr/unreal-engine.md#optimize-server-build-size) / [Unity](/fr/unity.md#optimize-server-build-size)).
* Vous pouvez procéder malgré tout, bien que nous recommandions de tester le temps de déploiement.

</details>

<details>

<summary>Pourquoi est-ce que j’obtiens des erreurs lorsque j’essaie de créer un nouveau Matchmaker ?</summary>

* Veuillez lire le message d’erreur, il est possible que vous ayez mal orthographié un identifiant, une règle ou un opérateur. - Utilisez [JSONLint](https://jsonlint.com/) pour valider votre format JSON, il se peut qu’il vous manque une virgule ou une accolade. - Contactez-nous via [notre Discord communautaire](https://discord.gg/MmJf8fWjnt) pour obtenir de l’aide, nous serons ravis de vous assister. 🙏

</details>

<details>

<summary>Pourquoi mon Matchmaker s’est-il désactivé automatiquement après 3 heures ?</summary>

* Les Matchmakers du niveau Gratuit sont destinés aux tests initiaux et sont automatiquement désactivés après 3 heures. Pour continuer à tester, vous pouvez [redémarrer votre Matchmaker](https://app.edgegap.com/matchmaker-management-v2/matchmakers/list).
* Envisagez de passer à un niveau payant pour une durée d’exécution illimitée.

</details>

<details>

<summary>Pourquoi ne puis-je pas lancer un deuxième déploiement sur mon compte ?</summary>

* Vous ne pouvez exécuter qu’un seul déploiement simultané dans le niveau Gratuit.
* Veuillez envisager de passer à un niveau payant pour des déploiements illimités.

</details>

<details>

<summary>Pourquoi est-ce que je reçois des affectations/déploiements à des moments aléatoires, en ignorant <code>player_count</code>?</summary>

* Vous ou un autre membre de l’équipe avez peut-être créé des tickets lors d’une session de test précédente qui n’ont pas été attribués. Veuillez [redémarrer votre Matchmaker](https://app.edgegap.com/matchmaker-management-v2/matchmakers/list).

</details>

<details>

<summary>Mon ticket reste bloqué dans <code>RECHERCHE</code> .</summary>

* Veuillez vérifier que vous avez créé suffisamment de tickets correspondants conformément à votre configuration.

</details>

<details>

<summary>Mon ticket reste bloqué en alternance entre <code>MATCH_FOUND</code>  et <code>RECHERCHE</code>  de façon répétée.</summary>

* Les comptes du niveau Gratuit sont limités à 1 déploiement à la fois.
* Veuillez envisager de passer à un niveau supérieur ou d’arrêter votre déploiement actuel pour en lancer un nouveau.

</details>

<details>

<summary>Mon ticket passe directement à <code>ANNULÉ</code>.</summary>

* Votre ticket a atteint sa date d’expiration. Créez un nouveau ticket ou augmentez la période d’expiration dans votre configuration à des fins de test.

</details>

<details>

<summary>Je reçois <code>HTTP 404 Introuvable</code> lorsque je vérifie mon ticket.</summary>

* Votre ticket a été supprimé soit par une requête DELETE, soit en atteignant sa période de suppression (qui commence après l’expiration du ticket, définie dans votre configuration). Recréez un nouveau ticket ou augmentez les périodes d’expiration/de suppression dans votre configuration à des fins de test.

</details>

<details>

<summary>Mon Matchmaker affiche une erreur, que dois-je faire ?</summary>

* S’il s’agit d’une instance de développement ou de test, essayez d’abord de redémarrer votre Matchmaker. - Veuillez signaler tout problème via [notre Discord communautaire](https://discord.gg/MmJf8fWjnt).
* Si ce problème impacte un jeu en direct, créez une [demande d’assistance urgente](https://edgegap.atlassian.net/servicedesk/customer/portal/3).

</details>

## 🔖 Journal des modifications

Veuillez consulter [Notes de version](/fr/docs/release-notes.md) pour le journal des modifications à jour de ce service.

#### Versionnement sémantique

Nos outils de développement et nos services managés utilisent la version officielle [Versionnement sémantique](https://semver.org/), indiquant quelles mises à jour sont ✅ sûres (mineures, correctifs) et lesquelles peuvent contenir des changements incompatibles ⚠️ (majeurs).

**Une fois qu’une version est publiée, elle ne sera jamais modifiée/changée**.

{% hint style="warning" %}
**Pour mettre à niveau la version du service - Arrêter, Modifier, Redémarrer.** Le redémarrage rapide n’appliquera pas les changements de version.
{% endhint %}

Votre fichier de configuration sera validé en fonction de la version du Matchmaker utilisée, assurez-vous que vos règles correspondent aux capacités de la version du Matchmaker.

[^1]: valeur d'exemple

[^2]: les clients de jeu rejoignent un lobby pour récupérer l'ID du groupe de matchmaking et rejoindre le groupe

[^3]: Nom de domaine pleinement qualifié

[^4]: par exemple, pour 3 emplacements libres = \["3", "2", "1"]

[^5]: remplacez "2" par le nombre réel de membres du groupe

[^6]: remplacez par le nom de votre propre application

[^7]: remplacez par la version de votre propre application

[^8]: différence maximale dépassée

[^9]: latence maximale dépassée

[^10]: Fournisseur de services Internet

[^11]: voir d’autres exemples

[^12]: [Function as a Service](https://www.ibm.com/think/topics/faas)
