Skip to main content

Déplacements et combat

Endpoint proposé : /ws/game. Les messages respectent les conventions communes.

Chaque commande entrante ci-dessous exige un joueur authentifié appartenant à la partie, le bon round en ROUND_ONGOING et un émetteur avec hp > 0. Le client ne peut pas imposer de HP au backend.

ÉvénementDirectionFonction, comportement serveur et restrictions
player.moveClient → ServeurRecevoir position, rotation et séquence ; vérifier nombres finis et séquence récente, remplacer l’état et diffuser, sans simuler collisions ni déplacement.
player.movedServeur → ClientsDiffuser username, position et rotation acceptés avec le même seq.
player.shootClient → ServeurSignaler un tir calculé dans Unity ; aucun calcul de trajectoire ni modification de HP.
player.shotServeur → ClientsRelayer le username du tireur pour les effets visuels et sonores.
player.hitClient → ServeurRecevoir identifiant de touche, cible et dégâts calculés par Unity ; vérifier cible adverse vivante dans la même partie, dégâts finis strictement positifs et absence de doublon, puis appliquer.
player.damagedServeur → ClientsDiffuser attaquant, cible, dégâts effectivement appliqués et HP restants ; actualiser les interfaces.
player.diedServeur → ClientsAnnoncer la première transition de la cible vers hp <= 0, compter mort et kill, puis vérifier les survivants pour décider d’une fin de round.

L’attaquant est toujours l’identité authentifiée de la connexion. Les HP sont bornés à 0 : une touche de 60 sur une cible à 40 HP applique 40 dégâts. MatchPlayerStats.damage et player.damaged.data.damage utilisent ce dégât effectif. Une cible déjà éliminée, alliée ou identique à l’attaquant produit INVALID_TARGET. Proposition : pas de tir allié.

player.hit déclare un résultat Unity ; le backend ne refait pas le calcul de touche. player.shoot relaie les effets et ne nécessite pas d’historique de tirs pour accepter une touche. Un tir produisant plusieurs touches utilise un eventId distinct pour chaque touche.

Charges utiles​

Mouvement, puis diffusion :

{
"type": "player.move",
"matchUid": "match_123",
"roundNumber": 2,
"seq": 152,
"data": { "position": { "x": 12.5, "y": 0, "z": 8.2 }, "rotation": { "x": 0, "y": 90, "z": 0 } }
}
{
"type": "player.moved",
"matchUid": "match_123",
"roundNumber": 2,
"seq": 152,
"data": {
"username": "alice",
"position": { "x": 12.5, "y": 0, "z": 8.2 },
"rotation": { "x": 0, "y": 90, "z": 0 }
}
}

Tir, puis diffusion :

{ "type": "player.shoot", "matchUid": "match_123", "roundNumber": 2, "data": {} }
{ "type": "player.shot", "matchUid": "match_123", "roundNumber": 2, "data": { "username": "alice" } }

Touche, dégâts et élimination (dans cet exemple, chloe avait 40 HP avant la touche) :

{
"type": "player.hit",
"matchUid": "match_123",
"roundNumber": 2,
"data": { "eventId": "alice-r2-hit17", "targetUsername": "chloe", "damage": 60 }
}
{
"type": "player.damaged",
"matchUid": "match_123",
"roundNumber": 2,
"data": {
"eventId": "alice-r2-hit17",
"attackerUsername": "alice",
"targetUsername": "chloe",
"damage": 40,
"hp": 0
}
}
{
"type": "player.died",
"matchUid": "match_123",
"roundNumber": 2,
"data": { "username": "chloe", "attackerUsername": "alice", "hp": 0 }
}

Séquence — tir et élimination​

La machine à états définit les phases autorisées. Les notifications de rounds décrivent la fin d’un round et la réinitialisation des joueurs.