Thursday, August 30, 2018

1-ups... At last.

Finally, something good does happen when you collect letters in School Rush. Nothing fancy, and not even anything original, I'm afraid: you just get an extra life. Yet, considering the difficulty of the -final level, this might be welcome.

It required some new tools, though. Lives, hit points and collectibles are managed through counters in the game engine. counters can normally get their value defined only when you parse the level script. Then, you would only increment or decrement the counter as game events occur. Then, you can define one or more actions that happen when the counter reaches zero.


Enfin! Ça vaut enfin la peine de faire la collecte des lettres dans "School Rush". Rien que du très conventionnel, j'en ai peur (on prend une vie supplémentaire), mais bon, vu la difficulté du dernier niveau, quelques vies supplémentaires ne seront sans doute pas de refus. Mais cela ne s'est pas fait sans de nouveaux outils.

When hit points counter gets to zero, for instance, a jingle and a death animation are played. We can even force a domino effect that decreases the "lives" counter then. But that mostly works because I load level" action also allow an expression to be defined, and because you're then allowed to reset the hit points value when reloading the level.

To provide 1-ups, I had to introduce a new elementary action dubbed "setcounters" that offers that freedom out of the level-loading machinery.


Les vies, les points de vie, les objets à récolter, tout cela est géré à travers des compteurs dans mon moteur de jeu. Normalement, on ne sait definir la valeur d'un compteur qu'au chargement du niveau. Durant le niveau, en revanche, on ne sait qu'augmenter ou diminuer la valeur petit à petit.

Le gros intérêt de ces compteurs, c'est qu'on peut forcer l'exécution d'une action lorsqu'ils arrivent à zéro. Comme redémarrer le niveau, changer la musique ou, faire apparaître un nouvel objet. Mais idéalement, ici, il faut surtout augmenter un autre compteur (les vies) et reprogrammer pe compteur arrivé à échéance (le nombre de lettres avant la prochaine vie). Bref, ce sera le rôle de l'action "setcounters", fraîchement ajoutée à la panoplie du parfait programmeur de GobScript.

Tuesday, August 07, 2018

Air Control

Bon, voyons un peu ces histoires de contrôle aérien, maintenant. Je sais qu'il y a des effets que je veux éviter et d'autres auxquels je tiens. Et ce à quoi je tiens par-dessus tout, c'est que le joueur ait la sensation qu'il tombe lorsque la gravité reprend le dessus. Pas question donc que le déplacement horizontal puisse devenir plus rapide que le déplacement vertical si ce n'était pas le cas au moment de commencer à sauter.

It's time to have a closer look at the mid-air player control. There are thing I want to have and others I want to avoid. And among them, my priority is that the player should feel Bilou is falling once the gravity pulls him back. No way the horizontal speed could grow higher than vertical speed, unless it was already the case at the jump impulse. If there is no wind, and if we can fall down for long enough, it shouldn't even be possible: air resistance is the same in all directions!

En fait, en l'absence de vent, et si on peut tomber suffisamment longtemps, ça ne devrait même tout simplement pas être possible: la friction de l'air est la même dans tous les sens. La seule chose qui peut faire qu'on se déplace plus vite horizontalement qu'on ne peut tomber, c'est le fait de planer. Et ça, j'ai déjà un power-up pour le gérer.

Maintenant, soyons honnètes: je viens de me repasser des vidéos de Super Meat Boy et de N+ jusqu'à plus-de-vaisselle-à-essuyer ce week-end et je n'ai jamais pu mettre en évidence ce "point d'inflexion" ou la vitesse horizontale accélèrerait plus vite que la vitesse verticale. Par contre, la gravité est tellement basse qu'on peut difficilement dire qu'on a l'impression de tomber.

The second key property is that we must be able to tell how far we can go with one jump. If Bilou is moving at top speed on the ground, there is no reason we seen in accelerate just because he jumped. So if it took us exactly 1 second to cover N blocks while walking, then it must also take us 1 second to clear a N-blocks hole, and we can only do it if the jump makes us stay in the air for at least a second.

Deuxième élément: la portée du saut doit être prévisible. Si Bilou se déplace à sa vitesse maximale au sol (soit en courant, soit en marchant), il n'y a aucune raison qu'il se mette à accélérer une fois en l'air. Si on met exactement 1 seconde à franchir N blocs en marchant, alors on prendra 1 seconde à franchir ces N blocs en sautant pendant la marche et on saura les franchir si et seulement si le saut dure au moins une seconde.

L'exception à ce principe, c'est le saut depuis l'arrêt. Ici, on ne sait pas conserver l'énergie d'origine du personnage. Par contre, il me semble important que le joueur ne puisse pas atteindre la vitesse de course à partir d'un saut-à-l'arrêt.

There is one important case where this rule is deliberately broken, and this is the case where we were initially standing still, but start moving sideways mid-air. Here, there is no initial energy we could preserve. I feel like we should not let Bilou gain running speed mid-air from a standing jump.

Jusqu'ici, on va plutôt dans le sens de garder ce qui a déjà été développé. Une chose que je voudrais améliorer, par contre, c'est le tuning du saut à plus grande vitesse.

Le simple fait de relacher la direction "avant" lors d'un saut permet dans Bilou de retomber à une vitesse horizontale nulle. Par contre, si la vitesse retombe en-dessous de celle de la marche, il est impossible de remonter de nouveau à une vitesse plus élevée...
J'aimerais mieux pouvoir moduler la vitesse en relachant puis ré-enfonçant le pad. On pourrait du coup avoir n'importe quelle vitesse entre la marche et la course.

All of this so far confirms the current implementation. There is one thing, though, that I'd like to see improved: high-speed jump tuning . I mean, by just releasing the forward direction mid-air, we allow Bilou's horizontal speed to fall down to zero. And once your horizontal speed falls below top walking speed mid-air, you are never allowed to be fast again. I would love to be able to modulate speeabgpressing and releasing the d-pad instead. we could then be moving mid-air at any speed between walk and run.

Grosse difference par rapport au contrôle de Super Mario, donc, où si on veut si arrêter son saut, il faudra faire demi-tour avant d'avoir atteint la hauteur maximale.

Finally, there is a significant difference between current Bilou air control and the one seen in Mario games : Bilou can make a complete turn-back mid-air. you do not even have to plan such a move ahead: if you press backwards before you reached the top of your jump, you will land back safely on the platform you just left. In Mario, instead, it already takes you a lot of effort just to cut the horizontal distance in half. No wonder why they imported Yoshi's rodeo arrack in the "New Super Mario"

Mais pour être franc, je dois admettre que j'aurais du mal à me séparer du comportement actuel. En particulier parce que ça donne la possibilité d'annuler un saut si jamais je n'avais pas assez de vitesse. un confort que Mario n'offre qu'aux plus ratons d'entre-nous.

Friday, August 03, 2018

Rolling Random Number.

I decided to map every known token of the GobExpressions onto the ASCII charset some other day. And it struck me that there was a pattern like "upper case for mostly side-effect actions" and "lower case for mostly functional actions". To some extent, the x being used to call eXtra functions such as spawning new game objects, triggering sound effects and the like should be replaced by X. Tracking that in all the command files won't be trivial, though.

It could be tempting to use S(for score) as a function since we have i(ncrement counter) and d(ecrement counter), but unlike game counters, the score cannot be read again. It's more a side effect to change it than really some functional extension to the core arithmetics.

So where should "roll a dice to get a random number" go ? likely r. What should be used to "get/set game state bit %n". That could be g and s. Pretty handy map.

edit: For long, I have delayed introducing OP_ROLL, and that was partly because I had no clear idea of what implementation to pick. Here is the one from Tetris, according to some gamedev talk. What is good for Tetris is good for me.

Et dans Wordpress ?

Peut-être qu'un jour je devrai migrer tout ceci hors de blogger. Avec google, qui peut savoir ? Ce qui est sûr, c'est que blogger depuis une tablette, c'est décevant. Et depuis un boox qui tourne un vieil androïd 4, c'est encore pire. Comme je suis tombé sur un autre bloggueur de homebrew sur wordpress et que je me suis rendu compte qu'il y avait une fonction "notification pour les (réponses aux) commentaires", j'ai voulu vérifier si le passage blogger->wordpress était possible. Un p'tit compte gratuit, un coup d'oeil dans les FAQs et en avant.

Côté PC, l'interface est assez chouette. Plus fonctionnelle et réactive la version dont je me souvenais pour l'avoir fait tourner sur le serveur de l'Université. Rien que les miniatures dans la liste des posts, c'est chouette et sympa.

Maybe I'll have to migrate this blog out of Goolge's services one day. One thing is certain: blogger on my fairy's Android pad is disappointing, and it's simply un-available on my Boox device that runs an old Androïd 4. But both could run wordpress application, so it was worth giving the export/import feature a try. Spoiler: it worked. And it imported much of the pictures I had on my blog (not all, or if it did, it doesn't mention the same count as Google's photo gallery)

The UI on PC for wordpress is quite nice. the one on pad, a bit less. Thumbs turned gigantic so you can hardly see more than 2 entries on-screen. Using it to decide what you're going to update in your sofa is as convenient as scrolling through one of Titus The Fox levels. With 158 drafts waiting for me, it could be better. But if I'm not afraid of raw HTML mode, I can input some stuff directly with my stylus. Huzzah!

Côté tablette, c'est un peu moins réussi. les miniatures sont devenues des images énormes: il y a à peine deux articles accessibles par écran. Aucun contrôle pour changer l'ordre, filtrer ni rien de ce genre ... Il faudrait scroller et scroller encore (avec la vitesse de rafraîchissement de l'écran à encre électronique qui ferait passer les pluies sahariennes pour un coup de karcher :-/). Et pour ne rien arranger, les posts brouillons sont mis en avant, dans un ordre que je peine encore à définir. Et des brouillons, j'en ai. 158. Enfin, au moins ça devrait m'encourager à en mettre plus au net.

Et la bonne nouvelle, c'est que le texte de tout ce petit monde semble avoir été téléchargé dans la tablette et que je peux donc éditer à l'envi tout ça du fond du jardin. Enfin, à condition de ne pas être rebuté par l'éditeur en version Andröid qui semble penser que juste de l'HTML brut, c'est assez pour tout le monde :-/

Mais bon, je peux le faire au stylet, écriture manuscrite et sans écran. Et ça, c'est présssscieux.

Mais le plus impressionnant dans l'aventure c'est sans doute que wordpress a ré-importé automatiquement les 500+ illustrations du blog. Difficile évidemment de s'assurer qu'elles y sont bien toutes, mais c'est déjà un énorme travail d'évité. Et la galerie fonctionne aussi sur tablette (à condition d'être connecté. 'faut pas trop en demander quand-même: 7.5% de 3Go, ça fait son poids dans la gestion de mémoire cache du boox.

Mais il doit en manquer parce que l'album google "photos de votre blog" en comptait pas loin de 1240...

Tuesday, July 31, 2018

Please define 'casual'

Is the NintendoDS retro ? will it ever be ? the question raised on twitter. Thinking about it, how it was launched and how different the titles available at launch were from other now-definitely-retro consoles (including SNES, PS1, and even GBA),
I'd say the NDS will have harder time to feel retro in general (although some games certainly will). The reason is that, by the time the Nintendo DS came out, the kind of games we played had changed significantly. GBA games play much like slightly simplified versions of SNES games all over the life time of the console. And they play themselves much like more refined versions of the NES games. The reason for all this is the controller.

To me, holding an SNES controller is a well-known feel. I don't have to think about where X or A stands. It is immediate. And it definitely wasn't the case when the SNES cames out: SMW gave me a hard time compared to the 1-button + dpad games I was used to (okay, I pressed SML B button from times to times). And for most games on those devices, it was frequent that you'd need to train yourself to the core mechanics and grow your controller skills before you could proceed further than world 1.

The DS, instead, came up in the world of casual games. Not games that you happen to play casually (as opposed to competitively), but those explicitly designed so that you don't really need training to experience their core gameplay. Zoo Keeper, for once, perfectly fits that line of titles targetted at bejeweled players. They're built around more intuitive and direct actions (thanks to the stylus). Any grown up can start playing them even when they have almost no training with gaming devices. They don't require players to know that they should hunt for 1-UPs or stock power-ups if they want to stand a chance against the end-of-world boss. Really, these are games that Hudson Hawk could have enjoyed despite he's been in jail since Pong is out.

That doesn't mean that there are no retro-like games on the system, but they were pretty rare gems compared to the avalanche of stylus-driven titles. And chances are that the youngster who had a DS as her first gaming system will have nostalgy towards titles that no longer plays like a DPAD+buttons retro game.

Will the NDS ever be retro ? of course. But it might have to wait until we no longer use touch screen as our primary model to design games. When virtual/augmented reality games become the norm, maybe.

Thursday, July 26, 2018

Madness? this is refactory !

Maybe you remember this picture, the first one I scanned with my iris mouse. Maybe you remember the times where I mentioned some more things in the collision engine needed a revision. At last, I'm at it.

When two objects collide, they need to have access to each other for some times until all the rules of their state machine have been evaluated. To do this, I used a "GobCollision" object, linking to the related objects, script variables and hit boxes (GobAreas). That was a nice first step towards clean design, but it still has some drawbacks, like using weird arrays of so-called "GobCollision" that each captured only one side of the collision, and copies into the array to somehow "swap" orders when the collision initiator finally runs the 'found' rule with the collided object as "other" (while it just was 'other' for the 'hit' rule on the collided object).

But I had a small extra "Swap()" call dangling around. With some odd effects on the game, as you can see. But hopefully, I just got it sorted out. Now I'll be ready to be gone with the "collision-specific variables" telling how much hitboxes overlap each other, which is currently stored as a game-wide static array, while it should really belong to the new, real collision state object.

Saturday, July 21, 2018

Junko Ozawa's Secrets

(re?-)Bienvenue à Upsilandre dans la blogosphère! Quel plaisir de pouvoir découvrir en détail ses analyses des techniques ancestrales de programmation assis confortablement avec ma liseuse. Son analyse de la "basse sunsoft" et l'utilisation du canal 'triangle' pour faire les drums (plutôt que le canal d-PCM comme dans SMB3) était un vrai délice. Du coup, j'ai envie de ressortir cette série de snapshot de l'interview de Junko Ozawa, responsable son et musique sur les jeux arcade Namco.

Some times ago, I found a video featuring an interview of sound designer Junko Ozawa, working at Namco. I was surprised that so early in video game history, there were digital loops send to sound chips. I had in mind that we went square waves -> SID-like waves -> FM chips -> samples playback. Then I found a post by French blogger Upsliandre mentioning old NES sound programming, and he pointed out the term for Junko's technique: wave tables.

Très tôt déjà, alors que les générateurs simplistes de la NES semblaient riches en possibilités et que la FM faisaient ses premiers balbutiements, les machines NAMCO travaillaient déjà avec des échantillons. Enfin presque.

Le hardware était capable de rejouer du contenu par modulation d'amplitude (PCM) sur 16 niveaux (4 bits) mais extrêmement courts ... disons 16 à 32 points par son. Plutôt que d'y envoyer par DMA un son enregistré en live de basse ou de trompette, Madame Ozawa va s'en servir pour comme d'un SID avec des ondes programmables. Des sons totalement synthétiques mais avec une signature unique.

Pendant que Myamoto retranscrivait sur des petits carreaux les traits de Donkey Kong pour faire du pixel art, Madame se livrait au même travail à partir d'un son visualisé à l'oscilloscope pour faire reproduire à son soundchip une "trompette pixelisée" ou un "violon pixelisé".

Unlike what happens with a SoundBlaster, the sound chip of Namco arcade boards isn't streaming digitized samples. Instead, it uses small waveforms made of about 32 4-bit values and plays them as a single loop, again and again. It's much lighter on the 8-bit CPU and memory chips with "slow" clocks: we only have to fill the soundchip's internal register with the sound wave and just update the pitch for the notes we want to play as we would do on a NES soundchip, but we have a wide palette of sounds at our hands.

Somehow, the variety of sounds we can get out of such chips is similar to that of the C64 SID, but the process to have them is different, just like vectrex graphics and NES graphics are different. While Myamoto is converting his Donkey Kong drawings into pixel art by tracing them, Mrs. Ozawa was performing similar pixel-sounds, checking what the instruments look like on the oscilloscope. Possibly easier to do than mixing sines and triangle-likes to get the sound you want ... but less likely to do live phase-modulations as the SID could do.

But power, tone, roundness of the sound is fully customizable. Tower of Duaga got released in 1984 and we are lightyears away from an Atari console. The NES is hardly reaching Pluto in comparison.


La puissance, la tonalité, la rondeur, tout est personnalisable. Ecoutez donc Tower of Duaga de 1984. On est à des années-lumière de la sonorité d'une console atari! et la NES est encore sur Pluton.

Sa bibliotèque de sons, c'est le trésor de Mme Ozawa. Elle les conserve dans un cahier, vu l'absence d'éditeur numérique pour ce genre de choses. Et il faudra bien longtemps avant qu'un synthé ne puisse interpréter en direct les sons imaginés pour le Namco WSG.

[Les wave tables], c'est la base notamment du son PC-Engine dès 87, mais on retrouve ca aussi dans le Famicom Disk en 86 (y a qu'un seul canal mais de bonne résolution, 64x64), dans la Gameboy ou on a une wavetable 32x16 qui remplace le triangle wave de la NES (j'aurais aimé la même chose pour la NES), aussi dans le soundchip SCC de Konami qu'on retrouve dans les cartouches MSX de Konami tel que Contra.
Effectivement, je n'avais pas fait le rapprochement, mais c'est bien la même technique qui permet à la version "Famicom Disk System" de Legend of Zelda d'avoir quelques sons inédits par rapport à sa version NES (dixit Nathan dans "I AM ERROR"). Et on voit bien les patterns un peu exotiques tout en étant très clairement des ondes simples dans la séquence de fin de Link's Awakening.  


Bref, de mon côté (et surtout vu que je suis assez fan des sonorités de Coryoon et Soldier Blade sur PC-Engine), ça me donne furyeusement envie de coder un petit Wave Editor for DS ...

Upsilandre also pointed out that those Wave Tables are the roots of PC-Engine soundchip (1987) -- that's giving this unique vibe to Coryoon and Soldier Blade soundtracks). And that the same trick had been added to the Famicom Disk System in '86, allowing some tricks in the Legend Of Zelda original soundtrack that couldn't be found in the NES version -- as mentioned by Nathan in his 'I AM ERROR' book). Another thing I didn't know was that the GB used that too. Sure, there were GB games that streamed a PCM sample through the 32-sample, 4-bit programmable PCM channel, but in Link's Awakening, it is mostly used as a Namco channel.

Maybe when I'll be a grumpy grand-dad, I'll find time to code a Wave Editor for DS ? Maybe we could morph one wave into another while playing on the DS hardware ? Time will tell.

edit: à suivre dans le post d'Upsilandre: le pixelat audio sur FDS