[Outdated] NodeJS + GDevelop

Bonjour,

:warning: Obsolète :warning: Outdated

:exclamation: :arrow_right: Ceci est un article proof of concept pour du multijoueur il a été fait sur GD4

Ce n’est en aucun cas un moyen de faire du multijoueur d’une façon correcte car les données envoyé aux serveur sont sous forme de chaîne de caractère, elle ne sont pas sérialisé.

En d’autres terme, les données sont envoyé en clair sans les avoir compacté se qui pose des soucis de latence, le perte de donnée, et rien n’est sécurisé, etc

Ceci est une base de démonstration pour une éventuelle personne qui voudra faire un vrais multijoueur.

L’extension Fonctionnalités réseau qui est devenue obsolète

Le principe est d’avoir Gdevelop pour faire la partie client du jeu en HTML5, un serveur Node.JS qui communique via socket.IO avec les autres clients.

Les technologies utilisé sont les mêmes que pour le jeu agar.io et autres jeux en .io

Le serveur est hébergé sur Heroku , ainsi que le client HTML5 que chaque utilisateurs peuvent rejoindre.

Voici les sources : github.com/Bouh/Prototypes
La version en ligne : gdevelop.herokuapp.com/


Je passe par les événement javascript dans GD, mon étape actuel et de faire transité les données dans des variables globale du jeu.
Pour ça j’ai un objet Texte qui affiche la varibale global qui s’appel “server_message” avec la valeur “bateau”.
Je tente de la changer la variable “server_message” avec la ligne de code javascript suivante :

gdjs.RuntimeGame.getVariables().get("server_message").setString("var_modif");

Hélas dans l’aperçus la console indique l’erreur suivante : code0.js:13 Uncaught TypeError: gdjs.RuntimeGame.getVariables is not a function

#nodejs #heroku #reseaux #multijoueur #online #multiplayer

gdjs.RuntimeGame n’est pas une variable, c’est juste un type. Il faut récupérer le RuntimeGame depuis la scène actuelle (qui est passée en argument de ton événement javascript). Je t’invite à lire la doc de GDJS.

Je trouvais pas logique le fait de devoir partir de la scène remonté au jeu et prendre les variables.
Quoi qu’il en soit j’ai fait lu un peu la doc et j’ai sorti c’est lignes qui fonctionnent :

var game = runtimeScene.getGame();
var variables = game.getVariables();
var server_message = variables.get("server_message");
server_message.setString(message);

Je suis maintenant sur une structure de variable et j’ai besoin de compter le nombre d’enfant d’une variable (pour connaitre de nombre de joueurs)
En passant par les actions il n’y a à priori rien d’utilisable outre que “Enlevé un enfant”, d’ailleurs “Ajouter un enfant” serait utile :wink: (Je vais cherché ça maintenant aussi j’ai cru voir un topic d’aide sur le forum à ce sujet)

Donc j’ai fait une recherche sur la doc, le forum, le wiki et le github pour compté le nombre d’enfant d’une variable globale et sur le github j’ai trouvé GlobalVariableChildCount, mais je doit être un manche pour pas comprendre comment l’utilisé :confused: .
C’est flou il y a des possibilités mais pas accessible, je suis perdu.

Au passage je fais mes test en online ici : gdevelop.herokuapp.com/
Je suis actuellement en local pour les structures de variables mais dès que ça avance je push sur le online.
Si j’y parvient sa sera un prototype de multijoueurs, du moins c’est l’objectif.
Je fournirais toutes les sources aussi :slight_smile:

Edit :
Pour l’action “Ajouter un enfant” qui n’existe pas j’ai pu passé à côté en déclarant directement une variable en voulant la modifié avec l’action “Texte d’une variable globale”.
Hélas dans le débug je n’ai pas moyen de le voir, la valeur de la variable indique “Structure” mais pas son contenu.
Pour le débug je passe donc par un console.log()

Prochaine étape :

  • Faire un menu pour choisir un pseudo et faire une validation (serveur)
  • Broadcasté (ça ce dit ?) le pseudo aux joueurs (serveur)
  • Faire la même choses avec plus de données notamment des positions d’objets sprite

Bonjour,

J’ai avancé sur le dialogue serveur/client (nodeJS/GD).
Je peux choisir un pseudo et l’envoyé pour validation au serveur, pseudo qui est inscrit dans un Array pour savoir si le pseudo est libre.

Pour compter le nombre d’enfants d’une variable globale je fais de la sorte :

[code]var joueurs = variables.get(“joueurs”);
var child = joueurs.getAllChildren();

var count = 0;
for (var k in child) {
if (child.hasOwnProperty(k)) {
++count;
}
}
console.log("Nombre d’enfants de Joueurs : " + count );

nb_joueurs = variables.get(“nb_joueurs”);
nb_joueurs.setString(count);[/code]
J’ai fait un test de Broadcast à tout les clients présent, test qui fonctionne !
Prochaine étape :

  • Switch sur la scène de jeu quand le pseudo est valide.
  • Sur la scène de jeu, créées les joueurs et leurs affecté leurs pseudo respectif.
  • Identifié le joueur du client et le déplacer.
  • Envoie de la position du joueurs au serveur pour Broadcast aux autres joueurs.

Ce qui me parait le plus compliqué ici va être de faire des boucles imbriqué pour les joueurs lors de leurs création.
Je fais un nettoyage dans mon dossier et je partage les sources.

Voici les sources : github.com/Bouh/Prototypes
La version en ligne : gdevelop.herokuapp.com/

Cette version contient :

  • Si le pseudo est pris il y a un retour du serveur qui en demande un autre
  • SI le pseudo est libre il est stocké sur le serveur et la liste entière est transmis aux joueurs (Visible dans la console du navigateur)
  • Un switch temporaire entre les scènes.

:exclamation: Les inputs vers le serveur ne sont pas sécurisé.
:exclamation: SI vous faites des tests changez l’ip dans les événement externes que vous remplissez pas mes logs :laughing:

Super intéressant, je réfléchissais pas mal à un serveur NodeJS avec le minimum pour certaines fonctionnalités réseaux… Je creuserai ta méthode, mais qui si j’ai bien lu (en diagonale) tu communique avec ton serveur sur platform HTML5 ?

Dans mes idées c’était plus sur la plateforme native et voir s’il était possible (avec l’extension “réseau” obsolete ou du code c++ rajouté) d’envoyer des requêtes http vers un serveur.

Sur ton projet, tu comptes aller jusqu’à la création de session (donc création de compte/mot de passe pour les joueurs) et stockage de sauvegarde, scores, etc ?

L’app qui sort de Gdevelop sort en HTML5 et communique par socket avec NodeJS.
J’utilise uniquement des langages web car je ne maîtrise pas le C et C++.
Il doit être possible tout comme je le fait avec une techno qui est nodeJS (Javascript), d’avoir l’équivalent d’une techno en C++.

Il est toujours possible d’envoyer des requêtes HTTP sans problème, cela ne fait pas partie de l’extension dépréciée.

Il faut que j’expérimente sur le sujet (même si je ne prevois d’intégrer de multi autre que local), si l’envoi de requête HTTP permet l’envoi et la synchronisation d’info à un serveur NodeJS, c’est top… Après quid des performances ? S’agissant en plus de “netcode” comme on dit souvent en gaming, je me pose aussi la question du protocole…

HTTP induit un transport de données en tcp, pour certaines c’est incontournable, on ne veut pas d’erreur dans les paquets… dans le cas de la synchronisation de certains éléments sur tous les clients, l’UDP serait plus approprié… Et je ne pense pas que la fonctionnalité réseau de base propose le choix du protocol enter UDP et TCP ?? (j’ai pas Gdevelop sous la main pour tester/voir ce qui est paramétrable…). Je suis pas du tout spécialiste du sujet du netcode, mais ça me paraitrait logique au regard de mes connaissances réseaux de plutôt axer les tranferts sur de l’UDP.

Bonjour,

J’ai fait quelques pas en avant !
update 0.2

Je suis actuellement sur la transmission des mouvements et actions du joueur local à tout les autres joueurs dans le jeu.

Principe :
Pour cela le joueur local envoi les touches appuyé au serveur qui les renvoient à tout les autres joueurs.

Cas pratique :
Mon test qui transfert les touches appuyé par le joueur local aux autres joueurs fonctionne !
Je le met en application en ce moment .

Ce qui fonctionne et qui est nouveau :

  • Création d’un utilisateur
  • Validation de l’utilisateur auprès du serveur pour ne pas avoir deux utilisateur avec le même pseudo
  • Création de l’utilisateur local en jeu
  • Création d’un utilisateur qui rejoins le jeu
  • Suppression d’un utilisateur qui ferme le jeu/la page
  • Nettoyage du code Client et Serveur

Restant à faire :

  • Création des joueurs qui sont déjà dans le jeu
  • Des idées ?

Les sources sont disponible ici : github.com/Bouh/Prototypes/
Une démo est disponible ici : gdevelop.herokuapp.com/
Ouvrez deux onglet de la démo et créer plusieurs joueurs pour voir. (transmission de la simulation de touche visible dans la console.)

Et surprise ! un tchat pour GDevelop ! (non officiel, @4ian)
J’ai fait un salon dans le logiciel / webapp Discord, très utile pour avoir un tchat des utilisateurs de GDevelop !

[size=150]LE LIEN DISCORD[/size]
Attention le tchat n’est pas une zone de support technique et ne remplace en rien le forum !
Le support des modo et admin est comme sur le forum, modo et admin passez sur discord que je vous donne vos attributions.

Je viens volontier sur le chat, tu peux me passer modo ? (victorlevasseur#4215)

Y a t-il moyen de mettre ce post dans la partie PROJETS EN COURS DE DÉVELOPPEMENT du forum ?
Le topic y serait mieux répertorié.

Update du projet :

Les déplacements de chaque joueurs qui rejoignent une partie sont bien transmis à ceux qui sont aussi dans la partie.
Le hic est qu’il y a un petit décalage de position entre la position du joueurs local et ce que vois les autres joueurs.
Du coup je test plusieurs manières de transmettre les données de déplacement du joueur local :

Test effectué :

Avec erreur de déplacement :

  • Envoi au serveur le signal que le joueur local bouge :
    Le serveur renvoi à tout le monde (joueurs local + distant) de bouger le joueur (simulation d’appuie de touche)

  • Envoi au serveur le signal que le joueur local bouge :
    Le serveur renvoi aux joueurs distants qu’un joueur bouge (par simulation d’appuie de touche)

Test à faire :

  • Envoi au serveur le signal que le joueur local bouge :
    Le serveur renvoi aux joueurs distants qu’un joueur bouge (transmission des positions du joueur en mouvement)

  • Déplacement du joueur local, et envoi des données positons au serveur, qui les renvoient aux autres joueurs distant.

Déplacement du joueur local, et envoi des données positons au serveur, qui les renvoient à tout les joueurs (joueurs local + distant).

Où en es-tu de tes recherches ? Ça m’intéresse beaucoup.

Concernant ton soucis de synchronisation, c’est un peu plus complexe que simplement transmettre une info. En réalité il faut créer deux “mondes” qui devront être les plus identiques possibles.
Dans l’ordre le joueur presse sur un bouton.
Le client (côté joueur), fais les calculs de collision pour savoir si il peut bouger. Si il peut il envoi au serveur l’instruction de l’appui sur la touche.
Le serveur vérifie la faisabilité du mouvement dans son monde qui sera celui de référence. Il déplace le joueur dans son monde et envoi la position du joueur a tout le monde.
Dès réception de la nouvelle position, tout les clients mettent a jour leur monde.
Avec ce système tu évites de créer un lag inutile qui peux frustrer un joueur (cas où le joueur doit attendre la réponse du serveur pour voir son personnage bouger).
Tu vérifies toujours les infos envoyées par les joueurs sans leur faire confiance (évite les tricheurs).
Enfin tu t’assures que tout les clients ont les mêmes positions a l’écran.

Avec ce système j’ai eu de bons résultats pour mon bomberman.