lundi, février 29, 2016

Catch that!

Not so long ago, I was regretting that HandMade Hero was just giving debugging hints for weeks instead of talking of game engine and game design ... And I haven't posted myself anything about developing games but fixing and debugging since then. Hear this, fellow game developer. At some point, either you'll dig deep into debugging or you'll have to trash your project and move to another project, possibly from scratch.

Désolé pour ceux qui aiment les articles sur le dévelopement de jeu proprement dit. À ce stade-ci, soit je m'accroche et je continue à nettoyer le code malgré les difficultés techniques, soit je laisse tomber l'idée d'avoir un School Rush fiable. La bonne nouvelle c'est que peu à peu, les choses mystérieuses perdent de leur mystère et je progresse vers quelque-chose de mieux compris et mieux contrôlé.

Par exemple, si on lance une exception depuis un destructeur appelé lui-même suite au déclenchement d'une autre exception, la bibliothèque libstdc++ jette le gant et met fin au programme sans autre forme de procès.

Allez, soyez encore un peu patients. Je suis certains que vous trouverez que ça vaudra la peine d'avoir le niveau suivant chargé en moins de 2 secondes plutôt que d'attendre 20 secondes ou plus entre chaque essai.

how could we have terminate called ? 
Something was driving me nuts in those debugging/testing attempts: I couldn't get any exception properly reported, but instead the program terminated with the exception reaching top-level.
Of course, I asked for help on Stack Overflow, but the question got closed as noone could reproduce anything.


So here is how C++ could easily fail to catch your exception, and you know it happens when you see "terminate called recursively".  Don't let that "terminate called after throwing an instance of std::runtime_error (or whatever exception you've thrown) fool you. During stack unwinding, all destructors are invoked. If any of these try to throw an exception while unwinding the stack, we'll find ourselves into a recursive-terminate condition.


Oh, maybe you have the right to throw an exception and catch it before it leaves the stack frame of the destructor, but if the destructor-originated exception escape the exception-originated destructor call, then the exception management runtime apparently gives up and terminate the program.

mercredi, février 24, 2016

releasable

Here we are. I got something that can be released. I got bugs fixed to a point that the new codebase can be played for some time without crashing. The thing is, I completely lost track of what are the improvement since the last one.

I beleive there is hanging-to-spongebops, double-B to punch baddies vs. Single-B that always picks up. There is throw-in-all-directions (well, almost all directions). There are droplets.
I'm afraid you'll start the game at the end of the last level ... but that's not that an issue, since you'll resume the game at level 1 as soon as you found how to trigger the end of the level. Let's say it will be sort of a live test.

Here you are: SchoolRush-Medit8.zip

I hope I'll be able to have fast level-reload in the next release.


Pfiouh. Je crois bien que j'ai à nouveau une version qui tourne. ça a été tellement laborieux que je ne sais même plus ce qu'il y a de nouveau.

vendredi, février 12, 2016

Still Hammering Bugs.

En combinant les tests automatique, la guru-meditation sur base d'écran bleus interactifs et le debugging à l'aide de DDD sur émulateur, j'ai fini par régler les différents problèmes liés au changement de type de gestion de mémoire concernant les machines d'état. Mais si, souvenez-vous, cet ensemble de règles qui indiquent au jeu comment le comportement des différents personnages évoluent au cours du temps.

J'ai donc à nouveau un chargement correct du niveau, y compris sur la vraie console, et j'ai réparé mon moteur de collision qui avait souffert du mécanisme de "verouillage" de cette machine d'état à la fin du traitement des scripts. Tout ça entrecoupé de parties de "Mario & Luigi : Dream Team" que ma fée a été chercher pour moi à la médiathèque ♥

All debugging tools have been used, so that I finally restored level parsing and collision system. The core difficulty has been to correctly manage the 'freeze()' calls used to drop malloc-driven stdlib objects used during parsing and coerce e.g. std::vectors into arrays that can safely be stored in the "memory tank" (essentially chained bottom-up allocators) for safer management while we're in-game. 

I cannot call it really "repaired" yet, though. 
  • There is something clearly wrong with the music-track followers that fire actions at specified moments in music (TrackSequence), and that are heavily used during level changes. I'll need dedicated tests that focus on the checking that this components performs as expected.  
  • I would also like to perform more systematic testing on the state/areas parsing by generating arbitrary -- but known -- code chunks that can be fed to the parser so that data structure inspection can later indicate whether the proper objects were created.

Il faudra d'ailleurs que je vous parle du système des badges, une alternative intéressante aux
objets de soin puisqu'ils peuvent être utilisés en plus d'une autre action dans son tour. Il faudra aussi que je vous parle de la manière dont les effets 3D ont été utilisés dans les combats pour dynamiser un peu les rencontres contre les boss qui font courir les frère Mario pendant leur attaques. Et des "pantalons d'expert" qui proposent un nouveau moyen de récompenser le joueur en lui permettant d'acquérir dès le début du jeu de l'équippement dont l'efficacité augmente ... avec le nombre de défis (une variante des achievement) qu'il a réussi à relever.

vendredi, février 05, 2016

Tests passed, Guru still meditating.

It's a bit disappointing: I set up an environment to stress-test the code, make sure uninitialized memory has garbage content, etc, and everything runs fine. I use the same code in SchoolTest (rush) application on real hardware and it crash before starting to run the title screen. What else could I do but add the "memory inspector" mode of the Guru Meditation screen in the game ?

Pff. Râlant. J'ai fait des cas de tests, j'ai émulé, j'ai fait des corrections, j'ai vérifié mon "build system". Tout semble bon, mais quand je fais tourner le vrai code sur la vraie DS, j'ai toujours un gros crash vers la fin du chargement de l'écran de titre. Il ne me reste donc qu'à reprendre le code d'inspection de mémoire hors de runme et l'ajouter dans le jeu pour repasser en mode "débugging post-mortem"...

Edit: Grâce à l'inspection libre de la mémoire de myGuruHandler(), j'ai pu reconstruire les différents groupes de paramètres des fonctions qui ont appelé un "free()"  là où il n'aurait pas dû, corrigé le système de tests pour qu'il vérifie le "tag magique" inséré par malloc(). Jubilation: le jeu lance maintenant son écran-titre.
Déception: dès le premier contact spécial avec un autre personnage, le moteur de jeu se re-plante.