C’est quoi, ce titre ? C’est ce que vous vous demandez peut-être. La réponse se trouve plus loin dans l’explication qui suit. Aujourd’hui, je vous présente :

  • Une information importante et qui contredit la doc officielle, concernant la façon dont sont lus les states négatifs, et notamment les ChangeState à l’intérieur de ces states négatifs,
  • Un « bug » potentiel de Mugen, qui peut être assez gênant, qui serait extrêmement difficile à repérer (d’après moi en tout cas), et qui ne sera pas corrigé (pour cela, il faudrait revoir la façon dont Mugen agit, et utiliser une méthode plus lourde et pas complètement logique, ce qu’Elecbyte se refuse de faire).

Je vous livre ce qui ressort d’une discussion un tantinet pointue sur la façon dont Mugen lit les states dans les personnages. Tout part d’un constat : la documentation dit que le déclenchement d’un sctrl dans les states négatifs n’interrompt pas le processus de lecture de ces states.

Pour rappel, à chaque tick, Mugen lit d’abord les states négatifs (-3, -2 puis -1) avant de lire le state positif dans lequel se trouve le personnage. Pour rappel encore, les states -1 sont utilisés pour changer le personnages de states en fonction des commandes réalisées par le joueur, les states -2 sont forcément lus à chaque ticks, et les states -3 fonctionnent sur le même principe que les -2, mais ne sont pas lus si le personnage est dans un « custom state » (ex : quand il est projeté).

Donc la doc d’Elecbyte stipule que lorsqu’un sctrl est déclenché en state -3, -2 ou -1, Mugen continue ensuite de lire les sctrl suivant. Or en pratique, c’est faux pour un sctrl : le ChangeState. Tous les créateurs le savent au moins implicitement lorsqu’ils créent leurs states -1 : quand on crée une commande « QCF + a », on doit la placer avant une commande « a », parce que quand le joueur réalise « QCF+a », la commande « a » est aussi (forcément) réalisée. Or Mugen ne déclenche que le 1er state -1 dont les conditions (dont les commandes) sont réalisées, et donc si on veut éviter tout bug, on placera les commandes complexes en premier, et les commandes plus simples en dernier, de sorte que lorsqu’une commande est réalisée, Mugen va éliminer les plus complexes pour aboutir à celle qui est vraiment réalisée.

Or si Mugen ne déclenche que le 1er state -1 dont les conditions sont remplies, ça signifie que le ChangeState déclenché interrompt la lecture du state -1, ce qui contredit bien la documentation.

Partant de là, certains ont fait d’autres tests, et il ressort que tout ChangeState déclenché dans les states négatifs entraîne l’arrêt de la lecture sur le state en question. Donc si on déclenche un ChangeState en state -3, tous les states -3 situés après ne sont pas lus, et Mugen passe directement aux states -2. Idem s’il y a un ChangeState déclenché en -2, Mugen passe direct aux -1 sans lire les autres ChangeState situés après. C’est en tout cas le fonctionnement « idéal théorique » voulu par Elecbyte. Dans les faits, il semble que pour le moment, cela ne soit vrai que pour les states -2 et -1. Pour les  -3, le ChangeState déclenché ne saute pas la fin du state. Ceci sera peut-être corrigé par la suite.

Ca veut dire, concrètement, que dans vos states négatifs, si vous souhaitez déclencher des sctrls (autres qu’un ChangeState) avec les même triggers qu’un ChangeState (dans le même state négatif), vous devrez placer ces sctrls avant le ChangeState en question, sans quoi, ils seront ignorés.

Ca, c’est pour l’information dont je parlais dans le premier point.

Passons au second point, le bug ; il est indirectement lié à la découverte faite dans le premier point. Certains se sont en effet penchés sur ce comportement, et ont découvert un élément important : quand un ChangeState est déclenché, le numéro de state du personnage est mis à jour, mais le StateDef correspondant n’est pas lu. Et alors ? Et alors je vais reprendre l’image qui a été fournie sur le forum d’Elecbyte, et vous comprendrez (enfin !) mon titre…

Imaginons que les states soient des véhicules, et que le StateDef indique le nombre de roues de ce véhicule. En gros, on est dans le State « Vélo », et le statedef a logiquement indiqué qu’on avait 2 roues. Le ChangeState négatif nous fait passer à un State « Voiture », dans lequel le statedef indique, toujours aussi logiquement, qu’on a 4 roues. Mais comme le StateDef n’est pas lu immédiatement après le ChangeState, nous sommes dans une Voiture, avec seulement 2 roues ! Nous ne passerons à 4 roues que lorsque le state « Voiture » sera lu, c’est à dire entre le déclenchement du ChangeState et la fin de la lecture des states négatifs, et du coup, les données n’ayant pas été actualisées, tous les triggers liés au StateDef (MoveType, StateType, anim, vel, etc.) sont possiblement faux après le déclenchement d’un ChangeState en state -3 ou -2, tant que Mugen n’est pas passé à la lecture des states positifs, car ces triggers n’auront pas été actualisés avec le nouveau StateDef.

On va voir avec un exemple. Prenons le code suivant :

[Statedef 1000]
type = S
movetype = A
ctrl = 0
anim = 1000
[...]

[State 1000]
type = StateTypeSet
trigger1 = time = 50
movetype = I

[...]

[Statedef -3]

[State -3]
type = ChangeState
trigger1 = ctrl
trigger1 = StateType = I
trigger1 = StateNo = 0
value = 1000

[Statedef -2]

[State -2]
type = ChangeState
trigger1 = StateNo = 1000
trigger1 = MoveType = I
value = 2000

J’ai volontairement mis les states -3 en premier pour garder l’ordre de lecture de Mugen, et ainsi mieux montrer ce qui se passe. On voit que le Statedef du state 1000 règle le movetype sur A, puis qu’après 50 ticks, le movetype devient I (une fois l’attaque finie, par exemple). Notre State -2, lui, est censé placer notre perso en state 2000 une fois que dans le state 1000, on est passé au movetype = I (donc après 50 ticks). On imaginera qu’il y aura d’autres conditions pour que ce sctrl se déclenche (ex : la valeur d’une variable liée à un mode de jeu, ou autre).

Donc, imaginons que nous sommes en state 0 : notre ctrl vaut 0, et le StateType est bien I. Conclusion, quand Mugen lit notre ChangeState en state -3, les conditions sont vraies, et donc il le déclenche. Il met donc à jour le numéro du state du joueur (0 devient 1000). Il saute le reste des state -3 et lit les states -2. Et là regardez ce qui se passe :

  • Trigger1,1 = vrai puisque le ChangeState du state -3 nous a placé en state 1000, ce qui a mis à jour le trigger StateNo.
  • Trigger1,2 = dans un monde utopique et idéal, il devrait être faux, puisque dès l’entrée en state 1000, le statedef précise que le movetype est A. Sauf que comme le statedef n’a pas été lu, le movetype n’a pas été mis à jour et vaut toujour I !!! Et la conclusion, c’est que ce trigger est donc vrai au moment où il est lu !
  • Les deux triggers étant vrai, le ChangeState est déclenché !

Résultat, on passe en state 2000 sans être réellement passé par le state 1000 !

J’ai pris le movetype comme exemple, mais c’est vrai pour n’importe quel trigger modifié par un ChangeState (vel, anim, statetype, etc.).

Pour éviter cet écueil, il faudrait qu’à chaque fois que Mugen déclenche un ChangeState en state négatif, il arrête la lecture de ce state négatif pour aller lire le StateDef du nouveau state afin d’actualiser ses données, puis reprenne la lecture du state là où elle s’était arrêtée. Elecbyte a fait savoir que cette « correction » ne serait pas faite, et que le comportement global de la lecture des states correspondait à ce qu’ils voulaient, malgré cette « faille ».

En attendant, si un jour vous avez des problèmes de changement de states, pensez à cette éventualité, parce que sinon, pour repérer le problème dans le code, faudra sérieusement s’accrocher ! Et pour l’éviter, le mieux serait peut-être de « renforcer » les triggers des sctrls qui suivent le ChangeState (dans notre cas, si on avait ajouté  « trigger1 = Anim = 1000″ ou « trigger1 = Ctrl = 0″, ceux-ci n’auraient pas été vrais, et donc on aurait évité le déclenchement non désiré du ChangeState en -2).

Laisser un commentaire

Vous devez être connecté pour laisser un commentaire. Connexion »