Envoi de différences d'état (deltas) et de connexions non fiables

8

Nous construisons un jeu multijoueur en temps réel, dans lequel chaque joueur est responsable de signaler son état à chaque itération de la boucle de jeu.

Les mises à jour d'état sont diffusées à l'aide d' UDP non fiable .

Pour minimiser l'envoi de données d'état, nous avons mis au point un système qui n'enverra que des deltas (quelles que soient les données d'état modifiées).

Cette méthode est cependant imparfaite, car un paquet perdu signifie que les autres joueurs ne recevront pas le delta, ce qui rendra le jeu inattendu.

Par exemple:

Supposons que cet état se compose de: {positionX, positionY, health}

Frame 1  - positionX changed --> send a packet with positionX only.
Frame 2 - health changed // lost !
Frame 3 - positionY changed --> send a packet with positionY only.

// Les autres joueurs ne connaissent pas le changement de santé.

Comment peut-on alors surmonter ce problème? l'envoi de l'intégralité des données n'est pas toujours possible.

spaceOwl
la source

Réponses:

7

Même si vous envoyez des données en utilisant UDP, vous devrez toujours ajouter votre propre forme de fiabilité pour gérer des situations comme celle-ci. UDP vous donne simplement la flexibilité de faire ce que vous voulez, plutôt que de gérer le format fiable mais moins flexible de la communication TCP. Des messages de confirmation ou des paquets d'accusé de réception devraient être utilisés lorsque la réception d'informations est nécessaire, sinon votre client n'a aucun moyen de savoir si les données qu'il a envoyées doivent être renvoyées. Par exemple, si vous envoyez des informations critiques et ne voyez pas de réponse dans un délai défini confirmant la réception de ces données, renvoyez-les.

Evan
la source
2
Battez-moi. Cependant, il convient de noter que des valeurs assez volatiles, comme la position et d'autres données physiques, n'ont pas besoin d'être garanties. Même au cas où ce serait faux sur une image donnée, il serait de toute façon fixé sur l'image suivante.
jmegaffin
1
Bon point, cela se voit le plus souvent dans les jeux lorsqu'un personnage se déplace soudainement vers un nouvel emplacement très rapidement (ou s'y téléporte tous ensemble). La plupart des jeux le gèrent de différentes manières, mais l'objectif est le même. Le serveur a simplement mis à jour la position de l'entité et votre client la met à jour immédiatement ou la met à jour avec un temps de delta très élevé sur quelques trames.
Evan
3

Vous pouvez également contourner le problème en envoyant une mise à jour d'état complète du serveur aux clients, par exemple toutes les secondes. Si un client n'a pas reçu de paquet, il se comportera incorrectement jusqu'à ce qu'il reçoive la mise à jour d'état complète. Ensuite, il sera à nouveau synchronisé.

Matthias
la source
3

De nombreux jeux utilisent à la fois UDP et TCP / IP pour envoyer / recevoir des données et selon la fréquence d'envoi des données, un protocole différent est utilisé.

Par exemple:

UDP: mises à jour de position et tout autre élément pouvant potentiellement être envoyé / reçu plusieurs fois par seconde.

TCP / IP: actions d'inventaire, actions de sort / capacité (la plupart des actions effectuées par l'utilisateur)

Cela dépend vraiment de la quantité de trafic de chaque article. Si vous trouvez que vous envoyez des mises à jour HP assez fréquemment, elles doivent peut-être être sur UDP.

UnderscoreZero
la source
1
TCP n'est généralement pas utilisé pour tout ce qui nécessite une précision en temps réel en raison de sa capacité à provoquer des pics de décalage importants.
TheNickmaster21
C'est bien si vous voulez vous assurer que votre paquet y arrive. Des trucs comme les mises à jour de position ne sont pas bons pour cela, mais si vous voulez vous assurer que votre utilisateur a appuyé sur un bouton à un moment précis, TCP gère toutes les vérifications d'erreurs et d'autres choses que vous auriez à implémenter pour UDP afin d'éviter la perte de paquets.
UnderscoreZero
Point valide; Je préfère simplement modifier UDP.
TheNickmaster21
1

Si vous lisez la revue du code source de Quake 3 , il explique le modèle de réseau qui est très similaire à votre conception, mais avec une solution pour les paquets perdus.

Essentiellement, dans votre modèle, vous envoyez des deltas par rapport à l'état directement précédent. Dans le modèle quake3, vous envoyez des deltas par rapport au dernier état acquitté par le pair.

le minisme
la source