Friday, October 31, 2014

Les p'tits trucs du monde 16 bits ...

Je trouve assez instructifs les commentaires de Tool-Assisted Speedrun de Coeur de Vandale, RealMyop et leurs invités. Dans sa présentation, le jeune Got4n nous explique par exemple que dans son portage GBA, le moteur du premier Rayman ne teste pas toutes les collisions à chaque frame. Les collisions entre Rayman et les ennemis ne seront évaluées qu'une frame sur 4 alors que les zones plus larges (sortie de niveaux et autres déclencheurs) se relaient et sont évalués une fois toutes les 7 frames. Une ruse élégante pour continuer à faire tourner un jeu conçu pour PC à 90MHz sur un processeur ARM 33MHz (le hardware graphique du GBA permet de sauver pas mal de temps, mais tout de même ...)

About one year ago, a colleague pointed me towards a video where two French guys comment a tool-assisted speedrun completing Super Mario World in a couple of minutes. It is not quite "abusing game rules" where you'd play Megaman as if you were Neo in the Matrix. No. It's looking much more a hacker exploit where you force the program to jump to some place where you can distort content of the code memory. There is no limit to what you can achieve once you reach such a point. You can immediately launch "you won" credits, you can replace any monster's behaviour with some machine code of yours ... you can even play Snake rather than Super Mario.

Since then, I keep an eye on speedruns and tool-assisted speedruns as a way to pleasantly discover the little tricks inside major games. Things like "given maximum speed is 8px/frame, you only need to test for collision with block-size spikes once every 4 frames (Rayman GBA). Or that all the dungeons of Zelda: LTTP are located in the same map and that you can move from one to another provided that you can drill hole between them.


Dans les autres découvertes sympas, saviez-vous que tous les donjons de Zelda: Link to the Past partageaient la même map, et qu'il est donc possible de passer d'un donjon à l'autre en s'y prenant comme il faut ? Eh oui. Quand on doit faire la première grande aventure sur une cartouche 8Mbit, tous les coups sont permis ;)

http://www.explodingrabbit.com/forum/threads/whats-needed-to-finalize-the-current-flash-version-of-smbc.15500/page-3
A la base d'un Tool-Assisted Speedrun, il y a un émulateur dont on utilise à fonctions d'inspection de la mémoire pour trouver où sont conservées les vitesses, les zones de collisions et tous ces petits détails croustillants qui permettent de définir la trajectoire idéale. On s'autorise aussi à envoyer à la console n'importe quels signaux d'entrée, même quand ils ne sont pas humainement possible avec une manette normale et des (gros?) doigts, comme relacher le bouton et le réenfoncer en 1/30 de seconde précisément avant de faire faire Gauche+Droite au D-Pad dans le 60ème de seconde suivant.

Allez, la prochaine fois, je vous explique comment on manipule les boss.

Tuesday, October 28, 2014

Couper les cheveux en quatre ?

J'hésitais à introduire le contrôle des boîtes de collisions dans mon éditeur d'animations. J'hésitais encore plus à ce qu'on puisse activer ou désactiver certaines de ces boîtes au fil de l'animation. Tout ça me semblait plutôt relever de la machine d'états et des gardiens de transitions. Et puis Shantae m'a fait changer d'avis.

So far, I have been able to keep hitboxes on a per-state basis. Anything more subtle was resolved either by spawning new GOBs (like the punch attack in Apple Assault) or splitting the animation (inkjet). I was growing the conviction that it wouldn't be enough for new grab-in-the-air mechanic, Shantae's move pushed the definitive argument: *any* punch or kick-like move has build-up and recover phases, and the hitbox shouldn't be active by then. Splitting the animation in such cases ? That would quickly turn into a nightmare!

At this point, not adding edition of hit boxes in the animation editor would strongly reduce my chance to have form-fit-function ...


Lors de l'animation d'un coup, on peut distinguer trois phase: la préparation, l'action et le retour. Idéalement, seule l'action correspond à une hitbox offensive. Selon la longueur de la préparation et du retour, enfreindre cette règle (qui dérive du "form fits function"), c'est produire des effets incohérents et du coup rendre beaucoup plus complexe l'apprentissage du système par le joueur. Je n'ai pas eu le problème dans Apple Assault parce que les coups de poing étaient en réalité des sprites indépendants. J'ai contourné le problème avec inkjet en tronçonnant l'animation en deux parties et en faisant en sorte que Bilou ne puisse réagir qu'au moment précis de la transition entre les deux tronçons. Mais soyons clairs: faire la même chose avec tous les mouvements "power-up" prévus serait un véritable cauchemar.

Saturday, October 25, 2014

GobAnim::isJedi()


jump, twist and roll!
That's quite amazing, how I manage to postpone an upgrade of the game engine for days and then have two of them implemented in a couple of hours simply because I used doxygen-on-cybook to brief myself on what's around and what is the most straightforward path for implementing them. I have now a way to instruct that a specific transition animation has priority over the running one, which is mandatory for your "air-grab" to have any visible effect when you're turning back or reaching the top of your jump -- in a word, for a consistent behaviour. It also allowed me to give "float-land" a first attempt.

Et voilà: j'ai pu indiquer que certaines animations peuvent "forcer" la main à certaines animations de transitions, comme prévu, mais plus facilement grâce à mon cybook-qui-garde-mon-code-sous-la-main. Comme quoi, je ne regrette pas son passage par le service-après-vente ;). Du coup, on peut déclencher l'animation "attraper en l'air" à n'importe quel moment. Je me suis aussi amusé à modifier l'autre "pirouette en l'air" pour lui donner un aspect de "je descend en planant", même si on ne peut pas dire que Bilou soit un très bon planeur jusqu'ici. Il faudra voir ce que ça donne avec une vraie DS en mains, par contre. Au clavier desmume, c'est assez moyen et on commence à bien s'embrouiller entre la course, le saut, le grab et la pirouette/vrille...

Allez, si ce n'est pas encore fait, profitez-en pour voter pour votre power-up préféré ;-)

Automated OAMs management

Over the summer, I crafted plans for managing larger levels, that would use more than 128 hardware sprites (the OAMs in DS parlance) for all the monsters. Some of those plans use the notion of a "Gob Group", that could be used to spawn several objects at once, at level-specific locations by having them statically placed (unlike shoot-able "dyngobs") but wouldn't be active unless their group is enabled.

Browsing through the game engine code for another purpose on my cybook, it struck me that it would be so easy to have lazy allocation of the hardware sprites as we approach on-screen area and early recycling of those OAMs when we're going far enough from that area. It's now coded. Funny enough, it doesn't affect activation and movement of GOBs in any way: only whether they have hardware sprites assigned to them or not.

done: find a way for Bilou to keep its priority (displays over monsters)

Monday, October 20, 2014

catch this!

A new animation and a good deal of "sprtools" to merge pixels drawn on "lime" DS and animations built on the DSi ... Unfortunately that will not be enough. There's one "dead" moment where you cannot see the "grab-in-the-air" animation whatever you do: when Bilou reaches the top of his jump. The reason is that there's already a "transition animation" running at this time, and that there is no way so far to cancel such an animation for another. I may have to fix that before I can proceed any further: it will likely be very important for super powers.

Une nouvelle animation, quelques coups de sprtools pour fusionner les pixels dessiner sur l'une des DS et les animations présentes sur la DSi. Eh pas de bol: ça ne suffit pas pour avoir un mouvement 'attraper en l'air' qui rendrait le gameplay de SchoolRush plus fluide. En fait, ça marche presque tout le temps sauf lorsque Bilou est au sommet d'un saut. La faute à l'animation de transition qui s'active à ce moment là: le moteur de jeu n'a pour l'instant aucun moyen 'd'annuler' une animation de ce genre. Je vais aller corriger ça, parce que ça risque d'être critique pour les coups spéciaux.

  • [done] "force" flag to override transition animations
  • [done] make "grab" a dedicated state
  • [done] edit areas directly in AnimEDS
  • [done] import AnimEDS areas in GOB states
  • [done] selectively activate/deactivate areas in AnimEDS

Sunday, October 12, 2014

Énergie Scolaire ...

Vous aurez peut-être noté le nouveau sondage de ce blog: quels power-ups ajouter au jeu "Bilou: School Rush" ? Ces power-ups seront essentiellemt détenus par les crayons-soldats, histoire de rendre les affrontements avec ces derniers plus excitants. Voilà donc ce à quoi vous pourriez vous attendre:

If you feel so, and especially if you have played Bilou: School Rush a few times, I'd love you to vote for the following nominated power-up candidates. Writing them down, and given the short length of the game, it would likely be cheap if these were permanent power-ups. I rather see them as "consumable" powers, e.g. you could have 3 throws, 5 float and 1 pound left.

Straight throw: fini le lancer en cloche. Comme dans les esquisse, le super-throw lance l'objet droit devant vous. Il reste actif jusqu'à ce qu'il sorte de l'écran ou heurte un mur. De quoi rendre plus aisé l'assomoir d'encriers.
Default throw fits physical laws by making bladors fall. Bilou throws them at an angle of 45°, making it a mid-range weapon that's demanding to aim, like Worms' grenades or DK barrels. Straight Throw switches instead to Blues Brothers' like weapons, where the blador is moving faster, perfectly horizontally, and at constant speed until it gets off-screen. The counter-part is that when you miss your target, your weapon is gone for good nonetheless.

Air dash: Le bon vieux mouvement aérien qui permet de se tirer d'affaire en nous soustrayant un instant à la gravité pendant qu'on part à toute vitesse. On le retrouve dans Giana Sisters, par exemple.

Air Dash and Ground Pound allows you to reclaim control from gravity. You should have fallen, but you're allowed for a short distance to follow a straight line by pressing a single button. You should have been waiting to reach terminal velocity but you get it instantaneously, and get rid of that annoying horizontal speed for an accurate land. Wall Kick, finally, is a twisted version of Air Dash, that can be chained (more open along time), but is restricted in space (only along walls). 

Ground Pound est son complémentaire direct, qui annule toute vitesse horizontale pour passer directement à une chute en vitesse terminale. (cf. les 2 derniers 'super pouvoirs' sentis pour la "version GBA" du jeu).

Wall Kick, la désormais célèbre technique de ninchat du jeu de plate-forme ne serait que moyennement utile dans ce type de jeu, à moins de bien l'ajuster pour qu'elle permette de compenser un saut un poil trop court.

Big Punch, l'attaque niveau 2 de Apple Assault, qui serait capable d'incapaciter crayons et gommes (voire encriers) à courte distance. Le seul avantage sur un lancer de taille-crayon serait ici ... qu'il n'y a pas besoin de disposer d'un taille crayon. Peut-être moins marrant que dans le jeu d'exploration puisqu'il perdrait en grande partie son intérêt de "brise-craie".

Remember Apple Assault ? "Big Punch" is the intermediate weapon you could receive, that dispatched apples at safe distance, with a massive move. Here, it could stun pendats and recto-verso jumping erasers without requiring you to carry bladors around.

Float-Land, lui aussi, agit directement sur la gravité. Il s'agirait de doter
Super Powers as sketched in Summer 2014.
Bilou de l'équivalent des cheveux de Rayman ou de Dixie, voire d'une feuille-mojo pour planer un peu et atterir en sécurité quand il s'avère que le saut est trop court.
Maybe you'd rather float safely to that next book rather than rely on a timed jump ? That power-up is for you, raccoon friend ;)

Last one, the Wide Grab, is for all those who'd love to catch big air with a spongebop, but typically miss their (B) timing. Wide Grab would double your grabbing hit box. How couldn't you love that ;)


Wide Grab permettrait d'élargir la distance à laquelle Bilou peut se saisir d'un taille-crayon ou d'une éponge, sans aller jusqu'à lui faire don d'une "main-lasso". Cette marge de manoeuvre supplémentaire permettrait soit un gameplay plus "nerveux" (assomer et attraper un blador en un seul mouvement) mais aussi donnerait plus de chance aux joueurs de faire du rodéo sur les éponges.

Restera un choix crucial: celui d'octroyer un pouvoir semi-permanent (p.ex. jusqu'à la prochaine blessure) ou des "munitions" pour le pouvoir en question (mais autorisant de cumuler plusieurs pouvoirs). Vu le côté "arcade" de School Rush, je pencherais plutôt pour la 2eme option.

Saturday, October 11, 2014

Palette Sonore : CJ à la rescousse!

Un point sur lequel je peux facilement donner raison à Kirby Kid, c'est le désert sonore dans lequel on évolue dans le jeu. Un petit "p'tcha!" quand Bilou se fait toucher, un "bop" quand on rebondit sur un monstre et un 'ting' quand on chope un bonus. Et c'est tout. Le lancer de taille-crayon, les encriers qui se préparent, les éponges qui bougent ... tout celà est aussi silencieux que si vous étiez sur Mars.

Kirby Kid also pointed out the lack of sound in the game. Especially, the fact that you don't hear anything when you jump makes it a curious jump-and-run game. I tried converting more of CJ's samples into sound effects, but it didn't really took off. I'll need dedicated samples so that we clearly hear the jump as not being a part of the background music. I also want dedicated sounds when you stun something, when you 'hap' in the air trying to grab something, when you bounce on a pink eraser or when you're interacting with an inkjet.

All this also stems for some code refactoring. As of writing, there is a limited palette of 16 special effects (including sound effects) you can use in the level. It is close to 75% of use, and the major problem comes from the fact that it is _global_. Much like each .cmd file now has its own palette of animations, I need to give dedicated effects palette to each character.


Il est donc grand temps que j'appelle CJ à la rescousse. Mais ça ne suffira pas. Actuellement, je suis limité à 16 effets spéciaux pour l'ensemble du jeux. Celà reprend les sons mais aussi les créations d'ennemis comme les petites étoiles qui indiquent que Bilou s'est fait assomer ou les pieds des Bladors quand on les assomme. Si je veux pouvoir proposer des bonus quand on dégomme un crayon ou une gomme sauteuse, il faut que je fasse d'abord disparaître cette limite.

Ah, par contre:
  • étourdir les encriers à coup de dumblador: ça marche;
  • moduler la force du lancer de taille-crayon par la vitesse de Bilou: mauvaise idée

Btw, I allowed bladors to stun inkjets but turned away from "blador are thrown faster when Bilou moves faster" -- this is just a nightmare for aiming.

Thursday, October 02, 2014

Kirby Kid's Advice: Inconsistent Spongebop

Inconsistent interactions with yellow things. The yellow swinging enemies are neat looking and they have neat physics to them. But interacting with them is very inconsistent and too complicated. It's hard to stay on top of them. It's hard to get the big jump off of them. And the momentum of their swing doesn't transfer to the player at all.
Let's first see what "inconsistent" means in this context. Kirby Kid validated the two definitions I formulated as below:

A mechanic is consistent with regards to 2 object if
  • applying it the same way on the two objects leads to the same result. E.g. slashing something with the sword breaks it into bits in Zelda series. That works on bushes, jars, skulls and even rocks in some games.
  • when it leads to different result, the objects shall be sufficiently different so that the player can easily tell what result it will get from passive analysis of the object. E.g. Jumping on an ennemy in SMB always attacks the ennemy unless the ennemy has spikes on his head. Moreover, the ennemy will always be defeated unless it is shelled.
A gameplay element (applying mechanic A on object B) is self-consistent if
  • it always produce the same result (e.g. bounce by 3 blocks height)
  • when producing different result, the player can relate the cause of this difference to visible difference of state. E.g. a spring that may be loose or compressed will throw you higher if compressed.

Pour corriger mon éponge-qui-se-balance, aussi connue sous le nom de "Spongebop" ou "Bop, l'éponge", je vais avoir un peu plus de mal. Kirby Kid lui a diagnostiqué un problème de manque de cohérence, ce que je peux traduire de la façon suivante: il n'existe pas de manière claire de savoir quel sera le résultat d'un rebond ou d'un balancer qui fait intervenir l'éponge. Kirby Kid mentionnait aussi le fait qu'il est difficile de déterminer si l'éponge va nous repousser vers le côté où si on va pouvoir atterrir dessus. La difficulté principale sera psychologique: dès les premiers coups de crayons, "Bop, l'éponge" est un personnage (et pas une plate-forme) au comportement erratique. Il sera utile, mais il faudra s'en méfier.

From the start I have designed spongebop to be somewhat chaotic, which makes it appear mostly only on the "hard path" of School Rush game. But chaotic must not mean "totally unpredictable". There are two moves that are expected with a sponge bop. The first is to use it to gain height, the other is to clear a larger distance with a jump. Both are based on the fact that, when you press A while un-grabbing a SpongeBop, its current velocity is added to the one of your jump.

Initially, I thought Kirby Kid was mostly criticizing the difficulty to do the first move -- gain height -- because when SpongeBop is  almost idle, the only moment when you can "jump off" is when it moves upwards. But getting that is more a matter of luck than skill: because oscillations of Spongebop across its equilibrium are small and that the "auto-bounce" that happens when you "land" on it can hardly be controlled, the best you can do is to try again and again until it works. You cannot even spam the JUMP button because you'll have to hold it down once successfully bouncing off if you don't want to cancel your jump.


Voyons un peu les interactions que permettent Spongebop:
  • SB peut pousser Bilou bas d'une plate-forme ou l'interrompre dans son saut si le contact est latéral. Incohérence: c'est un rectangle qui nous repousse alors que SB est un patatoïde protubérant.
  • Bilou peut rebondir sur SB s'il tombe dessus et rebondir plus haut s'il appuie sur (A) avec justesse. Incohérence: il est difficile de déterminer la hauteur qu'aura le saut effectué dans la plupart des cas.
  • Bilou peut s'accrocher à SB pour franchir plus facilement un trou. Incohérence: il n'est possible de s'accrocher que lorsqu'on tombe, et pas juste après un rebond malencontreux.
  • Bilou peut faire un long saut en avant en appuyant sur (A) au moment précis où l'on lache l'éponge. Incohérence: rien n'indique pour celui qui n'a pas encore suivi de cours de balistique (ou fait trop peu de balançoire) que la fin du mouvement est un mauvais moment pour cette manoeuvre-là.

 I've been more surprised to see Pierrick failing to clear a large jump by using SpongeBop's swinging speed. He was persistantly trying to jump *at the end* of the swing, but physically speaking, bop's momentum is nul at this time. So indeed, it doesn't transfer to your character.

The way Spongebop behaviour lacks consistency can be summarized as such: when you jump off a Spongebop, the velocity you have will depend on Spongebop's instant velocity. Due to its physics, Spongebop velocity is constantly changing in 2 dimension, meaning that it takes some careful study (or prior knowledge) to pick the moment where you'll get the desired behaviour.