Comment gérer des ordinateurs plus rapides dans un jeu vidéo client / serveur en temps réel


15

Je crée mon premier jeu en ligne en utilisant socket.io, et j'aimerais que ce soit un jeu multijoueur en temps réel comme agar.io ou diep.io.

Mais j'ai rencontré le problème d'essayer de comprendre comment faire fonctionner tous les ordinateurs à la même vitesse.

J'ai trois idées de modèles, mais aucune ne me semble juste, et je me demande comment les jeux vidéo normaux le font. (Vous pouvez sauter la lecture de mes idées; elles vous donnent juste un moyen de voir les problèmes que j'ai.)

  1. Le serveur permet aux clients de s'exécuter de leur propre chef et de transmettre les mises à jour au serveur, qui les diffuse ensuite au reste des clients. Cela a pour problème que certains ordinateurs fonctionnent plus rapidement que d'autres, ce qui les laisse se mettre à jour plus rapidement et se déplacer plus rapidement sur l'écran.

  2. Demandez au serveur de dire aux clients quand mettre à jour. Je peux ensuite attendre que le dernier client réponde (une idée terrible au cas où une personne a un ordinateur lent), attendre que le premier client réponde (encore une fois, attendre la communication avant chaque trame), ou simplement les envoyer le plus rapidement possible (ce qui semble rencontrer le même problème que le numéro 1).

  3. Au début du jeu, demandez au serveur d'indiquer aux clients la rapidité de la mise à jour. Cela signifierait que le client serait responsable de restreindre les déplacements entre cette période. Par exemple, si quelqu'un réussit à appuyer sur un bouton deux fois au cours de cette période, il n'enverra qu'un événement de pression sur un bouton. Cela pose le problème que certaines actions seraient ignorées (telles que la double pression sur un bouton) et que l'interaction dépendrait de l'horloge du client, qui pourrait ne pas correspondre à celle du serveur. Le serveur devra alors garder une trace de chaque client et s'assurer que leurs mises à jour sont soumises au bon moment.

J'ai fait quelques recherches , mais les articles que j'ai lus ne semblent pas aborder spécifiquement ce qu'il faut faire si un client envoie des mises à jour plus rapidement que les autres clients.

Dans mon cas particulier, j'ai affaire à des gens qui ont des vitesses de clavier plus rapides (leur ordinateur enverrait plus de mises à jour de clavier que les autres ordinateurs).

Comment les programmeurs gèrent-ils généralement cela?


1
D'après mon expérience, ce n'est pas le cas. C'est pourquoi les machines gamer existent; ceux qui paient 5 000 $ pour un lance-flammes à la pointe de la technologie ont automatiquement un avantage sur ceux qui utilisent toujours un Commodore 64.
Robert Harvey

1
Donc, mon jeu va sembler lent parce que nous devons jouer au plus petit dénominateur commun? Il semble que le serveur de jeu devrait définir le tempo et qu'il appartient aux clients de suivre le rythme ou vous n'aurez qu'à attendre.
JeffO

3
Je peux mal comprendre la question, mais l'utilisation d'un modèle client et serveur basé sur les ticks est probablement ce que vous recherchez. gamedev.stackexchange.com/questions/81608/… Fondamentalement, vous ne traitez que l'entrée et la logique toutes les X fois (généralement 1 / N seconde, comme 1/60 pour la logique 60 Hz)
Christopher Wirt

4
Après avoir lu la question de plus près, il semble que vous soyez trop concentré sur les aspects clients du jeu. Si vous voulez un jeu multijoueur "équitable", votre serveur devra faire autorité. Cela signifie que tout ce qui arrive aux clients est vérifié ou fait par le serveur. Ensuite, vous limitez les choses d'ici, probablement à travers un système basé sur les tiques comme ci-dessus.
Christopher Wirt

1
Ah, netcode en temps réel. L'endroit le plus profond et le plus sombre du développement de jeux. Bienvenue sur le navire, mon pote!
T. Sar - Rétablir Monica

Réponses:


8

Votre troisième idée semble être la plus proche de ce que je pense être la solution de l'industrie à ce genre de problème.

Ce que vous décrivez est communément appelé tiques . Dans chaque tick, un nombre fixe d'actions serait traité pour chaque client en série. Souvent, les serveurs de jeux auront des actions parallèles lorsqu'ils sont capables, mais c'est un problème beaucoup plus compliqué.

Un tick va probablement prendre la forme de 1 / N seconde, N étant le nombre de ticks par seconde, ou Tickrate. Ce tickrate peut être très très souvent ou très peu fréquent, selon votre cas d'utilisation. Ma suggestion personnelle serait d'éviter un taux de ticks supérieur à 60 ticks / seconde à moins que vous ne soyez sûr d'en avoir besoin de plus. Vous n'avez probablement pas :)

Les actions doivent être atomiques. Par exemple, dans slither.io, une action telle que bouger ne devrait pas immédiatement traiter quelque chose comme casser votre chaîne, à moins que le joueur que vous frappez n'ait déjà pris sa décision. Cela peut sembler trivial pour quelque chose au niveau des pixels, mais si vous avez affaire à un mouvement basé sur des carreaux, cela devient beaucoup plus évident et garantit l'équité. Si le joueur A se déplace vers la tuile X, Y et que le joueur B est actuellement sur cette tuile, vous devez vous assurer qu'à la fin de la graduation, le joueur B sera toujours sur cette tuile pour que toute action puisse avoir lieu entre eux.

De plus, je dirais d'éviter de faire effectuer vos calculs côté client, à moins qu'ils ne soient effectués indépendamment du côté serveur. Cela devient compliqué et coûteux avec la physique (de nombreux jeux optent pour un taux de tick inférieur pour la physique que de nombreuses autres actions et événements à cause de cela)

Pour référence, voici un bon lien pour compléter votre propre compréhension des serveurs de jeux et des réseaux multijoueurs.

Enfin, je dirais que ne laissez pas l'équité ruiner votre serveur. S'il y a des exploits qui rendent votre jeu injuste, corrigez-les. S'il s'agit d'un meilleur ordinateur ayant un léger avantage, je dirais que ce n'est pas si grave.


3
@ProQ, il vaut la peine de noter qu'écrire un bon netcode n'est pas anodin! Si votre application ne fonctionne pas bien depuis le début et que votre netcode semble être nul, n'abandonnez pas. Même les gens qui le font dans la vie de tous les jours ont des problèmes avec ça. c'est juste si dur!
T. Sar - Rétablir Monica

0

Le système suivant garantit que tous les clients et le serveur partagent à peu près le même état de jeu à tout moment.

Avoir l'état du jeu sur le client et le serveur.

Lorsqu'un client essaie d'utiliser une commande (souris, clavier, etc. autre entrée), regardez son état du jeu si elle est valide.

Si c'est le cas, envoyez la commande au serveur, sans l'exécuter sur le client émetteur.

Lorsque le serveur reçoit la commande, regardez son état de jeu s'il est valide.

Si c'est le cas, renvoyez la commande à TOUS les clients avec la date future exacte après ce qu'elle devrait être finie d'être exécutée sur le serveur, puis exécutez les actions demandées par la commande après un délai égal au temps minimum pour envoyer la commande aux clients . puis enregistrez la date, cela permet de faire des prédictions futures. Si le temps varie trop, rendez votre système de jeu plus déterministe.

Lorsqu'un client reçoit une commande du serveur, regardez son état du jeu s'il est valide, exécutez immédiatement les actions demandées par la commande, puis regardez la date actuelle et comparez-la à la prédiction de date reçue. S'il n'est pas valide, le client n'est pas synchronisé. (Tous les clients avec une connexion similaire reçoivent en même temps)

Si la date est antérieure, vous avez rencontré un problème à l'étape précédente, corrigez-le. Si la date est légèrement après, ne rien faire. Si la date est longue après, le client n'est pas synchronisé, c'est-à-dire que le client est trop en retard.

Lorsqu'un client n'est pas synchronisé, demandez une copie de l'état de jeu complet du serveur et utilisez-le. Si cela se produit trop souvent, corrigez cela car c'est plus cher que d'envoyer des commandes.

Sur les clients, restituez les choses à l'écran UNIQUEMENT lorsqu'il n'y a plus rien à faire. Dans des scénarios simples, la fonction de rendu ne prend en entrée que l'état actuel du jeu.

En plus de cela, vous pouvez optimiser beaucoup, en utilisant des systèmes prédictifs, des commandes de regroupement, rendre uniquement les différences etc ...

La validation doit différer, par exemple, c'est au serveur de limiter les demandes de commandes / l'unité de temps.


0

Je ne sais pas si c'est un problème de bibliothèques ou d'environnement que vous utilisez, mais je pense que vous vous en approchez totalement mal.

Dans la grande majorité des jeux multijoueurs, seul le serveur fait de vrais calculs. Les clients ne sont que des machines IO stupides où le seul problème de performance réel est de dessiner des graphiques 3D. Et dans ce cas, peu importe si le client peut fonctionner à 20 ou 200 FPS, car cela n'affecte que les visuels. Cela signifie que la «mise à jour du client» n'a absolument aucun sens. Le client peut essayer de "prédire" ce que le serveur pourrait calculer, mais cela ne fait que lisser la sensation de jeu et n'a aucun impact réel sur le jeu lui-même.

des vitesses de clavier plus rapides

Je ne sais même pas ce que ça veut dire. La plupart des gens ne peuvent même pas suivre la vitesse des claviers bas de gamme, alors comment cela affecterait-il les performances des joueurs?

Sinon, la question semble bien trop large et vous devriez plutôt vous concentrer sur un seul problème réel, au lieu d'essayer de résoudre un problème «général» que vous pourriez même ne pas avoir.


des vitesses de clavier plus élevées ne concernent pas la saisie, mais le nombre de commandes pouvant être envoyées si vous maintenez enfoncée la touche "avancer" ou la touche "tirer".
gbjbaanb

@gbjbaanb Et en quoi est-ce un problème? Vous ne devez vous soucier que des commandes pressées et relâchées. Vous ne devez pas vous soucier de la rapidité avec laquelle la mettre à jour.
Euphoric

Vous vous souciez si vous gérez tous les événements comme l'OP attendu - sur le client Donc, si vous appuyez sur w, vous avancez un peu et que votre clavier est plus rapide que celui de quelqu'un d'autre, vous irez plus vite qu'eux. La dernière chose que vous voulez, c'est de créer un jeu de course, vous devez continuer à appuyer sur une touche pour avancer!
gbjbaanb

@gbjbaanb Non. C'est faux. Le serveur sait que "le joueur va de l'avant" puis tous les 1 / 60ème de seconde, il met à jour les positions de TOUS les joueurs en fonction de leur progression. C'est ainsi que TOUS les jeux fonctionnent. La boucle de mise à jour est la même pour toutes les entités du jeu et les mises à jour NE SONT PAS basées sur les événements de l'interface utilisateur.
Euphoric

1
Non, ce n'est pas ce que le PO comprenait, c'est pourquoi il l'a demandé, et c'est pourquoi vous avez dit "je ne sais même pas ce que cela signifie". Si vous comprenez la position des PO, alors sa question est logique. Si l'OP a codé son jeu pour fonctionner avec une boucle de jeu entièrement basée sur la rapidité avec laquelle les événements sont livrés par le client, alors c'est ce qu'il demande - vous avez tort d'appliquer une conception de jeu hypothétique à ce que l'OP demande réellement, indépendamment du fait que sa conception soit erronée par la plupart des normes.
gbjbaanb
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.