Simulation en général > Atelier et créations

[FSX] Lettre ouverte aux développeurs d'appareils

(1/1)

JardY:
(Lettre ouverte aux développeurs d'appareils mais aussi à tous les pilotes qui veulent comprendre pour certains appareils ne tiennent pas sur des sessions GameSpy)

Bonjour à tous,

I) Introduction

Cela fait déjà un moment que j'ai envie de poster ce sujet très sérieux. Je ne souhaite pas accabler les développeurs de gauges que ce soit des développeurs d'appareils paywares ou frewares. Je souhaite une fois pour toute expliquer un phénomène lié au multijoueur par défaut de FSX que tous les créateurs devraient savoir.

Pour commencer, je me présente, JardY, je m'occupe de développements en tout genre pour la session Praetorians-Fs que certains connaissent déjà. Je sais ce que certains pensent du multijoueur par défaut de FSX (qu'on appelle souvent "GameSpy") mais justement ce sujet est totalement lié aux sessions FSX sur GameSpy et il va permettre d'y voir plus clair sur le soit-disant manque de fiabilité de ce réseau.

II) Le problème

Vous avez peut être déjà vu sur un forum ou sur un support technique, des personnes rapporter des problèmes du genre : "Je me fais déconnecté d'une session avec cet appareil", "J'ai le message l'hôte a terminé la session", "Mon PC rame plus en multijoueur qu'en solo".

Les réponses en général sont toutes bêtes : "Le serveur sur lequel tu voles n'a pas une bonne connexion", "Ta connexion Internet ne fonctionne pas bien", "Ta configuration n'est pas assez costaud" ou simplement : "GameSpy c'est de la merde".

Il est temps que tout le monde sache pourquoi des appareils ne "tiennent" pas en multijoueur !

III) La source du problème

Je vais essayer de schématiser le problème puis ensuite de rentrer dans les détails. Lorsqu'on développe une gauge (un instrument de bord), on utilise souvent des variables de simulation et des événements de simulation. Par exemple pour le transpondeur, on peut utiliser l'événement (K:XPNDR_SET). Les événements s'écrivent toujours (K:LE_CODE_DE_L_EVENEMENT). Lorsqu'on est connecté en multijoueur sur FSX, l'utilisation d'un événement déclenche l'envoi d'une information. Autrement dit, le pilote règle un code transpondeur et le simulateur envoie une information au serveur informant du changement de code transpondeur.

Tous les événements de type "K:" n'envoient pas une information au serveur FSX mais les événements basiques le font comme les COM, le transpondeur, les lumières, les volets, le train, etc.. Lorsqu'on utilise un événement "K:" sur un click de souris sur un bouton d'une gauge pas de souci, l'événement est envoyé une fois car il est lié à une action du pilote. Au contraire dans une gauge xml lorsqu'on utilise une balise <Element> à la racine de la gauge, le code est exécuté tout le temps. Plus précisément au rythme de rafraichissement de la gauge (soit environ 16 fois par seconde). Si on ne protège pas ce code, un packet réseau est envoyé à chaque passage dans le code soit 1000 fois par minute environ ce qui est hélas 999 informations de trop.

C'est ça qui est très problématique.

IV) Conséquences sur une session FSX

Que se passe t'il sur une session FSX lorsqu'un appareil envoit en boucle un événement ?

Il envoit jusqu'à 50 fois plus d'informations qu'à la normale. On pourrait dire que ce n'est pas grave si cela impactait uniquement le pilote envoyant en boucle un événement sauf que tous les autres pilotes doivent répondre à ces envois ! Au lieu de répondre une fois, "Transpondeur mis à jour", tous les autres pilotes de la session sont obligés de répondre environ 1000 fois par minute "Transpondeur mis à jour". Evidemment, je vulgarise un peu mon discours. Sur une petite session à quelques connectés, ce n'est pas bien grave mais sur une session hébergeant plus de 20/30 joueurs, ça devient beaucoup plus problématique.

V) Un exemple concret

J'ai construit une petite gauge xml toute bête pour illustrer mon propos. Evidemment, ceci est un exemple, il ne faut pas y voir un intérêt aéronautique mais un exemple de mauvaise utilisation d'un événement du simulateur (événement qui je le rappelle est de la forme "K:").

Voici le code n°1 (code non protégé) :


--- Citer ---<?xml version="1.0" encoding="UTF-8"?>
<SimBase.Document Type="AceXML" version="1,0" id="ExempleEnvoiEvenement">
    <Descr>AceXML Document</Descr>
    <Filename>ExempleEnvoiEvenement.xml</Filename>
    <SimGauge.Gauge id="ExempleEnvoiEvenement" ArtDirectory=".">
        <FloatPosition>0.000,0.000</FloatPosition>
        <Size>500,500</Size>
        <Element id="eltNbEvents1">
            <FloatPosition>25.000,150.000</FloatPosition>
            <GaugeText id="ggtNbEvents1">
                <BackgroundColor>red</BackgroundColor>
                <Bold>True</Bold>
                <FontColor>white</FontColor>
                <FontHeight>16</FontHeight>
                <GaugeString>%((L:COMPTEUR_EVENEMENTS_1,NUMBER))%!d!%</GaugeString>
                <Size>100,50</Size>
                <Transparent>True</Transparent>
            </GaugeText>
        </Element>
        <Element id="eltFlood">
            <FloatPosition>0.000,0.000</FloatPosition>
            <Select id="sltSelect1">
                <Expression id="expNonProtegee">
                    <Script>7777 s0 10 % l0 10 / int 10 % 16 * + l0 100 / int 10 % 256 * + l0 1000 / int 4096 * + (&gt;K:XPNDR_SET) (L:COMPTEUR_EVENEMENTS_1,NUMBER) 1 + (&gt;L:COMPTEUR_EVENEMENTS_1,NUMBER)</Script>
                </Expression>
            </Select>
        </Element>
    </SimGauge.Gauge>
</SimBase.Document>
--- Fin de citation ---
Cette gauge fait deux choses, elle affiche un compteur qu'on incrémente dès qu'on utilise l'événement (K:XPNDR_SET). Et une zone "Element" qui affecte toujours le code 7777 au transpondeur. La zone "Element" contient un select et une expression. Cette technique est couramment utilisée pour être sûr que le code du select sera toujours exécuté et effectivement c'est le cas, il est exécuté autant de fois que la gauge se met à jour (je parlais précédemment de taux de rafraichissement de la gauge). Dans ce code n°1, on affecte simplement 7777 au transpondeur et comme je l'ai dit, si vous êtes connecté en multijoueur, vous enverrez un packet / une information réseau à chaque affectation du transpondeur. Autrement dit, vous allez "flooder" le serveur.

Je le rappelle une fois de plus, seules les variables d'événement de type "K:" sont susceptibles de déclencher l'envoi d'un packet en multijoueur.

Voici le code n°2 (code protégé) :

Je ne recopie pas tout le contenu de la gauge mais simplement la balise "Element" et son script associé. Ici, je veux protéger mon code pour ne pas déclencher l'événement du transpondeur si je n'en ai pas besoin. Comment faire ? Simplement en regardant si la valeur du transpondeur n'est pas déjà dans la valeur que je veux lui affecter :


--- Citer ---<Element id="eltFlood">
   <FloatPosition>0.000,0.000</FloatPosition>
   <Select id="sltSelect1">
      <Expression id="expNonProtegee">
         <Script>(A:TRANSPONDER CODE:1,NUMBER) 7777 != if{ 7777 s0 10 % l0 10 / int 10 % 16 * + l0 100 / int 10 % 256 * + l0 1000 / int 4096 * + (&gt;K:XPNDR_SET) (L:COMPTEUR_EVENEMENTS_1,NUMBER) 1 + (&gt;L:COMPTEUR_EVENEMENTS_1,NUMBER) }</Script>
      </Expression>
   </Select>
</Element>
--- Fin de citation ---
Pour bien comprendre ce principe, j'ai fait une petite vidéo d'exemple :

(Désolé, c'est trop sombre, il faut la visualiser plein écran pour y voir quelque chose)
<!-- m -->http://www.youtube.com/watch?v=iA_0ajdadF8<!-- m -->

Rappel : Attention, ceci est un exemple bien sûr comme je le dis, les événements de type "K:" sont à affecter avec la plus grande prudence pour éviter de les affecter en boucle et donc de rendre instable un appareil en mode multijoueur.

VII) Conclusion

Comme dit au départ, sur des forums, nous voyons souvent des demandes de support à propos de "problèmes" en mode multijoueur. On peut certes avoir un serveur pas très puissant ou sa propre connexion un peu dans les choux mais la plupart du temps, ces problèmes ne sont jamais résolus !

Et bien voilà la solution, aussi complexe soit elle, les corrections à apporter aux appareils sont mineures. Encore faut-il prendre le temps de vérifier son code. Pour finir, je propose mon aide à tous les développeurs d'appareils qui souhaitent se renseigner et tester leurs appareils. Nous avons déjà évoquer ce sujet à demi-mot, de mémoire, pour le Rafale de Rollus, mais aussi et c'est d'actualité pour le PMDG 737 NGX. Voici l'explication globale du problème.

Ce sujet a simplement pour but d'informer les développeurs d'appareils qui sont soucieux que leurs appareils soient stables en multijoueur. J'aimerais ajouter que ce problème peu connu ronge les sessions GameSpy depuis le début de FSX sans qu'il soit décrit de façon clair. C'est chose faite ! En espérant avoir été pris au sérieux car PMDG en plus de nous prendre de haut, ne nous a jamais écouté depuis la sortie de son 737 et ce n'est pas faute d'avoir essayer.

Pour finir, je comprends tout à fait que ce sujet n'intéresse pas grand monde mais il me semblait important de le faire.

Bonne journée à tous.

Laurent Jardillier.
<!-- m -->http://www.praetorians-fs.com<!-- m -->

eric_marciano:
Bonjour Laurent,

Ton post est très intéressant, et en tant que développeur d'avions, je l'ai lu avec attention. J'ignorais le problème que tu décris ici (qui est sans doute le fait de la fonction "shared cockpit" de FSX), mais je connais très bien un problème similaire: l'impossibilité de déclencher une commande avec une séquence de touche, genre Shift-E 2. La séquence de touche ne marche pas dès qu'une gauge envoie des évènements à répétition.

Petite question: est-ce que tu sais si le problème que tu décrit arrive aussi avec les gauges C++ qui envoient des évènements avec "send_key_event"? Je suppose que oui, mais j'aimerais bien en être sûr. En ce qui me concerne, je ne développe mes gauges qu'en C++. Pour moi, le XML n'est pas un language de programmation...
Il faut savoir que dans le développement de gauges, l'envoi d'évènements à répétition est parfois inévitable. Par exemple, dans les Airbus Wilco que j'ai développé, il y a plusieurs asservissements, dont 1 pour les FADEC et 1 pour les commandes de vol électriques (maintien de l'inclinaison et du facteur de charge). Ces asservissements, de type PID, sont en boucle fermée, c'est-à-dire que le système analyse en permanence l'erreur (différence entre la valeur actuelle et la valeur désirée) et corrige l'erreur pour atteindre au mieux la valeur désirée (consigne) puis pour la maintenir. Ce type de fonctionnement implique une correction continue, donc un envoi incessant d'évènements pour FS. Tout ça pour dire que la correction de ton problème n'est pas forcément possible...

Eric

JardY:
Salut Eric,

Je n'avais même pas vu ta réponse (qui date maintenant) : Je te prie de bien vouloir m'en excuser.

Pour répondre à ta question, dans une gauge en C++ oui le send_key_event va se traduire par un envoi de packet UDP.

Après, il faut à tout prix éviter d'utiliser des K:EVENTS pour faire de la régulation ou de l'asservissement : Même si c'est tentant, il faut faire différemment.

L'exemple le plus répandu de flood est le SPOILER_SET (plein de créateurs d'appareil utilise l'aérofrein pour simuler de la trainée) :

Exemple : A2A et le Piper Cub (lorsque tu ouvres la porte en vol), Carenado et C337 lorsque le train est descendu, ça flood du SPOILER_SET...

Je me répète mais il faut à tout prix éviter.

Après ta régulation utilise quels d'évènements ?

J'en profite pour t'inviter sur PFS si un jour tu souhaites que je te montre ça de visu et qu'on échange vocalement sur le sujet.

Navigation

[0] Index des messages

Utiliser la version classique