Tuesday, March 29, 2022

Les piles momies animées.

Au milieu d'un mois de dingues, j'ai quand-même réussi à améliorer un peu les graphismes de mes piles-momies et à faire une petite machine d'état qui fonctionne.

En fait, maintenant que j'y pense, pour ceux qui arrivent à atteindre la plate-forme là-haut, on peut même essayer de voir ce que ça donne de sauter par-dessus. Allez, ça mérite une démo téléchargeable, ça.

It's been a tough month. Let me tell you, when release-day came out on 24th, packing a binary with some new stuff to offer to you all was the last thing I had in mind (just before I'd fell asleep. Or maybe just after). But I still managed to improve a bit the undead-cell graphics, mirror the animation and give it a state machine so that it can be placed in levels. It isn't interacting with anything yet, just checking whether it should turn back at the edge of platforms, but there it is. You can practice tricky jumps if you feel so ;) The downloadable .nds finally made it to the Internet.

Friday, March 25, 2022

try { week(); }

 


try {
   week();
   homebrew();
} catch(BirthdayException&) {
   cake--;
   year++;
} catch(UnpluggedFreezerException&) {
   while(!freezer.empty()) {
      cook(freezer.front());
      freezer.pop_front();
   }
   freezer.clear();
} catch(SparklingUnicornException& su) {
   return new friend(su);
} catch(UnexpectedWindowUpdate& wu) {
   money -= wu.price();
   light++;
   // FIXME: headache
}
Mais sinon, ça va. Pardonnez l'absence de release-d-anniversaire, du coup.

Friday, March 11, 2022

Animating the Undead Cell

 

I admit one of the reason for playing Epic Mickey again was to see how they had dealt with the sands and desert things in the Agrabah level, but I was far from imaginating that it would unlock my animation issue for the UndeadCell. One of the ennemies we face in the game is a mushroom species that has level-themed variation.

J'avoue: une des raisons pour lesquelles j'ai rejoué à Epic Mickey, c'est parce que j'ai réalisé qu'il y avait là la meilleure version graphique de l'univers d'Aladdin, tout en sable fluide et pierres jaunes. Quoi de mieux comme source d'inspiration pour ma pyramide bilouteuse ? Mais je ne m'attendais pas à ce que ce soit le champi-turban qui me serve le plus de source d'inspiration.

Conveniently enough, the sprite table was available on the Spriter resource, but let's be clear: if you can rebuild the animation from the sheet, you're the original animator. But at least, there was one thing I could extract from it: the sine motion for the pot of the character and the fact that the 'hat' more or less follows the slope of the sine. Colors for the turban are h30s18v99, h31s40v87, h27s51v75, h29s60v62, h25s59v55, just in case I wouldn't be satisfied with the current ones.

So I tried to sketch that and it looked nice on paper. I redrawn it in my SpriteEditor and it looked interesting (although I couldn't loop 'walking' animations properly). Getting it to work in AnimEditor was a bit harder: you can lock a sprite in the world while you're animating the rest, but the undead cell has no thing such as a foot that could be locked and moved backwards (pushing the rest of the character forward) like dumblador had.

C'est que, voyez-vous, l'animation actuelle de la pile-momie est tellement peu concluante que je ne l'ai toujours pas intégrée dans le niveau-test. Mais ce champi mélange pixel art et technique d'animation "cartoon-ancestrale" qui me montre la voie à suivre. Je gribouille donc une sinusoïde qui servira de repère. Je note que dans leur animation, l'orientation et l'étirement du chapeau suit la pente de cette sinusoïde. Je fais de même.

Il y a encore une 'pose iconique' dont je veux m'inspirer: cette manière dont le personnage fait une courbe montante au moment de se redresser. Comme s'il se déplaçait en utilisant le poids de sa coiffe qu'il laisse d'abord tomber vers l'avant puis qu'il doit courir pour la redresser telle la pile de livre de Lagaffe.

Hopefully, while animating in SEDS, I made the character actually move within its 32x32 frame. Part of why it moves now is because I kept that, but scrolled the frame backwards so that the eye always remained at the same spot within the bounding box.


So here it is, in a "how it started / how it is going" sort of animation (from a file beamed before I could fix the forward motion). As you can see, it still need to be significantly polished, and I got barely any time to work on it this week, as my kid had to finish a show-and-tell for school.

ça me fait pas loin de 11 étapes d'animation pour la pile qui avance. de 32x32 chacune, mais bon j'ai 256K de sprites à ma disposition... ce serait dommage de faire le gripsou et ne pas en profiter à ce stade-ci.

J'ai du chipoter un peu pour trouver comment adapter le mécanisme de 'verrouillage de sprite' qui avait bien marché pour dumblador sur un personnage qui ici n'a pas de pied. Est-ce la bonne vitesse ? Bah, dans le pire des cas, je la mettrai sur du sable qui coule, et ça justifiera une vitesse plus élevée, hein ;) La voir revenir en arrière dans les premiers temps de son développement m'a donné l'idée que la vitesse d'écoulement du sable devrait être telle qu'elle reste immobile à contre-courant.

edit: ouaip. C'est bien beau tout ça, mais une animation qui "marche" dans AnimEDS n'équivaut pas forcément à une animation qui marche dans le jeu. En particulier, l'éditeur joue en réalité l'animation à la vitesse indiquée, forçant le déplacement correspondant. Le moteur de jeu, au contraire, asservit l'animation au déplacement. Ce qui donne ici une pile qui reste immobile un long moment puis joue presque toutes ses frames d'un coup parce que j'ai abusé du 'mov#1' et du 'mov#0' (enfin, je crois).

Saturday, March 05, 2022

Illusion.2: les PNJ

J'ai passé Agrabah, et ce n'était pas de la tarte:

  • la densité d'ennemis augmente significativement;
  • la plupart des ennemis ont un nombre de points de vie quasi prohibitif; (10 ennemis à 6 HP sur le premier segment du niveau ... et j'ai le 1er bonus de dommage pour les sauts)
  • le design des niveaux réduit notre marge de manoeuvre avec des couloirs étroits où on trouve des pics, des sables mouvants, etc.

La caverne des miracles ? C'est pire. Des pics partout. Il faut à la fois surveiller les approches d'ennemis sur l'écran principal et les objets invisibles de l'écran du bas, au risque d'avoir loupé le tapis magique qui devait permettre de passer l'obstacle. Ou louper un PNJ.

Triumphing of dangers untold as well as countless trials, I finally made my way through Agrabbah to the Cave of Wonders to claim NPCs Mizrabel had jailed. Compared to the previous part of the game, ennemies density raised significantly and most of them require a ridiculously high amount of hitpoints (up to 6 hits, even for apparently low-level baddies). Plus the level design now features a large amount of narrow corridors, spikes and quicksands. Oh, and many of the baddies are throwing things at you, too.

The cave of wonders itself isn't any better. Spikes everywhere. You've got to keep an eye on the upper screen to see baddies coming in and another eye on the bottom screen to spot hidden platforms to activate while you jump. I'm failing again and again, and if the game decide I have to redo a level, I'll also have to rescue all the NPCs again -- a bit like NSMB star coins aren't 'validated' until you hit a checkpoint. If you want to bring everyone back at the fortress, you *have* to one-life the level. 

Bref, je meurs, je meurs et je re-meurs. Et le jeu ne mémorise pas quel PNJ a déjà été sauvé quand il nous renvoie au début d'un niveau. A l'instar des pièces-étoiles de NSMB, il faut faire le sans-faute pour ramener tout le monde à la forteresse.

Le message du jeu est clair, pour moi: "t'as pas le niveau. Fais des quêtes pour augmenter tes stats!". Parce que des stats, il y en a. Et pas qu'un peu. Jauge de vie, de peinture, de dissolvant, puissance des attaques par saut, par tornade, par peinture et par dissolvant. Coût de la peinture et du dissolvant pour les dessins et pour les attaques. Tout ça peut être amélioré chez l'Oncle Picsou, mais dès la 2eme mise à jour, on arrive à un tarif de 1500 crédits/upgrade pour encore monter à 4500 pour le niveau 3. Vu que je fais au mieux dans les 600 crédits en traversant un niveau, comme je l'ai dit, on va espérer que les quêtes des PNJ vont me simplifier la mise.

In terms of game-to-player communication, this is as plain as can be: "you're not ready for that level. Go farming, level up and then come back". You thought Epic Mickey was a platformer ? Hah! See how many stats can be improved by purchasing items at Scrooge Mc Duck's shop! Health bar, ink (shots) bar, thinner bar, damage level for every possible type of attack, ink cost for all the various ink-related moves. And at prices above 1000 credits as soon as you want a second upgrade (nearly 5000 for the 3rd upgrade) while you can expect collecting 500-600 credits in a level. The side-quests NPCs offer better have to improve that or I'm done with playing. But unfortunately, that's precisely where the game experience degrades.

Et c'est là que l'expérience de jeu commence à sombrer sérieusement.

Avec le 2eme monde, un nouveau type de quête est débloqué: faire l'entremetteur de PNJ. On va
emmener Donald voir Picsou, puis Dingo. On va chercher du bois chez La Bête pour que Picsou puisse avoir une pancarte annonçant sa boutique, échanger des livres et des peignes entre Raiponce et La Bête ... vous voyez le tableau. On est à peine au-dessus de la quête des cocottes. ça pourrait avoir un petit goût de Point-n-click à la Day of the Tentacle, ... sauf que non.

Starting with world 2, a new kind of quest appears: "trade" items between NPCs within the fortress (a sort of hub world). Find Donald Duck, take him to Scrooge, then to Goofy. Get some wood at the Beast's place so that Scrooge can have a sign for his shop. Swap books and hairbrushes between Raspunzel and the Beast. etc. Barely above the interest level of cuccoos quest in a Zelda-inspired RPG. It could have had the funny taste of a Day-of-the-Tentacle (point-n-click) game, but it doesn't.

In a (great) point and click, there's quite few things that could trigger an NPC's behaviour to change -- beside your own actions in the game, that is. Does Ed needs something that belongs to Ben? Well, you'll discover that by the time you discover where Ben stands. You don't know yet how to pick/steal/be given the item Ed needs, but you can anticipate Ben will be part of the solution and start searching for ways to reach your objective. And having anticipated things makes the solution interesting to find (and possibly fun, if it somehow breaks some of your assumptions). Looking for the solution is made fun by allowing plenty of things to be tried with no penalty on picking the wrong option (plus using a bit of humour to comment on player's silly attempts).  

Dans un P'n'C, il y a relativement peu de causes extérieures au changement de comportement d'un PNJ. Ed a besoin d'un truc mais c'est Ben qui l'a ... on découvre ça en débloquant (ou juste découvrant) l'endroit où Ben se trouve, on anticipe que la solution sera de prendre le truc de Ben et on commence à chercher comment parvenir à cet objectif. C'est cette anticipation qui fait que la solution est intéressante à trouver. C'est parce qu'on peut essayer plein d'actions différentes sans pénalités (et avec un peu de chance, avec une pointe d'humour dans le signalement de nos échecs) que la recherche de la solution est distrayante.

Mais rien de ce genre dans Epic Mickey. Juste déplacer une icone sur une carte avec des contrôles "qui accrochent" et chosir 'Parler / Améliorer / Quitter'. Les personnages qui cherchent quelque-chose sont marqués d'un symbole jaune, et quand une quête est validée "Une arme de fille -- trouvez une poële à frire pour Raiponce", un symbole vert est ajouté à côté de la pièce où se trouve sa solution (enfin, si on a sauvé le personnage correspondant). Autant pour l'anticipation.

You won't find anything alike in Epic Mickey sidequests. All you're doing is moving a mouse-shaped curor on a generic map with unresponsive controls and pick "talk / improve / leave". Characters who need something have a yellow sticker next to them and when a quest is validated, a green sticker is added in the room where the solution is (given that you've rescued the required character for that room). So much for anticipations.

And even more unfortunately, there are annoying loading times every time a character has to be shown. Over a 20-minutes gameplay session, you'll spend easily up to 5 minutes navigating menus to unlock things with NPCs.

Ajouter à ça des temps d'attentes à chaque fois qu'un personnage va parler pour faire apparaître
son portrait dans l'interface et vous commencez à comprendre comment 'faire des quêtes' va s'annoncer aussi gai qu'une opération choco un jour de janvier pluvieux ... Sur une séquence de jeu de 20 minutes, la partie dédiée à la navigation dans la forteresse et aux "dialogues" avec les PnJs représente quand-même 5 bonnes minutes. C'est loin d'être négligeable!

Pour enfoncer le clou, comme si ce n'était pas encore assez bancal, il est impossible de découvrir un des personnages ou des objets à ramasser dans le niveau tant qu'on a pas activé la quête correspondante depuis la forteresse: la cachette en question sera tout simplement un recoin vide du niveau. Ou éventuellement on y ramassera quelques crédits. Et Mickey ne dispose pas du 6eme sens de Princess Peach pour deviner dans quel segment d'un niveau un objet/personnage se trouve. Jimini non plus, d'ailleurs. Allez, au moins on peut leur reconnaître que le level design est construit pour qu'on ait (le plus souvent) la possibilité de voir qu'on approche d'un personnage-quête quelques écrans avant qu'il ne soit nécessaire de le délivrer.

Could it be even worse ? Sure! Some of the items and characters you could rescue from a level aren't present in a level before you trigger the quest for them. You could travel London Skies 3 times in a row, if you haven't been chatting with Wendy Darling first, you might never encounter her brothers. Instead, the (hidden dead-end) place where they'd be hiding is instead an empty spot -- optionally offering you a few credits as 'reward'. And Mickey doesn't even have a 'sense of magic' like Super Princess Peach that would tell you whether some NPCs are being held prisonner in a specific area of the game. The only help you'll get is that the level is somehow twisted in such a way that you're being shown that there's someone to rescue ahead of the spot where you have to prove your skills to go rescue them.

Friday, March 04, 2022

Shikadi Walk

There's 120 ms between two frames of the Shikadi walk. They cover 1 full block in one full step (2 frames -> ~240ms for a full step). 

En gribouillant quelques idées de level design, voilà qu'apparaît la possibilité que les piles-momies de la pyramide de Bilou puisse déclencher des pièges sur leur passage. Par exemple électrifier des piliers qui soutiennent les plate-formes que Bilou emprunte. Mais il ne faudrait pas qu'elles fassent ça trop vite quand-même, histoire que le joueur ait le temps de réagir... voyons ... Omégamatic ?

Comparatively, the 'wander' state of the zooming bot (Sparky) covers 32/20th of that distance.
And keen runs at 37/20th of the shikadi walk speed. Almost twice as fast. Since I'm considering giving UndeadCells the ability to trigger electricity sparks when they reach some level elements, I'd like to ensure I at least don't make Bilou a game harder than Commander Keen in the Armageddon machine ...

Ah, and by the way, the dumblador (currently the slowest hazard in Bilou) needs 880ms to cover half a block. When walking, Bilou takes 8/60th second (133ms) to do the same. And he can run twice as fast.

J'ai donc ressorti Keen5.exe et tenté de recalculer la vitesse de déplacement des Shikadis -- ces personnages fait d'électricité -- qui ont un comportement similaire à l'approche d'une de ces barres auxquelles Keen peut s'attacher. Eh bien on est à 240ms pour un bloc de l'éditeur de niveau, soit 90% de la vitesse de marche de Bilou et 54% de la vitesse à laquelle Commander Keen se déplace.

ça reste relativement lent par rapport aux autres ennemis du jeu. En mode 'surveillance', le robot Sparky ne met que 150ms pour couvrir un bloc (et non, je n'ai pas mesuré la vitesse de Sparky en mode 'attaque').