Sunday, October 28, 2018

Petit test de TomDroïd

Parce que oui, Tomboy, mon outil de post-its virtuels a références croisées existe pour Androïd et même tourne sur ma tablette e-Ink "onyx boox". C'est une version Beta (>_<) et open-source (^_^) mais pas encore vraiment utilisable à l'heure actuelle.

- parce que saisir des WikiWords avec un système de reconnaissance d'écriture manuscrite qui pense que "Une phrase commence par une majuscule et se termine par un point.", c'est pas top
- parce que modifier un wikiword pour en faire un WikiWord avec un stylet, c'est très moyennement précis
- parce que de toutes façons, il ne suffit pas d'avoir un WikiWord inconnu pour qu'en cliquant dessus on puisse faire une nouvelle note sur ce sujet (contrairement à Tomboy)
- parce que de temps en temps, l'application se dit que ce serait bien de faire une sauvegarde de secours de la note en cours d'édition et qu'elle me renvoie du coup au début de la note. En plus de quoi, le système de reconnaissance de google me sucre les traîts tracés pendant la sauvegarde en question >_<

Donc bravo à ceux qui ont travaillé là-dessus, ne vous étonnez pas si je consomme quelques soirées à m'installer un devkit Androïd quand-même, hein ;)

Saturday, October 27, 2018

1 heure par jour

C'est en gros le temps que je peux encore consacrer au développement homebrew ces temps-ci, avec les déplacements supplémentaires pour les activités des enfants et l'entretien minimum de la maison. Une heure ou je réouvre mon vieux laptop "grizzly" de 2007 qui surchauffe et s'éteint quand on regarde plus de 15 minutes de vidéo youtube en plein écran, qui a besoin d'être sur secteur à chaque cycle d'horloge mais qui offre le confort d'un écran 1680x1050 et d'un clavier avec le bloc "insert/home/pgup/del/end/pgdn" identique à un clavier classique qui s'est révélé plus important qu'un pad numérique.

Une heure par jour pour ajouter une petite brique par-ci par-là. Ou pour constater que ce que j'ai planifié à coup de tablette-à-encre-électronique pendant les creux où j'attends qu'*deline ait fini ses activités ne va pas se combiner avec les autres composants.

Si j'essaie d'ajouter une demie-heure supplémentaire par-derrière pour blogger des micro-succès, je ne tiens pas la distance...

A l'unif, je prenais facilement une demie-heure sur mon temps de midi pour essayer un truc ou l'autre, entre autres grâce à la connexion SSH quasi-automatique entre le PC du bureau et celui à la maison. Mais je faisais régulièrement les trajets en basket+bus, voire à vélo. Avec les loupiots à déposer, je ne marche quasiment plus dehors en semaine à moins de le faire sur le temps de midi. Et moi, si je ne marche pas, je disjoncte. Donc je marche. Tant pis pour les lignes de code homebrew que j'aurais pu mettre (ou les traductions de post) pendant ce moment-là.

Thursday, October 25, 2018

stop using %i!

Hey me-from-the-past. Here is you-from-the-future. Stop using %i. I know you're used to it because your re-implementation of printf for your own x86 microkernel had only %i for printing numbers instead of the standard %d. I know as well that even in my world, printing %d and printing %i produces the same result, but listen, here's the catch:

scanning for %i enables automated base conversion while scanning for %d guarantees digits are interpreted as decimal numbers and nothing else. You don't want "${width}x${height}" to fail being recognized by "%ix%i" just because it looks so much like a single hex number as soon as width is null, right ?

right.

So stay safe, and stop using it.

GameScript vs. Hud

The HUD is a bit special in libgeds in that the engine doesn't know what it is, nor what it does. All it knows is how to pass it informations, more in the LUA spirit (afaik).

so when you type

  • hud.load "somefile.spr"
noone ever checks that there is a file. All it does it passing that string untouched (*) to some iHud::showScreen() function. 'hud.show' works similarly, and simply change one boolean argument so that the iHud-derived class knows it should make the picture visible immediately.

The other kind of command,
  • hud.mode=menu
 Will just be recording the first letter ('m') and make that available when the parsing is over through a call to iHud::setup(). The engine doesn't even know how to build such a iHud-derived object: instead it receives it from the rest of the program.

 So the HUD is something that the advanced programmer sets up and that can interprete freely that string that is meant to be a filename. In other words, rather than hacking "let's show the score" when the 'show now' bit was passed, we could have a more explicit
  • hud.show "chapter2.spr" // only while loading
  • hud.show "+score"
  • // all the level setup goes here
  • hud.show "-score"
  • hud.load "hud-basic.spr" // what goes on the bottom screen during one level.
 (*) Well, not exactly untouched. It actually prepends some stuff to make it an absolute path. Like "efs:/" or so. I'll have to work that out.

Monday, October 22, 2018

Showing the score

If I want to have a "leader board" shown in the game won / game over screens, it would be nice too if the player can have a look at her performance. My idea is that you're evaluated either on the distance you covered (when game over) or on the time you took to beat the game (when congratulated). A good time to report that to the player is when we're loading the level, but by then the screen settings are fairly locked.

It looks however, that if I hack the 'window control register' WIN_OUT while we're updating the picture shown on the bottom screen, I could use sprites on the top screen to render some digits without messing up with the scene setup. That's only part of the solution (I'll also need some tiles with digits, which I haven't in the sprites tileset atm), but it's better than nothing.

And it looks like I should be able to use the last 16 tiles of the spriteset to put some 8x8 digits font... We'll see that some tomorrow.

Tuesday, October 16, 2018

Final Scene

Immense pardon d'avance à tous les développeurs de jeux que j'ai terminés (pas si nombreux que ça, donc) et dont la séquence de fin m'a déçu. J'en suis à l'étape de faire la séquence de fin et je dois reconnaître que c'est extrêmement difficile de contourner les limites techniques pour parvenir à faire passer quelque-chose qui ressemble à l'idée que je m'étais faite de la séquence de fin qui soit fun pour le joueur sans devenir un casse-tête complet.

Donc, oui, il était prévu d'avoir un "centre de rééducations des gommes" où Pr. Gommaster moustachu leur montre qu'il faut se défendre des crayons, mais que Bilou est "un gentil", avec des gommes-élèves qui sont plus où moins attentives selon que le joueur a assommé plus ou moins de taille-crayons pendant son parcours. Et non, je n'essaie plus de faire rentrer ça dans ma "spritesheet" devenue trop étroite et le gobscript qui atteint ses limites en terme de maintenabilité.

Et évidemment, le blog n'aide plus vraiment à rester motivé pour terminer ça parce que 1) on est plus en 2006 et mes lecteurs sont nettements moins assidûs et 2) j'aimerais que ça reste une surprise, donc je ne peux pas vraiment faire du teasing avec les images.

13/10: une p'tite idée gribouillée sur papier pour l'écran "game over": un pendat arrive par le côté et pousse Bilou assomé dans un trou. Les lettres "G" et "O" de gameover se décrochent et viennent se placer pour faire le "GO" de l'écran titre. Retour à l'écran-titre.
14/10: bonne idée pour intégrer les derniers crédits et l'enregistrement des scores
15/10: mise au point d'un des derniers éléments interactifs qui sera quand-même dans la séquence de fin
16/10: nouvelle tentative pour la map correspondante (2x1 écrans). Peut-être un peu trop dense, par contre. La présentation de "Verso" y est simplifiée à l'extrême par rapport à l'idée de départ.
17/10: ajustements des compteur
18/10: soirée chargée IRL, mais j'ai quand-même trouvé 1/2h pour corriger les compteurs 
19/10: ça marche. J'ai du bricoler avec les propriétés de collisions pour pouvoir faire disparaître les reconstitués, mais ça y est. Je peux le mettre comme niveau après le niveau "secret". Aucune idée de la piste sonore choisie ... et toujours pas d'écran inférieur, par contre.
20/10: vidage de garage
21/10: Ultime Décathlon 6 -- tournoi de la dernière chance (oui, je sais, là aussi j'ai du retard).

Et il est temps de conclure, parce que

http://sylvainhb.blogspot.com/2015/03/il-faut-que-je-finisse-school-rush.html
http://sylvainhb.blogspot.com/2017/10/finishing-steps-for-school-rush.html
...

Et please, dites-moi que j'ai corrigé l'écran bleu dans la branche "démo", parce que sortir ddd et faire des backtrace juste pour connaître la ligne de script fautive ... bof.

Monday, October 15, 2018

Bug Punch

I have one last bug (hopefully) to fix in School Rush: with the latest builds, there is an unexpected additional Bilou head showing in addition to the big punch, and stays until the “shot sprite” takes over the regular animation..

Doing some more testing, it appears that the latest unaffected build is last year’s “xmas” release. It could be something that went wrong with the refactoring, or it could be an accidental modification of the site sheet itself.

Ce n'est pas si inhabituel de voir des têtes de Bilou partout, quand mon moteur de jeu buggue, et il a remis ça. La release-de-Noël est la dernière à ne pas en soufrir. Erreur de refactoring ? modification accidentelle de la spritesheet ? A moins que ça ne soit lié à la manière dont je gère les sprites "invisibles". Il faudra vraiment que je me rajoute une commande pour ça dans les animations.

A look at the source shows that I implemented an “invisible” sprite by not picking any sprite until the 6th frame. This isn’t clean and chances are that I was exploiting some undefined behaviour. I should definitely have a dedicated command that hides the sprite through the animation that works whatever the contents of the sprite page.

Well at last, in the refactored code, there is a clean INVALID_BLOCKNO value that is set to the frame number as the GOB is created. All I need now is to make sure the sprite remains hidden until we give it another value.

edit: likely the root cause is that I just used unassigned page entry to have a transparent image. Of course, if I accidentally add an image to that page, things that once were transparent might no longer be transparent.

Thursday, October 11, 2018

Amy Zing

It only took Ant a few days to include my little "Amy Zing" sprites into his neat labyrinth crawler homebrew, actually. For some reason, I completely missed it by then (March '18) and only realised that the game was released thanks to some anonymous internet folk who followed a link from simian zombie web site to mine, leaving a mark into the logging system which I tracked backwards to hit the page with the release.

So I grabbed the game, enjoyed it, enjoyed again, tried the various resolutions (normal is my favourite one) and smiled: that was my first ever homebrew collab as a spriter ^_^. And then started to wonder... Could such simple labyrinths work for Bilou, under gravity ?

I traced some of them in a notebook and started to check where I would put collectibles or hazards and why. In a platformer, you shouldn't (imho) try to make your labyrinth with individual blocks, because the player will need some room to manoeuver. If I pick 4x3 Bilou-sized blocks as a "maze cell" (3 blocks being a standard jump height), the maze now scrolls over 4x3 screens. You can no longer plan your move easily with that limited visibility, so you'll end up more often in dead ends and will have to back-track. Hence the rewards and hazards.

And well, Imho, with properly tuned jump distances and some wall-kick mechanics, you might not even need fancy ladders or similar tricks to support those labyrinths.

That's not quite "infinite pyramid", but it could be a nice step towards it.

edit: good news: my 5-year-old J.L.N wasn't afraid of the half-dead monkey and accepted the maze game as something to do when he's bored.

Monday, October 08, 2018

Trotôptimiser

Je voulais faire une pyramides de taille-crayons. Quelque-chose de fun, original et un peu inattendu pour récompenser les joueurs persévérant. Mais voilà. ça veut dire beaucoup de sprites ... beaucoup de collisions ... alors est-ce que le moteur de jeu va le supporter. J'ai passé déjà quelques après-midi et cogiter la chose.

Basculer entre tiles et sprites, peut-être ? ou simplement entre une version mono-sprite du taille-crayon assomé et une version trois-sprites comme celle utilisée dans le reste du jeu ? Oui, parce que les pieds de taille-crayon sont animés avec des sprites séparés histoire de pouvoir faire plus d'étape d'animations avec le même nombre de pixels, mais le moteur de jeu ne supporte pas qu'un objet existant doive acquérir ou libérer des sprites hardware au fil de son existence. Quand le taille-crayon est assommé, ses pieds sont cachés par-derrière lui alors que deux nouveaux objets d'un seul sprite sont créés pour les pieds projetés au loin.

J'aurais donc pu faire ma pyramide avec des tailles-crayons-d'un-seul-sprite. ça m'aurait permis d'en faire tenir jusqu'à trois fois plus à l'écran. Sauf que quand Bilou transporte un taille crayon, les pieds-cachés deviennent les mains de Bilou tandis que les sprites hardware de Bilou sont temporairement désactivés. Ce n'est donc pas quand le taille-crayon reprend ses pieds qu'il faudrait passer (en détruisant un objet pour en reconstruire un autre) à 3 sprites hardware, mais bien quand on ramasse le taille-crayon pour la première fois.

Oui mais et si le joueur réempile les taille-crayons ailleurs, alors ? on va se retrouver avec le même nombre d'objets mais cette fois à 3 sprites ? ça va mal finir ça.

Heureusement, un premier test montre qu'on tient toujours les 60 images secondes avec une trentaine de taille-crayons à l'écran rien qu'avec l'objet de base, tel qu'il intervient dans le jeu. Même les empilements ne posent pas de soucis, sans doute parce qu'en réalités, ils ne sont pas gérés comme des collisions.

A la place, c'est le mécanisme de plate-forme mobile qui entre en jeu, dans lequel on se contente de vérifier la relation avec l'objet auquel on s'était attaché précédemment. Les collisions proprement dites (nécessitant de comparer chacun des taille-crayons avec chacun des ennemis) n'aura lieu que depuis les tailles crayons qui tombent.

Je m'inquiétais donc pour rien. Par contre en en profitant pour mettre un générateur de pieds-baladeurs dans le niveau, J'ai compté jusqu'à 28 pieds générés sans que l'émulateur ne tombe sous les 55fps (la DS serait donc probablement toujours à 60), mais par contre après ça, il y a trop d'objets à gérer et certains d'entre eux ne sont tout simplement plus affichés (un bug bien connu du moteur de jeu actuel, contre lequel il n'y a pas grand chose à faire à part éviter d'en arriver là par le level design). Bon à savoir je calibrerai mes générateurs de pieds en conséquence, un peu comme j'avais fait avec les générateurs d'applemen dans Apple Assault.

edit: une jolie pile d'une 30aine de taille-crayons, un personnage de chaque autre type et quelques pieds baladeurs ... ça tient toujours.