samedi, mars 22, 2014

Stack'm'up!

totally totem !
Commencer par les choses simples. C'est ce qui m'a permis de progresser en fin un peu sur le systèmes des plate-formes dans mon moteur de jeu, malgré des semaines bien remplies. L'objectif: permettre d'empiler des dumbladors l'un sur l'autre pour que plus tard, Bilou puisse lui aussi grimper sur un dumblador puis sur des objets qui bougent.

C'est un bon premier pas, même si dans l'immédiat, le taille-crayon du dessus ne se rend pas compte du "démarrage" de celui d'en-dessous, ce qui m'a permis de l'envoyer à son tour par-dessus le premier.

that was too much for one chunk.
At last, I've got one more step performed on the game engine. Too many times, I picked up my laptop after the kids when to bed to end up watching things on youtube or hunting for a new car. Somehow, getting at once into "Bilou riding some platform" was intimidating and I couldn't get things in place. When picking up my notes again this morning, I wanted to come back to small steps that can be chunked with a single tea cup. How about having Bilou able to stand on a stunned blador and call it a milestone ? As I started converting blador.cmd into the new cpp-assisted format, it turned out that I could get something even simpler to check the bare mechanisms: having stunned blador stacked onto each others. Well, tonight it's done.

Oh, and I'm afraid you'll have to wait somewhat for my "Critical Link" series comparing the gameplay of 2D Zelda games: my scanner has apparently entered the dark world of non-functioning appliances.
PS: it's easy to explain the fact that the "stacked" blador stays in place: I was missing the "attach to path" statement. More annoying: the new GameObject::ride() method was built under the assumption that Gob's movement in (dx,dy) would be consumed, which is not the case with dumblador's stepped movement.

dimanche, mars 16, 2014

un bout de code ... d'alignement ?

Je range ... Et au milieu de tous les brols qui reviennent de mon ancien bureau et qui ne trouveront pas de place dans le nouveau, je tombe sur une tentative d'illustration du roll-jump de DKC returns précédé d'un morceau de code:

while (! cando(dx, dy)) {
  if (dx!=0) {
    dx=(dx>0)? (((x+w+dx)|7)-x)
               : (((x+dx) & ~7)-x);
  } else {
     if (dy==0) return FAIL;
  }
  dy=(dy>0)? (( y+h+dy ) | 7) - x)
             : (( y + dy) & ~7) -y);
  }
}
return NONE; 

Some code snippet I found on a flying sheet of paper while cleaning up and shifting some books around. It should help dealing with alignment along walls and floors while being carried by a platform. Time constraint do not allow me to integrate it into the source code so far, and I've been wondering where it could be for about 2 weeks, so I'll just keep it here for now. It should complement the newly introduced GameObject::ride() function.

Il doit s'agir de la logique d'alignement impliquée dans le déplacement "sur une plate-forme", gribouillé une fin de soirée, mais comme je n'ai aucun schéma qui l'accompagne et que j'ai été avare en valeurs symboliques, on verra ça plus tard: c'est l'heure des tartines.

jeudi, mars 13, 2014

encre ? yeah !

Je ne veux pas me contenter de flaques d'encres immobiles pour la School Zone de Bilou. Je veux pouvoir en profiter pour construire des puzzle autour du principe des vases communiquants. Je veux aussi pouvoir utiliser un seul niveau qui monte pour tout le niveau, histoire de proposer des niveaux à terminer dans un temps limité.

So far the ink is static. Puddles where you shouldn't fall in or some bottom-of-level deathly trap. I want to go beyond that. One of my favourite puzzle elements in Fury of the Furries was involving sand or water level that you raise or lower to transform the level. It re-appears in two of the levels I had envisioned for the School Zone, and it would be the base for both deep-ink-pit and rush-to-completion arcade-games I have in my furnace. Several elements need to be sorted out to get that working, though: rendering, interaction with monsters and implementation of the levels equilibrium mechanics.


Côté implémentation, j'ai écarté l'utilisation d'un plan dédié (je n'en ai plus). Combiner une ligne de sprites pour l'animation de la surface avec un remplissage de l'arrière-plan par des pavés tout noirs pourrait faire l'affaire quand l'encre va toujours vers le haut, mais pour des vases communiquants, qui pourrait "réparer" la map quand l'encre descend ? ... A moins que la map complète en mémoire ne soit jamais dégradée, et que seule sa copie à l'écran ait des pavés noirs. Mais Infinimap n'est pas conçu dans ce sens-là. Des gros sprites partout, ça ne marchera pas bien. Le plus souple, ce serait sans doute de règler ça à coup de polygones.

Rendering still has a few options possible on the DS, but in my current setup, the constraints start to pile up. I cannot have a dedicated BG layer. I don't have any left since I introduced 3D objects, which need their own layer. I might be using 3D polygons when the ink sits "between" the two layers of the playground -- that's for Deep-Ink-Pit and Bilou's Adventure. When the ink rise up through the whole level as in Rush-to-Completion, I'd better use the "window" feature (or possibly a raster interrupt to affect background priorities on the fly). For the animated surface of the ink, sprites are the best I can think of.

Ensuite, il y a les personnages. En remplaçant les codes du bloc d'encre sur la map du niveau d'*deline, j'ai pu faire en sorte qu'un taille-crayon lancé dans l'encre fasse des gouttes. C'est aussi un premier pas pour faire en sorte qu'une éponge qui tombe sur l'encre flotte (enfin, à moins que Bilou ne se tienne dessus assez longtemps).

Spongebops and other monsters might have to interact with the ink. I made a first step with Dumblador getting "killed" when touching the ink and generating droplets. That required to change the tile properties so that monsters can also interact with the ink. Initially, I thought making spongebop floating on contact would require some intermediate "liquid" tile before the interactive "kill-Bilou" blocks, but it turns out that the same interactive block can also trigger state transitions such as fall/float for spongebop. neat.
That's actually very good news. It means I don't *need* the ink to be tiles in order to trigger the floating. A GOB with the appropriate collision mask will transparently produce the very same kind of state transition.

Je pensais au départ ajouter une couche de tiles "flotteurs" par-dessus les tiles qui blessent Bilou, mais le même code "F_INK" peut à la fois se traduire en une transition tombe/coule pour Bilou et tombe/flotte pour l'éponge. En en faisant une collision ordinaire (et pas un type de tile spécifique, ce que je garderais pour l'eau), ça veut dire aussi qu'un GOB qui possède la bonne zone de collision F_INK peut interagir avec les éponges, y compris pour l'encre qui monte et qui descend.

A partir de ce moment-là, je peux commencer à concevoir les réactions "vases communicants". Un objet-déclencheur peut forcer les deux GOB-surface à se mettre en mouvement. On peut aussi les lier l'une à l'autre pour leur permettre de s'équilibrer, avec une variante du contrôleur qui ajuste la distance entre Spongebop et son pivot. Reste un élément délicat: comment faire en sorte que les niveaux d'encre se mettent en mouvement simultanément ? Un coup de sonde à l'aide d'une zone de collision bien calibrée pourrait faire l'affaire (de la taille du bouquin central, par exemple), sauf que les zones de collision sont normalement définies pour un état donné, pas pour un objet donné.

If the part of the ink that's animated is allowed to be a GOB, the use case of ink-level-equilibrium turns closer to something GobScript can readily handle: it mostly comes down to two ink-surface objects that adapt to each other so that they reach the same level, possibly assigning them top speed that depends on the width of the pit they're in. Then, I have to figure out a way to kick them so that they start moving simulatenously (e.g. after Bilou opened some path between the two pits). I could build something inspired from Badman II boss rooms in RSD Game-Maker, with a lock-type block that shoots invisible trigger-sparks moving along the same kind of directional block as those controlling inkjets.

J'ai donc commencé à construire quelque-chose qui fait fort penser aux boss de Badman II: faire en sorte que la serrure génère des "étincelles déclencheuses" (invisibles) vers la gauche et la droite et placer le même genre de blocs-directionnels que ceux qui contrôlent les déplacement des encriers pour faire en sorte que les GOB-étincelles atteignent simultanément les deux surfaces pour les mettre en mouvement.

If that's funny to demonstrate that the a-priori simple engine can handle elaborated things, it would quickly turn into a nightmare for any sophisticated situation, like the twin-corks in Remi's level (where each cork might trigger raising ink from the other's position). You'd end-up crafting chuchu-rocket puzzles on your map and hope the timing you computed in your mind is correct when launching the level. As a second thought, I'd rather have the surface GOBs both attached to the "lock" and start raising when this link is lost. Yet, it would be nice to have test-zones that can be defined through GOB variables so that the level editor can precisely define a trigger region for each of them (but it's unclear I have true *need* for that in any of the level I designed so far).

C'est rigolo un instant, et ça fait plaisir de constater que les abstractions construites jusqu'ici sont suffisament Turing-esque (comprenez, expressives) pour ce genre de déviance. Mais soyons clair: si on veut passer à un niveau un tout petit peu plus élevé -- les bouchons jumeaux du niveau de Rémi, par exemple -- on peut rapidement se retrouver à construire un puzzle à la chu-chu-rocket qui va promettre de sérieuses migraines au moment de la mise au point.

Il y a bien une autre possibilité: quand un Gob (ici, la surface d'encre) est attachée à un autre (la serrure), il reçoit un évènement si le Gob de référence disparaît. On peut alors faire monter le niveau d'encre suite à la disparition du bloc-serrure -- ou du bloc invisible qui s'est fait détruire par le bouchon-qui-s'enfonce. La bonne nouvelle, c'est que l'éditeur de niveau supporte déjà ce genre d'approche. La moins bonne, c'est qu'un Gob ne peut être attaché qu'à un seul autre. On saura donc faire des niveaux avec 2 bouchons, mais pas avec trois. Cela dit, ça mériterait vérification, mais je pense bien que je dois pouvoir m'en sortir avec juste "2 bouchons" dans tous les niveaux dessinés jusqu'ici.

dimanche, mars 02, 2014

Shake it!

It's time I shake up my life! Tomorrow, I'll start with a new position in a quite different job. Don't worry too much if you see the post rate dropping: it will take some time for me to drain those buffers of cardboards that suddenly left my former office ... Plus I'm reaching the 5th wise-person freed in Zelda: Link Between World and 5th tome of the Mallorean cantos (yes, once again)..