Wednesday, October 30, 2024

October update

That week off has been pretty B-usy ... The 'three rooms' demo now actually feature 2 additional rooms, including one that is level-sized. There are still quite some things to fix, tileset updates, adjusting to .more loading, and the like... 

Well, some recent development are incompatible with some old mistakes... especially bounding boxes. I remember being puzzled by what worked and what did not worked when I introduced the 'sand waves', which did require one bbox x y w h command to align the visuals with the slope ... but it really was almost blind guesses.

For some reason, the "box size" bits were ignored, and the "offset" bits were ... well, it will work better with offsets that says "pictures starts 4 pixels on the right in the 16x16 frame. Of course, fixing the size first made most of the offset wrongs until I've got new offsets computed.

Even after one more afternoon of map fixing, there are weird things happening in that school zone level, like 

  • [todo, not critical] Bilou not always hidden by front layer (e.g. hidden if you jump, but not if you're idle or walk)
  • [todo, not critical] Inkjets not moving up and down following rails
    •  

Friday, October 25, 2024

Hanging around in the ICE ...

Good thing with the German express trains is that they provide unlimited power and some WiFi. Your trip might not go as you expected, but at least you've got time to sit, think and check your code base to plan what you'll do in your homebrew project afterwards.

Among those "what's next", some are already done now, like "converting furblock to treebump"... which it did not need after all.

For some time, I have this little note in my notebook... Because many of the levels in the design book expect that we could hook and hang to some objects. I'd like it to be stylish, with swinging animation and all. But for the purpose of testing the levels and trying the game, just snapping to the hook and waiting for the player to press JUMP or leave would do the trick.

The train-idea here is for the step just after that bare proof-of-concept: I already have a "radius" controller that keep a character within a given range of a "pin point". Being hung could use that controller rather than being snapped to a static position. 

To do so, we can shoot a new game object, Bilou's hand(s), that will snap to the hook and use that as a pin point for the swing. That means we'll have to hide bilou's hands on the existing hero game object (like we do when he's carrying something) ... or just don't draw the hand at all, and reuse its OAM slot to draw Bilou's eyes separately from his body, meaning we'd gain one extra freedom degree for the animation, and wouldn't have to draw a dedicated body-and-eye sprite for every angle.

Then I started brainstorming about the croc-platform: I'm not satisfied with its current look. I dug some real egypt crocodile pictures (and real statues pictures). I toyed with the idea of having the crocodile head showing sideways rather than front view -- that would have meant it wouldn't stop sands when flapped anymore ... The blue book said it wouldn't harm that much.

But I couldn't convince myself it would work either. When the crocform#1 flaps down, it completely cease to interact with characters. A sideways crocodile head flapping down by 90° wouldn't "disappear" that way. It would still be in Bilou's way, mostly as a small wall, but it should still be possible to stand on the rear of its neck ...

A few spots in the ongoing level design would work fine with crocform#2 repurposed, but in other spot, it would mean throwing the player into spikes, rather than just let them fall down...

And then I thought about a type of object in New Super Mario Bros that would behave quite like what I need for my collapsing platform, and it meant I wouldn't even need to drop the "shut the sand door" idea:




Monday, October 21, 2024

bug on blador

J'ai tout les morceaux pour qu'on puisse à nouveau utiliser la map "anniversaire" de la school zone dans l'exécutable de "Three Rooms Demo" ... mais quand je veux le faire tourner, on ne peut pas vraiment dire que les choses se passent merveilleusement bien. J'ai cru au départ que c'était des choses que j'avais "cassées" en développant le "soft landing" des furblocks (la motivation n° 1 à faire revenir ce niveau *maintenant*, c'était précisément de vérifier l'absence de régressions). Et des choses qui vont de travers, il y en a quelques unes ^^°.

I wasn't 100% confident with the changes I made to special flags used to implement the furblock... So as I'm entering one week off, it seemed appropriate to ensure I have all the required material to revive a School Zone level where all the "monsters" are featured and ensure there aren't regression. So here's the "anniversary" level again.

Mais pour certains bugs, un petit voyage dans le temps avec Mercurial ne laisse aucun doute: ils étaient déjà là avant. C'est notamment le cas avec dumblador, et Bilou qui tout d'un coup se retrouve bloqué et immobile s'il lui atterrit dessus au moment où il devrait pouvoir servir de plate-forme...

Cette fois encore, c'est dans ddd que la réponse est apparue. Si le n° d'état renseigné par InspectorWidget (bi28) est pour "RIDLE", l'affichage de Bilou en train de tomber n'est pas un glitch: on a jamais su rester sur le taille-crayon parce que le contrôleur "onpath" estime qu'il n'y a plus de plate-forme... la faute à une modification pour crocform qui ne s'est pas re-propagée jusqu'à dumblador: le choix du bit d'état qui indique si on est bien sur une plate-forme ou non ...

And well, we do have some regressions, and some of them are quite older than the furblock modification. Today I repaired the ability to stand on a stunned blador, which should have been updated after I implemented the pyramid "collapsing" platform: it reuses bit-testing that allowed stacking dumbladors, but for obscure internal reasons, it did not use the same bit to declare that the platform is indeed valid. Tricky to find, but easy to fix.

Saturday, October 19, 2024

On y est !

Enfin ! Un peu de bidouille, un sprite qui doit encore être invisibilisé, mais j'ai enfin les physique voulue pour cette branche rebondissante! Dites-moi ce que vous en pensez, mais moi, je suis plus que satisfait par son mouvement ^_^

Euh ... non, je n'ai pas grand-chose de plus à en dire, en fait... mais bon, ça traine depuis tellement longtemps que je voulais marquer le coup avec un p'tit post qui reprenne l'image. 

Je ne suis pas sûr que ça mérite de ré-uploader un .nds ... je vais plutôt me faire un jus et me mettre au lit. Ciao tutti ;)

Finally ... Finally, I've got my bouncing branch working with the intended "furblock" physics. Almost everything else is said in the previous post, and you also have a download link there to try the physics on the original furblock ... But this has taken so long, I wanted it to have its own post.

edit: there was a little issue left: if you watch the animation closely, you'll note that the branch makes an extra wobble one time, and no such thing on the next time. It wasn't intended at first, but it felt nice when happening, so I made an extra "smaller wobble" animation to use as a transanim in the "throw->idle" transition. But it still had that odd/even behaviour, doing it only every other time. It turned out that when Bilou lands on the branch during a transanim, it did not reset the transanim flag. This is a desirable feature when making transition animations for Bilou mid-air, but not here. there's an extra anim2.force script line I can add to say "this animation (big wobble) may interrupt any ongoing transanim", but its implementation was apparently broken. Should be fixed now.

Newer collision flags

It wasn't as easy as I wanted to make the "soft land" mechanism work, and knowing that Bilou will have to attach to an invisible block for it to work with the "bumping branch" rather than to the branch itself will make it even a bit harder. The issue is to allocate new "kinds of collisions" in an already crowded 16-bit space.

That issue is not new: it already appeared when I wanted to add pick-and-throw mechanism together with get-your-feet-back while I was just done with direction tiles for inkjet. Each of these would require about 4 different type of "messages" exchanged between game object and I had barely more than 8 flags left... And the solution had been to use some combination of bits for the different things. So you'd still have 0010 saying "up" and 0020 saying "down", but that would only be valid in connection with 0100 that says "direction tile" and not with 0400 that says "interplay" or with 0800 that has been used to collect feet and animate ink level in pipes.

I've got notes already about addressing that, but they mostly question the fact that there are only two "casts" (read game object lists) in the engine: heroes and foes. And that actually address a different issue (collision performance) although they somehow partition "messages" as well: almost only Bilou can receive a "HURT" collision (well, blador receives it too from spiky pencils tiles so it can align with them and this is likely BadDesign ^^")

And well, introducing bridges and things like that could easily use more casts to keep good performances: both heroes and baddies will collide with bridges, but that doesn't requires baddies to test each others to work. And likely only part of the bridge internal.

I had collected a set of questions on my new notes, and one of the first one got its answer: despite we have only 16 bits communicated to the script about what truly happened in a collision, a full 32-bit number is stored internally. Some of the high bits are already use for special purpose such as "keep checking collision even after a first item was found" or "only consider objects attached to me", but plenty others could be used to restrict the scope, e.g. creating a private "namespace" between blador and blador feet so that the feet cannot accidentally attach to an inkjet (although maybe that's redundant with "must be attached to me"). It makes little sense to keep the upper 16-bits as "flags" and process them the same way the lower 16-bits are processed (a single matching bit and bingo, we have a collision) because we would be unable to identify which flag had a match. Did we caught fire ? or get smashed ? or got an electric shock ? no way to find out.

So the plan would be the following:

  • 8 "casts" (lists) seems a good number. Each test area indicates exactly which cast it tests. If we have casts Evil and Bridge and need to test both for STOMP, then 2 test areas are needed.
  • two "control" bits: ALL and ATTACH
  • 16 "flags" bit: a collision occur as soon as two masks have at least one in common
  • 8 "namespace" bit: a collision occur only if the two area exactly use the same namespace
  • any other are reserved for future extensions.

Saturday, October 12, 2024

Un furblock qui a du ressort

ah. Voilà qui est mieux... Le saut est amorti, puis le bloc re-propulse Bilou en l'air une fois dans la phase à gravité positive. J'ai encore un glitch temporaire à régler, mais au moins Bilou ne se met plus à rebondir dans le vide une fois sur deux. Alors je suis sûr que vous avez d'essayer ça, donc.

And give it a try yourself. I finally have a bouncy block that is bouncy the way I want, dampening your fall, kicking you up when it is back.

Not only that, it also allows buffering of your JUMP commands so that you get a high-jump if you press and hold the JUMP button anytime while the furblock is dampening. JLN managed to get a high jump on any of his attemps. (of course, he is disappointed that it isn't possible to use the glitch to charge even more jump power and make a super-jump taking you out of the map into a super-secret area :P)

Et si on appuie sur le bouton de saut au bon moment (c'est à dire n'importe quand pendant qu'on est sur le bloc), on part en super-saut. Hahaa... On est prêt pour ramener ça sur la branche aussi...


$BACK->$IDLE on event2 [v1 256 <] ($VTHROWN(0) 0 :1 0:6); // 1 
$BACK->$IDLE on event2 [v6 0 <=] ($VTHROWN(0) 0 :1);      // 2
$BUMP->$BACKLAST on event2 [v6 1 =] (v1 2 / :1 v6 1 - :6 $DIR(D_DOWN));
$BUMP->$BACK_ on event2 (v1 2 / :1 v6 1 - :6 $DIR(D_DOWN));  // 4

$BACK->$BUMP on event2 (v1 2 / :1 $DIR(D_UP) $VTHROWN(VTHROWN 3 * 2 /);

$IDLE->$BUMP on hit0 [w1 0 >] ($VTHROWN(200) w1 512 m :1 $DIR(D_UP) 3:6);
$BACKLAST->$BACK_ on hit0 [w1 0 >] ($VTHROWN(200) w1 512 m 2 * :1 3:6);

The little glitch we still observe is linked to the BACKLAST state. Normal cycle alternates between BUMP where Bilou can stay landing on the block (think as "compressed" state) and BACK where Bilou would be ejected ("expanded" state). There may be up to 4 such oscillations before the block comes to a halt. A former glitch happened when Bilou would fall back while we're in BACK state and react as if it hit an eraser although it isn't close enough.

BACKLAST was intended to fix this: it let the block oscillate one last time, but it doesn't feature the hitbox that would propel Bilou up. Of course, that does not work alone, so I also added a transition that restart a cycle if Bilou still shows up, exactly as if we were idle. But we cannot simply do BACKLAST->BUMP, else we will screw up how the "on grid" controller decide where we should transition.

My last glitch came from the speed division on line #3, that makes each oscillation smaller than the previous one: if we keep the last line's expression identical to that of $IDLE->BUMP, the speed will almost immediately be very low, and we might not hit and propel as intended, hence the additional 2 * to compensate the division that is about to occur as soon as we've reached the "default" position of the block. (still, I'll have to cross-check the collision coordinates: it doesn't feel right that it need that much fine-tuning...)

update: okay, works for the branch as well. Just took 1 or 2 hour of tuning...

Friday, October 04, 2024

furblock de montée

La dernière tentative d'améliorer la branche s'est plus ou moins soldée par un échec constructif. Puisque le week-end de montée m'offre un peu de répit, je vais partir sur une idée qui m'est venue en passant en revue les autres jeux avec des éléments de gameplay similaire: commencer par me faire un "bloc-note" à la SMB3, qui se concentre sur le mécanisme, pas sur l'animation. Et une fois que le mécanisme sera validé, je fait la même chose avec un objet invisible.

So trying to combine physical motion and animation for the bouncy branch proved to be a bad idea. Rolling back. I'll keep my satisfying animation and combine it with an invisible block behaving like the "note block" of Super Mario Bros 3 instead. And I'll prepare that with non-invisible block in an easier-to-test environment, that is the pyramid room.

  • premier fix: je dois retirer les zik.import de mon script pyrat.cmd: ces commandes sont propres à la "trhee rooms demo" qui pré-charge un module de base (bilou.xm) et runMe ne connaît pas (encore) l'équivalent, même après recompilation du dernier modèle
  • deuxième fix: runMe a besoin d'un "../spriteB.spr" explicite pour aller chercher le nouveau fichier (et pas un vieux fichier de SchoolRush dans efs:/moving/spriteB.spr ^^")
  • 3eme fix: ma petite anim' faite à la main doit utiliser la SpritePage 8+2 (parce que le fichier bilou.spr préchargé contient 8 pages)

Bon on y est. J'ai un "furblock" dans le niveau-test de la pyramide. Je saute dessus et il s'enfonce bien puis ... il décole vers l'infini et au-delà (ç.à.d  -2147483648). Ah oui, et il n'a encore un tête de fury que sur DS, pas sur l'émulateur. 

J'ai utilisé pour le réaliser un nouveau contrôleur "grille" qui indique si on est repassé au "bloc" suivant, histoire de passer d'un état "repoussé vers le haut" à un état "repoussé vers le bas", et que le bloc finisse par se stabiliser à sa position d'origine. Mais manifestement, ça ne marche pas encore.

There have been a few "setup" issues, leading to a few TODO items to be processed later (this season?) in my notebook, like runMe not supporting the multi-music commands and the lack of "translate to that sprite page" macro for multi-spriteset that leads to annoying magic numbers. But I have to admit that even with that done, the behaviour was fairly surprising. Well, on the DS, the "furblock" did a downwards bump and then skyrocketed to negative numbers: I needed something to fire an event when the original position has been reached. And that thing could be the "grid" controller that was part of my "how to code bosses" arsenal.

But even with that, the resulting behaviour is emerging and perplexing. I guess I haven't found the proper set of rules yet.

Et nous voilà le week-end d'après encore plus au calme, ce qui m'a permis de décortiquer avec InspectorWidget le comportement émergeant (mauve) et de trouver les corrections (bleues) nécessaires pour que ça marche pour de vrai ;)