Showing posts with label level2. Show all posts
Showing posts with label level2. Show all posts

Wednesday, October 30, 2024

October update

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

Bienvenue dans un post-qui-change... ma petite semaine de congé d'automne aura été bien remplie de p'tits Bilous (entre autres choses), avec en objectif #1 l'ajout de deux "niveaux" dans la démo "Three Rooms", comme proposé en Mars. Evidemment, comme ils datent tout deux d'avant SchoolRush, il y a eu pas mal de mini-couacs à corriger pour éviter de se retrouver avec un niveau au décor psychédélique qui se termine dès qu'on casse une craie

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

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

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

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

Le plus gros morceau, ça aura été de corriger le code qui permet à un simple sprite 16x16 d'être considéré comme étant plus grand ou plus petit ... une modification essentielle pour passer du furblock à la branche mais qui interférait avec les gouttes d'encres d'inkjet et les vagues de sable ...
Alors, voilà: un joli bouton vert vers une nouvelle démo à essayer chez vous. Bien sûr, ça reste très en chantier et vous trouverez pleins de trucs pas au point, mais au moins, les horreurs ont été éliminées. Rendez-vous en Décembre avec une démo incorporant BangBash ?

Ah, and it's not in the school zone, but [done] that ugly pink background showing up in the green2 level, too... I'd rather have that fixed before uploading a new demo...

edit: There we are: 2 work-in-progress levels can be found if you explore the three rooms properly. There is still much to do, but also much to explore if you've never launched anything earlier than School Rush.

Sunday, July 21, 2024

map poked!

map.poke is done. Okay, it doesn't read "map.poke" in the level script but rather block (coordinates) = (hex) so that it mimmics the block (hex) { ... } definition. And that makes it specific to special blocks.

But there it is. After some branches untangling and more commits weaving, I could use it to add a secret exit in the trunk of the 'greent' room without having to go through the now-clumsy steps of patching the level on NDS while editing code on the PC.

Bon, je crois qu'il n'y a pas besoin que je vous dise que quelque-chose n'a pas marché, hein ? vous vous en doutez rien qu'en regardant l'image... En mars, j'avais évoqué la possibilité de reprendre les vieilles maps pour étoffer un peu "Dreamlands" (ou à tout le moins, proposer un peu plus de contenu pour la démo "3 rooms"). Et bonne nouvelle, j'avais fini par retrouver les maps en question. Je m'étais donc rajouter un peu de script qui dise "alors, le bloc de type 11, c'est une sortie secrète, et dans le niveau greent (le nouveau), si on la touche, tu charges le niveau greeny (l'ancien)". Sauf que pas moyen de tester, évidemment, parce que sur greent.map, il n'y a aucun bloc de type 11...

C'était donc l'occasion de se bouger un peu et de coder le mécanisme dénommé "map.poke", à savoir permettre au script d'aller modifier les propriétés d'un bloc du niveau sans rien demander à personne (et en particulier pas à l'éditeur de niveaux ;P). Et oui, la vie est telle qu'il m'aura fallu un bon mois pour que ces malheureuses lignes de code finissent compilées sur le PC qui avait aussi le fichier greeny.map ce matin. Tout ça pour se rendre compte qu'avant de pouvoir faire une "release" avec la vieille map n°1, je vais devoir lui faire un sérieux ravalement de façade pour l'adapter au nouveau tileset ^^"

Oh I presume you don't really recognize the big tree of my so old two-levels demo: since I re-structured the tileset, there are quite some editing to happen there before you can actually enjoy anything :P

Saturday, July 22, 2023

DS Ram Leakage in TestNScripts

I had thought that fixing 'slope unit-tests' in addition to 'wall unit tests' would mean my fixes to get the scorpeye behaving as intended. That would mean the 'summer code review' would be over and the 'summer game dev' could start. Well, that was hoping too much, because there's actually one more test that, for some reason, doesn't show up in ./testme --list but still exists and is important: TestNScripts. This one loads the real .cmd files of SchoolRush and checks parsing went fine. And it does not only check one of them: it will reload many scripts in the same "engine", the way the game does.


while (ntests < n) {
   TestBench tc;
   for (uint i=0; i < REDO; i++) {
       printf("== R%i/%i redo%i ", ntests, n, i);
       tc.ResetEngineResources();
       ParseScript(tc, scripts[rand()%nscripts], __FUNCTION__);
       tc.CheckEngine();
   }
   ntests++;
   tc.Over();
}

No assertion failure here, instead one of the trickiest things to track: memory exhaustion. So it's time for me to learn how to use my tracking tools again. I even left documentation for my future self back in the past (thanks, past self ^^). Once again, the problem arise also in 'default'... looks like I had been over-optimistic in September 2021 when I merged sprites overlay into default.

Well, at least if gives me hope this time: on the 'newmap branch', the forgotten test terminates with 'Out of DS memory'. I managed to get a log of what is allocated at that time, but it would require filtering what has leaked from last ParseScript, and what belongs to the current, interrupted because there's no more memory, running ParseScript. Hopefully, when the bug occurs on default, it gives me a nice 'halt because of leakage' and not a 'out of DS memory' condition. 

  • [done] understand why the new branch gets so high on memory consumption
  • [todo] make sure .spr and .cmd files in fakeroot/ are working fine (despite they now need bilou.spr and school.spr)
  • [todo] that should be the job of UnitTest.mk

edit: dummy! dummy! dummy! ... the 'DS Ram Usage' statistics in those tests is a lie! when it says 95% used, it doesn't mean you'd use 95% of the NDS 4MiB of RAM to play the script. It means that the dummy-allocator-that-never-recycle-memory used 95% of its storage to process the script. Should parsing become more complex (e.g. because we're loading one more file, or creating more intermediate structures), the memory used by the script will grow while the true RAM usage on the NDS would stay roughly the same.

Eeet ouaip. Je me suis donc morfondu un bon morceau de l'été sur le fait que mon moteur de jeu faisait péter sa consommation de mémoire. En tout cas, ça a sérieusement refroidi mon appétit pour le dévelopement de jeu après les heures de boulot. Trouver le problème, ça demandait de se plonger dans une montagne de données et les outils d'il-y-a-longtemps pour comprendre où était la fuite... Sauf qu'en vrai il n'y avait pas de fuite. Tout ça, c'était juste un ou deux messages d'erreur mal nommés qui me faisaient croire que la lecture des scripts prenait plus de 4MB de mémoire (tout ce que la DS a, en somme), sauf que l'environnement de test pour faire tourner les niveaux de mes jeux DS sur PC n'est pas prévu pour qu'on joue, mais pour qu'on trouve les erreurs. 

Donc contrairement à un système de gestion de mémoire ordinaire, quand on lui "rend" un bloc de mémoire il ne le réutilise jamais. La mémoire qu'il fournit à la demande est toujours de la mémoire qui n'a jamais servi pour une autre tâche dans le niveau, et c'est elle qui finissait par faire défaut. Vous me permettrez de croire que si vous avez envie d'en savoir plus, vous êtes aussi en mesure de lire l'Anglais?

If I want to have an estimate of the memory it would take on the NDS, I'd have to keep track of individual allocs and frees and see whether they reach some maximum at a new alloc. (2023-10-23)

What is that one-time allocator ? well, maybe you've heard of bottom-up allocator, where you just keep track of one position in memory: the top-of-used-area, and everything above the top is unused memory. Of course, as soon as you free things out-of-order compared to how you allocated them, that allocator is no longer enough. You would like at least a list of freed-blocks-that-could-further-reduce-top in case the block at the top is eventually freed. Well, the one-time allocator does not even do that. Any byte of one-time memory can be allocated exactly only once. If freed, it is "painted" as free and will remain like that until the ongoing test terminates. 

That is silly as far as memory management is concerned, but it means if some block has not benn freed when the test terminates, you know what role this memory had when it failed. There can't be any tricky-as-hell case where "yeah, that memory had been used for A and then freed, but then it has been re-allocated for B. So maybe B is wrong or maybe something still had a reference of when it was used for A". Sometimes it truly helps. When I'm not misguided by my past self with lying error messages.

Saturday, July 08, 2017

Loading Chaos

Il y a environ 2 ans, quand j'ai reçu le commentaire d'Eric sur School Rush, j'étais en pleine tentative de changer radicalement la manière dont fonctionne le chargement des niveaux dans GEDS. Malheureusement, rien ne se déroulait comme je voulais. Du coup, sa remarque

Pourquoi le chargement des niveaux est aussi chaotique ??
est un peu restée en suspens. Je ne savais pas vraiment en faire grand-chose.

Remember Eric's comment that level loading felt like chaos? I haven't addressed it so far, partly because when he mentioned it, I was struggling to improve the way levels are loaded with libgeds. Meanwhile, the reason for which I wanted improved levels loading (a power-up shop) vanished and the chaos got hidden by "black curtains" (actually, the "window" feature of the NDS hardware). But loading time was still excessive and nothing happens while loading.

Entre-temps, le projet de "marché au bonus pendant les temps de chargement" est passé à la trappe en faveur d'un niveau-à-vies/power-ups. Le chaos du changement de niveau (en partie dû au fait que j'aime bien savoir si les étapes se passent correctement en phase de développement, j'avoue) est masqué par un "rideau noir", mais le temps de chargement, lui, est toujours aussi long.

En relisant son commentaire cette semaine, juste après avoir ajouté une "page-de-livre magique" supplémentaire, je me rends compte que l'écran du bas (le livre, donc) ne subit presque aucun changement pendant tout le chargement.

I reached that comment again this week, right after I took some time to have a custom "bottom screen picture" for the "credits level" and then realised that the bottom screen remains mostly unchanged (although completely hidden) while we're doing a lot of chaotic stuff on the top screen as result of the level loading. So If I want the player to get some info about the story, or tease/teach him, the bottom screen could do the job.

En haut, tous les graphismes sont re-chargés, puis la nouvelle map est mise à l'écran, puis -- seulement quand tous les scripts ont étés traduits en machines d'états et tous les personnages positionnés -- on peut positionner la caméra dans le niveau à l'endroit où doit commencer l'action.

Mais en bas, rien ne se produit jusqu'à ce que le niveau soit déclaré "prêt". Je peux donc repêcher une des illustrations qui servaient à présenter les niveau de difficulté et les donner en pâture au joueur -- peut-être avec un message adapté à sa performance (première arrivée dans le niveau, première raté dans le niveau, dernière chance). 

So I crafted a small prototype, that shows one of the 'difficulty selection' pictures and hides it just before we're about to show the "let's play" pages of the HUD book again to resume playing. Now that this is satisfying, I'll have to think about a few more pictures (one per level) and some messages.

J'ai un premier prototype pour ce genre de chose. Afficher l'image au moment où on commence le chargement, c'est facile. Je dois maintenant retrouver dans la séquence "démarrage du niveau" le moment où le niveau va démarrer de sorte qu'on puisse éviter un "glitch" du genre "la page de chargement était affichée, la page de jeu s'affiche un instant, puis l'écran devient brusquement noir avant de se rouvrir sue la page de jeu". N'est-ce pas, Eric ?
  • [done] glitchless showScreen() while loading.
  • [unplanned but done] refactor so that "hud.mode" is defined through script
  • [unplanned todo] refactor so that showScreen is called from "hud.load/show"
  • [done] adapt the picture to show to the level we're in
  • [>>>] adapt the position to show to the lives we have (for specific messages)
  • [done] make it tell the story of the game

Monday, January 25, 2016

Leakage: 0%

Un script pour décoder les traces d'allocation de mémoire combinées à un mécanisme qui remplace malloc/free par une progression linéaire dans l'espace-mémoire et j'ai pu éliminer la totalité des fuites de mémoire dans le parsing des scripts.

Deuxième étape, une inspection systématique des listes d'animations maintenues par l'Engine lui-même histoire de s'assurer qu'il ne reste aucune référence à un objet libéré (c'est désormais facile, puisque chaque objet libéré se voit écrasé par des 0xfefefefe et que sa mémoire n'est pas ré-attribuée lors du test). Me voici armé pour tester les enchaînement de niveaux, mais jusqu'à un certain point seulement: au bout de quelques itérations, la mémoire disponible pour le test aura été complètement utilisée. Allez, je devrais pouvoir passer aux chargements-suite-à-une-fin-de-niveaux dans le courant de la semaine, et étudier les "script reset" expérimentaux supposés accélérer les chargements de niveaux.

I reached stable parsing, where no trailing objects exist when the GameScript is destroyed. The next test I implemented pointed out an object that was "recycled" but that was still referenced by the Engine's global state. So I am now ready to investigate what happens during levels transitions, both regular and "just reload" experiments. More testing to follow.

Saturday, August 15, 2015

Todo list des vacances

Petit arrêt au calme au milieu des écureuils. L'occasion de faire un peu le point sur "School Rush" et de ce qui manque pour compléter le jeu en faisant le tour de mes petits calepins:

  • [don't] BigPunch => StraightThrow. Une façon d'encourager le joueur à continuer à emmener des Dumbladors avec lui même après avoir obtenu un "BigPunch".
  • [done] Rallonger l'effet d'un "air punch" sur les Pendatz.
  • [how?] Implémenter quelque-chose de similaire sur Verso.
  • Une "danse de la victoire" à la fin du niveau
  • [done] Autoriser le FLOAT à partir du High-Jump (inkjets, gommes-bumper)
  • [done] Passage à FLOAT automatique quand Bilou obtient le Power-up FLOAT
  • [how?] quelque-chose de similaire pour BigPunch
  • Indique l'état des power-up sur le "HUD"
  • [done] Eliminer les Pendatz en mode "dizzy".
  • Donner une utilité aux bonus à récolter.
I played some School Rush this week, and read back scribbled notes to isolate todo items I still have to address. Many of these are related to the power-ups, the way to ensure their state can be understood by the player and to have coherent behaviour accross the game.

I would like to augment the GameScript class, too -- the level parser -- with a "reload()" method that would keep the state machine structures, but reload maps, evaluate expressions and reset GOBs to their scripted positions, so that we can efficiently retry the level when the player failed.

I also analysed the layout of my two first levels. I want to add a layer of collectibles that would give gameplay hints:

  • you can pick up a stunned blador
  • you can throw bladors at pendats
  • you can ride spongebops
  • have you tried to throw a blador in spikes ?
  • bladors can un-wire spongebop
and in the level 2:

  • hold (A) and you'll float at the top of your jump
  • big punch can defeat pendats
  • DOWN + (B) let you grab bladors although ou have Big Punch
  • sponges do float
  • bladors can stun inkjets.
The idea would be to have it look like a star-coin in NSMB, but also reveal a small drawing when discovered.

Thursday, August 12, 2010

AppleAssault : 98% done

  • [done] level maps
  • [done] soundtrack
  • [done] punch behaviour
  • [done] instruction screen
  • [done] credits
  • [done] game over
  • [done] game state display
  • [done] one-file packaging
  • [done] compute score
  • [wish] reward style with 1UPs
  • [wish] funghi-applemen interaction
  • [done] check "damned-jump" bug disappeared
  • [done] mario-compatible jump = A ; punch = B
  • [done] try appleassault.nds on real hardware
  • [wish] random level ordering
  • [done] investigate buggy background screen.
  • [done] fix buggy background screen
  • [mouais] sound effects
  • [done] remove "state xxx !SET" and similar debug message
  • [done] remove the "ghost appleman" of level 1
  • [wish] home/visitor highscores.
PS : vous vous demandez sans doute "si ça, c'est 98%, à quand remonte le 2%". Excellente question. Pas à l'introduction du nom, en tout cas, ni même à la proposition de l'objectif du jeu. Je dirais plus volontiers qu'il s'agit des premiers tests avec l'appleman aggressif (qui vous saute dessus quand il vous voit), donc début août 2009. Quoi que ce serait déjà plus 10%.

Maybe you find it odd that I claim this is 98% ... 98% of what ? when was 50% when was 0%. I'm not fully sure, of course, but I'd say we started moving towards AppleAssault when applemen started to attack Bilou in the green zone, that is, when I implemented detection of Bilou's position to trigger behaviour change for the applemen.

Monday, August 09, 2010

C'était bien ça ...

J'avais pris une approche un peu trop "frileuse" en choisissant d'exécuter l'expression accollée à un changement de niveau avant le changement de niveau lui-même. Cela signifie en particulier que l'action "changer le niveau" aura le dernier mot quoi que l'expression puisse tenter de faire, rendant impossible des construction du genre si (vies=0) alors gameover() sinon réessaie(ce_niveau).

Let's put it somehow back in perspective. First, my friend Pierrick suggested that the amount of apples to defend against would be based on the #level we're in. Then I realised that some tweaking was required to let the game engine distinguish "you're dead. try again?" from "well done! next level!". That tweaking took the form of a GobExpression attached to the action "level(greenX.cmd)", which compensated the automatic "level++" incrementation I added in the game script.

In that setting, it should have been fairly simple to "code" the game over. When the hitpoints counter reach zero, it automatically executes the action "level(greenX.cmd)" and evaluate the expression "level--" to restore balance in the world. Unfortunately, I coded that a bit timidly by evaluating the expression first, and launching the new level next. The side effect is that when I replaced "level--" by "level--; lives--", the effect of 'lives reached zero. Game over. launch level0' were immediately undone by the setNextLevel("greenX.cmd") that took place afterwards. Although that looks odd, I am allowed to swap them to get it fixed, as the "setNextLevel" just stores the level's name and the actual world destruction / loading / re-creation cycle is deferred and happens between regular "game frames".

Pretty neat, uh ? no matter how many GOBs try to trigger world termination : they won't testimony it anyway because it happens out of their timespace. It's just a pity I couldn't get this sorted out last Saturday (I should have typed "cvs commit" before I powered down that workstation for the week-end) and I only know how my alpha-tester reacts in face of an endless challenge.


En réalité, exécuter setNextLevel() en premier est correct parce qu'il s'agit d'une opération qui se déclenche à retardement. Pour raisons techniques, il n'est pas possible de changer de niveau (ce qui inclus une destruction de tous les objets en cours pour reconstruire le nouveau niveau à partir du script donné) pendant la phase "animation/détection de collision" qui provoque en cascade l'exécution des actions.

L'important, c'est que le problème est réglé: on peut donc être "game over" dans Apple Assault.

PS: En général, j'évite de m'étendre sur ce genre de graissage d'engrenages, mais peut-être que ça permettra de me l'ancrer un peu plus définitivement dans la caboche. Quelqu'un a une cheville de 8 à me prêter ?

Wednesday, September 09, 2009

Un Bilou tout neuf.

Wait a minute. Look at the date: the guy who posted a news on your forum hasn't dug this blog properly. You might be looking for a more recent demo

Level 2 is merely there to demonstrate we can now have multiple levels.
Voilà. Je vous livre mon travail de vacances: la forêt mystérieuse de Bilou, revue et corrigée. C'est une démo jouable de mon moteur de plate-forme toujours en cours de développement, où vous incarnez Bilou (la balle bleue) et récoltez les pommes pour progresser dans les niveaux. Nouveautés dans la release 0.999:

En cours de jeu, sautez avec X ou Y et dirrigez le personnage (la boule bleue, faut-il le répéter) avec le Dpad. Start passe le jeu en mode pause debugging, L+START revient au mode normal.

The sign points to the left: you haven't collected enough apples to access the second half of the level.
Here comes at last the new playable demonstration of my game engine on the Nintendo DS and a two-level game featuring Bilou, my blue and round mascot. Dodge angry applemans, avoid getting stomped by the funky funghis and collect enough apples to pass through the tree-with-a-sign (see picture on the left). You move Bilou (the blue hero) with the Dpad and jump with X or Y. Only yellow Woodworms can be stomped for now. In this new release:
  • sound & music by Pierrick H thanks to 0xtob's libntxm,
  • ease-of-use thanks to Noda's EFS
  • new monsters
  • improved controls
  • one extra (draft) level
  • 5 hitpoints per lives and unlimited lives
  • a few hidden places you needn't to find
  • some more gfx
  • parallax scrolling
yet, this is still work in progress. your comments are welcome on any aspects.

Tuesday, September 08, 2009

Compacting Tilesheet

'faut que je me méfie: j'atteinds de nouveau des taux d'occupation de ma tilesheet assez hauts. Il y a encore de la place (les bilous de la tilesheet peuvent être remplacés), mais j'aimerais autant éviter le genre de problème que j'ai eu dans le passé.

Et une solution pour ça consisterait à pouvoir réutiliser le même tile dans plusieurs blocs. C'est clairement un atout dans les blocs de terre, qui commencent à devenir fort nombreux. J'ai déjà des algorithmes pour ça sur le PC (en PERL), reste à voir si je parviendrais à les transposer en C++ sur la DS... Si c'est le cas, je descendrais de près de 1000 tiles à 666. Pas trop mal.

(PS: oui, je sais, c'est crapuleux de redimensionner une image comme ça. C'est pour ne pas gâcher la découverte des améliorations)

I'm done with the behaviour of appleman for now. It isn't perfect yet, and he can't be defeated, but it will do the trick for the next milestone. So i've started packaging all this into a new gedsdemo.nds, a job that has been greatly simplified with the addition of Noda's EFS library (when i don't forget to patch the .nds i produce :P) i still have to make sure the background music (and SFX) are properly loaded, and fix things here and there on the maps, but the last 5% shouldn't account for too much work.

Mais le "packaging" progresse bien. Du moins j'ai une première approximation pour faire des snapshots. Je la joue "ambitieux", mais je vais tenter d'ajouter le petit mod de Pierrick, cette foi-ci. Il y a encore du boulot pour arranger les maps et comme d'habitude, je me bagarre avec l'EFS de Noda. Je te parie que j'ai oublié de patcher le .nds, tiens.

Pour simplifier, j'oublie régulièrement un élément ici ou là, et je modifies les sources sans les mains pendant que je berce ma p'tite puce.

Friday, September 04, 2009

95% done.

J'ai repris ma petite todo-liste que j'avais fait après la release de ma dernière démo pour cocher les derniers développements. Bonne nouvelle: il ne reste rien à faire.

  • Techniquement, donc, le moteur de jeu est prêt pour la prochaine petite démo.
  • Artistiquement, je voudrais encore améliorer un peu le feuillage des arbres.
  • Niveau gameplay, je dois finir le comportement de l'appleman et rendre visible la sortie du niveau 1, histoire que vous puissiez essayer le niveau 2 ^_^
Ensuite, il sera franchement temps que je me remette au boulot sur l'éditeur de niveaux. Il est à la traine, le pauvre, avec des "fix" qui attendent depuis ... houu ... un an ?

Right after I released my the last demo, I came up with a little todo-list of things to be done before a new demo was worth to get out. Good news: they're all flagged as "done" right now. I still have non-technical things to finish, such as the trees' art or Appleman and BerryBat's behaviour. Then I'll have to ensure levels are playable and contain no "dead ends". It is just a matter of day before you see "grab-the-apples-and-find-the-exit-2.0-new-and-improved" (aka. gedsdemo). Some packaging will have to be done, as usual: i guess you don't want to bother with installing small files all over the place, or tap "B A R R Y L" to see the game starting so I actually build a separate binary that shares the game engine library.
The next goal: improve the level editor. The poor thing is waiting for an update for roughly one year now. It's getting too easy to screw up a level and too hard to fix the same level.


Bon, comme d'habitude, il y aura aussi un peu de "packaging" à faire: reprendre le moteur de jeu, les graphismes, la musique, tout ça, et l'intégrer dans un petit .nds prêt à la distribution. Avec l'EFS de Noda, ça devrait passer sans trop de problèmes.

Sunday, August 30, 2009

première photo du niveau 2 ...

appleman-photo Bon, on ne s'emballe pas : j'ai encore un paquet d'écrans à compléter dans ce niveau-là. Mais ça prend forme. Je teste des passages vicieux avec les Funky Funghi, etc.

J'essayais donc ce matin d'avancer un peu sur le comportement de l'appleman, et en particulier le faire "stresser" lorsqu'il aperçoit Bilou (une sorte de première phase d'attaque). J'ai donc ajouté une petite zone "déclencheuse de pièges" (cf. système de gestion des collisions) à Bilou (que je pourrais éventuellement désactiver lorsque Bilou a obtenu un bonus 'mode furtif'), et j'ajoutais une zone sensible à l'appleman. Bin pas de chance : ça n'a pas marché. J'avais oublié que si la zone active dans un test peut être plus grande que le personnage, il n'y aura vérification des zones passives que si l'objet lui-même est en contact. En d'autres termes, les zones passives sont toujours plus petites que les objets qu'elles recouvrent.

While I'm working on the improved behaviour of the Appleman, i have been tricked by the asymmetric nature of collisions in my own engine. While the *active* collision area can be larger than its own sprite, the *passive* area (that 'recieves' the collision, somehow) is inherently restricted by the bounding box of its sprite, meaning that the Appleman has to be active into detecting Bilou around (not the other way round). It requires a little more code to attach actions there that I'll write down as soon as we have sleep == (*deline && !me). I could also introduce a new kind of controller that simply fires an event when the player enters a given area, but for rectangular checks, it would just be useless work.
Alors on pourrait se dire "bah, il n'y a qu'à inverser" ... Le code n'était pas prêt pour ça, mais vous avez parfaitement raison. Alors cliquez sur un lien quelque-part pour continuer à lire, parce que moi ... bin Yaka.

Thursday, August 13, 2009

bilou.cmd

Ca y est. Une petite classe abstraite "InputReader", deux sous-classes BufferReader et FileReader et un peu de bricolage, et je peux ranger tous les éléments relatifs à un personnage dans un fichier séparé, inclus depuis le "script-maître" du niveau.

Ca fait plus propre ... je suis prêt à rajouter des niveaux dans tous les sens.
Mais j'ai aussi pas mal de fonctionnalités à béta-tester:

  • [done] composition de contrôleurs
  • [now][done] gobs dynamiques (tirs, étoiles-bobo, etc) et état "nil" pour les détruire, qui utiliseraient de nouveau un mécanisme de liste auto-itérée pour leur gestion
  • [done] utilisation d'actions externes dans les expressions de la machine d'état
Three tiny classes added, a few edits, and i can finally store everything related to Bilou in bilou.cmd, the bouncy logic of Funky Funghi in funghi.cmd, etc. Those files are then 'included' from the level script, and can thus be reused in as many levels as one wishes. Hooray. That's a major step towards a multi-level game, despite the actual coding is still a bit crude (e.g. you can't #include with blocks, and you *must* have 'end' statement in every file, including included files).

Am i going to do a release right now ?
Or am i going to toy a bit with chained controllers (useful for the appleman), dynamic Game OBjects (useful for shots and the like) and external actions invoked from the state machines (useful for sound effects) ?

Monday, August 10, 2009

loading ... please wait

howdy. I can now load and run level 2 when Bilou reaches "the end" of level 1. This brings me one step closer to my "grab-the-apples" milestone game. The only poor thing remaining is that you'll end up with the script code for Bilou, the bonuses, the monsters, etc. duplicated in every ".cmd" level script.
I'm in need for an "include" statement in those gamescripts, but once again, nothing had foreseen that your level would need pre-processing (or that you'd change the source of data while parsing the script). Some more design effort will be needed.

Bien. Je peux charger et jouer le niveau 2 quand Bilou atteind la fin du niveau 1. On se rapproche de l'objectif "petit jeu tout simple où on ramasse les pommes pour atteindre la sortie". Il reste un couac avant une release: la définition de Bilou, des monstres, etc. doit être répétée dans chaque script ".cmd". Il me faudrait une petite commande "include" que je n'avais pas anticipée . . .

(PS: l'illustration vient d'un t-shirt ThinkGeek, bien sûr. Il n'y a qu'eux pour en faire des comme ça ;)

Tuesday, August 04, 2009

Try Again ...

La bonne nouvelle, c'est que j'ai enfin un mécanisme me permettant de recharger un niveau quand Bilou s'est pris trop de coup. La mauvaise, c'est qu'à recommencer 20 fois le même niveau, je finis par mettre en évidence des fuites de mémoire dans mon code.
Il est temps de reprendre le code de mon prototype de manière un peu plus rigoureuse, de passer en revue mes classes en suivant les bons conseils++ d'Axel. Jusqu'à 300K qui partent en fumée à chaque vie, ça coûte vite cher sur une machine qui n'a que 4MB.

Good news first: I can at last reload a level when Bilou has been hit too much. The downside is, that this highlight a memory leak in my game engine. Most likely some machine state isn't properly reclaimed. It's time to print my code and read it back with a mop in hand ...

  • double invocation of GameScript ctor on reload : >280 K goes away
  • not taking care of transitions when cleaning the state machine : 5K
  • not taking care of cleaning "guns" : neglectible right now
  • other (under inspection) lost things : 5K
  • not taking care of OAMs allocation over iterations : invisible sprites after ~16 attempts
edit: fixing a stupid and obvious bug reduce the leak from 300K per live to 10K per live. Below comes the checkram() function i'm using to count available memory (that simply allocate as much as possible, then releases everything). Just refrain yourself from using std::whatever to store allocated chunks if you don't want to see a bad_alloc exception thrown in the middle of the process.

int checkram() {
int total=0;
iprintf("grabbing ...");
void **chunks=0;
void **chunk=0, **prev=0;

for (int chunksize = 1024*1024; chunksize>32; chunksize=chunksize/2) {
int n=0;
while((chunk=(void**)malloc(chunksize))) {
*chunk=(void*) prev;
chunks=chunk;
n++;
total+=chunksize;
prev=chunk;
}
iprintf("%i,",n);
}

iprintf("releasing ...");
while(chunks) {
void **chunk=chunks;
chunks=(void**) *chunk;
free(chunk);
}
return total;
}
Bien sûr, une telle fonction est une dépense de resources matérielles inutile si l'on connaît suffisamment l'implémentation de malloc dans l'environnement précis où l'on développe. En l'occurence, ludo connaît une méthode bien plus efficace et élégante pour libnds. And ludo's sources come from this gbadev post