Jeu en réseau

Le principe de l’automatisme est de mettre automatiquement à jour une grande liste d’objets.

Il est ainsi particulièrement utile de créer un groupe contenant les objets à mettre à jour, et appeler l’action pour générer les identifiants sur ce groupe, le tout au lancement de la scène afin que tous les ordis possèdent les mêmes identifiants.

-Donc, si tu gère deux joueurs, le mieux est peut être de gérer toi même leur déplacement, d’autant plus que le deuxième doit pouvoir être bougé par le deuxième ordinateur. Ainsi, tu peux envoyer toi même la position/angle/animation des joueurs par exemple.
-Tu peux aussi utiliser un automatisme avec un nom différent pour chaque objet joueur, et ensuite configurer l’automatisme en envoi/réception suivant que l’ordinateur controle le joueur ou non. Dans ce cas, il te faut donc un automatisme avec un nom différent pour chaque joueur, et faire attention à ce que le nom des données envoyées par chaque automatisme diffère. Tu peux ainsi remplacer “Object” par “Player1” ou “Player2”… dans la configuration de l’automatisme.

Question pas facile, dans l’exemple que j’ai commencé à faire, j’ai laissé chaque ordinateur gérer ses projectiles vu qu’on les voit pas.

Sans automatisme, le principe serait le suivant :
Quand un ordinateur créé un tir, il envoie une demande au serveur de créer un nouveau tir à telle position.
Le serveur reçoit la demande, et créer un objet tir. Il envoie aux clients une information comme quoi ils doivent créer un tir à telle position, avec telle force.

Le principe est que l’autorisation et la gestion des tirs est faite par le serveur. Les clients ne font qu’afficher le tir.

Avec l’automatisme, il faut t’assurer de créer un objet tir sur chaque ordinateur, en envoyant comme précédemment une demande de création d’objet tir par exemple, et qu’ils possèdent tous le même identifiant, en envoyant par exemple aussi l’identifiant aléatoire choisi par le serveur.
Ensuite, l’ordinateur qui envoie les données doit s’occuper de gérer le déplacement de l’objet, et ce sera répercuté sur les ordinateurs recevant les données.

Une seule fois, à la création par exemple, suffit. De même pour l’état de réception.

Si tu met en mode réception de donnée, l’automatisme va récupérer les données de la forme ObjectX/… ( X représentant un nombre, et les … représentant le nom de la donnée, genre X, Y, Angle… ). Ensuite, il mettra à jour l’objet ayant l’identifiant X avec les données.

A l’inverse, en mode envoi de données, l’automatisme va envoyer pour chaque objet des données de la forme ObjectX/… où X représente l’identifiant de chaque objet, et les … le nom de chaque donnée.

C’est aussi pour cela que si tu utilise plusieurs automatismes de ce type, il est possible de changer le “Object” en autre chose. Tu peux aussi vérifier manuellement les données que tu reçois en affichant par exemple la valeur de la donnée nommée “Object0/X” qui te donnera la position X de l’objet avec l’identifiant 0. ( Souvent le premier objet )

D’accord :slight_smile:
Et si j’ai bien compris, je peux également créer un groupe qui s’appelle “Ennemi/X” + variable ?

Par exemple, tu peux en effet créer un objet ( ou un groupe d’objets ) qui utilise un automatisme qui envoie les données sous la forme “ennemi…/…” en mettant ennemi à la place d’objet dans le nom de la donnée de l’automatisme.

Désolé mais j’arrive pas trop à saisir le sens de ta phrase (j’ai bien relu 15 fois) :blush:
Je voulais savoir, si je veux que les ennemis soient mis à jours par le serveur manuellement sans l’automatisme je peux envoyer la valeur avec l’intitulé/groupe “ennemiX” + ennemi.VariableString(ID).

Et histoire d’être sûr d’avoir compris au sujet des automatismes :
Je met en envoi/réception les données dans l’évènement qui test si l’on est joueur 1 ou joueur 2 ( l’évènement avec comme condition : le texte de la variable “firstplayer” est = à “yes”) et pas au lancement de la scène (qui prend en compte les deux joueurs).

Et quand j’ajoute un destinataire, les port doivent être différents pour chaque joueurs c’est ça ?

à titre d’exemple un jeu à 5 joueurs je met :
le j1 ajoute quatre destinataires avec les ports “50002” (j2), “50003” (j3), “50004” (j4) et “50005” (j5)
le j2 ajoute quatre destinataires avec les ports “50001” (j1), “50003” (j3), “50004” (j4) et “50005” (j5)

le j5 ajoute quatre destinataires avec les ports “50001” (j1), “50002” (j2), “50003” (j3) et “50004” (j4)

PS : d’ailleurs je peux pas mettre un port qui s’appelle “1” ?

Tu n’est pas obligé de mettre des ports différents, mais si tu veux tester en local (127.0.0.1), il faut absolument que les ports soient différents.

Tu es sûr ? car une fois j’avais laisser les ports des deux joueurs identiques et ça n’a pas marché, j’ai d’ailleurs passé 4 heures à voir que c’était juste ça.

Les ports inférieur à 1024 sont réservés et ne doivent pas être utilisés.

Tu peux par exemple faire :

Pour chaque objet Ennemi
Conditions : Aucune
Actions : Envoyer la donnée Ennemi.Variable(VieRestante) avec le titre “Ennemi”+Network::GetIdentifier(Ennemi)+“/VieRestante”

Merci 4ian :slight_smile:

Une petite conclusion de ma part :
Évitez d’inclure un chat “in game” avec les fenêtres d’entrée de texte car cela stop le déroulement du jeu du coup cela peut fausser le nombre de, par exemple, tirs présents sur les deux ordinateurs.

Exemple :
Le j1 tire alors que le j2 rentre un texte.
Pendant qu’il rentre le texte les données ne sont pas reçus et le j1 a tiré 10 balles.
le j2 ferme cette fenêtre et où sont les 10 tirs ? Non créés.

Sauf si vous créez un système d’entrée de texte vous même avec les évènements, permettant ainsi de ne pas stopper le jeu, il ne vaut mieux pas faire de chat in game.
Vous pouvez aussi permettre la communication en mettant des touches raccourci du style :
Si j’appuie sur “1” ça envoie “Suis-moi” à l’autre joueur
Si j’appuie sur “2” ça envoie “à l’aide”
ect…

Edit :

Au fait quand je rentre cette syntaxe : Fantomes.::GetIdentifier()
ça me dit que c’est mal formulé, c’est normal ? Enfin du coup je peux pas valider mon action.

En effet c’est mal formulé : La syntaxe est : Objet.NomAutomatisme::NomFonction()

Si tu a laissé le nom par défaut, ce sera alors Fantomes.NetworkUpdater::GetIdentifier()
Normalement, en utilisant l’éditeur d’expression, tu devrais pouvoir utiliser la liste des expressions disponibles pour laisser Game Develop générer ça tout seul.

Ce qui veut dire que dans cette fenêtre je suis censé avoir quelque chose ?
Sans titre.JPG

Tu coup moi comme c’est vide, j’ai jamais mis le nom de l’automatise (NetworkUpdater) dans mes actions :

je doit l’écrire moi-même?

Edit : là je viens d’essayer la syntaxe Fantomes.NetworkUpdater::GetIdentifier() et il me dit que c’est mal formulé.

Oui, je viens de tester sur un jeu vierge en ajoutant un objet avec l’automatisme, ça marche bien.
Le plus probable est que tu ait mal orthographié le nom de l’objet, ou que tu ne lui ait pas associé d’automatisme.

En effet, je crois que je vais faire une pause, je lui avait pas associé l’automatisme.

4ian, pourrai-tu m’envoyer ton Exemple quand tu l’auras fini?
Car là j’ai tenté d’utiliser l’automatisme réseau pour les ennemis dans mon jeu et le seul résultat que j’ai c’est des ennemis qui clignotent.

j’ai fait ça :

Il y a un problème dans mes évènements ?

Voilà ce que j’avais commencé à faire :

NetworkUpdaterAdvancedExample.zip (212 KB)

Mais comme je le disais au dessus, je n’ai pas géré la création de tir ou d’objet dynamiquement.

Dans ton screenshot, tu regénère des identifiants unique pour un seul fantome, il ne risque pas d’être unique, car il y a de grande chance qu’il soit mis à 0. Le mieux est d’utiliser l’action permettant de modifier toi même cet identifiant en utilisant par exemple un numéro aléatoire.

Ok, merci :slight_smile:
Bon j’ai fait comme tu m’a dit, ça marche maintenant :slight_smile:
Par contre quand les ennemis sont créés. Des fois, ils ne sont pas créés pour le second joueur. et ça me fait pareil pour les tirs.
Ensuite j’ai également le problème opposé des tirs ou des ennemis sont créés en plusieurs exemplaire presque au même moment chez le joueur 2 et pas chez le joueur 1 (chez lequel il y a bien un ennemi ou un tir de créé) (pour les tirs on se retrouve avec une jolie chenille).

UP
(j’aime pas trop faire ça)

Le truc c’est qu’envoyer une donnée et la recevoir ne permet pas de s’assurer qu’on la reçoit une seule fois.
Pour éviter de tels créations multiples, on peut utiliser une variable contenant un nombre aléatoire qu’on transmet avec “l’ordre” de création de tir/ennemi. Ensuite, l’ordinateur qui reçoit ça va s’assurer de créer le tir/ennemi seulement si la variable contenant le dernier ennemi/tir créé n’est pas égale au nombre transmis. Une fois le tir/ennemi créé, on stocke la valeur de ce nombre, et on s’assure de ne plus recréer de tir/ennemi tant que le nombre alétoire transmis est toujours le même.

A l’inverse, je suppose que c’est dû au fait d’une trop grande rapidité du jeu qui fait que seulement les données du dernier tir créé sont envoyés. Tu peux alors essayer d’envoyer plusieurs données, par exemple pour chaque tir créé, tu envoie la donnée comme quoi un tir est créé en rajoutant un petit nombre si tu as plusieurs tirs :

(Remettre à zéro auparavant la variable count )
Pour chaque objet Tir ( qui vient d’être créé )
Envoyer les données : Par exemple les données avec comme intitulés “Tir”+VariableString(count)+“/X”, “Tir”+VariableString(count)+“/Y” et “Tir”+VariableString(count)+“/RandomIdentifier”
Faire +1 à la variable count

L’ordinateur qui reçoit ça va comparer la donnée RandomIdentifier avec celui qu’il a en mémoire pour s’assurer de ne pas recréer un tir plusieurs fois.