JeuWeb - Crée ton jeu par navigateur
Mouvement et jeu en temps réel? - 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 : Mouvement et jeu en temps réel? (/showthread.php?tid=6706)

Pages : 1 2 3 4 5 6 7


Mouvement et jeu en temps réel? - Argorate - 12-03-2013

Bonjour,

le besoin:
j'aimerais avoir de nouveaux avis face a un problème purement technique, à savoir comment gérer les déplacements de personnage en temps réel, via les touches claviers (ce sujet ne parlera pas de la technique du "je clique pour me déplacer" qui ne se gère pas du tout de la même manière).

Le problème:
Actuellement j'ai implémenter mon mouvement via les touches zqsd du clavier (classique), l'animation en temps réel marche. Le soucis est plutôt que le serveur ne suit pas derrière. C'est à dire qu'a chaque mouvement, je fais une requête ajax pour synchroniser le mouvement du client avec le serveur pour rester dans un monde cohérent.

Je ne peux pas ne pas vérifier ou vérifier que de temps en temps l'emplacement des joueurs. Pour que tout fonctionne, il faut que tout soit cohérent. Si je ne vérifie pas l'emplacement, je ne pourrais donc pas vérifier le lancement d'une action (attaque par exemple), et si je ne vérifie rien à cause de cela, via javascript c'est la porte ouverte à toutes les triches! pas très envisageable même si ça serait tellement plus simple...

Donc le problème c'est qu'en laissant appuyer sur les touches de mouvements, les requêtes ajax prenne du retard dans leurs exécutions par rapport à ma position réel, ce qui fausse donc tout le jeu.
De plus, le changement de map (quand on arrive au bord pour passer à une autre) demande lui aussi une requête ajax. Du coup il y a un gros lag dans le sens où toutes les requêtes ajax de mouvements se font une par une dans l'ordre dans mon firebug, avant d'arriver à celle du changement de map, qui débloquera la situation (puisqu'en attendant rien ne se passe).

Voilà les faits et le problème, j'aimerais vos avis, comment gérer cette aspect? En plus si ça lag en étant seul et en local, qu'es ce que ça donne en multijoueur...? On imagine aisément que c'est encore pire.

je suis tout ouïe ! Tout idées, retour d’expérience et autres remarques constructives Wink


Merci!


PS: je n'utilise pas canvas pour le projet dont il est question, mais même avec un jeu en canvas en temps réel, il y aurait tjs se problème de syncro avec le serveur en temps réel...


RE: Mouvement et jeu en temps réel? - niahoo - 12-03-2013

Haha. ça me rappelle un topic ou justement je proposais une solution pour contourner ce problème. En relisant tes posts sur le topic en question, je vois qu'à l'époque tu ne saisissais pas le problème qui arrive quand on balance 50 000 requêtes ajax au même moment.

Voilà le topic en question : http://www.jeuweb.org/showthread.php?tid=8061&pid=102699#pid102699

en utilisant ajaxq, tu peux mettre toutes tes requêtes de déplacement dans une queue spécifique et elles ne partiront qu'une par une. Oui, mais, ton joueur change de case deux fois par secondes, et tes requêtes prennent 2 secondes pour faire l'aller retour. Soit 1 seconde (l'aller) pour que le serveur soit à jour (+ le temps de traitement en PHP). Dans ce cas, c'est simple : à chaque requête de déplacement, tu peux 'clear' la queue, tu annules toutes les requêtes en attente et tu les remplace avec celle du dernier déplacement effectué.

du coup, tes déplacements lancent plein de requêtes, mais seules celles qui sont lancées alors qu'il n'y a plus de communication en cours vers le serveur sont lancées. je sais pas si c'est clair ... tu te déplaces, ça lance la requête T1, elle part. la queue est vide. Tu te déplaces et mets en queue les requêtes T2, T3, T4, chacune annulant la précédente (sauf qu'il faut bien s'assurer que la T2 n'annule pas la T1 puisque cette dernière est en communication avec le serveur (point important)). Tu te déplaces encore, tu clear la queue et place la T5 en queue. La T1 se termine, *pouf* la requête T5 est envoyée vers le serveur. La queue est vide, tu te déplaces, la T6 est mise en queue, etc...

C'est une première approche je pense, ton serveur ne sais pas toujours ou est ton joueur, mais il pourra, dans notre exemple, contrôler les points T1 et T5. Si tes attaques ont une portée courte ça sera gênant car un joueur sera considéré au point T1 tant que le serveur n'aura pas reçu T5, alors qu'en T2 il aurait été hors de portée d'un tir ennemi.

Mais bon, on ne fait pas du real time avec de l'AJAX hein Smile

Je vois que tu as posté sur le topic de Maks. Je ne sais pas comment il fait, mais je pense qu'il confirmera, en envoyant juste l'ID du joueur et sa nouvelle position, la taille de la requête est légère et donc ça va assez vite pour capter la plupart des points de déplacement.

Tu peux ensuite essayer avec deux queues, et balancer tes requêtes sur chaque queue chacune leur tour. Mais ça pose un problème de race condition car tu ne veux surtout pas qu'une requête T2, lancée après une requête T1, arrive avant cette dernière, ce qui peut arriver si T1 était dans une queue ou une précédente requête mettait beaucoup de temps.

Avec ajaxQ je prendrais donc une queue unique pour chaque type de requête : 'moves' pour les déplacement et 'default' pour tout le teste (tout ce qui ne demande pas une précision temporelle particulière). Si les attaques doivent se faire dans l'ordre, une queue 'attacks', etc.

J'aime bien ce plugin mais encore une fois pour un jeu faut voir, ça ne sera peut-être pas suffisant ! Peut-être qu'avec websockets on peut faire quelque chose de similaire (à savoir annuler les requêtes en attente pour envoyer des informations plus fraîches). WS va plus vite à ce qu'il me semble.


RE: Mouvement et jeu en temps réel? - php_addict - 12-03-2013

euh oui mais sauf que là ca va pas du tout...surtout pas d'ajax, faut un serveur push, j'y connais rien mais lit ceci: http://www.jeuweb.org/search.php?action=results&sid=da747384916adc40a28090b972be67a9&sortby=lastpost&order=desc


RE: Mouvement et jeu en temps réel? - srm - 12-03-2013

Ne vérifie pas la position du joueur côté serveur à chaque mouvement.
Tu contrôles tout ce que tu peux contrôler niveau utilisateur et tu envoies la nouvelle position au serveur toutes les secondes par exemple. Voire plus.

Lors des interactions (combat par exemple) tu demandes une vérification au serveur avant d'engager l'interaction pour voir si le client n'a pas triché pour arriver à cette position.


RE: Mouvement et jeu en temps réel? - Sephi-Chan - 12-03-2013

(12-03-2013, 02:24 AM)php_addict a écrit : euh oui mais sauf que là ca va pas du tout...surtout pas d'ajax, faut un serveur push, j'y connais rien mais lit ceci: http://www.jeuweb.org/search.php?action=results&sid=da747384916adc40a28090b972be67a9&sortby=lastpost&order=desc

Même si la communication se fait plus vite (ce qui n'est pas forcément sûr), le traitement côté serveur prends forcément du temps. Il faudrait coupler ça à un serveur de jeu qui répond extrêmement vite (soit un micro-serveur HTTP comme Sinatra, mais l'idéal serait de mettre un hook dans un serveur de push comme Faye) couplé à un stockage in-memory type Redis (ou dans le process ? Mais attention à la stabilité du truc !).

Selon moi — n'ayant jamais fait ça en vrai, ça vaut ce que ça vaut — il faudrait commencer par abandonner le mouvement case par case puisque ça n'a pas de sens dans le cas de petits mouvement pour un système de coordonnées. Tant que le doigt est appuyé sur la touche de déplacement, on envoie (avec un throttling de X ms (disons 100 ms, des fonctions existent déjà pour l'implémenter) un ordre de mouvement (up, right, down, left) et le serveur se débrouille pour les résoudre quand il en reçoit.

Du coup, très peu de validation à faire, on peut tester très efficacement la disponibilité de chaque case en modélisant les zones indisponibles sous forme d'un hash rapide à accéder.


Côté implémentation, je partirais sur une implémentation sans application Web classique : mais plutôt à base de daemon qui fait évoluer le monde de jeu de manière autonome. La couche Web sert uniquement d'interface (edit : merci Niahoo pour avoir pointé ma phrase pas finie).

Idéalement avec un langage taillé pour ça (Erlang ou Scala) mais en restant sur du Ruby on peut utiliser Celluloid, qui implémente pas mal de concepts d'Erlang (sur la concurrence et la tolérance à la faute) et qui fonctionne pas mal. Ses extensions comme Reel permettraient à priori de faire ce que tu veux, mais je ne sais même pas comment j'utiliserais chaque composant.

A mon avis, tout ça peut marcher dans une certaine mesure, mais ça va forcément poser des soucis de mise à l'échelle. L'inconnue, c'est le nombre de personnes à partir duquel ça va devenir problématique : je ne sais même pas l'ordre de grandeur avec des machines pas chères (je serais curieux de voir les chiffres pour la Dedibox à 12 € et celle à 30 € par mois).


Après, te concernant Argorate, je te déconseille de partir là dessus : ça demande d'y mettre un peu d'argent et requiert vraiment beaucoup de recherches et d'expérimentations. Vu comme tu galères à trouver l'info avec Rails (pour lequel il y a de l'aide à la pelle, même en français), tu vas te perdre dans ce genre de technologies plus complexes et qui sort des sentiers battus. C'est peut-être le plus constructif des conseils de ce message.


RE: Mouvement et jeu en temps réel? - niahoo - 12-03-2013

Ce qui serait cool, ce serait de développer un petit plugin qui permettrait une connexion UDP ça serait puissant. Faudrait voir combien de personnes seraient prêts à l'installer.


RE: Mouvement et jeu en temps réel? - Maks - 12-03-2013

Argorate > L'AJAX pour le temps réel, ça le fait pas Smile Les requêtes HTTP sont beaucoup trop lentes.

Citation : Je vois que tu as posté sur le topic de Maks. Je ne sais pas comment il fait, mais je pense qu'il confirmera, en envoyant juste l'ID du joueur et sa nouvelle position, la taille de la requête est légère et donc ça va assez vite pour capter la plupart des points de déplacement.

Oui personnellement j'envoie toujours l'ID du joueur (l'id mongodb actuellement, y'aurait moyen de faire plus court et optimisé donc), et une direction (et non des coordonnées). Ainsi je limite les cas de vérification. C'est moins intéressant pour le pathfinding par contre, mais ça me permet mouvement par mouvement de vérifier si le pathfinding est toujours valide (si un mob se déplace sur une case où l'on avait prévu de passer).

Pour un ordre d'idée, j'ai 5ms de ping en moyenne avec Socket.IO et Node en local (sans prédiction donc, avec un serveur dit "autoritaire").

Citation : N'empêche, développer un petit plugin qui permettrait une connexion UDP ça serait puissant. Faudrait voir combien de personnes seraient prêts à l'installer.

Malheureusement les WS c'est du TCP. Ca pose problème parce que l'on peut perdre un paquet il me semble ?

Sinon pour rejoindre Sephi sur le choix technologique, en 2013, les WS étant de plus en plus adoptés, il peut être intéressant de s'intéresser à autre chose que Node/Socket.IO. J'ai des problèmes de concurrence par exemple que j'ai du mal à gérer par exemple avec Node (exemple je tue un mob, il est supprimé de la map, mais entre deux le tick de l'IA s'est lancé et une action a été demandée alors que le mob n'existe plus levant une erreur). Cependant ça reste une solution très très rapide.

Enfin il faut introduire une dose de prédiction. Alors bien sûr c'est toujours facile d'en parler, mais dès que tu sors d'un canvas blanc avec deux points noirs c'est déjà beaucoup moins simple. Si tu fais une action sur le client, que tu as un conflit avec le serveur, il faut pouvoir rétablir "l'état" de ton jeu. Si ton jeu est pas trop compliqué et basé sur des déplacements ça va. Si tu as des animations, de la physique, que tu as fais une attaque que tu aurais pas du pouvoir faire changeant les caractéristiques d'un autre joueur, bon courage pour rétablir ça.


RE: Mouvement et jeu en temps réel? - niahoo - 12-03-2013

Mais est-ce que tu as déjà mis ton jeu en ligne pour voir comment ça se passe avec un vrai ping ? parce que en local évidemment tu as un ping proche de 0 ...

Sinon oui en UDP tu peux perdre des paquets et ils n'arrivent pas dans l'ordre forcément mais c'est pas grave, c'est adapté à la situation. Mais rien à voir avec les WS.


RE: Mouvement et jeu en temps réel? - Argorate - 13-03-2013

Je vais tester avec le serveur de push, ça ira sans doute mieux en effet. Je comptais sur le push coté php suite à l'ajax pour envoyer le mouvement à tout les autres joueurs, mais j'avais oublié que le fait d'utiliser les websocket en soit (sans parler de syncro plusieurs clients) faisait gagner de la vitesse, j'ai calqué sur ma manière actuel de faire mon chat sur DVO c'est pour ça^^

Donc c'est ce que tu fais Maks, tu push au serveur les mvts? Sinon j’envoie aussi uniquement la direction et non des coordonnées, puis je vérifie coté serveur que la case de destination est dispo.

Après le problème de gérer la concurrence: le fait de faire une attaque alors qu'on ne devrait pas par exemple, c'est justement très lié au fait de vérifier tout les déplacements, non?

Ce qui m'amène à répondre aux propositions du système de queue ou de ne pas envoyer tous les déplacements (et donc ne pas faire toutes les vérifications), c'est quand même risqué. Il suffit qu'un mec ajoute sa fonction JS de téléportation, et ainsi il pourra facilement tricher et esquiver des attaques par exemple ou lancer des attaques alors qu'il ne devrait pas justement... C'est ça qui m’embête dans le fait de ne pas tout vérifier.

Ensuite, oxman je ne vois pas comment tu veux vérifier lors des combats si le joueur est bien placé si tu n'as pas toutes les données (chaque mouvement), tu peux au mieux délimiter un carré (une zone max) dans lequel tu es sur que le joueur doit être, mais c'est tout...?!

Pour l'histoire de l'IA maks, tu fais comment pour qu'il soit indépendant, tu as un script qui tourne en boucle quelque part sur ton serveur et qui lance des push pour les actions d'IA de temps en temps?
Puis pour l'histoire de l'attaque d'un mob mort, si tu vérifies l'existance du mob avant l'attaque ET juste avant le save() des dégats et autres sur la cible, ça devrait résoudre le pb non? Comme ça tu es sur que pendant toutes la "transaction" de l'attaque, le mob existe tjs.
Le problème c'est que ça te fais refaire une requête SQL à la fin de chaque attaque pour la valider, mais bon...


RE: Mouvement et jeu en temps réel? - Ter Rowan - 13-03-2013

je me suis jamais confronté à ce type de sujet

mais ce que j'ai compris du fil de discussion pour optimiser :

- on n'envoie pas un message au serveur à chaque mouvement (chaque pression de touche)
- on envoie un message au serveur à chaque "événement" important (combat, loot, ...) voire à chaque n déplacements, ou à chaque t milli-secondes.

Le message envoyé consiste à fournir dans l'ordre tous les déplacements réalisés depuis le dernier envoi (plus autre chose si besoin)

Ainsi lors de la réception du message, le serveur peut tout contrôler et réagir (corriger la position, tracer la tentative de triche, refuser une action, consommer de l'énergie, etc...)

le tout est de trouver où positionner le curseur (n ou t, ...)

j'ai bon ?