Sunday, April 24, 2016

Costumes, folks.

https://www.youtube.com/watch?v=xI3xZAn7r2AJe vais appeler "costume" un ensemble alternatif d'animations pour un personnage qui ne change pas fondamentalement le comportement du personnage. Ce sera le cas par exemple de Mario quand il grandit. Bien sûr, mario-grand est capable de faire des choses que petit-mario ne sait pas faire, mais les animations modifiées vont bien au-delà des nouveaux mouvements. Devenir Mario-tanooki, c'est enfiler un costume. Devenir Mario-feu ou Mario-Marteaux aussi. Devenir Mario-Grenouille (SMB3) change fondamentalement l'ensemble des mouvements du personnage, la physique des déplacements et ne peut clairement pas être assimilé à un costume comme défini plus haut.

Some heroes use costumes. When they have some specific powers, their apparence is changed. Their set of moves doesn't fundamentally change -- it's a costume, not a mutation, but they gained an important additional move that may change strategic choices at some points. Yes, exactly like the fact that Mario is currently able to shoot fireballs, just in case the last platforming section made you forget about it. Grabbing the tanooki suit is a costume. Same for the Hammer Bros. suit. The Frog suit in SMB3, however, is more like a mutation. Many basic moves of Mario like running and jumping are no longer available when you're a frog, and replaced by another set of moves. This is truly a distinct part of Super Mario's state machine, while the Fire Flower merely grant you to access one conditional state (throwing fireballs). I need to find something similar for Bilou's BigPunch power-up.

https://www.youtube.com/watch?v=xI3xZAn7r2ALa question qui se pose pour le développement de Bilou est de choisir le bon moyen de réaliser ce changement d'apparence. Vu la complexité de la machine d'état, plus franchement question de doubler l'entièreté des états pour tenir compte de la disponibilité ou non d'un power-up.

Dans certains cas, un simple changement de contenu de RAM grahique suffit. C'est plus ou moins le cas de SMB3: en utilisant son "mapper" pour remplacer la page de ROM présente, les dessins de Mario petit disparaissent et ceux de Mario grand prennent leur place. A part modifier le visage de Bilou, cette technique ne me permet pas vraiment de changer d'animation parce que moi, je fais de l'animation modulaire: la mémoire vidéo ne contient donc pas d'étapes d'animations mais uniquement des fragments d'image génériques.

I've seen some costume as simple as a palette swap. Megaman uses it quite efficiently. I don't feel to use it for Bilou: its colors are deeply linked to his identity, as far as I'm concerned. I've seen other costumes implemented as a video memory update: some new pictures are loaded and used, while the rest of the code -- including the one that decide which portion of the video memory to use at what time -- remains unchanged. Super Mario Bros 3 obviously works that way, at least for Big / Racoon / Tanooki / Hammer Mario. Same moves at the same place within the different pages. A simple re-mapping of the video ROM and the costumes are swapped.

As much as I like that behaviour, it's useless for me. Bilou's hands and feet cannot be easily replaced because they're shared with bladors and pendats. Only the head could be updated. It wouldn't make the animations -- especially the idle animation -- fundamentally different because I'm doing modular animation: the video memory doesn't contain frames but merely fragments.

A more practical alternative would be to reuse Sonic's shields idea, because those shields are animated and rendered independently from Sonic himself. I don't quite know how I could convey the idea "you have punch power" with such a shield around Bilou, though.


La version plus facile, héritée de la NES et de ses palettes séparées, c'est de changer le jeu de couleurs du personnage (demandez donc à Mega-Man, il en sait quelque-chose). Une approche que je mets de côté pour Bilou: ses couleurs font bien trop partie de son identité.

Autre alternative possible, on se la joue Sonic et son espèce de bouclier transparent. Ici, le sprite de base et toutes ses animations restent inchangées: il suffit de faire suivre Sonic par un sprite supplémentaire suffisamment creux pour qu'on voie encore le personnage par-dessous. Jouable pour Bilou aussi, j'imagine.

Je choisis un système moins rétro mais mieux adapté à mon moteur de jeu: j'introduis des sections conditionnelles dans les animations elles-même. L'idée est d'éviter de devoir modifier les infos liés à l'état -- il continue à ne connaître qu'une seule animation -- mais de profiter du fait que j'ai déjà des instructions type RISC pour les animations (déplacer tel OAM, changer l'image utilisée par tel autre, etc.). Du coup, il est assez facile d'ajouter une "instruction d'animation" qui est en réalité un saut conditionnel dans la séquence, sur base d'un des compteurs de bonus ou d'une des variables internes du personnage. Reste à construire la séquence correctement. Ça, ce sera le rôle du lecteur de scripts. Les animations elles -- et leur éditeur --
restent totalement inchangés. On se contente au moment du parsing de construire quelque-chose de plus complexe comme "if [compteur%] animA else animB".  C'est encore insuffisant pour émuler SMB3 (au niveau script, je veux dire), mais ça devrait faire l'affaire pour Bilou.

So there's one option left if I want to swap animations without modifying the states (and e.g. start having multiple animations per state): the animations themselves. They are build as a sequence of a RISC-styled instructions, each instruction changing one specific parameter of the rendering. My idea is to have one additional instruction that behave as a conditional branch, and allow merging of two animations (or more) in a single one.

It's not quite perfect: it requires the two animations to use the same pages with the same structure because at the moment, only one of the structure will be kept for the merged - conditional - animation. The script-parser that performs the binding is still a bit crude too. Likely too much problem-specific while those instructions could do much more. But it will do the trick for Bilou: School Rush and that's my current interest.

Enfin ... le ROM mapping de SMB3 est peut-être un peu plus compliqué que ça. On voit sur la vidéo de Bisqwit qu'une seule "page" de 256x16 pixels est utilisée à la fois pour Mario, or il y en a 4 différentes par "costume" de Mario. Selon l'action en cours (marcher: +0, courir et tenir une carapace +2, voler +3), la page choisie est différente.

And while we're at it, the costume management for SMB3 could be a bit more sophisticated than I originally thought. Only 1 row is accessible to the NES' GPU at any time, and one "costume" offers at least 3 such rows (dubbed 'pages' on bisqwit's original picture) plus one that is used for star-powered sommersaults. I also spot a "page" that is useful only when Mario is carrying a koopa, or turning back. But excepted for little Mario and Frog Mario, all the rest replicate the same layout for common movements.

2 comments:

cyborgjeff said...

La lecture semble t'avoir bien inspirée : )

PypeBros said...

inspiré, et guidé aussi parce que je ne me rendais pas bien compte à quel point l'animation de Bilou et celle de Mario avait besoin d'approches différentes.