Thursday, January 29, 2015

Time to fix things.

After graphically resolving dependencies between my huge list of todo items, I attacked with usability issues in RunMe. I trashed a couple of evening on long-lasting bugs (although pathetically trivial >_<) in InspectorWidget and adjusted further the areas reporting so that I can follow which one is active when. That way -- and with another fix on AnimEDS -- I can check that flashing hitboxes needed to improve GRAB animations work fine.

There is also a curious asymmetry in the "GRAB" states. Just having left-facing GRAB react "on dpad" prevents the animation to run to completion. Indeed, the button will appear to be released (triggering a "dpad" event) a few frames after it was pressed (as a result of the mechanic allowing for precise jumps). Better seems to be Good's archenemy.

I've got an on-going experiment that allow beaming only "tiles" or "animations" or "sprites" (...) of a .spr file, in an attempt to work around limited reliability of WiFi transfers for increasingly large files from the DS... It's not very convincing so far.

Oh, and compared to June, Inspector widget has improved. I can expand/shrink behaviour controllers, set breakpoints on their events, and touching left/right "monster area" change the "suspect" in the GOBs list (only selecting those that are active, iirc).

Friday, January 23, 2015

Les vieux tout doux

Eh bien, il y en a, des choses marquées "à faire" depuis les années. Plus de 20 pages si je veux les imprimer sur papier. Ce sont principalement des améliorations pour les éditeurs, comme la possibilité de définir les zones de collision et les points-tests dans un éditeur graphique, aujourd'hui (enfin) très actuel.

La plus ancienne des fonctions manquantes du Level Editor -- les propriétés des blocs -- serait plutôt revu en "appliquer la combinaison graphisme/propriété à l'ensemble du niveau", et il faudrait aussi que je permette aux descriptions de blocs d'être partagées entre plusieurs scripts de niveaux.

Enfin, il y aura la liste des projets devenus hors-propos ou qui ne sont plus à l'ordre du jour pour mon projet actuel, rebaptisés "wish", comme l'éditeur 3D de bangbash ou l'intégration de RunME dans la PAlib :P

Mais la palme du PlusVieuxToutDouxDuMonde, c'est sans doute la possibilité de partager des tiles d'un bloc à l'autre (les blocs faisant 2x2 tiles), qui apparaît dès les premières réflexions sur l'animation des blocs en 2005 et marqué "need" en 2008 (traduisez: fonctionnalité jugée indispensable pour l'avancement du projet, qui permettrait de redescendre à 66% du nombre de tiles actuels). La possibilité de poser des quarts de blocs dans LEDS aidant, évidemment... Dans l'immédiat, j'aimerais plutôt pouvoir enregistrer des morceaux de niveau pour capturer des objets complets (qui apparaissait 6 mois plus tard, puis revient à la charge).


Voilà. J'ai fait un peu le ménage dans ce qui datait d'avant 2013 ... je ne suis pas sûr que ça m'ait vraiment fait progresser pour améliorer le niveau des expériences en cours, par contre. A suivre. Comme toujours :P
codes couleur: [done], [todo nécessaire pour school rush], [todo dans l'absolu], [wish]


That's what gets out of the 20+ pages of 'todo'-tagged posts already available on this blog. When you condense them on a sheet of paper, with focus on releasing the 'School Rush' game. There's one big point missing, though.

Write a documentation page for AnimEDS

Thursday, January 15, 2015

Pixel Prospector dug "Drop Wizard"

Très chouette découverte grâce à PixelProspector: Neutronized revisite un monument du gameplay: Bubble Bobble. Tableaux fixes, quelques monstres et on passe au tableau suivant quand ils sont tous éliminés. En tombant de l'écran, on réapparait par en haut -- et pareil pour les ennemis. Il faut toujours deux actions pour se débarasser d'un ennemi (comme dans Apple Assault ^_^): une étoile magique et un coup de genou. Dans l'ordre.

I'm glad I found +PixelProspector back. Just in time to discover "Drop Wizard", a really nice game by Neutronized, adapting Bubble Bobble classic gameplay into something definitely more strategic. You still have to dispatch all the cute monsters out of the screen. You still need one long-distance attack _plus_ one close dash to definitely get rid of a monster. You still wrap around the screen vertically. But this time, you cannot jump. You cannot shoot any time, either: you only shoot when you land. If you don't want to end up trapped, you'd better plan your moves and analyze those of the monsters.

Mais "Drop wizard" est beaucoup plus stratégique. On ne peut pas sauter, et le personnage ne lance une étoile que lorsqu'il atterit sur une plate-forme. Il faudra anticiper bien davantage son parcours pour éviter de se retrouver bloqué, pris en sandwich par deux ennemis... un peu comme dans space panic. Mais il y a une échappatoire. Un mécanisme de combo qui n'est pas sans rappeler les carapaces de koopa de Super Mario.

There's one (funny) way out, hopefully. When you dash into a monster, it rolls to the next wall. While rolling, it can clump into others and chain into a combo. Trust me, this one is a true gem.

Le bon tempo

J'essaie de rendre les manipulations de taille-crayons plus dynamiques. Quelque-chose qui soit plus adapté au gameplay du "school rush" ...

Compared to "Anniversary Level", the tempo of the game has quite evolved. Current animation of Bilou grabbing something on the ground with his eyes going "whoo! Look what we've got here" doesn't fit the action anymore. With the ink rising and pushing pressure, having to stop on a blador to GRAB it is a pain. It would be neat if we had the opportunity to grab it on the fly, just after we stunned it. That the best I can think of to "make things snappy".

J'utilise la nouvelle fonction "édition des zones de contact dans AnimEditor", mais ça n'a pas encore l'air très au point ... entre les dumbladors qui s'envolent quand je tente de les ramasser, les animations qui s'interrompent prématurément et les éponges qui glissent des mains de Bilou. Ce serait sans doute une bonne idée de prévoir une amélioration de l'InspectorWidget pour permettre de visualiser ces changements de zones de contact.

Yet, things are not quite working as expected

  • [done] Bilou may stomp-and-grab a dumblador in one jump
  • [done] why is left-grab not playing ?
  • [wish!] how could I end up with an editor that damages animation when opening them ? I need unit testing here.
  • [done] bladors should skyrocket when I try to grab them.
  • [todo] why do I have anims with over 10 'control: done' statements ?
  • [done] make sure InspectorWidget can report areas masking.
  • [done] do not flash colors when holding L in InspectorWidget, please.
  • [think] export over WiFi has become too complicated. Plan a multi-connection approach
Unrelated (except for timing) todo items:
  • [done] allow meta-information about tiles (rules.gam) to sit in a separate file, included by level scripts.
  • [todo] allow spawn point (and possibly spawned GOBs) to be modulated by some global game variable (checkpoints, difficulty settings, etc.)
  • [think] a simple map editor for PC would be better suited to those "surgical edits" required in current development cycle. That or easier-to-upgrade runME with the cycle moving back to DS device.
  • [done] print and deep-review todo items to establish battle plan for 2015.

Saturday, January 10, 2015

Keen: ClipToWalls()

Pour éviter que Keen ne passe à travers les murs ou ne reste bloqué en bas d'une pente, les niveaux attribuent à chaque bloc de 16x16 pixels un ensemble de propriétés. C'est la technique des "tiles" bien connue de la plupart des lecteurs. Ce qui est particulier dans le moteur d'ID software, c'est la possibilité de définir séparément l'animation, la pente de sol, le comportement en tant que bloc spécial (valeur du bonus, couleur de la clé, etc.) et la polarité du mur.
Plus fastidieux à définir que le simple remplissage en tant que bloc solide de mon éditeur de niveau, mais heureusement, dans Keen, il y a presque systématiquement correspondance entre graphisme et propriétés, et l'éditeur de niveau peut automatiser tout ce qui n'est pas passages secrets.


Levels in Commander Keen are build out of tiles -- 16x16 pixels squares combining a graphic content and some in-game properties. In ID's engine, the tile number (*map) is used to index a set of arrays that are present in game definition, and read at game startup into tinf. NORTHWALL, in the snippet above, is the offset to the array holding information about how the tile behave as a floor. Is it sloped ? can we move through if we're sliding down a pole ? tinf[NORTHWALL+*map] tells you that. And only that. If you'd like to know whether there's a bonus of some value, you should definitely check another "slice" of the tinf array.

Interestingly, the behaviour routines won't immediately react to wall/floor/ceiling collision. Oh, well, character will immediately be _clipped_ to that wall. Aligned, if you prefer, so that it doesn't enter a rigid structure. But the alignments that were performed are saved into four boolean variables: hitnorth (floors), hitsouth (ceilings), hiteast and hitwest (walls). Behaviour routines like KeenAirReact use this information to adapt the current state (stop falling when reaching the ground, for instance).


La notion de "polarité des murs" est intéressante. Lorsque le personnage se retrouve partiellement dans un mur, c'est cette polarité qui décide si Keen est repoussé vers la gauche ou vers la droite. On aura donc jamais de situation comparable au "zipping" des jeux NES où Megaman se met à traverser le niveau à vitesse super-sonique lorsqu'il rentre dans un mur simplement parce que les programmeurs se sont contenté de "si on est dans un bloc solide, on repousse Megaman sur le tile suivant". Evidemment, ça suppose que les murs font toujours au moins deux tiles de large.
A Zipping technique in Megaman. Propelled at 1 tile/frame or so.

Another interesting thing is that walls have polarity. They're either left wall or right walls. And they're not plain ground either: you could fall through a wall if there were no floor on its top to prevent you from entering there. And it's actually more resilient against zipping through walls. Unlike Megaman, Keen wouldn't be propelled to the (arbitrary coder decision) right if he ends up into the wall from the left while heading left. A wall on Tuberia knows whether it is an east wall, no matter the direction, speed and age of the Commander. And if it's an East wall, it will push you to the East, back where you're supposed to belong to. That makes ID software's collision handling the perfect opposite to Epic Megagames' cando() function.

C'est intéressant de voir que ID software a choisi ici une technique radicalement opposée à celle d'Epic Megagames. Pour Jill of the Jungle et Xargon, Epic faisait en sorte que le personnage n'entre jamais dans des tiles qu'il ne peut pas traverser (grâce à la fonction "cando"). Pour Keen, think() peut potentiellement faire rentrer un personnage dans un mur, mais le déplacement via ClipToWalls() le repoussera automatiquement dans la bonne direction, sans risquer de se faire piéger par un demi-tour de dernière minute comme dans Mario Bros.

Thursday, January 01, 2015

Kirby Kid's advice: things to avoid.

Most enemies are just things to avoid (lacking interplay). When I see enemies I don't get exciting to avoid them or take them out. All the mechanics are just move, jump, and run. Not too much to do or play around with considering there are no powerups, the "coins" are clumped and generous, and the enemies are mostly obstacles to avoid. 
no checkpoints for long level is annoying.

A last item of KirbyKid's advice on School Rush. I will debate it later. Happy new year.

(last but not least as it took me 1.5 year to address, but I think I can be proud of the result).