JeuWeb - Crée ton jeu par navigateur
Boucle & tick coté server NodeJS? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Boucle & tick coté server NodeJS? (/showthread.php?tid=7509)

Pages : 1 2 3 4 5 6 7 8


Boucle & tick coté server NodeJS? - Argorate - 22-11-2015

Bonjour,

j'aimerai bien discuter de comment gérer la boucle qui génère un jeu temps réel coté serveur avec NodeJS par exemple. Ça pourrait être bien de voir l'ensemble des solutions existante et leur avantages/désavantages.

Pour gérer la simulation d'un monde coté serveur, on raisonne en "tick" ou "tour". La première chose qui vient donc à l'esprit c'est combien de "ticks" par seconde choisit-on?
Comment faire ce choix? Quel impacte sur le jeu?

Ensuite, comment l'appliquer en pratique?

J'ai vu certaines implémentations qui utilisent un
Code :
while(true){ tick(); }
mais ça semble très douteux puisqu'on ne contrôle plus le nombre de ticks en faisant cela. Ça dépend de la capacité de la machine et du nombre de choses à calculé par tick. Ça me parait être une mauvaise solution, peu stable.

Ensuite il y a la méthode du
Code :
setInterval(function(){
tick();
}, INTERVAL);
que l'on peut justement minuté en milliseconde, mais le problème c'est qu'on ne peut pas descendre plus bas que la milliseconde...
EDIT: mais finalement a-t-on besoin de pouvoir faire plus que 1000 ticks par seconde? Cela semble déjà être beaucoup. Du coup cette solution parait attrayante.
J'ai d'ailleurs trouvé un module (dont je ne vois pas l'utilité réel en pratique) mais qui semble confirmer cette approche : https://www.npmjs.com/package/game-loop-dispatch

Mais un autre problème qui me vient en tête : quelques soit la méthode choisit : que se passe t-il si le temps effectif pour passer un tick est supérieur au temps théorique?


Voilà, pas mal de problématique, si vous avez des idées, des retours d'expériences, ou des articles/tuto en français, je suis preneur.


Merci.


RE: Boucle & tick coté server NodeJS? - Sephi-Chan - 22-11-2015

Ce n'est pas du français mais il y a du code pour comprendre : Fix Your Timestep!. Bien sûr, je t'invite à faire l'effort de le lire quand même, car c'est très intéressant. Les mots clés sont "game loop" et "physics loop".


RE: Boucle & tick coté server NodeJS? - Argorate - 23-11-2015

Ça ne répond pas a mes problématiques. Quel métrique adopté? Pourquoi 60 ticks/s ? On nous donne se postulat mais pourquoi pas 10 ticks par secondes, 100? 1000? il est illusoire de vouloir faire coïncidé les 60 FPS d'affichage avec les ticks serveur, il est d'ailleurs intuitivement plus malin qu'il y ait plus de ticks serveur que client, ça permet une granularité et donc une précision plus grande.

Que se passe t-il si un tick est plus long à calculé que le temps qui lui ai prévu? le setInterval va lancer un nouveau tick avant que l'ancien ne soit fini, y aura de grave problème, deux tick se dérouleront en parallèle...


RE: Boucle & tick coté server NodeJS? - Xenos - 23-11-2015

Plus de ticks que ce que l'on peut afficher n'est pas forcément utile si cela génère des frames perdues. Sans compter des dégénérescences mathématiques possibles quand l'intervalle de temps devient trop fin (té, c'est dans le lien de Sephi ça aussi, je crois)

Citation :Que se passe t-il si un tick est plus long à calculer que le temps qui lui ai prévu?
Je crois que c'est dans le lien donné par Sephi (intéressant, en effet): il suffit de se référer à une timeline fiable (ie: microtime) et de calculer l'écart temporel depuis le dernier tick.

Après, t'as aussi des jeux qui se basent sur les ticks sans aucun lien avec le temps. Là, oui, suivant la fluidité de la machine, le jeu donne l'impression d'être "au ralenti" ou "en accéléré" par rapport au temps réel (cf: PCSX2, l'émulateur: le jeu est "calculé" à 60FPS, si la machine est trop lente, le jeu sera ralenti et la bride à 60FPS évite qu'il ne soit accéléré). Ca peut être une façon de jouer.

Quant à ton histoire de tick qui se chevauchent, c'est inhérent au calcul parallèle. J'avais un article pas mal là dessus, soulignant que le temps du SetInterval s'écoule pendant que la callback s'exécute. Mais tu peux t'inspirer de ceci : http://stackoverflow.com/questions/729921/settimeout-or-setinterval et lancer le timeout une fois la callback exécutée. Là, t'as pas de chevauchement. Et le délai du timeout peut être calculé à partir de la timeline, comme dis ci-dessus.


RE: Boucle & tick coté server NodeJS? - Argorate - 23-11-2015

Le fait de mettre par exemple deux fois plus de frame qu'afficher peut être utile pour la précision du jeu, car entre les frames sont prit en compte les events des joueurs qui eux meme joueront sur les collisions par exemple. Même si à l'écran on ne met qu'une frame, le fait de la découper en deux, permet d’être plus précis sur la gestion des collisions dans le temps.

Le problème de 60 FPS coté serveur déjà, c'est que ça tombe pas rond en 1000 ms. On est plutôt sur un multiple de 10 que de 60.

Non justement, il faut que le temps soit compté pendant le calcule d'un tick vis à vis du démarrage du tick suivant. Sinon on a pas des ticks a intervalle régulier mais fonction de la capacité de la machine.
Je préfère l'approche de la régularité quitte à la borné comme il le dise, avec un boolean par exemple, pour empêcher un tick d'avoir lieu si un autre n'est pas fini. Du coup y aura des pertes de ticks, qui feront ralentir le jeu, mais apriori il n'y a pas d'autre solution... La question est donc quel taux de rafraichissement pour un jeu en temps réel?

La réponse est peut être simplement qu'il faut tester par rapport à la machine et au jeu qu'on a pour appliquer le delta time max comme il l'explique. Mais du coup, j'aurais bien aimé avoir l'avis de dev NodeJS qui ont déjà fait des jeux, ça serait intéressant.


RE: Boucle & tick coté server NodeJS? - Thêta Tau Tau - 23-11-2015

Tu parles d'un jeu en temps réél ou d'un jeu web classique où le nombre d'action par minute est très bas?
Parce que dans le second cas, je ne vois pas du tout l'intérêt d'une boucle de jeu côté serveur.


RE: Boucle & tick coté server NodeJS? - Argorate - 23-11-2015

Donc avec un poil de perspicacité, tu dois en conclure que je parle du cas numéro #1 dont tu parles^^

Les boucles cotés serveur = temps réel sinon effectivement, si c'est du tour par tour, c'est juste le serveur qui réagit à des actions du client, ce qui n'est pas tout à fait vrai dans le temps réel.
En théorie, un jeu temps réel avec nodeJS doit pouvoir ce jouer sans aucun client. Si je charge une sauvegarde avec des éléments et des états, le jeu doit pouvoir continuer sa simulation tout seul. Les clients ne font que changer des états ou des valeurs dans la simulation, c'est tout.

j'édite mon premier post pour rajouter "temps réel"^^


RE: Boucle & tick coté server NodeJS? - Xenos - 23-11-2015

J'ai pas fait de NodeJS, mais je peux te dire que même pour un jeu temps réel, 60Hz, c'est déjà une bonne fréquence, y'a pas besoin de plus.
Sur Oban Star Racers (projet offline, jeux classique de course en temps réel), un calcul de 30Hz était suffisant. Voire même 10Hz (car l'afficheur fait l'interpolation entre les étapes calculées) sous certaines conditions (vaisseau se déplaçant à faible vitesse par exemple).

Pour info:
NeoAxis a écrit :Ticks in the world occur to constant intervals. Usually 30 frames per second.

En gros, t'as un ticker (setInterval) toutes les N millisecondes (à la louche, 350ms) qui est exécuté. Quand le ticker est exécuté, il lance les codes qui lui sont attaché (Observer) qui font leurs calculs. Après, tu peux avoir un mécanisme de simili-sémaphore qui va refuser l'exécution du code si celui-ci n'a pas encore fini son calcul et stocker le nombre de "ticks" ainsi ratés pour le lui passer en paramètre la prochaine fois (histoire que le code sache combien de ticks se sont écoulés).

Ah voilà, ça, ce sera surement plus formel:
http://www.neoaxis.com/wiki/Documentation/Programming_Articles/Entity_System#Ticks_and_Timers


RE: Boucle & tick coté server NodeJS? - Argorate - 23-11-2015

Il ne faut pas confondre l'affichage et la simulation du jeu.
350ms coté serveur ça veux dire même pas 3 tick par seconde. Ça veux dire que ton joueur quand il click pour tirer, il n'y a aucune différence qu'il l'ai fait à l'instant X ou X + 350ms. (enfin en vrai c'est un peu moins à cause de la latence, mais même 250ms, c'est beaucoup).

Ça veux aussi dire qu'un objet qui tombe, il n'a que deux étapes par seconde, donc en gros : tu as un verre sur une table, puis il se téléporte à coté, et enfin il est éclater en mile morceau au sol. C'est comme un gif auquel il manquerait des images...


RE: Boucle & tick coté server NodeJS? - Xenos - 23-11-2015

35ms* désolé, c'est le soir (=30Hz)

En revanche, non, le verre ne se "téléporte" pas justement. C'est appelé "Continuous Collision Detection" comme modèle: l'objet est à un emplacement X(t), puis il sera à l'emplacement X(t+dt) et le système calcul si la collision a lieu entre temps ou non. Si elle a lieu, l'objet ne sera pas en X(t+dt) mais en X'(t+dt).

Ensuite, l'afficheur sait que l'objet est à X(t) et X(t+dt), et c'est lui qui se charge de faire une transition esthétique entre les deux. Il n'y a donc pas de "téléportation" (car là, dans ta pensée, tu mélange justement le calcul et l'affichage, alors que les deux sont décorrélés: le calculateur détermine l'état à des instants donnés, peu importe leur régularité d'ailleurs, et l'afficheur se charge de faire une interpolation entre deux états calculés).