Thursday, December 29, 2022

crocform #1

You may remember I had plans for a larger variety of platforms in the desert/pyramid zone of Bilou Dreamland. There's a second flavour of the crocodile-inspired platform that I barely shown so far, but which got a significant role to play in the work-in-progress level design. Unless you have some sandfall around, it is merely behaving as a "disappears after some time" platform. With sandfall, it adds "respawn" to the mix.

Last week end, I finally got to the point where I wrote some script to give it existence in the ongoing 3-room demo. There's a thing that went significantly wrong, though: Bilou couldn't notice when the platform is gone.

 


I've had a similar issue with dumbladors when time came to 'stack' them: when one recovered, those stacked on top of it had somehow to detect they'd no longer have a platform behind them. It would be trivial if the gameobject implementing the platform was destroyed, but here it stays around.

  • extend dumblador's extra "gobbit(when 7.1)" to Bilou
  • trigger an extra "throws up" temporary hitbox when flapping down the platform
  • implement it all with brand new "larger animated blocks" feature, not with a sprite, because that platform doesn't truly "move".

The temporary hitbox seemed to be the least-resistance path, so I gave it a go. But unfortunately, it led nowhere. Mostly because the already-implemented collision I was trying to reuse (that use to make Bilou bounce of erasers, for instance) is only tested in states where Bilou is airborne. Here, I'd need it in states where Bilou is supposed to be on the ground.

Yet, I hesitate going for an additional micro-controller 'gobbit' (despite it already has C++ code) because that would introduce new events to deal with. I'd rather have the 'onpath' controller be able to fire an event when the platform-object it is attached to signals it is no longer a platform, the same way the controller can signal the object no longer exists.

I could try having some automated test into 'onpath' that would ensure the current state of the 'platform' object still has the area active and using the proper flags, but that would require extra care if I don't want Bilou to behave weirdly when the platform turns back or does any state transition that don't actually imply losing its 'platform' behaviour.

Friday, December 09, 2022

#infinitePyramid

 There once was a project dubbed 'Infinite Pyramid' that should have featured Bilou in a procedurally-generated pyramid. Just like "nuts'n'bolts", it is no longer seriously considered since the introduction of "Bilou Dreamlands", but I have kept tagging some tweets #InifinitePyramid, especially when it came to others' pixelart to study. It's now time I actually study some of them a bit more.

"sunset in a bottle" by Chrysoperla2. I like the overall aesthetic of the bottle and the color raster for the golden part works quite well. Possibly the curvy style is more "arabian nights" than truly egypt, but I don't think I should care too much about that.

The 'ramp' for the shady part is replaced by small and smaller islands of intermediate shade, which makes nice clusters. the two lightest shades are almost always together, the second-brighter being rarely seen alone unless in the darker parts of the object that get not enough light to show the full ramp.

A quick overlap test with my existing tileset shows however that these golden tints look very close to the tints I picked for the rocks, and using them instead of my yellow ramp for the mummy's crowns doesn't work as is. I'll have to find something in-between Chrysoperla and my current colors to improve.

The 'small' jewelish pot at the left of Nerkin's Egyptian scene seems to blend better into my own mock up.

Greenish creature by CJJammies

Pretty effective shape, which could work pretty well as a reference for my crocodilish monster . At least the colors blend fairly well with my current tileset.

I note how we mostly either use the top-3 colors of the ramp (areas in the light) or the bottom-three (areas in the shadow, like the head), but rarely the middle-three as main colors.

The textureless style has some charm, but I will likely try and put some 1-pixel-wide strokes to suggest scales on my own character.

I'll have to return on the eye later on. The shading work here is brilliant. It still sticks to 5-colors-ramps if we consider that the pupil is "another color" than the rest of the eye.

That could have been all, but Master Henk has recently published a mockup of Shantae palace (3DS) together with a full tileset for that area. There's so much to study in here, and unfortunately, JPEG compression has made it nearly impossible to identify precisely which and how many colors Henk has been using. Yet, quick preview in my mockup suggests the color could blend in nicely. The pillar seems compatible with Egyptian style enough to provide an extra reference. The stonework is awesome as well, including almost all the little tricks I've seen in others with just the right amount of stylization. Maybe it's not really appropriate for plain pyramid walls, but something alike could surely work deeper under the ground.

And then, there had been an interesting sarcophage by Juanito Medinart, but it doesn't seem to blend so well... It might still be an interesting reference for style or so, but not as pixels.

Friday, December 02, 2022

baloo_file ?

 Je tente une migration de ma VM ubuntu au bureau. De 18.04 à 20.04, en espérant que ça me permettra de partager plus facilement les produits de builds avec les machines de tests tournant en 20.04 ...

Mais au moment où j'essaie de prendre la machine en main, je suis face à un système tellement peu réactif que passer en mode console est à peu près ma seule option. Le coupable, c'est kswapd ... enfin non. Le coupable, ce serait plutôt baloo_file, qui semble s'être décidé à indexer l'entièreté du système (à travers un process fils baloo_file_extractor) en même temps que d'autres opérations de bienvenue (regarder si il y a une mise à jour dispo) sont aussi en cours. Sur un système avec 2G de mémoire au total, ça ne pardonne pas vraiment.

Le message d'erreur quand le programme de mise à jour d'une distribution à l'autre aurait pu être plus clair, cela dit. https://ubuntu.com/blog/how-to-upgrade-from-ubuntu-18-04-lts-to-20-04-lts-today ... Voire, l'outil aurait pu auto-installer ses dépendances plutôt que de signaler une erreur :-P

L'outil de mise à jour voulait me virer e17 ... mais pas de panique: c'est juste parce que le package a été rebaptisé "enlightenment". Heureusement, il est possible de passer le 'nettoyage des anciens packages' le temps de vérifier que tout se passe comme il faut, découvrir les alternatives de la nouvelle distro puis valider le nettoyage avec apt auto-remove (ou quelque-chose du genre suggéré au premier apt-get remove e17)

La bonne nouvelle c'est que je vais pouvoir utiliser terminology dans cette VM aussi. à moi les tyls et autres tycat pour avoir des images en ligne de commande $_$

Par contre, terminology n'a pas de support pour la ruse "un 2eme fond d'écran parfaitement ajusté pour qu'on puisse lire le texte par-dessus" que j'utilisais avec Eterm... 'faudra peut-être que je travaille à une PR.

Sunday, November 27, 2022

Tué par la caméra

C'est devenu un problème récurrent pendant que je progresse dans les niveaux de Super Mario 3D World: tôt ou tard, je finis en-dehors du niveau, et régulièrement, c'est suite à un mauvais mouvement avec le stick-caméra.

Le jeu a fait le pari d'un mélange 2D/3D qui (globalement) marche plutôt bien. la perspective montre une généreuse partie du sol, ce qui autorise la création de "salles" dans lesquelles les quatre joueurs peuvent aller et venir, coopérer ou entrer en compétition. La manipulation des personnages y est d'ordinaire plus proche d'un Link's Awakening Switch que d'un Super Mario. ça, c'était prévisible. Elle est aussi plus proche d'un Link's Awakening Switch que d'un Mario 64, et ça, ça vaut peut-être la peine qu'on y regarde de plus près.
Dans Mario 64, le personnage peut normalement prendre n'importe quel angle sur le stick. Le contrôle est doublement direct (pour reprendre le terme défini par Kirby Kid dans The Coefficient of Clean ): la direction du stick s'applique directement à l'orientation de Mario et l'amplitude du stick s'applique directement à sa vitesse (ou à son accélération ... ma mémoire du jeu me joue un tour). En comparaison, les mouvements de Mario dans 3D World sont confinés aux 8 directions accessibles à un D-Pad, comme si le jeu avait été conçu sur SNES. 
En soi, le 3D world étant principalement consitué d'objets alignés sur une grille cubique, c'est un excellent choix de design: quand il va y avoir une passerelle un peu étroite à franchir, le joueur aura toujours moyen d'être pile dans l'axe où il ne se met pas à tomber au bout de trois pas. Mario 64, au contraire, était construit avec des polygones "libres". Une passerelle pouvait se trouver sous n'importe quel angle entre deux plate-formes qui adoptaient une géométrie polygonale quelconque (croyez-en un vieux qui y a joué au pavé numérique sur émulateur, et qui donc devait zig-zagger dans ce genre de situation)
Les mouvements de caméra eux aussi ont été discrétisés. On regarde de face, de profil, ou sous un angle de 45° entre les deux. Un léger mouvement du stick droit de la switch nous fait basculer d'une perspective à l'autre dans un mouvement adouci dans le temps mais déclenché d'un coup quoi qu'il en soit. Et ça, en jeu solo, ça fait mal: le stick caméra est alors normalement sous les 4 boutons d'actions. Le moment où vous avez le plus de risque de l'accrocher par mégarde, c'est au milieu d'un saut un peu long. Pour peu que vous soyez dans un niveau qui reproduit en réalité un parcours 2D dans un moteur 3D, il ne faudra pas longtemps pour que ce changement d'orientation se traduise par un changement de la trajectoire de Mario (la direction imposée par le stick est relative à la vue, pas à Mario lui-même, or la vue vient de changer). Le temps de s'en rendre compte, il est trop souvent trop tard pour réagir et on aura au mieux le droit à 2 ou 3 wall-kicks pathétiques avant de ouahaouhouahouahoahahahahaaa au fond du niveau.


Et pour ne rien arranger, le jeu nous met sur la même input (stick directionnel vers le haut) deux mécaniques: avancer vers le fond de l'écran ou grimper vers le haut. On casse ici le principe d'individualité des contrôle (chaque mécanique a son morceau de manette qu'il ne partage avec aucune autre mécanique, toujours d'après le lexique de Kirby Kid).


 Dans la plupart des niveaux, c'est plutôt un bon compromis: ça rend le fait d'escalader un mur spontané par rapport au déplacement sur le sol bidirectionnel, de même qu'il paraît naturel d'utiliser le DPAD vers le haut pour monter les escaliers dans un Zelda 2D (et si on avait pu y escalader les montagnes, ça aurait marché aussi). Mais revoilà les niveaux linéaires où les traceurs de parcours ont décidé de nos faire profiter de la vue splendide sur les nuages en arrière plan plutôt que de nous coller un mur devant les yeux. Soit.

Sauf que si vous ajoutez une grille à escalader (direction vers le haut), une fois Mario arrivé en haut de la grille, vous avez assez peu de temps pour relacher la direction 'vers le haut'. Faute de quoi, vous irez dire coucou aux jolis nuages d'un peu plus près. "Dommage", comme dirait Bowser. 

Notez que les concepteurs ont réalisé qu'il y avait un problème, et qu'ils ont ajouté une grille-de-fond par-derrière la grille-à-escalader. ça rattrapera le J.L.N qui avait mis uniquement son stick vers le haut (et donc ira s'accrocher à la grille du fond une fois arrivé en haut de la grille-qui-bouge), mais pas le papa qui avait maintenu haut et avant simultanément dans une habitude d'optimisation des mouvements sur les lianes de la Jungle Jaja.


 

Notez aussi que le problème ne se limite pas aux niveaux sans mur en arrière plan. Ici, par exemple, on est supposé se promener en rebondissant sur les fourmis invincibles tandis qu'on passe par-dessus des pics. Fort bien tant qu'on ne se met pas en tête d'utiliser la 3eme dimension pour aller s'accrocher au mur avec le costume de chat. Parce qu'en réalité il y a un espace de la taille d'un Mario entre les fourmis et le mur, donc vous pouvez parfaitement vous retrouver à les louper parce que vous êtes par-derrière alors que ce tronçon de niveau est conçu pour être joué sur un seul plan. Et vous pouvez aussi vous retrouver à tomber par-devant le niveau suite à un rebond mal calculé sur le mur du fond, naturellement.

Sunday, November 20, 2022

#RIPTwitter ?

C'était un drôle de vendredi, ou tout Internet semblait convaincu qu'on vivait les dernières heures de twitter.

Cette année-ci, j'ai une bonne raison de ne pas me laisser affecter par ce genre de nouvelle, mais ça ne m'a pas empêché de voir que j'étais loin d'être indépendant de ce réseau social, même si j'ai pris pas mal de distance (plus de #screenshotsaturday ou de #OneTagPerWeek, par exemple)

Il faut dire que twitter a pris la place des forums quand j'ai migré hors de l'environnement universitaire (enfin, ceux qui étaient encore existants). Il a aussi bouché tant bien que mal le trou laissé par la disparition de Google Reader et des flux RSS. Et il me sert de va-et-vient pour les images et vidéos provenant de ma switch comme de ma 'liseuse' avant d'en faire quelque-chose de précis pour mon blog.

Mais plus gênant, j'ai pris l'habitude de faire des liens vers des conversations twitter quand il y a eu des discussions préalables, ou quand une image full HD d'un jeu switch est en ligne mais qu'une version réduite suffit pour les besoins d'illustration du blog. Et tout ça, ça veut dire que mon blog lui-même perd un membre si twitter disparaît.

J'ai donc demandé une archive de mes données twitter. Mais le 'takeout' est loin d'être automatique, et quelques heures plus tard, ne voyant toujours rien venir, je prend une archive de mon blog (instantanée) et je greppe tout ça un bon coup pour trouver tous les liens du blog vers twitter (enfin, je pense).

Mauvaise nouvelle, les pages correspondantes ne sont que des coquilles vides, dans lesquelles du code javascript ira écrire le contenu des tweets. Le seul outil capable de faire ça, c'est un navigateur complet (je pense). C'est donc au clavier-souris que j'ai passé presque la totalité de mon samedi à copier-coller les tweets identifiés dans un gros .odt sous google-document (365+ pages au final) avec les URLs par-devant pour pouvoir retrouver et reconstruire le contenu-satellite au cas où ...

edit: il aura fallu finalement près d'une semaine pour recevoir l'archive de 1Go avec entre autres toutes les images et toutes les vidéos postées dans mes tweets.

Bref, ça m'a permis de fortifier un peu mon compte Mastodon.

Et il faudra que je vous parle de ce https://goodboygalaxy.com/



Sunday, November 06, 2022

Scorpeye... Enfin!

 Oui, je l'avoue, j'ai été lent. J'ai été distrait (au sens attention détournée). J'ai été démoralisé par cette "carapace" qui ne voulait pas faire demi-tour à chaque fois ou qui faisait des demi-tours intempestifs. J'ai douté, de cet empilement de couches qui devait me permettre de laisser des personnes non éduquées au C++ de bricoler aussi leur propres personnages. Sauf que tout ça, c'est bien joli mais que quand vous avez un dysfonctionnement quelque-part, le débugger vous balance des instructions machines alors que le problème est dans le bytecode qu'elles interprètent. Et mon "inspector widget" (pas encore fonctionnel dans le projet 3 rooms) est loin de valoir ddd.

It's been a long time, I have to admit. I've been slow to get things running; I've had lost the hope that I could get that scorpio-shell turning back when it hits a wall... and only when it hits a wall. It felt like I had built a Jenga stack of complexity in order to have a 'simple' interpreter for state machines. But a language is never less complex than the tools you provide to debug it. And Inspector Widget fell short when trying to explain the issue (partly because it is surprisingly not yet working on Dreams.nds)

Une intuition pendant mes vacances ... j'ai retracé la machine d'état de mon scorpion-cyclope. J'ai bien identifié deux ou trois incohérences, mais rien qui ne conduise au bon comportement une fois corrigé.

Oui, je sais aussi, par rapport à ce que je bricolais sur le côté pendant mes semaines de vacances, c'est maigre. C'était des vacances un peu ... particulières.

Puis hier, j'ai repris la machine d'état de pendat. Lui aussi, il réagit quand il fait demi-tour en se prenant un mur. Et il n'est peut-être pas parfait, mais il marche en général bien mieux que cette satanée carapace.

Alors que scorpeye tentait de reconnaître l'absence de sol à l'aide d'un testpoint, pendat se contentait de "dire" "ah bin si la vitesse horizontale est tombée à zéro, c'est qu'on s'est pris un mur. Sinon, c'est qu'on a plus de sol. C'est forcé."

I found only a small evening of ndsdev during my summer holiday this year, and I used it to map the state machine of Scorpeye. It helped me finding a few weird stuff, but it would not make things run properly enough, unfortunately. Then I realised past Inktober that I already had a 'working' monster that bounced off walls. That was the running pendat. And I started mapping its state machine too (granted, after all these years of dsgametools, I should have given myself a tool to make that automatically). To my surprise, it almost never used the same tricks to perform the same task.

For instance, I used a TestPoint below scorpeye to tell me whether there was ground underneath when it claims it failed to slide on the ground. But this is unreliable because it checks only one point to decide for ground while the WalkController checks the whole surface. Instead, the pendat would test whether it came to a halt horizontally. If it did, that means there has been a wall. Otherwise, it bets there's no ground left.

Same with fall/slide transition: the scorpeye tried to use a testpoint to know whether it FAILed because of a ground. Pendat code author (past self) knew the only thing that can make GobGravityController FAIL was a ground. Being stopped by a wall triggers an event. That means no testpoint validation is required.

Finally, I gave myself an extra variable (there are still plenty available for scorpeye) to remember the sliding speed so that we can bounce walls without having to rely on an ImpactController to save the last speed, because so far I don't think GobWalkerController is an ImpactController. It requires to double some states (like left-thrown vs. right-thrown), but that should not be a big deal.

Still, there's one thing that I'll need to fix with unit testing: from times to times, being stopped by a wall while 'walking' doesn't make the move FAIL, but it does clears the speed. Pendat doesn't suffer for that because it has an "increase horizontal speed" statement in its running states that prevents the speed to stay null. I had to add the same statement to the shell, but it shouldn't be required. that's a todo item for XMAS, I guess.

Il me fallait un double-état pour la carapace lancée, une variable supplémentaire pour retenir la vitesse à la place de la 'variable d'impact'... ce genre de choses. Mais il y a un élément suspect. Pour qu'il n'y ait aucun soucis, je suis obligé de mettre une instruction forçant la carapace à accélérer. Sans ça, il reste des situations dans lesquelles je retrouve ma carapace toujours dans l'état "on glisse vers la droite" mais avec une vitesse nulle est un mur juste à ça droite.

Comme si GobWalkerController avait un bug qui l'empèchait parfois de signaler l'échec (FAIL) même si la vitesse tombe à zéro. ça, ce sera une tâche pour un test unitaire.


Super Mario Bros 5

Ai-je eu raison de snobber Mario Maker ? jusque là, je n'en doutais pas. Parce que jusque là, les niveaux présentés étaient essentiellement des niveaux quasi-impossibles ou des productions fafelues avec des canons à Bullet-Bill accrochés sur le dos d'un parakoopa qui lancent des spineys ... ce genre de choses. Mais l'ami Antistar nous a annoncé il y a quelques jours qu'il allait tenter de traverser un jeu qui a retenu mon attention: Super Mario Bros. 5.  

Il s'agit toujours bien d'un titre Mario Maker, mélangeant essentiellement les thèmes SMB3 et SMW (miam) dont l'auteur cherche à rester fidèle à l'esprit des jeux de Nintendo tout en proposant des idées et du contenu original.

Replay Twitch du 29/09/2022 avec un let's play de Super Mario Maker 2 dédié au super monde "Super Mario Bros. 5" conçu par MetroidMike64, qui contient 8 mondes de 5 niveaux chacun. En voici le code : 0G9-XN4-FNF Session de jeu effectuée et streamée depuis une Nintendo Switch.

N'ayant toujours pas Mario Maker2 (essentiel pour tester ce titre puisque le 1 ne permettait pas encore de lier ses niveaux sur une map), je me contente donc du stream d'Antistar. Et au milieu de pas mal de bonnes idées, je me rends compte que les niveaux "maison fantôme" offrent probablement un excellent point de comparaison pour le type de niveaux qu'il faudrait que je réalise pour la pyramide de Bilou's Dreamland ...

Voyons un peu ... on y retrouve régulièrement des portes en apparence difficiles d'accès qui nécessiteront de récupérer un objet pour les atteindre. D'autres objets qui *pourraient* les rendre accessibles (les fantômes n'auraient-ils pas envie de se changer en blocs ?) sauf que non, et des objets qui pourraient aussi (les plantes grimpantes, sauf qu'ils ne sont pas au bon endroit.

On y retrouve également des portes *carrément* inaccessibles. enfermées. Des portes pour plus tard qui détournent l'attention du joueur. En particulier parce qu'il ne sait pas dire à l'avance s'il s'agit d'entrées ou de sorties.

Et pour compléter le tableau, des sorties d'écrans qui sont ... hors de l'écran et que la caméra tente de garder invisible le plus longtemps possible.

 

Sunday, October 23, 2022

Ori and the winning strategy

Immobilisé, incapable d'enregistrer des chapitres de HPMOR à cause de ma toux et ma fée en formation plusieurs soirs par semaine, tout ça après que j'aie redémarré une partie d'Ori and the Blind Forest, il n'en fallait pas beaucoup plus pour que je me refasse le jeu presqu'en entier. Mais suite à un bug casse-pied, j'y rejoue sur un nouveau compte de ma Switch, plutôt que "à côté" de la partie terminée. Pas question, donc, de retourner jeter un œil sur la carte d'une partie plus avancée pour renifler où sont les power-ups cachés et améliorer plus vite ses compétences.

Vous vous doutez bien que, depuis le temps, je n'ai pas non plus retenu leurs emplacements. Mais par
contre, je n'ai pas oublié que le jeu propose les compétences "voir les cellules de vie sur la carte" et autres annotations du genre. Ma stratégie sera donc la suivante :
  • mettre tout sur la branche de compétences qui mène aux cartes complètes, dès le début du jeu, et ne regarder aux autres qu'en cas d'absolue nécessité.
Une autre chose que je n'ai pas oubliée : le terrier noirracine, avec son DASH (disponible dès le téléporteur avant la baignade interdite) et surtout sa petite lumière-à-lancer (disponible presqu'immédiatement après), vu que je sais qu'elle va permettre de déverrouiller l'accès à pas mal de points de compétence "gratuits".
Eh bien cette stratégie s'avère plutôt gagnante, puisqu'à l'arrivée à l'entrée du 2eme "donjon" du jeu, j'arrive à débloquer malgré tout le triple-saut, tout en pouvant échanger 1 point de Mana contre 2 points de vie lors d'une sauvegarde. J'ai aussi tellement de points de vie que les obstacles qui pourraient me one-shotter sont devenus rares, et tellement de points de Mana que je n'ai presque plus besoin de me retenir de faire des Sauvegardes. Bref, on est loin du feeling de "die and retry" injuste ressenti lors de ma toute première partie.

Friday, October 07, 2022

Finally doing some pthread stuff

For years and years, I've staid away from multi-threaded programming. Not that I dislike threads per se: I once made a multi-threaded micro-kernel myself after I spent countless hours studying IA32 Task State Segments. But who needs threads when you have two ARM cores, hardware interrupts for driving your sound DSPs and proper multi-layers video chip anyway ?

Even for network / system programming, I tend to prefer use pipes or socketpairs over threaded stuff. They strace better. You can actually see the flow of acknowledgements between entities. For most things, this is preferable over raw performance.

But a couple of years ago, I've been thrown in a pool where threads are already there and I need to swim with them. Parts of the pool use boost abstractions and are usually not too hard to work with because my colleagues did a great job at building robust RIAA things around those abstractions. But other parts of the pool use plain pthread + plain Windows thread/event/locks API. And as you can guess, upgrading corporate project to use C++11 threads is usually not easy (not that I know these any better, though).

One function that is used a lot in that code is pthread_cond_timedwait(). And there are a few things you must not do with that:

  • do not call it if you're not holding the mutex argument
  • a corresponding pthread_cond_signal is lost (not buffered) if no one is waiting on the condition at the moment of cond_signal

(more to come)


Monday, August 29, 2022

SuperMario 3D World

Oui, côté topic réchauffé, j'avoue qu'on fait difficilement mieux sans tomber dans le retrogaming. Mais voilà. Après l'avoir essayé sur la WiiU de mon frère il y a déjà quelques années, j'ai fini par craquer pour la version Switch, dans une tentative pour introduire un nouveau jeu intergénérationnel dans la maison.

Donc, oui, il y a eu la partie-de-papa (sur laquelle les enfants sont invités), la partie-de-J.l.n, la partie-de-*deline et enfin la partie-de-papa-sans-les-enfants. Parce que si le jeu à 3 est sympa, il est aussi assez décousu et ne permet pas franchement de se faire une idée de ce que le level design a dans le ventre.

Granted, there is little chance I can say anything fresh about a Mario game that has been released about 8 years ago. It's not like I had not played it until this summer, but a 4-player game in my bro's living room or a 1-player game in a quiet place doesn't feel the same to analyse the game's design. And even that way, I must confess that so far, I'm mostly writing down observations that my 9-year-old mentioned to me after he saw me playing.

And one of them connects quite well to a weird feeling I had about how the levels were 'disconnected' from one another. I mean, here are two pictures of 4 different levels. Each picture picks levels from one of the worlds: desert world or ice world. Can you relate one picture to one word ? To be honest, if you had asked me like 2 months after I'd been playing those levels, I don't think I could have answered.

Pourtant, c'est J.l.n qui m'a fait observé que, même si on a droit à un monde du désert et un monde des glaces (d'après la carte), une fois dans les niveaux, ce n'est vraiment pas évident qu'il y ait le moindre élément thématique. C'est vrai au niveau du choix des ennemis, de l'habillage des objets, du décor de fond ... tout. Le premier niveau de chaque monde est jusqu'ici (monde 3) le seul à vraiment jouer la carte du thème.

Tenez, chacune des images de ce post correspondent à quatre niveaux venant d'un même monde. Lequel est celui de la glace ? Lequel est celui du désert ? Il faut déjà avoir bien mémorisé le jeu pour pouvoir répondre.

Now let's be honest: there have been desert and ice worlds in Mario games since SMB3. They are present in NSMB, NSMB2 (checkme), NSMBWii and NSMBU. It is perfectly fine that we (at least?) see something new and different. It is perfectly fine that levels are located in the game according to their relative difficulty rather than according to some arbitrary theme. But still, the game designers insisted that we're taken back to a map showing snow or sands after we crossed that moving-grids-aerial-level. It isn't bad enough to break the player's illusion that it shares the adventure with Mario, but if you ask me on the next day "oh, so you're just in front of the Ice Castle. Was there anything interesting in the Ice World, then ? I can only remember of the 1st level in that zone" ... well ... I'll be pretty much in the same situation, because none of my memory of playing world 3 really relates to "snow" or "ice" or whatever.

Alors est-ce que le jeu est moins fun pour autant ? Pas forcément. Les niveaux restent bien trouvés et intéressants, mais il se peut que ça contribue au sentiment de "design décousu" que j'ai en reprenant le jeu.


Thursday, August 11, 2022

Funghi v2.0

 Bon, il est temps que je blogge les cogitations de nouvelle année, vous ne croyez pas ? Je m'étais installé pépère dans le canapé pour récupérer un peu, agenda-cahier sur les genoux histoire de faire un peu le tri de ce qui doit encore être dit et ce qui doit être transférer dans la nouvelle année, mais c'était compté sans J.L.N.

Le p'tit bonhomme venait de se rendre compte qu'une SpongeBop, si on la repeind en vert, ça fait comme une branche d'arbre et que donc on pourrait en mettre dans la forêt! Il n'a pas tort, mais j'ai voulu vérifier ce qu'il connaissait déjà des autres habitants de la forêt de Bilou. Après tout, à part quelques parties de Apple Assault, il n'a pas encore eu beaucoup de contact avec la green zone.

Il y a Funky Funghi, notamment. Le champignon sauteur. Si je permets de ramasser les applemen à la manière des dumblador dans School Rush, que se passe-t-il quand on lance une pomme sur un Funghi ?

Sketches in this post were actually drawn on January 1st, while I was brainstorming Green Zone with my nearly-9-y.o. son. He's been mostly playing the School Zone so far, and only bits of Apple Assault. So little that he suggested I put a green spongebop as a spidey-branch platform of some sort.

At my first drawing of Funky Funghi, he'd almost immediately suggest that we can jump on his hat and use it as a platform to climb higher. Not a bad idea, but completely incompatible with the Commander Keen-inspired, decades-old setting where the whole funghi is highly toxic and that any contact should be avoided. But that was at a time where a Manic-Miner clone was considered.

L'idée de base, celle de la version BASIC, c'était que le champignon était ultra-toxique. Tiré assez directement de Commander Keen, je dois bien dire. Le moindre contact est dangereux pour Bilou. On ne peut même pas lui sauter dessus.

Mais bon, avec le recul, pour un premier niveau, c'est peut-être un peu exagéré. Je n'irais pas pour autant jusqu'à proposer que l'on puisse monter sur la tête de Funky Funghi et s'en servir comme plate-forme. Ce n'est pas franchement dans le caractère du personnage d'accepter ça.

Pas question non plus de permettre à Bilou de simplement 'pousser' Funky Funghi comme il le ferait avec un encrier (même si je n'ai toujours rien implémenté de la sorte ^^")

Faire se déplacer un ennemi sauteur invulnérable en visant correctement, voilà qui promet d'être fun. En tout cas, c'était fun dans Rayman.

I still would like to avoid a platform-like behaviour -- I even already have another mushroom design for that. And I now have throwable monsters in the rest of the game, meaning it would be good that we could pick up and throw applemen in Green Zone (that was the plan from long ago, before I came up with Apple Assault mechanics). That means something fun is bound to happen if you throw an apple at a funghi. Right ?

I bet being able to knock the otherwise-camping mushroom to an alternate location should be both fun and interesting (I take it from Rayman). But beware, said my bro: we don't want to end up locking the progression by poorly "chosing" where we put the funghi. And with an all-toxic one, chances that we lock ourselves are much higher. Especially with limited supplies of applemen in the level.

Mais contrairement à Rayman, on joue ici avec des "munitions" limitées. Il ne faudrait donc pas que l'on bloque un Funghi dans un coin du niveau où il peut nous empêcher définitivement d'avancer! Une solution pratique contre ça, évidemment, c'est de placer un 'trou à champignon' au bout de la zone-bac-à-sable dans laquelle il est prévu de le déplacer. Quoi qu'on fasse, il ne peut aller plus loin et on a remplacer "passer par-dessous l'obstacle" par "passer par-dessus l'obstacle", qui est en théorie plus accessible.

Final thought: if Edward is true claiming that goomba were picked mushroom-bumper-shaped because that should suggest the players they'll be safe jumping on them, making my bouncy-funghi hurt you when you stomp him won't be a neat way to teach the players they're in a traditional platformer when they're playing level 1 of Bilou's Dreamland. (not to mention that mushroom=bumper has been over-used in all platformers after that, to the point that it's almost more natural to try using them that way than trying to eat them and expect to grow or shrink, nowadays).

So let it be bouncy. But only his hat (foot is still toxic and you shouldn't try to push Funghi like you'd do with inkjet). And bumping you to the side as well. If you want to have a Funghi ride, you'll have to master it first. Else all you'll get will be a funghi-rodeo. 

Mais tout ça devient secondaire si - une fois déplacé - Funky Funghi devient utile. Bon, comprenons-nous: ça reste un PNJ peu fiable et dangereux sous les bords. Disons par exemple que son pied reste toxique (on ne le pousse pas à la main) et redoutable (on ne reste pas trainer en-dessous). Mais son chapeau, lui, avec sa jolie tête de bumper pourrait ne réserver aucune vacherie et agir effectivement comme un bumper. Mais un qui soit susceptible de nous propulser vers l'arrière ou vers l'avant si on ne le prend pas bien comme il faut. Bref, un bumper qui amène une touche d'imprévu pour le joueur inexpérimenté, une touche de challenge pour le paddawan, et une variable supplémentaire à intégrer pour le Maître.

A méditer.


Saturday, August 06, 2022

scanf %ms ou scanf %n?

 it should have been quickly done. Almost trivial. Edit "DHud.cpp", revive calls to the MuadDebug class, change the GOB number so that it tracks the scorpeye rather than Bilou, and make it rewind time

  • when the shell's horizontal speed turns to zero
  • after it has been thrown (there's a flag telling us that)
  • after it has been picked up (need a new flag for that).

Except that however I tried to do it, and regardless of the amount of instruction-by-instruction stepping I made, I couldn't get the second condition to trigger. The optimizer did a great job at packing the expression evaluation code -- I mean there, that you can't tell anymore where you're in the source while doing it, and thus mostly can't set a breakpoint on a specific instruction.

Hopefully, there's the B opcode (not D, which is for Detach) to break at the script expression level. That one at least allowed me to realise that the expression for that second condition was indeed evaluated. But for some reason, the part I was interested in, with flag-setting, never got executed. A 'all done, bye' opcode always showed first. Mysterious...

Faire des essais dans le jeu pour essayer de reproduire un 'trick' pas fréquent, et avoir programmé un critère d'arrêt qui nous permet de passer en débugging pas-à-pas mais en revenant une image en arrière dans le temps, donc en revivant exactement l'évènement qui fait que tout est parti de travers en bullet-time pour pouvoir le comprendre et savoir ce qui doit être corrigé. J'appelle ça le muad-debugging, et c'est vachement pratique.

Enfin, surtout quand ça marche.

It turned out the reason was the expression got truncated even before it was turned into bytecode. Such a thing is not viable to extend the game to "Bilou Dreamland" level.

The code to parse an expression basically looks like

siscanf(base+cont,"[%64[^]]] (%64[^)])",predicate, axion)

And both 'predicate' and 'axion' arrays are static-sized. I know there's another way you could do the 'same' thing, but with any-sized arrays. That'd be something like

siscanf(base+cont,"[%m[^]]] (%m[^)])",predicate, axion)

in which case the siscanf function will allocate some memory by itself and you'll have to invoke free(predicate) when you're done with it. It is sure the way to go in most of your production code, but to be honest, I do not want this within GEDS script parsing code. Parsing a level already takes too much time. Adding dynamic memory for strings processing will only make things worse. Not to mention that it will fragment memory with temporary strings requested while we're making big blocks for the 'tank'.

But there's another trick I could (and likely will) use:

%n Nothing is expected; instead, the number of characters consumed thus far from the input is stored through the next pointer, which must be a pointer to int. This is not a conversion and does not increase the count returned by the function

Combined with the fact that %*s scans a 'string', but does not store it, I should be able to write

siscanf(base+cont, "[%n%*[^]]%n] (%n%*[^)]%n)", &predistart, &prediend, &axstart, &axend);

Now, I'd have start and end pointers for both expressions (if they're actually there), plus that would be copy-less and I would directly perform ascii-to-bytecode conversion. The conversion code would have to be adjusted, of course, so that it takes two pointers instead of one and that it does not expect a terminating \0 character at the end of the expression. So that will be a new "todo" item for when ongoing things are cleared and time is right to start something more experimental.

Oh, yes. And I could just grow the static arrays, of course. That's what I did in the past when they were 32-character long each, and I thought "well, 64-bytes predicates ought to be enough for everybody, right ? ". In another context, I could pick ridiculously large arrays (like 2048 bytes each) and forget about the issues for decades until it strikes back with some auto-generated script. But that would be a bad idea on the Nintendo DS with its fairly small stack. And nah, I won't make the arrays global either. That would sure break so many things in the ability to run that code out of its current context that it has even been considered as an evil thing to do by the former generation of developers.

Wednesday, July 27, 2022

Oh!? A post! A shell !? Progress ?

I know it's been a long time. Would you like an explanation ? It's a nice one, with Persian princes and oversea travels and unicorns. Maybe even a dragon!

Anyway, I finally got some code refactory completed so that more 'controllers' can record impact speed into script-friendly variables. That at last allow me to code whether a scorpeye shell should bounce or not when it can no longer keep moving the way it was.

Salut! Vous êtes toujours là ? Bien! Merci ^_^ Allons-y, alors. J'ai enfin repris mon projet NDS, finalisé cette classe GobImpactController dont dérive maintenant GobGravityController, mais aussi GobFreemoveController, ce qui devrait (enfin) permettre à cette satanée carapace de scorpion de faire demi-tour quand elle se prend un mur.

Enfin, ça aurait suffi sur un sol lisse et infini. Mais j'avais justement un trou dans mon miniveau de test, j'ai donc pu chipoter un peu plus avec les testpoints, pester sur le fait que le contrôleur de chutes signale un event quand on se prend un mur (plutôt que d'annoncer l'échec du mouvement, vu qu'on peut toujours continuer à tomber ... dans un sens, c'est logique).

Je vous aurais bien mis une vidéo de tout ça, mais à 1Mo la vidéo de 10 secondes ... les plus irréductibles sont invités à la regarder sur twitter.

Oh, granted, there's been pitfalls. The fact that moving along the ground fails when you hit a wall while falling down and hitting a wall just creates an event, wasn't exactly welcome-back-to-coding-friendly.

But well, there it is. There it bounces. Unless you throw it straight into a floor+wall corner or on some odd location on the sand. I'll need more runME+InspectorWidget to find out what is going on there. Or maybe some more muad'dibugging ?

Monday, June 27, 2022

gdb, intel flavour

J'ai beau avoir de nombreuses heures de gdb derrière moi, la syntaxe AT&T opcode source, destination, ça reste quelque-chose de complètement non-naturel. Quand on s'est habitué à écrire du code assembleur avec opcode destination, source, on y reste. Pareil pour les 42(%eax,%ebx,4) vs. [eax + ebx*4 + 42].

Et voilà qu'à travers le wiki du projet "gdb-dashboard", je découvre qu'il est possible de passer gdb en mode 'intel' d'une simple commande.

set disassembly-flavor intel

là. c'est tout.

Et si on veut la même chose en sortie d'objdump, ce sera

objdump -M intel -mes-autres-options

[ sauvegarder et continuer ]

Attention: gdb-dashboard et ddd sont mutuellement exclusifs.

Et si jamais le débuggeur insiste sur le fait que "No function contains program counter for selected frame", on peut toujours forcer disas address, +size ou utiliser set disassemble-next-line on

Sunday, June 05, 2022

Nova the Squirrel

She's created some games on the NES and now she's creating a sequel for her best title on the SNES. How could one be more awesome than this? Well, she could be doing it in open-source 65* assembly, for instance ? Check: she does that too. She's Nova, likes world building and character design and her mascot character is a green squirrel going also under the name "Nova". I've been following her twitter account for a handful of years now, and it's really about time I give her platformer a try, be it only to tell you about it.

I can't deny a mario-worldish aesthetics to the world in which Nova the Squirrel takes place, but it would be reductive to claim it to be a Mario clone. 

Elle est plus jeune que la NES, plus jeune que la SuperNES, et à son âge, je me disais que finalement, en programmant sur GBA/NDS je pourrais probablement faire mon jeu sans avoir besoin de reconstruire un OS en premier. Elle, c'est Nova. Elle a décidé de faire son jeu en assembleur 6502 sur NES puis de lui donner une suite sur la reine des 16-bits. Tout sa dans son propre univers, avec ses propres graphismes. Et en open-source, s'il vous plaît. De quoi faire péter le compteur de génialitude.

Ne vous laissez pas endormir par l'aspect Mario-like de ses graphismes: considérer "Nova the Squirrel" comme un clone de SMW serait réducteur. Les comportements des adversaires sont plus variés, et le personnage peut 'emprunter' les techniques des monstres qu'elle rencontre. On rencontre des bumpers, des briques destructibles, des items à ramasser ... tout le panel d'interactions avec l'environnement qu'on pourrait attendre d'un jeu peaufiné et ambitieux des années 16-bit répond présent.

From what I've been able to test from her demo, there's an interesting variety of monster motions, power-up that come as a sort of 'copy ability' flavour (triggered by UP+SHOOT, which I always seem to forget ^^"), bumpers, breakable bricks, collectibles and such. And slopes.

Your default attack is just stunning monsters, copied abilities may defeat them. Although not all power might defeat all monsters (conway's Glider deletes the red stompers, but bombs just stun them, for instance).

Since it's a demo, i can't really tell the story yet, but it could go like some fastfood-king has invaded squirrel-land and over consuming fastfood twisted the mind of inhabitants making them dangerous to anyone. If you see a flying burger in this game, remember: it is not trying to heal you.

The game smartly comes up with a sort of level selection screen that acts as a mini-map. Some of the levels come up with so many mechanics that I fail to find words to describe them, producing avalanche of block-changes, with crates-that-turn-into-bumpers-that-then-disappear, or blocks that disappear into arrows that destroy more nearby blocks.

Seriously, there's significant amount of work in the game engine here.

Si son jeu NES est aujourd'hui achevé, l'épisode Super-Nintendo est toujours à l'état de démo. Il faudra imaginer soi-même le pitch du jeu et on pourra sans vergogne passer en revue toutes les armes prévues dans le jeu. Il faudra se débrouiller un peu aussi pour découvrir les commandes disponibles et les mouvements du personnage, y compris le "copy ability" assez cruxial pour avancer. Mais à part ça, la démo propose déjà des environnements variés et des niveaux bonus en mode 7. Possible que l'aspect sonore soit toujours en grand chantier... je n'ai plus la mémoire très précise à ce sujet (traduction écrite plusieurs mois après la version Anglaise)

And just when I thought I had discovered enough to write a post about it, Nova surprises me with a mode-7 bonus round (?) possibly inspired by chip challenge.

And I was also about to miss that START takes you to an inventory where the demo-mode pre-loaded all sort of powers for you to toy with. From the fire and bottles-throwing you can already find in-game to exotic devices like a sword or a fishing rod.

Seriously, the amount of work and love in here is amazing. (yeah I know, you expected 'insane' instead, but that wouldn't be respectful at all. This is dedication).

Seriously, girl/miss/ma'am/squirrel, you rock. I hope you'll keep rocking for long and I'd better start coding again so I can be up to the challenge and get at least half as amazing as I see you are.




Tuesday, May 24, 2022

Flop ...

Aaw. un câble de portable trop tendu, et j'ai toutes les prises de mon bureau-à-NUC qui se retrouvent sans courant. j'avais justement bien besoin d'un contretemps comme ça pour me remettre à bilouter, tiens.


(et comme de bien entendu, impossible d'avoir un professionnel qui réponde à mes appels au secours :-/ )

Wednesday, May 11, 2022

freemove ou pas

Bon, le week-end était bien chargé et la semaine qui commence risque d'être du même accabit, mais j'avais quand même trouvé le temps de modifier la configuration de runMe pour corriger l'affichage des sprites 32x16 et du même coup pouvoir utiliser InspectorWidget convenablement. Il est temps que je trouve pourquoi les carapaces de Scorpeye ne font pas demi-tour quand elles rencontrent un mur.

Et on dirait bien qu'une des raisons, c'est que j'ai utilisé pour cet état-là le contrôleur "freemove". (oui. encore;) Et freemove n'a pas le code C++ qu'il faut pour 'rapporter' la vitesse à laquelle on se déplaçait au moment où une collision avec le terrain a empéché un déplacement d'avoir lieu. Or c'est cette valeur qu'il faut utiliser pour faire le demi-tour.

Despite a week-end with a good deal of events, I managed to fix runME so that it could too display 32x16 pixels sprites properly. That unlocked the use of InspectorWidget to find out why scorpeye shells won't bounce when they hit a wall.

Apparently, the core reason for that is that the GobFreemoveController I use for sliding shells is unable to tell at what speed it was moving when there had been an impact with the wall. As a consequence, the script handling state transitions cannot properly program the new speed. And yes, that is very similar to an issue I've had with 'swimming' state for Bilou not so long ago. That sounds like I should refactor something so more state controllers can report impact speed...

Bref, soit un contrôleur comme 'walker' ferait l'affaire, soit il faut que je prévoie quelque-chose d'autre. peut-être que 'sauver la vitesse actuelle si le déplacement en cours n'est plus possible' devrait en soi être un contrôleur autonome dans la chaîne ?

Ou je met une vitesse 'hard-codée' pour l'instant ?
 

Monday, April 25, 2022

Silence, on tourne ...

 J'ai repris un tour de Harry Potter et les méthodes de la rationalité. Dès le 1er chapitre, j'avais envie de le faire connaître, mais les gens qui ont le temps de tourner les pages ne sont pas légion autour de moi. Par contre un audio book, ça a l'air plus commun. En particulier pour mon frangin.

Du coup, c'est logique que je lui chipe son enregistreur Zoom. Evidemment, il y a déjà des enregistrement de l'excellentissime version originale. Ici, je m'attaque à la traduction française, en réécrivant des p'tits bouts à gauche ou à droite pour avoir un rhytme qui me plaît mieux.

J'ai encore du chemin avant les Sparkling Unicorn Princess, mais on devrait voir débarquer Drago d'ici un week-end ou deux.

Lucky you, English speakers. Harry Potter and the Methods of Rationality reads so well. But for most of my family, reading a novel in English is far beyond their level. And well, there is a translation in French, but every here and there, you stumble upon some sentence that sounds awkward, or not like something someone would have said. The meaning is almost always preserved, but the rhythm is lost. Can I do better ?

(tout ça ne booste pas la vitesse de développement de Bilou's Dreamland, mais que voulez-vous: il faut maintenir son équilibre psychosophique aussi, non ? ;)

PS: pour le chapitre suivant, il faut obligatoirement que je prépare un faux-guru-meditation-screen sur le thème "Fundamental Attribution Error"

PPS: on dirait bien que hpmor est en 'creative common' ... ça va plaire à mon frangin, ça.

PPPS: la conversion en .mpeg marche moins bien pour ces derniers épisodes. 

ffmpeg -loop 1 -r 2 -i Downloads/hp-stairs.jpeg -i Documents/hpmor12.mp3 -c:v libx264 -preset medium -tune stillimage -crf 18 -c:a copy -shortest -movflags faststart -pix_fmt yuv420p hpmor12.mkv

Behaviour edition on DS. ?


I'd like to be able to edit state machines (for Bilou and monsters) on the Nintendo DS itself. That'd be the pinnacle of on-the-road game making. There's a significant drawback to address before I can do that, though: usable state machine scripts currently heavily rely on GCC pre-processor to turn into engine-compatible text. Most of it is just providing nicknames for things that the engine solely knows as numerical identifiers.

So I'd need at least a sort of token-parser that can handle some of the substitutions on the DS itself. Both for potential Behavour Editor on DS and for runMe. Only the compiled .nds that embed the game would still use PC-pre-processed scripts (and see only numbers).

I've been toying with that idea summers ago, digitized and kept-as-draft the best part of it for seasons. It's not yet time I start implementing it (I don't think so, at least. It's irrelevant to the 'dreamland' effort), but it may be time I stop being silent about it...

Tuesday, April 19, 2022

des sprites 32x16 ?

Le support des sprites rectangulaires, c'est pas encore une grande réussite dans GEDS. En chipotant un peu, on parvient à avoir une planche de sprites verticaux ou horizontaux dans SEDS. Ils sont quand-même édités sur une grille carrée, mais soit.

Les choses sont déjà un peu plus louches dans AnimEDS, où de curieux résidus viennent se placer par-dessous un sprite 32x16. ça gâche un peu l'effet, mais disons qu'on s'en serait accommodé le temps de d'un ennemi ou deux.

There is somehow way to introduce non-square sprites in my SpriteEditor (with those 'new W(ide)' and 'new H(igh)' buttons), and the NDS hardware definitely has support for them, but let's face it: none of the game engine or Animation Editor was half ready for a 32x16 scorpeye 'shell'

Mais le moteur de jeu a l'air de perdre complètement les pédales, lui.


Une petite réactivation de l'afficheur-de-sprites finit par me pointer le problème: je suis déjà au bout des 1024 sprites possibles dans ce nouvel environnement... enfin, pas exactement. Je n'ai pas encore saturé les 128K de mémoire disponibles pour les sprites, mais seulement les identifiants disponibles.

J'ai déjà joué avec ça pour l'éditeur de sprites, mais le moteur de jeu, visiblement, n'était pas prêt non-plus pour ça ... ça va faire un gros commit ...

You see: it really doesn't make sense. We get parts of Bilou heads instead of getting our expected shell, and the shape isn't even rectangular. Part of it is because the engine cannot change the shape of a 'limb' for a compound character while playing (changing states doesn't let you break that rule). If you're rectangular on your frame one, you're rectangular all your life long. Another part of it is because I'm hitting the tile number limit. I thought SchoolRush was already using 128K of VRAM for sprites, but it seems I was wrong and everything used to fit the default 64K. Only the background tiles had been increased. Anyway, the Makefiles didn't like it, but it is now expanded to 128K. Anything else ? Yep. size = 16 + mode = wide gives you 32x8 sprites. Not 32x16. That explains the lone stripe I had in the final attempts.

Un autre soucis visible sur l'animation: les tailles de gobs pour une page donnée ne peuvent pas être changées en passant d'une animation à l'autre. Et j'avais gardé la première version 32x32 pour l'animation "immobile". Du coup, les autres animations tentaient aussi d'utiliser du 32x32 même quand les images à charger étaient en 32x16.

Ah, et j'ai probablement sous-estimé l'existence des sprites 32x8, ce qui fait qu'encore après tous ces patches, il me manque la moitié de ma carapace ...

Tuesday, April 12, 2022

La castle zone

La 'castle zone' n'a pas été retenue pour "Bilou's Dream land, mais ça reste toujours bien un des environnements prévus pour la "grande aventure". D'ailleurs, quand je tombe sur ce genre de petits croquis dans mes carnets, je numérise... Bon, celui-ci est resté "à blogger" bien longtemps, je le reconnais. Au point que lors de ma tentative annuelle de produire des fichiers epub à partir de mon blog, je me suis rendu compte qu'il avait disparu ...

Castle... Not the fictional author, but the zone in Bilou's Adventure. It might not have been selected for the Dreamland project, mostly because I already had 2 'indoor / artificial' areas with school + pyramid and that I wanted an 'outdoor / natural' area to balance the 4-areas game, that doesn't mean I forgot it.

From times to times, I might encounter such small sketches of potential characters to encounter in the castle zone... although I admit scanning and 'publishing' was a long road. So long that when it showed up in my yearly check that my blog-to-epub chain was still working, the picture was gone. It was scanned with my fairy's tablet before I got my own android boox. But last year, I migrated most of my bilou-ish shots out of her google photos quota and links went broken ^^". Well, at least, I had backups. and filenames to help me locating the 'lost' file in my own google drive.

C'était au temps où je n'avais pas encore ma liseuse-androïd et où Blogger-pour-androïd marchait encore sur la tablette de ma fée. Je l'avais donc ajoutée elle comme rédactrice virtuelle du blog histoire de pouvoir poster des brouillons avec les images scannées que j'aurais ensuite complétés sur PC.
Mais du coup, au moment de migrer mes bilouteries hors de son compte 'google photos', les liens sont devenus invalides... voilà voilà.

edit: got to open-in-new-tab, save and upload the picture again so it could show up in the post. Apparently, copying the URL of an in-drive picture is a bad idea altogether.

Tuesday, April 05, 2022

Codons du scorpion

J'ai fini par avoir un petit temps creux avec le cube allumé. J'en ai profité pour faire deux animations-bidon du scorpion dans AnimEDS et les transférer par wifi hors de la Nintendo DS. Du coup, en reprenant le comportement de base de dumblador (seul autre ennemi que l'on puisse ramasser pour le moment), je peux *enfin* voir ce que donne le fait de ramasser une carapace de scorpeye pour se promener avec.

Eh oui, vous aviez reconnu les pieds de bladors qui s'échappent, hein. On ne vous la fait pas. A terme, ils seront remplacés par les pinces du scorpion, évidemment. Avec à la clé une question de game design: est-ce qu'elles devront pincer Bilou ou non?

I've been creating dummy animations for the Scorpeye with existing pixels and beamed them out of my DS so I could start toying with the ennemy in the playground level. The dumblador state machine provided a neat template to start with, and despite there are still many rough edges, I could get a proof-of-concept within a couple of hours.

Mais bon, un dumblador, ça s'arrête net quand ça arrive sur le sol. Moi, je veux un comportement de carapace de koopa. quelques petites modifications dans le script permettront ça en moins d'une heure: deux nouveaux états $LSLIDE et $RSLIDE au lieu de $STUNSTAND

Les transitions du style 

$STUNFALL->$STUNSTAND on fail [t] ($8000 F $vPlatform(1));

sont maintenant remplacées par une paire de transitions

$THROWN->$LSLIDE on fail [v2 1 & v0 0 <= &] ($8000 F $vPlatform(1));
$THROWN->$RSLIDE on fail [v2 1 & v0 0 > &] ($8000 F $vPlatform(1));

Un petit rappel de la syntaxe ? l'expression entre crochets [] est la condition à vérifier pour que la transition puisse avoir lieu et l'expression entre parenthèses, l'effet de bord à appliquer en plus de la transition. (ici, j'ai du nettoyage à faire, puisqu'une carapace ne devient pas une plate-forme quand elle touche le sol. $vPlatform() ne sert donc à rien)

Les expressions utilise la notation polonaise inverse, donc soit vous ajoutez des valeurs sur une pile (v2 qui empile le résultat des test-points, v0 qui empile la vitesse horizontale, les nombres qui s'empilent eux-même), soit vous retirez des valeurs pour faire une opération (comparer deux valeurs et les remplacer par vrai/faux avec <= ou >, faire un ET logique avec &).

I'd like to tell you that I've got more animations done on the DS and that they are going to be integrated soon. The reality is somewhat different. I've lost several improvements attempts while animating yesterday and I'm not 100% sure of what got saved and what didn't. Apparently, there are still many combination of altering the 'animation structure' and returning to edition that need to be unit-tested and fixed. But that's not done yet. I'd like to be able to give you a 'meet you on saturday afternoon for a updated demo', but IRL struck again, and fairies only know where I'll be by then.