Monday, August 21, 2017

End of Cybook ?

After about 5 years of helpful operation, my e-ink device "cybook odyssey" seems to be definitely damaged. I cannot do more than a few minutes of reading before getting the system to reset. Sometimes even just clicking a link or trying to change the font size will jam the device. I tried a factory settings restore, but that only help for a few minutes.

And now the "gadget" class of the device really shows up. I have no logs that could point out the flaw, no way to access the critical components (namely the internal flash). The device as a whole will have to be recycled just because one component is weared out.


Mon Cybook me lache à nouveau. Trois ans après son passage en service-après-vente, mais sans espoir d'intervention de garantie, cette fois-ci. Me le réparerait-on de nouveau ? Peut-être. Est-ce que j'ai envie d'injecter encore de l'énergie dans un appareil que je ne peux empêcher de vieillir ? Pas franchement. Est-ce qu'il y a mieux à acheter ? Peut-être si je suis prêt à lâcher 300€ pour un modèle Androïd-à-encre-électronique.

So what ? Shall I replace it with another one, with slightly increased screen resolution, take advantage that I know the beast, including the annoying amount of time it takes to accurately select a phrase to highlight it (and risk having issues with memory again within a few years) ? Shall I pay up to 3 times the price for a device with stylus, android (including the ability to program my own tools on it), bluetooth, but unfortunately not the version of Android required to run the infamous "inkspace" application required for my bamboo spark ?

There is even 13" models, but they seem to be sold near 700$, not the 400$ I spot on alibaba. The same company makes 9" devices too, claimed to be half the price (which gets into the "expensive but affordable" category). Maybe I should wait for a few weeks and see whether that "ReMarkable" thing actually ships this august and at what price ?

None of these could be found in stores so far, but I had a look at a Kobo Aura One this afternoon, and it was quite sexy, with its all-flat front side. No stylus and no android (afaik), though.

Saturday, August 19, 2017

Les autres pentes

Du point de vue du moteur de jeu, un niveau est avant tout une grille dont chaque case reçoit des propriétés: solide, solide uniquement quand on tombe, pente, spécial, etc.

(note to English reader: the handwritten text on the pictures is part of the post's text this time).

... A grid, with tiles telling "solid" or "sloped", or "jump through, but don't fall". And sometimes just "special block".


Les "blocs spéciaux" ne sont pas compris par le moteur de jeu lui-même (d'où leur caractère "spécial") mais décrits dans les scripts qui définissent les règles du jeu.

Ainsi, quand Bilou touche par exemple un Bonus, le moteur de jeu récupère quelques bits d'information pour chaque pavé (8x8) de la grille constituant le bloc (16x16) et reconstruit un numéro de bloc spécial (de 0 à 255) qui permettra de retrouver les instructions à exécuter (faire un son, déclencher une animation, donner des points, etc.)

... each "special block" tile provide two bits that are combined to define the "block number" used to retrieve collision properties, hit box and script expression that makes a bonus play a sound and spikes hurt Bilou. The game engine itself, to some extent, doesn't know anything about the special blocks except how to delegate block/object collisions to the appropriate script sections.

Quand Bilou touche une pente, en revanche, le moteur de jeu sait qu'il doit aller regarder une petite table indiquant la hauteur de chaque pixel de la pente. A priori, la forme de cette pente pourrait être n'importe quoi. Mon éditeur de niveau connaît les pentes à 45° et à 22.5°

The height array tells how high is each pixel in the tile. The game engine knows very well what to do, this time. Some tuning could provide an alternate height array to support a different kind of slope, but I haven't used that so far in the game.


Mais voilà: j'aimerais pouvoir avoir plus de souplesse: des escaliers, des coudes, par exemple. Un petit schéma de rien du tout qui traîne depuis des années (2010?) sur un bloc de brouillon en atteste.
"Le mieux serait d'avoir deux boutons 'pente' [dans l'éditeur de sprites] qui forcent le remplissage d'une ligne de 64x16 pixels avec des pentes suivies (les modèles)"
 ajoute encore le calepin.

That "sprite editor / stripe of sloped tiles" approach hangs around in draft mode for years. Because each tile has a unique address in video memory, I had plan to use that address to extend "advanced slope-to-the-right" into "start-of-slope, 0° to 22°". The issue is that the Sprite Editor has no real control of which blocks goes where in memory. Just filling a row of the tile sheet with slope patterns doesn't guarantee that the corresponding tiles will all receive consecutive (and not even aligned either) numbers in the tile set. The solution was in realising that the Level Editor is the component that should solve the more-slope-types problem.

En effet, la technique que j'envisageais alors consistait à utiliser comme information supplémentaire la position du graphisme au sein d'une ligne de blocs dans l'éditeur de niveau (une "tranche" de 16 pavés de 8x8 successifs). On pourra alors convertir l'information de la grille "pente compliquée vers la droite" en "transition douce de 0° à 22°" parce qu'on est dans le 6eme pavé sur une tranche de 16.

Sur les dernières années, ça n'a jamais été mis en service et mes derniers tours d'horizon dans le code de l'éditeur de Sprites me confirme que travailler "par tranche de 16 pavés" serait un vrai casse-tête (le mode et le moment de l'allocation des pavés dans la mémoire vidéo n'étant absolument pas prévu pour ça).

Et cet été vient une idée qui jette un autre éclairage sur ce problème: "Les pentes douces, c'est un problème pour l'éditeur de niveaux. Ce n'est pas quelque-chose à régler dans l'éditeur graphique.

Et l'éditeur de niveau sait par contre traiter des groupes de chiffres pour montrer qu'un bloc spécial est soit un bonus, soit des pics, etc. En prenant donc un type de pavé qui dit "pente compliquée, regardez les chiffres en-dessous pour en savoir plus", je peux diriger le moteur de jeu vers une autre table de hauteurs qui définit la pente (parmi 16 pentes possibles), mais aussi éventuellement fixer le coefficient de friction (sol dur, glissant, boue-qui-ralentit, etc.)

"Special Slope" type merges the behaviour of "sloped tile" and "special block": it will have less bits available to encode the type of slope (e.g. "only" 16 possible slopes), it will require collaboration of multiple tiles, but instead of creating a BlockArea and trying to match collisions, it will just provide an alternate height arrays.

Il me tarde d'essayer ça ^_^




Friday, August 18, 2017

Habillage ...

Il est temps de passer du 'test fonctionnel' à quelque chose de plus "habillé" pour le dernier niveau vertical. Jusqu'ici, je m'étais contenté d'un minimum de graphisme (les blocs-sol) pour vérifier si les sauts étaient possibles. Il est temps de dessiner le reste des objets.

Ouais, sauf que pour avoir des dessus-de-fardes-sur-lesquels-on-marche un peu partout dans le niveau, c'est pas forcément simple. J'avais pensé à des "couches" suggérées par différentes couleurs (il y a déjà une convention dans l'ensemble du jeu du genre farde verte = mur, farde brune/mauve/vert-foncée = plate-forme semi-solide), et faire des structures un peu imbriquées comme avec mes bons-vieux-buissons.

Since April, I've been extending the "vertical, last level" of School Rush with some more platforming challenges. I intentionally kept the look of the level ultra-minimalist for monthes, as it is much easier to tweak the location of the platforms and adjust difficulty that way. I haven't touched the layout of the level in weeks, so I guess it is ready to receive more complete look.

I had plans to fake depth between level elements such as books or binders to justify the presence of so many platforms without having significantly more "ground", although there is some from time to time. And I was also planning to reuse the color conventions present in earlier levels of School Rush, such as "green book = wall, purple book = jump-through platform".

But that was missing the annoying fact that I can change the colors only on the background layer of tiles, while I typically need both background and foreground together to combine small objects into larger structures as I did with the green zone's bushes.


Sauf que pour faire facilement ce genre de choses avec un tileset réduit, je jouais sur les deux plans de tiles, toujours le même pour ce qui est par-devant, l'autre pour tout le reste. Mais mon moteur de jeu ne permet pour l'instant de changer la palette de couleurs que pour les tiles d'arrière plan: les tiles d'avant-plan sont systématiquement "verouillés" sur la palette #0 et les bits correspondants sont utilisés pour encoder le type de bloc.

This is thus one more motivation to change things in the game engine and take the "tiles properties" array out of foreground palette information, but hopefully, I have enough room (~20% left) in my blocks tileset to accommodate for some "combined" tiles, be it at the cost of manual palette retro-fitting.

But I know this cannot be labeled as "the solution" for this problem: It killed the Badman III effort by making the art impossible to manage. Later on, I'll have to address the issue for real.

Bref, pour cette fois-ci, je vais me débrouiller en créant "à la main" des tiles supplémentaires qui "combinent" les deux couches, avec des imports de palette, mais ce ne sera pas beau à regarder dans l'éditeur (parce que le joueur ne devrait pas voir la différence, lui). Décidément, tout cet été pousse vers un déplacement des propriétés du niveau hors des couches de "rendu".

Wednesday, August 02, 2017

On reprend les crayons

(enfin, le porte-mine, plutôt). Les aspects techniques pour avoir une petite image originale au chargement de chaque niveau sont réglés. Je gribouille un peu pour avoir les 4 images qui me plaisent pour raconter l'histoire de School Rush (invasion des crayons-soldats, résistance, déroute et vengeance des soldats en question).

Let's pick up pencils again and draw some 'cutscenes' for SchoolRush to be shown while the level loader is parsing the characters behaviour descriptions again. I had initially planned to recycle those choose-your-difficulty pictures, but the story they're telling shows the pendats defeating the inkjets (comic book's scenario) while I actually need the opposite...

Ce qui s'avère être plus ou moins l'opposé de ce que j'avais prévu de faire raconter au cancrier dans la BD, en fait ... donc il va me falloir encore au moins une dernière image.

Tuesday, July 25, 2017

simplifions le HUD

J'ai attaqué une révision du code de contrôle entre le moteur de jeu et l'affichage de l'écran du livre-magique. J'ai déjà remplacé les tests douteux sur des variables obscures supposés indiquer si on est sur le menu ou dans le jeu par une commande explicite "hud.mode=%c"

The code controlling the HUD logic deseperately needed some refactoring. It smells it has been written with a "oh, come on: this is just testing X and doing Y". As the rules for the game status display became more complex (different pictures for the menu, then custom behaviour for power-ups, then a complete different behaviour for the credits level ...

Je continue avec une simplification des relations entre "GameScript", "GameWindow" (qui s'appelle toujours CmdWindow parce qu'elle s'occupe des fichiers .cmd) et "Hud". Le Script et le HUD sont maintenant créés avant le chargement du niveau, le "setup" qui permet au HUD de savoir quel objet est le héro, où sont les compteurs, le score, etc. se produit explicitement lors du dernier "end"

So I started with making the behaviour of the HUD explicit through hud.mode=xxx in the scripts -- since both menu, credits and game levels are separate scripts. Then I refactored the way the HUD is constructed and linked to the GameScript so that parsing hud.show "xxx.spr" can lead to some Hud::showScreen() although the HUD isn't ready to run its play() function yet (i.e. because it doesn't know the pointer to Bilou's state and to game stats, which will be taught by the GameScript through the Hud::setup() call).

Once again, all this was made possible thanks to doxygen-on-cybook where I could annotate code with refactoring thoughts until I was ready to sketch the desired behaviour as UML. Once this is done, I'm ready to code it in small chunks, one evening at a time.


Enfin, je suis prêt pour un 'hud.show "somefile.spr"' qui me permettra de raconter une petite histoire sur l'écran du bas avec une image différente pour chaque niveau.

Thursday, July 13, 2017

cyblog de retour.

Voilà ... quelques retouches à mon projet "blogpress" puisque je m'étais fait exiler sur le vieux PC bruyant où je l'avais développé. Et j'en extrait un livre de 600 mini-pages avec les posts sur le thème "quel jeu ?"

Bien sympa. En Français exclusivement (puisque je filtre le contenu des balises "<en>" au moment de l'export pour le format .epub), et perfectible:
  • j'approche les 50Mo pour un thème (une dizaine de tags sur le blog)
  • trop d'images dupliquées. Il faudra les identifier (fdupes) et n'en garder qu'une de chaque
  • la construction d'un chapitre par tag est plus intéressante parce qu'elle permet de cibler la lecture (en tout cas pour moi)
  • Tous les liens page-à-page sont pour l'instant perdus (si on clique dessus, la liseuse essaiera d'aller se connecter sur le blog)
Enfin, je serai prêt à affronter les plages et les plaines de jeu ^_^

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"
  • [todo] adapt the picture to show to the level we're in
  • [todo] adapt the position to show to the lives we have (for specific messages)
  • [todo] make it tell the story of the game