Sunday, August 18, 2019

Starting a new world/level

Starting to work on a new level should be a trivial task in a game making tool. Unfortunately, this is far from being the case in Game Editors for DS, and especially in LEDS. I got this sorted out with text editing on the PC in almost every previous iteration, but now I'd like to have the tools level-up and be able to assist the game designer through this task
[done] the level editor seems unable to change the tileset of the level. At best, it is replaced by ".spr", which fails to load in the game engine, obviously.
[todo]. there is no way to indicate that the spriteset used for monsters should be changed
[todo]. there is no way to indicate that some state machine description files should be dropped, or that new ones should be used.

[todo] make it easier to produce a set of *EDS tool that call each other (e.g. "cube" for those produced by the NUC)

The goal for the last item would be to use the upper screen in "welcome" mode to list all the baddies, now with the file names and the number of states used for them.

At least, the blocking bug is now fixed, although I could have pushed the refactoring deeper 

Wednesday, August 14, 2019

__cxa_begin_catch

Voilà un symbole à surveiller de près. Quand mon code C++ me fera des misères et que le débugger semble me téléporter d'un bout à l'autre du code sans passer par les blocs catch(), il pourrait bien être salvateur d'aller mettre un breakpoint sur la fonction du run-time responsable de démarrer le traitement d'une exception interceptée.

Dans la même série, _dl_runtime_resolve est une vraie plaie en cours de debugging (et
LD_BIND_NOW, sa némésis, est donc notre alliée), mais j'aimerais bien en savoir plus sur son fonctionnement.

Monday, August 12, 2019

Les couleurs du désert


Un peu des couleurs que j'ai jusqu'ici, un peu de couleurs venant de Ilkke ou de Commander Keen ... quelques mélanges ... et je commence à avoir des combinaisons qui me semble intéressantes (sur la droite). Qu'est-ce que vous en dites ?

In the center, the mock-up I had previously for Bilou's desert zone. On the left, I tried using Lost Vikings, Commander Keen or one of my reference from Ilkke. On the right (and esp. in the corners), mixing of reference-based colors and current colors that imho provide interesting shades and hues. What do you think ? (I put the focus on ground tiles and background, btw. 'green' block and power-up were either untouched or got crushed in the blending process).

[x] comparer avec les couleurs d'Aladdin SNES/Genesis -- bof. Par contre le palais de Jafar a des éléments de décor intéressants.
[ ] comparer avec les couleurs de Sandopolis (Sonic) -- en fait non. Elles sont trop criardes à mon goût.
[x] essayer la palette de verts du chateau d'Hyrule qui avait inspiré les téléporteurs de Bilou's Quest ... sauf qu'ils n'étaient pas verts. (voir ci-dessous)

PS: je me suis concentré sur les couleurs des briques. J'aimerais que le bloc vert reste dans les tons verts, mais genre "masque de jade", que je n'ai pas encore réussi à reproduire. J'ai pris le temps de re-copier-coller Bilou avec les bonnes couleurs (presque?) sur chaque écran mais j'avoue que le bonus n'a pas eu droit à autant de considération

Je fais une deuxième passe. Les verts de Bilou's quest (top-right) retravaillées (bottom-right) me plaisent bien. J'ai essayé d'importer les couleurs d'Agrabah (mid-left et bottom-center) par contre, mais ça ne donne pas aussi bien.

edit: J.L.N a bien voulu laisser la NDS à son papa une demie-heure avant de rejouer un peu au niveau-où-l'encre-descend de School Rush. J'ai pu me faire une petite map, et j'ai aussi un second jet plus convaincant des "boules de poussières" inspirées des techniques de pixel-art de Fury of the Furries ...

Jeu vidéo, violence et Pirlouit

Bon, les jeux vidéos font partie intégrante de ce à quoi mes enfants sont exposés. Que ce soient des jeux auxquels je joue, des jeux plus "RPG" que je raconte comme s'il s'agissaient d'histoires au lieu de mettre un dessin animé ou les speed runs de l'ultime décathlon que je regarde en faisant la vaisselle, ils sont partouts. Et mes enfants savent bien qu'il y a des jeux vidéos qui ne sont pas pour eux (les fps -- "jeux de mitraillettes", que je ne sais pas complètement faire partir de youtube, et aussi certains 'run-and-gun' tels que Iconoclasts ou Metal Slug auxquels je jouerai/regarderai quand ils seront au lit).

Dans l'ensemble tout semblait bien se passer jusqu'au jour où l'institutrice maternelle de J.L.N m'annonce qu'elle l'a rattrapé de justesse alors qu'il s'apprétait à sauter sur la tête d'un camarade de classe qui était étendu par terre. Je tombe de haut. Le coup de "on ne frappe pas un adversaire à terre" me vient immédiatement à l'esprit ...

si si, c't'un boss ... 'faut lui sauter sur la tête
mais là, je repense au Super Mario Odyssey auquel nous avions joué tous les deux pendant le week-end. Et dans SMO, les combats contre les boss sont presque toujours identiques: on débarasse le boss de ses protections, on utilise des attaques-casquette pour l'assommer, puis lui écrabouille la tête pour passer à la phase suivante. La similitude est trop grande pour que je n'en tienne pas compte.

Alors bien sûr, les coups sur la tête, ce n'est pas nouveau dans un Mario. Mais jusque-là, qu'il s'agisse de Koopas, de Goombas ou autres, on devait juste "leur sauter dessus". Ils étaient bien debout et dans la VTJ, on ne sait évidemment pas sauter haut assez pour retomber sur la tête d'un adversaire. La violence fantaisiste restait bien cantonnée dans le monde imaginaire sans plus d'effets que si on avait lu "Jack et le Haricot Magique" dans sa version originale.

Difficile évidemment d'être sûr que c'est bien ce qui s'est passé dans sa tête. J'ai expliqué à mon fiston qu'on ferait une pause dans le jeu, le temps qu'il se mette bien en tête que c'est dangereux, que ça fait très mal et que ça peut même envoyer les copains à l'hopital, etc. Et pendant que j'essayais de faire comprendre tout ça, je me suis revu à son âge, au moment où j'étais complètement accroc au "Pays Maudit" de Peyo, où je m'identifiais tellement à Pirlouit que je pouvais être assez fatiguant à force de faire des farces ... et où mes parents ont un jour dû me tenir un discours un peu du même genre parce que je commençais à flanquer des coups de poings sur la tête, comme quand Pirlouit veut faire taire Monulf. Pour moi, ça ne devait pas être grave: dans la BD, les personnages auxquels on faisait ça étaient "juste assommés", même pas blessés. Je n'avais aucune notion de ce que "traumatisme crânien" pouvait signifier, évidemment.

Saturday, July 27, 2019

Refactoring "QuickGo" widget

I'm trying to make that "mini-map" widget better following good practice software engineering, so that I could maintain the rest of the tool more easily. I've done that refactoring one small touch at a time, in usually one-hour session while it was damn hot outside and while kids were sleeping in the living room.

It looks like I've introduced a few bugs with the refactoring, though. It's been a while since I didn't get something that messy !

edit: oh, btw, that got fixed through early August.

And yeah, I know, it's a bit odd to keep blogging such things. Likely something that is both a public version control and a social website would do the job, and 'github' would immediately come to mind. Unfortunately, A) I hardly trust Microsoft to keep running github nicely and B) github doesn't work with my boox device >_<

Thursday, July 18, 2019

documenting

My colleagues brought me from the habit of explaining lots of things through comments into the habit of writing almost no comments in my code. Explaining a lot came from my 386 assembly years, where I'd have to write code that does the desired processing on the one side, and carefully detailed what I was trying to achieve in the comments section.

The new fashion is to go from
sprtrsp(spr1, spr2); // make the sprite more transparent
into
makeSpriteTransparent(newSprite, oldSprite);

As I'm applying this over the QuickGo class to better see whether I can structure that code better, I still stumble upon code chunks that remain pretty obscure. Why the hell am I doing those computation on the map size ? and why the test with those * 4 multiplications ?

Hopefully, seeing the widget in action with up to 4 slices of the 'School Rush' level made me understand myself again.


When I want to fit a large stripe of level or a tileset into something that's closer to a square, I tend to cut it in two and put the halves above one another. If that isn't enough yet, I repeat the process. In each step, I exactly halve the largest dimension but double the other. It only makes sense to do so if I'm going closer to a square by doing so, that is if width/2 >= height * 2 when the image was currently wider than high. That exactly converts to width >= height * 4.

When that condition is false, I could still keep processing it further, but by doing so, I'd make the picture less readable. It doesn't make sense to consider it once we have reached the perfect square of course (the sprite rendering the mini-map is always square), but if we end up with a 3x2 rectangle and consider going into 2x3 instead, then sticking to 3x2 remains more readable.

Saturday, July 13, 2019

Monster selector

Okay, it's not much and it wouldn't even be posted alone despite I haven't been posting about tools development for weeks. I have now the 'selected monster' arrow showing you where on the map is the selected monster if you happen to get it off-screen.

But it is not alone. Changing that required more refactoring that I kept track of, and I'll have to break that giant "stash: okay, it works" commit into proper commits. It's not just that the code was old or buggy: my coding standards have quite evolved by working in a team where most of the code you have to deal with has been written long ago (and likely not by yourself).

It's not that much about the lack of comments. Having something like

// use sprite tile 0 for the cursor
sprites[CURSOR].attribute[2] = 0;

only works if this is the only place in your code where it can happen, and without coding habits that guide you towards

const oamno_t CURSOR_TILE=0;
sprite[CURSOR].attribute[2] = CURSOR_TILE;

you're very unlikely to get it done at a single place.

I had to fix things like that, as over time, I ended up with two widgets deciding to use sprite tile 0 for their own special purpose. I had to migrate the 'sprites granularity' into the recently-introduced "UsingSprites" class as I realised that more and more parts of the code now depended on that granularity (like whenever you're allocating sprite tiles) and top-screen and bottom-screen might not be using the same granularity...

Among the ugly things in LEDS code, I shall name a global "UI-like" object -- QuickGo -- that renders the level into a small bitmap, so that we can quickly navigate the level. That object is created in the 'MapEditWindow', but it is never inserted as a widget. It seems to be a global pointer, which is accessed through LayersWindow -- the part of the application where it actually shows up -- and even there, it doesn't directly reacts to user inputs. Instead, there is a 'QuickWidget' object that doesn't show anything on screen, but that does produce events on stylus touches that MapEditWindow will further catch and process.

Such a "code-that-works" approach that breaks almost every coding convention in the "GEDS" library is tricky to reason upon. You see QuickGo in a window, so you should be allowed to assume it is part of the UI, and used in that window. 

Tuesday, July 09, 2019

Salut!

Salut. Je m'appelle Bilou et je suis explorateur de l'espace. j'ai eu le malheur de m'approcher un peu trop d'une planète non-répertoriée dans le quadrant 79.03.24 et j'ai été mystérieusement happé sur la planète. Mon astronef est hors d'usage, la planète pour le moins curieuse et mon sort serait lié à 7 pierres mystiques auquelles les autochtones prêtent des pouvoir magiques.

Je n'irais pas jusqu'à dire que je peux compter sur mon coéquipier et ami Bouli pour nous tirer de là : cette planète a l'air de faire ressurgir en lui tout ce qu'il semblait avoir réglé comme problèmes d'adolescent... quand il ne se fait pas tout simplement kidnapper *soupir*

centres d'intérêts: astroconduite, planetologie, haute-technologie, biologie des blobs, physique des plate-formes scrollantes, téléportation par ondes Wi-Fi, spirographe hyper-spatial, tir de précision à l'astro-flasheur à perforation en vrille

(c'était la présentation du personnage fictif "Bilou" sur Facebook, mais l'Ordinateur a décidé de remplacer ça par une "description de page" qui est malheureusement limitée à 255 caractères >_<

Toolset and MonsterPropWindow

I've got less free-reading time during my vacation this time, and likely, I should be not blogging right now, but cleaning up all the mess that going to vulcan(eifel) and back brought to the house. When I did get some time, I spent it clarifying some obscure parts of my Level Editor which puzzled me when I initially tried to add some additional monster edition features, like being able to decide within LEDs whether a given game object belongs to the 'hero' cast, the 'evil' cast or none of them.


I refactored a few things to make that possible already and I hope I'll get some time to continue working on it within the upcoming days.

I also took some time documenting one of the more elaborate (but arcane) widget that I might have to use to do that: the 'ToolSet' meta-widget, which is truly a bunch of buttons hacked to behave like the typical radiobuttons of point-and-click GUIs.

Tuesday, June 25, 2019

couldn't list the directory.

For some reason, recent desmume (0.9.11) shipped with my Ubuntu distro cannot list files in directories passed as --cflash-path.
and this time, my 'old version' of desmume binaries are 32-bit while the system is running a 64-bit OS. I had multiarch-support package installed, but not libc6:i386, nor libstdc++6:i386, and as a result, and I just had a weird message about the 'file not being found', while it was obviously there. Once those core packages had been installed, I got more coder-friendly error messages mentioning which library was missing, so I could just find the corresponding package with apt-file and install e.g. libsdl1.2debian:i386, libglib2.0-0:i386 and the like.

And eventually, I could run a copy of desmume-cli so old that --version isn't even supported :P 0.9.6 svnr3873 dev+, it says. And that one granted me with proper file loading, so I'll be able to investigate whether my edits on the extended monsters editions are OK or not ... next time.

(and no, this time adding --load-type=1 did not help)
(bug confirmed with filesystem/libfat/libfatdir example from devkitpro)

Sunday, June 02, 2019

Iconoclasts


I could hardly point you to the old "wish-to-play-that-game" blog post about Konjak's "Iconoclast" game, because I've been post-poning writing that post since 2011, hence the "#veryOldDraft" tag. 

From the very first notice on the tigsource blog, I've been in love with the pixel art used. I loved the gameplay as well, which I managed to get running through Wine on my old laptop ... but It wasn't comfortable to go much further than the first true boss.

But yesterday, I just noticed it was available on the Nintendo Switch, so this is my second indie download, and it's a marvel to experience the game at full frame rate with responsive and friendly controls. Plus, the switch has a "snapshot" button, and a separate galery mode, meaning that I'll be able to do pixel studies when I'm not playing it.


Bon, il y a 8 ans que j'aurais dû commencer cet article, parce qu'il y a 8 ans que Iconoclast de Konjak m'avait tapé dans l'oeil. Il y a même 8 ans presque que j'y ai joué pour la première fois, dans le salon de mes beaux-parents sur un portable Linux tournant laborieusement Wine. J'avais apprécié, mais l'expérience n'avais rien de comparable à avoir la chose au milieu de son D-PAD et calibré pour tourner à pleine puissance sur la Nintendo Switch. Je ne regrette pas l'attente et je ne regrette pas la dépense (vu que la version PC avait été gratuite :P)

La bande son est de toute bonne qualité aussi (sans pousser jusqu'au niveau d'un Shantae ou d'un Fez quand même), et je suis assez surpris de constater qu'elle est signée également Konjak! "Pixel" avait fait de même dans "Cave Story", mais ça reste suffisament rare pour le mentionner.

Bon, je vais quand-même faire une petite intro du jeu pour ceux qui le découvriraient ici: Robine est une jeu passionnée de mécanique. Elle n'hésite pas à donner un coup de clé à gauche ou à droite pour dépanner les gens de sa colonie. Elle se débrouille aussi assez bien avec un flingue, et ça va lui venir bien à point, parce que dans son monde, le carburant est considéré comme une manne divine et seuls les prêtres assermentés peuvent intervenir sur les équippements alimentés en carburant sans être pourchassés par les agents du Projet et "jugés" pour hérésie.

Je pourrais être tenté de dire qu'on est face à un métroïdvania, vu qu'on se déplace librement dans des niveaux un poil labyrinthique, qu'on débloque des mises à jour de ses armes pour continuer à progresser dans le jeu et qu'on dégomme tout ce qui bouge sauf si ça nous adresse la parole avant de nous charger. Mais ce serait une insulte de ne pas préciser la présence d'une forte composante RPG, étant donné la quantité de PNJ qui nous distillent leur connaissance du monde, de ses intrigues et des relations curieuses entre les différentes factions. De nouveau, c'est de Cave Story qu'on se rapproche le plus ici.

Encore que Konjak a veillé à choisir des mécaniques de combat qui permettent aussi des phases de puzzle entre les séquence de combat pur -- chose qui colle tout à fait au caractère du personnage, ce qui ne gâche rien.

Saturday, June 01, 2019

touchInit()

J'espère que ce sera la dernière surprise dans la branche "mise à jour de mon kit de développement DS"... Après avoir enfin réussi à avoir des programmes qui tournent à nouveau sur la DS (et dans l'émulateur, au passage), je finis par me rendre compte que plus aucun de mes widgets ne fonctionne. Au point que j'en viens à soupçonnner quelque-chose dans le code qui relaie les mesures depuis le composant SPI en charge de l'écran tactile à travers le processeur ARM7 pour être exploité sur le processeur ARM9. D'autant que tous mes programmes utilisent un code ARM7 "custom", chose qui ne sera forcément pas testée lors des mises à jour de libnds, devkitARM et leurs sbires.

Mais mon code ARM7 voit toujours bien son gestionnaire d'interruption appelé, recompiler un des programmes d'exemple avec mon code ARM7 au lieu de la version officielle marche toujours ... Ou en tout cas, c'est l'impression que ça donne au premier regard. En débugguant de plus près, je constate que mon code sur l'ARM9 reçoit bien des 'touchPosition' en bout de chaine, mais chose curieuse, deux paramètres (px et py) sont toujours nuls. Il s'agit des valeurs traduites en pixels, à l'aide des paramètres de calibrage. Et le programme d'exemple fait pareil: il ne nous donne que les valeurs "brutes".

En réalité, il faut maintenant appeler une fonction "touchInit" pour appliquer les données de calibrage, et la version du devkitpro que j'avais installée avait fait la mise à jour correspondante dans le "code ARM7 par défaut", mais pas encore dans les programmes d'exemple utilisant du code ARM7 custom ... On va finir par y arriver.

Monday, May 27, 2019

.arm7.elf

écran tout blanc sur une DS, cascade de message d'erreur "MMU7 write32 to undefined register 044xxxxh = 00000000h (PC:00000000)" produits par desmume, avec des valeurs xxxx commençant je ne sais pas trop où et qui continuent de 2BD4 à 3A34 au moins, et ça même si j'essaie d'attacher un débugueur sur le processeur ARM7.

Il y a clairement quelque-chose qui va de travers avec les programmes recompilés sur mon NUC et sur le nouveau portable avec la dernière version téléchargée de devkitPro. Pourtant je parviens sans difficultés à recompiler les exemples. En essayant de retrouver la commande qui fait appel à ndstool -- cet outil permettant d'emballer deux programmes jusque-là tout à fait classiques (format ELF) en une image de ROM nds. Et en relisant la ligne de makefile produisant "lib/ppp7.arm7" à coup de copie de section de fichier (outil GNU 'objcopy) je suis pris d'un doute: et si la technique passant par objcopy était devenue obsolète pour l'ARM7 aussi. Après tout, j'ai réussi à compiler les sources avec le nouveau devkit, mais est-ce que j'ai essayé de les faire tourner après ? pas sûr.

Et effectivement, en utilisant ppp7.arm7.elf directement, ça marche beaucoup mieux. 'faudra que j'aille corriger tout ça.

Wednesday, May 01, 2019

HoB: les combats

Les combats dans HoB ne sont pas simples. Pourtant, même après avoir découvert qu'il était possible d'en ajuster la difficulté, je n'en fais rien: chaque fois que je parviens enfin à venir à bout d'un monstre, je sens que c'est parce que j'ai mieux joué que les fois précédentes.

J'apprécie assez l'équilibre entre le système de sauvegarde (respawn rapide, sans temps de chargement) et les effets permanents/temporaires du jeu. Ainsi, quand vous éliminez un monstre, il est éliminé à jamais, mais les points de vie retirés à un monstre plus costaud lui sont rendus si vous mourez. Il m'a fallu du temps pour m'en rendre compte, mais ça devient évident dès qu'on commence à affronter des ennemis en armure.

Inutile contre certains ennemis de rester planqué derrière son bouclier en attendant l'ouverture: leurs attaques sont tellement puissantes qu'il n'a presqu'aucun effet.

La solution n'est pas non plus dans une plus stricte observation d'une boucle "narguer - esquiver - bondir - frapper (un coup) - esquiver" : ce genre de tactique rend le combat trop long et finit par me conduire à la faute ... et comme en début de partie on peut tomber sur des monstres qui vous tuent en un coup, mieux vaut éviter.

La clé, je pense, réside dans la mobilité: parvenir à éliminer d'abord les monstres de moindre importance sans attirer l'agressivité du "boss", utiliser à bon escient la roulade (ou la téléportation quand on l'a débloquée) pour pouvoir battre en retraite un peu plus tard. Pour ça, il est indispensable d'apprendre les distances de sécurité et d'action, et de garder la tête froide, histoire de ne pas se retrouver juste devant un caïd quand on espérait passer derrière. Plus tard, dans le jeu, on pourra aussi se servir du terrain pour empècher ces caïds d'utiliser leurs attaques, ou les faire se frapper les uns les autres pendant qu'on esquive.

Fort heureusement, la caméra nous laisse largement de quoi voir les antagonistes, et évite de nous balancer dans un plan serré et confus comme dans un Wind Waker.

Mais bon, je vous raconte tout ça depuis ma première partie où j'ai tardé à trouver des mises à jour pour mon épée, passé une bonne moitié du jeu avant de me rendre compte que je pouvais défoncer certaines armures et tardé à utiliser le bouton "courir" pendant les combats. Il est fort probable qu'une fois les subtilités du jeu maitrisées, il n'y aura plus autant de challenge (mais là, ma deuxième partie est plutôt en mode 'esquive' pour ne pas voir mon fiston commencer à mettre des coups de chaise à tous ses camarades de classe).

On est pas non plus dans un jeu où le système de combat était le coeur de l'attention des développeurs et où il faut presqu'autant de concentration pour jongler avec les mouvements possibles que dans un Street Fighter. Mais aller dire qu'il a été ajouté "parce qu'il fallait bien" ? non, ça serait pousser trop loin. Ne serait-ce que parce qu'une grande partie des items cachés servent à tenir plus longtemps en cas de combat, et pas vraiment à obtenir des "clés" pour avancer dans l'aventure comme ce serait le cas dans Fez.

Friday, April 12, 2019

HoB, btw.

I've been fascinated by HoB's design since the first trailers I've seen. I collected as many wallpapers as possible, I've done style analysis, but unfortunately, I had no hardware compatible with the game ... that is, until I logged in the Nintendo shop last week and discovered a promo on HoB definitive edition!

That was the best possible conditions to play it. I could drop the adventure at any time, and resume exactly at that point. I hadn't to fight against "where is [] again?" because I've trained myself to the ABXY with the Mario & Luigi series. I wasn't fighting against my glasses because I could just keep the console in my hands. I'm even surprised I am not feeling any eye strain despite I added about 2 or 3 hours of play every evening in addition to my work hours, but it lasted only for one week...

I think I haven't played a game that intensely since Fez! About every moment in the day, I could feel slight excitation about getting back to the game when I'll be done with the day's tasks, exactly the same way you feel excited about continuing to read a Harry Potter book for the first time. The core difference with Fez is that I had no need for a journey log nor to scribble everything I encountered.

As surprising as it is, I could keep all I had to know about HoB's world in my head -- partly thanks to the icons feature on the map that will automatically pinpoint collectibles the minute you have them onscreen, so that you can track and collect them later on. I should mention that I played the game in "normal" mode, not in "definitive mode" (which would have provided more signposting and hints about quests, if I'm correct). I used the map a lot, and I found it interesting that only the overworld has a map, and that I got a different feeling when entering a cave where I would have to rely solely on my brain to know whether I've visited a room already and never know how far away I was from the exit.

I'll keep the game design analysis for other posts. I must confess that I did encountered some glitches while playing: mostly walls disappearing when the camera angle got too extreme, but also getting stuck into trees where I wasn't supposed to be ... The game even crashed once, which I really wasn't expecting on a console system. But let's be honest: compared to the huge amount of bugs PS and PC users reported at game launch, that Switch version is clearly much cleaner. I was also stunned to see the game lagging that much on earlier releases. The switch port seemed to run at full frame rate most of the time. I don't recall I had to blame lagging for any missed jump or failed fight.

Saturday, April 06, 2019

Shantae en perspective...


Je me refaisais un longplay de shantae pour voir un peu quel genre de level design a été utilisé dans les phases "face-à-face avec les monstres". Et comme je viens de travailler sur la perspective de Bilou dans sa pyramide les blocs m'ont sauté aux yeux.

Dans certaines zones, on a bel et bien une perspective 3/4 sur certains blocs (comprenez, la face avant du bloc est trois fois plus grande que la portion d'écran réservé à sa face supérieure -- j'ai noté ça 3:1 sur l'image). Dans d'autres salles (la plupart du donjon, en fait), on est avec un à-plat parfait. Enfin, le monde extérieur, lui, est plutôt en perspective 2/3 (un cube aurait une face supérieure qui occupe moitié moins de pixels à l'écran que sa face avant), ce qui se traduit par un rapport 2:1 pour la face supérieure assez flagrant pour les objets cylindriques ... et qu'on retrouve notamment dans les grandes fleurs de certaines salles du donjon de la forêt.

Je note aussi que ça m'avais complètement échappé quand j'ai étudié les graphismes du jeu, donc il est probable que ça n'ait choqué qu'une infime proportion d'architectes pendant leur partie.

Tuesday, April 02, 2019

Tout-en-Karton ?

Après un troisième round, il était temps que j'exporte les petits pixels actuels de la pyramide avec Bilou dedans ... Il faudra aussi que je prépare un niveau de test, histoire de vérifier que Bilou bouge bien dans ce décor-là.

I'm far from being done, but I've got now invested some more time pushing pixels for the pyramid zone, the next environment planned for Bilou's games. So it was time to pull the SD card out of my linker and make a backup of all this. Enjoy.

edit: I've spent significant time trying to figure out how this new perspective will affect layers use. I note that in early level of The Lost Vikings, the background wall is locked with the foreground tiles, but that in subsequent level, there is a slight parallax effect between the two. A feature I was planning to do myself, and that appears to work pretty fine.

Thursday, March 28, 2019

nohup NUC

I got a NUC as Christmas gift, and it was more than welcome. I hope to use it as the post-desktop device for plenty of purpose, mostly just by turning it on and interacting with a WiFi-capable gadget...

[ongoing] be the music machine of the living room
It is not too noisy with its fans, gets a jack output and can easily fit next to the HiFi system. I can use the WiFi connection to quickly view which song is being played, skip to the next song and switch between "fairy-lover" or "chiptune-lover" modes, from any device in the house including smartphones and tablets.

I would still need to let it learn which songs are less liked, or migrate some titles to other folders, etc. Preferably in a way that would not take effects immediately, but rather that is approved over ssh after having been collected during play sessions.

[done] make Fairy's laptop devkit-free

Fairy's laptop still has a battery. Mine is now powercord-tied to the ground. Fairy's one has poor resolution but increase mobility, but Fairy's one isn't always there, so it would be better to use it just as a remote terminal to the NUC instead.

[ongoing] let it serve (auto-generated) epub doxygen
That means having it a mercurial hub with improved features. I use to have something like "nohup hg serve --webdir-conf /path/to/hg/hgweb.config -p 5555 &>/dev/null &" at work, where hgweb.config is simply a list of 'printname = full/path/to/repository', where printname may be 'organizational-folder/repository-printname'. It all falls under a [paths] section of an INI file. But I'd like it to try building and generating documentation whenever I push a new set of commits there.

The ultimate goal is being able to browse up-to-date code from my boox without having to power up a laptop. That will also help integrating all sort of support pictures like screenshots and UML diagrams into the documentation.
 
[todo] make it download OC Remix updates on a daily/weekly basis

Because having OC remix on the wrong side of the firewall at work is a pain. My "coding music" is an open playlist,
  • and html class pl-video-title-link allows  to identify all the links to the mentioned videos.
  • and there is the page to the remix (https://ocremix.org/remix/OCR%%%%%) in tags
  • and there is a tag in youtube pages!
So I could have a script that automates download of new OC titles running on the cube...

[todo] enable Androïd development
 
That will be for when I got it plugged into a wired network again: I don't know whether this is due to the extra disk enclosed in the device, but the WiFi connectivity is a nightmare. I get a few 100Kbps at best ... barely enough to use a remote terminal. I'd rather not start installing big things that way.

[todo] make it a better youtube-on-TV than what the ISP provides in their box

Partly because there is no support for user accounts or playlist of any sort in the box...

Friday, March 22, 2019

Level Editor vs new engine

Mes cogitations pour rénover la gestion des maps dans mon moteur DS commence à porter ses fruits, au point que je peux commencer à réfléchir à l'impact que ça aura sur l'éditeur de niveaux. ça me tient à coeur parce qu'avec le système actuel, je ne vois de bonne solution pour réaliser les cours d'eau souterrains que mon frère avait mis dans les niveaux historiques de la Grande Aventure.

Je me dirige vers un système avec uniquement un byte par tile de 8x8 pixels, et quatre grande classes de blocs:
- les morceaux de blocs interactifs, provoquant des collisions auxquelles le personnage doit réagir (pics, bloc-question, bonus, portes ...)
- les zones non-solides mais succeptibles d'affecter le comportement de certains morceaux de code (eau, échelles, courant d'air ...)
- les blocs de "sol" (solides) qui encodent la forme des pentes
- les blocs solides qui encodent les propriétés physiques (friction, déplacement forcé, etc.)

ça signifie que la petite palette de blocs utilisée dans LEDS va devenir plus complexe, avec un bouton "montrer les autres options", et que je pourrais bien en avoir trois tranches plutôt qu'une seule pour éviter les opérations de navigation fastidieuses.

ça signifie aussi que c'en est fini de l'encodage de petits "0" et "2" dans la map pour former un code entre 1 et 256 en base 4: l'éditeur de niveau ne pourra plus proposer que les blocs qui auront été décrits, ce qui devrait au passage rendre les choses plus lisibles et plus faciles pour des gens qui auraient envie d'utiliser LEDS pour leur propres projets (on peut rêver, non?)

Autre truc intéressant: puisque l'information concernant un bloc spécial (mettons des briques cassables) n'est plus encodée que sur 1 tile, je vais avoir besoin de tiles qui disent "suite du bloc, cf. à droite" ou "suite du bloc, cf. en haut", etc. Chose qui devrait être plus simple à étendre à des blocs interactifs de 24x24 ou 32x32 si le besoin s'en fait sentir...

Nincha'ts

Avec cette pyramide, j'entre dans l'inconnu, moi aussi. On a jamais dessiné aucun niveaux, on a jamais vraiment fait de 'monster design', à part quelques Bilous couverts de bandelettes (momificum, momificus et momificae, de mémoire) et une sorte de robot affublé d'une caisse en guise de tête et baptisé "Toutencarton". Tout est à faire.

Alors après avoir un peu cogité le graphisme de super cat adventures et regardé J.l.n affronter les bêbêtes à poils de Kirby Squeak Squads, je me dis qu'une sorte de chat-ninja pourrait être sympa. Il faut qu'il soit Bilou-style, bien sûr, d'où l'absence de pattes. Il faut aussi qu'il ait des mouvement intéressants, d'où l'utilisation de la queue rayée comme d'une patte en cas de besoin. 
Il doit y avoir moyen d'en tirer quelque-chose de sympa...


Sunday, March 17, 2019

Labyrinth flavours ...

Oh mazes. Amazing Mazes. I quite love maze games, and as you may have guessed, I would like to delegate parts of the level design of my next game to a maze generator. I've written a few of them so far, including some that needed little resource, but most of them were creating so-called "perfect" mazes, where two locations in the maze are always linked by exactly one path .

Bon, j'aime bien les labyrinthes. Depuis longtemps, et j'aimerais bien que le prochain jeu de Bilou puisse se dérouler dans un niveau plus labyrinthique. Mais j'ai envie d'y jouer moi-même aussi, du coup ce serait sympa si le jeu pouvait partir d'un générateur de labyrinthes et les maquiller en niveaux de Bilou. Par contre, tous les générateurs de labyrinthes que j'ai fait (ou fait faire) jusqu'ici produisaient des labyrinthes parfaits, c'est à dire des labyrinthes dans lesquels il n'y a jamais qu'un et un seul chemin entre deux endroits. Et du point de vue du gameplay, j'ai peur que ce soit loin d'être génial.

 Imho, this is not ideal for gameplay. It creates maps that are essentially trees, with lots of dead ends and narrow hallways. I believe it will reduce many of the gameplay opportunities. it means that you can hardly dodge monsters. In some way, in such mazes, you hardly have any real choice once you stop seeing it all: you merely guess which might be the correct path and turn back a lot.

I have the feeling that interconnected loops will provide more interresting behaviours. we see them in PacMan - as well as in Phantom Hourglass. They provide interesting backtracking and let you chose between fighting or sneaking when you encounter a monster.


Parce que s'il n'y a qu'un seul chemin, ça implique qu'il y a de nombreuses voies sans issues. Sans une vue globale de la situation, il est extrêmement improbable de parvenir à "trouver" son chemin, et donc pas de réel choix à faire pendant la navigation. En plus, la plupart des obstacles ne pourront pas être contournés: ou bien on les affrontes, ou bien on ignore le chemin sur lequel ils se trouvent. Bref, mieux vaudrait un environnement proche d'un niveau de pac-man, avec de nombreuses boucles, où le défi est moins de trouver le chemin que de choisir celui qui offre le meilleur rapport récompenses/risques.

So how can I make levels than feature such loops? I gave it another try this week-end, by first laying out loops of random size on the map, making their center "unbreakable" and then setting the rest of the map as cells ready to be processed by a regular "perfect maze" algorithm. 

But this time, I do not need to push the execution to the point where the maze becomes all-connected. Instead, it is sufficient that all rooms get connected. Some cells will then remain obstacles, which I'm fine with.
Je n'ai pas encore d'algorithme idéal pour ce genre de labyrinthe. Je fais quelques essais sur papier quand j'ai un peu de temps les week-end... Une des idées serait de commencer par créer un certain nombre de boucles de ce genre dans une grille avant d'y faire tourner un algorithme de "labyrinthe parfait" sur les cases restantes jusqu'à ce que toutes les boucles se retrouvent inter-connectées.

Friday, March 08, 2019

pixdox

bon, je voudrais réintégrer une partie des images de ce blog à l'intérieur de la documentation Doxygen pour avoir un document de type "e-book" un peu plus complet. C'est particulièrement le cas avec les screenshots d'interface graphique pour les éditeurs, parce que redessiner les positions des boutons quand je veux comprendre pourquoi certains ne s'activent pas à chaque fois, ça devient vite lassant.

j'ai déjà fait un essai avec un fichier pour libgeds, qui s'était rangé dans 'pixdox/html' et qui était invoqué avec un \image html InspectorWidget.png dans InspectorWidget.cpp, moyennant IMAGE_PATH=pixdox dans le fichier Doxyfile pour libgeds... reste à faire pareil pour les autres.

Et il faudra copier les images de 'pixdox/html' à l'intérieur de dox/html ...

edit: oui, pendant quelques jours, ce post a bloqué tout le reste du blog. La faute à un copier-coller trop aggressif qui s'est terminé par une image encodée directement en base64 dans le post... J'imagine que les buffers de google n'ont pas apprécié.

Thursday, February 28, 2019

Sandopolis Zone and Mega-tiles.

Ok, au départ je cherchais des références pour les couleurs et le style de la "desert/pyramid zone" de mon prochain jeu. Et je venais de découvrir l'existence de Sandopolis, région d'un jeu Sonic jusqu'à laquelle je ne suis probablement jamais allé.

At first, I was just trying to find colour references for the pyramid/desert level of my next game, and I just had discovered the Sandopolis zone in some Sonic game (where I never managed to have my red shoes around). The tileset was a big .zip where I should have found all the backgrounds, but instead of the expected 'tilesheet', I stumble upon a set of 128x128 pixels pictures.

Un beau gros .zip dans lequel était supposés se trouver tous les décors, mais au lieu d'une "tilesheet" habituelle, je tombe sur une collections d'images de 128x128 pixels. J'étais resté un peu intrigué mais sans plus. Puis en revoyant la vidéo "making of Sonic 2" de splashwave, le doute n'est plus possible: il y a un niveau intermédiaire de map, et ces blocs de 128x128 pixels sont bels et biens des morceaux de puzzle construit à la main pour servir ensuite de de bloc de construction dans un niveau. On va les appeler des "mega-tiles".

I then shifted from "puzzled" to "enlightened" while watching the Sonic 2 making of video by Splashwave. There was no more doubt to have: there is truly an intermediate level of design -- 128x128 pixels areas hand-crafted by the graphics people out of brainstorming proposals, and making best reuse of the 8x8 tiles. Level design people then use them as jigsaw pieces to get the desired chains of jumps, boosts and loops. Note how the in and out ground height is standardised over the mega-tiles, btw. The core idea of this technique is of course to improve space efficiency: levels in Sonic may get as large as 10000x2000 pixels and the machine only has 64K of RAM. A 100:1 compression ratio is more than welcome in this context.

Avec les mega-tiles, on peut atteindre ainsi un taux de compression proche de 100 pour 1. Les niveaux de Sonic avec leur taille surréaliste de 10,000 x 2,000 pixels tiennent en réalité dans moins de 64K de mémoire.
Et si on regarde un niveau construit avec suffisamment de recul, on peut commencer à trouver des correspondances. Commencer seulement, parce que c'est loin d'être complètement évident ... et j'aurai eu recours au mode "soustraction" de Gimp pour les mettre en évidence.

Yet, when you have a look at a sonic map, it isn't obvious that it is made of such mega-tiles. To see them,  I had to use the same trick I used to locate tiles in SuperFrog: duplicate the layer and turn it in "substraction" mode, so that tiled area suddenly turn as all-black squares when they overlay.

Et si on ne s'en rend pas compte en jouant, c'est grâce aux différents éléments qui eux ne font pas partie de ces blocs : les télévisions, les anneaux, les ennemis ... Et parce que contrairement à un jeu "type Mario", la disposition des blocs de taille 16x16 au sein du jeu a nettement moins d'importance. J'entends par là que Mario interagit avec un bloc de brique ou un bloc-question individuellement. Et le fait qu'un saut soit possible ou non se décide à un bloc près.

I see two possible reasons explaining why those mega-tiles remain hidden to the player. First, the level designers have an additional layer of diversity with rings, screenchests, spikes, bumpers and baddies. Second, unlike a Mario-styled game, 16x16 blocks layout within the level makes little practical sense: Mario interacts with individual blocks frequently, and a mere block may define whether you an clear a jump or not. This isn't the case in Sonic: the speed, not the layout, defines whether you make it through -- or whether you find the appropriate bumper to gain extra height/speed. And even when you aren't high enough, you can still make it through a less-impressive backup route.

Pas dans Sonic. Selon qu'on va plus ou moins vite, on passe ou non. Selon qu'on trouve le bon bumper ou non, on va assez haut. Et quand on n'est pas assez haut, il y a de toutes façons une route inférieure à suivre. 

Thursday, February 21, 2019

L'ère post-desktop

Bon, soyons clairs: être sur un PC - un vrai, avec une souris, un clavier, une connexion réseau et un écran - ça ne m'arrive plus qu'au bureau. La bricole homebrew, ce sera de temps en temps sur le laptop ... avec tout ce que je peux préparer hors-PC hors PC. Le "engine design" dans un cahier atoma -- pour pouvoir mettre en vis-à-vis les idées et leur conséquences -- la documentation UML dans un cahier A4 quadrillé à spirale, etc. J'ai même tenté une sorte de 'bullet journal' pour suivre ce qui devait aller sur le blog, les posts en standby etc, qui est tombé plus ou moins dans l'abandon depuis que je me suis installé Wordpress sur mon Boox. Et depuis cette année, je me suis trouvé un super petit cahier pointillé à la fin duquel j'ai écrit "proudly powered by CreaCorner ... c'est plus ou moins devenu mon vrai blog, sauf qu'il n'est pas en ligne... allez, quelques photos de temps en temps sur Twitter.

Je me fais aussi mes petites "todo listes" dedans. Les choses à relire dans du code converti en e-book. Pourtant, une bonne partie des 'todo items' auront besoin de repasser sur PC. Parce que vu l'heure à laquelle j'en ai fini avec la vaisselle ces jours-ci, quand j'ouvre mon portable, je suis en mode demi-zombie ... je passe de forum vide en forum vide sans vraiment avoir l'énergie de lire ce que les gens y ont mis.

Donc, bin je vais me les ré-encoder ici, histoire d'avoir cette liste sous la main dans les rares cas où je suis sur PC :-P

  • Q: où est-ce qu'on en est avec LevelModel, pourquoi ::SaveCommands() est vide ?
  • Q: pourquoi avais-je introduit "MonsterGeneration"
    • A: cette classe apparaît en même temps que le système de tri des 'blocs' de texte pendant les liens entre objets ... sans doute une tentative avortée qui sera restée au moment du commit faute de reviewing correct du code.
  • Q: pourquoi est-ce que je n'ai aucune doc sur EditorLevel::scanSubFile() ?
  • [todo] Refaire un coup de -WeffC++ sur le code, et trouver les #pragma push qu'il faut pour que le code incapable de supporter 'effective C++' se taise une fois pour toute et que ça devienne le mode par défaut pour la compilation.
  • [todo] transférer des captures d'écran des outils dsgametools à l'intérieur de la doc doxygen
  • [todo] faire en sorte que SpriteRam apparaisse dans la doc du SpriteEditor
edit: voilà. je viens de terminer d'écrire ça et mon GSM me rappelle à l'ordre façon Monkey Island: "maintenant éteignez votre ordinateur et allez vous coucher".

Tuesday, February 19, 2019

Cupido power!

To be honest, the "Cupido" power of Kirby's adventure is one thing that I almost never used, and certainly almost never enjoyed. But things are apparently fairly different for J.L.N-6yo, who enjoys it enough to prefer losing a life over going forward without it.

Peut-il y en avoir encore ici qui ignorent que Kirby -- cette petite boule rose qui vole la vedette à Bilou depuis 1993 -- est capable d'acquérir de nouveaux pouvoirs en avalent des ennemis ? Parmi eux, il y en a un que j'ai personnellement boudé : Kirby-cupidon. Si par hasard je finissais par l'avoir équipé, il était rare que j'apprécie l'avoir et je ne l'ai probablement jamais recherché (contrairement à Kirby-Link, Kirby-Marteau ou Kirby-Soucoupe). Mais pour J.l.n, c'est apparemment le pouvoir idéal, et il préfèrera perdre une vie pour recommencer le niveau et récupérer son pouvoir-cupidon plutôt que de continuer le jeu sans. Analyse...

Cupido has ranged attack, making the other monsters less intimidating. Interestingly, the other power he enjoys a lot is metal, which also makes monsters harmless. And I find it excellent that the same level just features them at the start of two contiguous rooms. Just as if those rooms were thought as sandboxes to have fun.with those powers.

Kirby-cupidon attaque a distance. Avec lui, tous les monstres deviennent du coup beaucoup moins inquiétants. Ce n'est sans doute pas annodin puisque l'autre pouvoir qui a les faveurs de J.l.n n'est autre que "Kirby-Métal", que je trouve personnellement trop lent et trop lourd pour être agréable, mais qui passe tel un tank à travers (presque) tous les obstacles... et qui annule tout inquiétude que les monstres pourraient produire.

Cupido also makes floating even simpler. Normal kirby requires you to flap with A like when Mario is swimming. cupido, once in the air, remains at the exact pixel it was until you press the D-Pad. It makes many precision challenges completely. undermined and lots of timing challenges much easier to focus on.

Last but not least, the details making the arrow fun is admirable: it sticks for some seconds where it landed, including on monsters, making them look grotesque and stupid since they keep wandering around as if they didn't realised what happened to them. This is reinforced by the fact that arrows are weak compared to most other attacks, making the weakest monster need two hits.
Note, too, than those sticky arrows provide valuabe feedback to the young player: it gives lots of time to analyse why a shot failed and where to move to make the next shot a hit.


Note amusante : après avoir rejoué sur mon ancienne partie (où on peut faire son marché-des-pouvoirs et où j'ai débloqué le pouvoir du fantôme), J.L.N. m'a fait lui-même sa petite analyse de "pourquoi il aime bien kirby-ange et kirby-métal" ^_^

Sunday, February 10, 2019

La face cachée de Bubsy

La video "Did you know gaming" au  sujet de Bubsy, est surprenante, et d'une certaine manière digne des meilleurs articles de Pix'n'Love. Le premier Bubsy - le seul réussi de la série - est l'oeuvre d'un employé d'Accolade qui voulait faire un jeu à la Sonic dans une société où ce qu'on attendait de lui, c'étaient des jeux d'aventure (eh oui, on ne faisait apparemment pas que des jeux de course chez Accolade). Mais son analyse de "ce qui fait de Sonic un bon jeu " est d'une telle qualité que la direction s'incline et donne son feu vert .

En résulte le très bon jeu que nous connaissons bien, sorti en '93. Drôle, captivant et plein de charme sans pour autant être parfait ni nécessairement un exemple en matière de gameplay.

Mais vu le budget de la production et de la promotion du jeu, ils décident d'en rester là, et l'employé de quitter la compagnie. Sans la license de son succès. Quand l'heure viendra malgré tout de faire un Bubsy2, ce sera avec la consigne de limiter les frais mais surtout en contraignant de s'y atteler une équipe qui préfére les simulations sportives habituelles de la société et déteste devoir travailler sur Bubsy...

Thursday, January 31, 2019

Les arbres de Mocha

Je manque de temps pour re-blogger ici toutes les trouvailles de Sylvain "Tohad" en matière de graphisme -- d'ordinaire touchant plutôt aux décors de dessins animés (avec un penchant pour les ghibli, en ce qui me concerne) ou au concept art de futurs jeux vidéo.

Mais là, vu le temps considérable que j'ai passé moi-même à chercher des références pour dessiner les arbres, je peux difficilement passer à côté de ce tutoriel épattant de Mocha.

'faudra que j'étudie ça d'un peu plus près.

To Mocha (him/her)self: I hope you won't mind if I host a copy of your wonderful tutorial here until I'm done studying it and applying it to improve my own trees in my "green zone" game level.

Tuesday, January 29, 2019

Loco Roco ... enfin!

A force de faire des brocantes, mon frère a fini par mettre la main sur une PSP et une petite collection de disques de jeux, parmi lesquels Loco Roco, le jeu que j'avais envie d'essayer depuis près de 10 ans. Un concept de jeu assez sympa, mais avec un mode de contrôle que je trouve lassant au bout. de quelques niveaux.



20181228_133722.jpg
Le principe de base me fait penser à Soul Bubble : suivre un parcours, trouver des petites cachettes et faire gaffe à ses points de vie.

Là où Soul Bubble semblait se battre contre le hardware de la NDS, Loco Roco offre un graphisme tout en finesse et fluide à souhait. Les structures mobiles sont particulièrement réussies, mais malheureusement trop souvent utilisées comme des mini-cinématiques.

Même impression pour le mécanisme "fracturer Loco Roco en plein de petites boules": il est presque toujours équivalent à un "démarrer la cinématique"... Et là où Soul Bubble offrait une mini-map du niveau et un indice sonore à proximité des zones secrètes, on navigue beaucoup plus en aveugle sur ce titre. Et trop souvent sans possibilité de faire marche arrière.

Bon, venous-en an coeur du problème: on ne contrôle pas son personnage. On peut seulement incliner le niveau dans un sens ou l'autre. Et pour sauter, maintenir les deux gâchettes pour "charger" le saut puis relâcher. Le résultat est imprécis, il y aura beaucoup d'erreurs. Il faudra réessayer encore et encore. C'est le genre de chose qui devrait pouvoir se travailler, mais j'avoue ne pas avoir l'impression de m'en sortir mieux après une dizaine de niveaux. Je crois que je vais en rester là.

Friday, January 18, 2019

4MB ?

Bon, je dois avoir quelque-chose de foireux dans la configuration de mon système de build avec le dernier devkitarm que j'ai installé: la plupart des outils prennent soudain une taille de 4MiB... avec plein de vide au milieu du fichier ...

Première question, est-ce que ce problème est déjà présent dans le fichier .elf, ou est-ce quelque-chose que j'ai introduit au moment des conversion vers le format .nds ?

J'utilise pour ça l'outil objdump, et il y a déjà quelque-chose de louche: vous voyez ces vaddr et paddr ? l'une est une adresse virtuelle, que les données doivent avoir pour que le programme tourne bien. l'autre... bin c'est la première fois que je vois des valeurs différentes pour ces "adresses physiques"
Et en particulier, une de ces commandes de chargement va utiliser une adresse "physique" 4MiB plus loin que le début de la RAM de la NDS.

Si je croise ces information avec la liste des sections, disponible un peu plus bas, j'ai une correspondance (grâce aux offsets à l'intérieur du fichier ELF) avec une section baptisée ".twl" -- là aussi, c'est une première pour moi. C'est en tout cas bien les bytes qui correspondent à ce qu'on trouve au bout du gouffre du fichier .nds, aux alentours de 4MiB.

Renseignements pris, cette section contient des instructions spécifiques au démarrage pour DSi (et son TW Loader). Une petite mise à jour de mes makefiles pour éviter le passage par un fichier .arm9 (version pré-applatie du contenu du fichier .elf) et c'est réglé: l'outil ndstool qui construit les .nds est maintenant suffisamment évolué pour manipuler lui-même les .elf, comme dit WinterMute.

Et au passage, une simple utilisation de stringstream pour des manipulations de chaînes me coutait 250K dans runMe (qui autrement ne prend "que" 500K).

Voilà qui cloture (enfin) la branche "latest-devkitpro"

Sunday, January 13, 2019

Tile Engine Revision

Bon, j'ai une grosse révision de mon moteur de jeu en cours. Jusqu'ici, les propriétés du niveau étaient conservées dans les bits "palette" du niveau, soit 4 bits par mini-bloc de 8x8 pixels (les tiles, pour les intimes. Prononcez avec de l'aï comme dans light). Pour "School Rush" et ses niveaux de 16 écrans de large pour 1 écran de haut, on parle de 8KiB de données. Un niveau de Commander Keen (mettons la machine infernale des Shikadis) avec ses 1200x1200 pixels nécessite 22500 de ces tiles.

Much of my hobby time has been spent in tileset engine investigation since SchoolRush release. The current one has a few shortcomings which proved annoying during the " finish him " phase. Among other things, I want to stop using the palette bits for metadata, but it is still unclear how many bits per tile I can afford.
Most levels in schoolRush need a mere 16 screens, and consume only 8KiB with the current 4-bit-per-tile implementation. A Commander Keen level in comparison is 1200x1200 pixels, which would require about 22K tiles.


Pourquoi tous ces chiffres ? parce qu'au coeur de la révision, il y a le besoin de faire sortir ça des bits de palette pour pouvoir utiliser librement les changements de couleurs si utiles dans School Rush tout en permettant de nouvelles mécaniques de jeu. Jusqu'ici, j'ai pu m'en sortir avec des blocs spéciaux (bonus, pics) qui utilisaient les "codes couleurs" des 4 tiles qu'ils couvraient pour encoder un numéro suffisamment large. Mais quand on commence à réfléchir à faire de l'eau, des ventilateurs ou des tapis roulant, ce système devient bancal.

Of course, one of the goals for the revised engine is to enable multi-palette edition on both tile layers, but I would also like to increase the number of unique materials in the game. My attempts at having ice blocks, conveyor belts and flowing water highlighted that special blocks are not enough for all purposes.
One reason that makes it misfit is that special blocks only work for 16x16 blocks, not for arbitrary layout of 8x8 tiles or for transparent areas.


En particulier, il était basé sur le fait qu'un groupe de 4 tiles sont liées par les numéros de tile (en mémoire vidéo) utilisé parce que l'éditeur de sprites fonctionne comme ça. Impossible donc de définir un bloc-bumper sur un graphisme qui serait fait d'une moitié de gomme et d'une moitié de lettre. ça, c'est plutôt un avantage. Impossible aussi de rendre une pointe de crayon blessante si elle est sur 'l'arrière-plan'.

So from those figures, and given that the NDS has 4MiB of RAM, upgrading to 8-bit per tile should be possible. Granted, it could be nice to include some decompression techniques or some 16-bit era fancy techniques, but none of this seems to be mandatory right now. That's one of the strengths of the DS, imbo, that you can already make interesting games while keeping the engine simple.
And yet I know that at some point I'll wonder how such function could be achieved on a much simpler system - let's say a GBA, a SNES or a Mega-Drive...



Faut-il donc que je continue avec ce système (données 4-bit) sachant que je travaillerai maintenant sur un tableau séparé ? Puis-je me permettre une extension à 8-bit par tile ? et si oui, comment organiser au mieux les données ? Est-ce que ça m'impose d'intégrer de la compression ?

A mon avis, avec 22Ko pour une map type "Commander Keen" et sur une bécane qui dispose de 4Mo de mémoire principale, ça reste parfaitement jouable. Oui, c'est loin des techniques de trapéziste de l'époque des consoles 16-bit, mais c'est justement une des raison de choisir la DS à mes yeux: elle permet de se concentrer sur le jeu lui-même, avec des contraintes, certes, mais des contraintes simples à apprivoiser.

Tuesday, January 08, 2019

debugging PERL regular expressions

Okay, I'm using PERL when I can, because it makes the job. I like how it is not distracting my train of thoughts when tackling a problem and how it makes scripts that are easy to hack later on. I love how it integrated regular expressions, but so far, I wasn't fond of how I had to test input patterns one after another with stripped down versions of the regular expression to find why it was failing.

And today I discover use re 'debug'.

With a simple line, I can get an overview of what the regular expression evaluator is trying to do when parsing a string (coloring added manually).

In yellow, we can track the position within the string: how much has been accepted so far. In green, a quick overview of what was just behind that position and what is just ahead. The blue code seems to identify the next operation that the regexp will do -- its program counter, sort of, and in white the detail of what is tried/done.