Skip to main content

Lobby et équipes

Endpoint proposé : /ws/game.

ÉvénementDirectionFonction, comportement serveur et restrictions
match.createClient → ServeurCréer la partie en MATCH_STARTING et y inscrire le créateur authentifié. Refuser une deuxième appartenance active.
match.createdServeur → ClientConfirmer UID, créateur et état initial ; envoyer ensuite match.stateChanged complet au créateur.
match.joinClient → ServeurInscrire dans un lobby non plein en MATCH_STARTING. Un membre déjà présent peut se reconnecter dans les autres phases sans ajouter de joueur.
match.playerJoinedServeur → ClientsAnnoncer une nouvelle inscription ; envoyer séparément un instantané complet au nouvel arrivant.
match.leaveClient → ServeurRetirer le joueur et son affectation dans le lobby. Pendant la partie lancée, détacher sa connexion en conservant son état, comme une déconnexion.
match.playerLeftServeur → ClientsSignaler le départ ; supprimer l’entrée dans le lobby, conserver le joueur dans une partie lancée.
team.assignCréateur → ServeurAffecter un membre à une équipe en MATCH_STARTING ; vérifier créateur, équipe et capacité de deux. Retirer atomiquement l’ancienne affectation en cas de changement.
team.updatedServeur → ClientsDiffuser les deux équipes complètes après affectation ou retrait ; garder Player.team et Team.players cohérents.
match.startCréateur → ServeurVérifier quatre joueurs connectés et deux équipes de deux, puis passer à ROUND_STARTING. Refuser un démarrage répété.
match.stateChangedServeur → ClientsDiffuser la phase et l’instantané complet ; également utilisé en réponse ciblée à une inscription/reconnexion. Seul le backend décide de state.

Charges utiles​

Création, puis confirmation :

{ "type": "match.create", "data": {} }
{
"type": "match.created",
"matchUid": "match_123",
"roundNumber": 0,
"data": { "creatorUsername": "alice", "state": "MATCH_STARTING" }
}

Inscription, puis notification :

{ "type": "match.join", "matchUid": "match_123", "data": {} }
{
"type": "match.playerJoined",
"matchUid": "match_123",
"roundNumber": 0,
"data": { "username": "bob", "teamId": null }
}

Départ, puis notification :

{ "type": "match.leave", "matchUid": "match_123", "data": {} }
{ "type": "match.playerLeft", "matchUid": "match_123", "roundNumber": 0, "data": { "username": "bob" } }

Affectation, puis diffusion (exemple après les quatre affectations) :

{ "type": "team.assign", "matchUid": "match_123", "data": { "username": "bob", "teamId": 1 } }
{
"type": "team.updated",
"matchUid": "match_123",
"roundNumber": 0,
"data": {
"teams": [
{ "teamId": 1, "color": "bleu", "players": ["alice", "bob"], "score": 0 },
{ "teamId": 2, "color": "rouge", "players": ["chloe", "david"], "score": 0 }
]
}
}

Demande de démarrage et transition avec instantané complet :

{ "type": "match.start", "matchUid": "match_123", "data": {} }
{
"type": "match.stateChanged",
"matchUid": "match_123",
"roundNumber": 1,
"data": {
"state": "ROUND_STARTING",
"players": [
{
"username": "alice",
"teamId": 1,
"position": { "x": 0, "y": 0, "z": 0 },
"rotation": { "x": 0, "y": 90, "z": 0 },
"hp": 100
},
{
"username": "bob",
"teamId": 1,
"position": { "x": 0, "y": 0, "z": 2 },
"rotation": { "x": 0, "y": 90, "z": 0 },
"hp": 100
},
{
"username": "chloe",
"teamId": 2,
"position": { "x": 30, "y": 0, "z": 0 },
"rotation": { "x": 0, "y": 270, "z": 0 },
"hp": 100
},
{
"username": "david",
"teamId": 2,
"position": { "x": 30, "y": 0, "z": 2 },
"rotation": { "x": 0, "y": 270, "z": 0 },
"hp": 100
}
],
"teams": [
{ "teamId": 1, "color": "bleu", "players": ["alice", "bob"], "score": 0 },
{ "teamId": 2, "color": "rouge", "players": ["chloe", "david"], "score": 0 }
]
}
}

Le créateur affecte aussi sa propre équipe. La fermeture ou le transfert d’un lobby après départ du créateur reste à décider ; aucun autre joueur n’obtient implicitement ses droits.

Séquence — rejoindre et démarrer​

Voir les conventions communes, la machine à états et la reconnexion mobile.