Saturday, October 31, 2020

Cancelled refactoring

I had a checkbox in my notebook asking whether BlockArea really needs to be a full-fledged GameObject or could be something simpler. So I started to refactor things and see whether we couldn't have more features moved from GameObject into CommonGob instead.

Yeah, I know. You're lost. 

Let's start with GameObject. That one is how the engine sees Bilou, Bladors and all the other characters in the game.

Now the 'BlockArea'. This is a temporary object that captures information about where a GameObject interacts with a special block on the map. During that time, that part of the map must be able to trigger and get collisions.

The part that annoys me is how being a GameObject implies being an Animator. That implies being registered with the engine. There's no good reason for BlockArea to be an Animator: it won't exist for more than one frame. But because being a GameObject implies being an Animator, I have no choice.

Or do I ? I started trying to change the inheritance graph so that now CommonGob -- the thing I introduced to capture what was previously into SimpleGob (AppleAssault-like GOBs made of only one hardware sprite) but had to be shared with CompoundGob (SchoolRush-like GOBs made with AnimEDS). 

But that turned out to be a bad idea: many parts that used GameObject (including the script-parsing code) assumes that GameObjects are Animators that can be played, stopped, etc. 

So I'll have to roll back and return the things as they are. That would have been a nightmare in the CarzyBrix era, but hopefully, it's just one command in mercurial. 

c:> oubliette


Sunday, October 11, 2020

Direct Flags

Signing in for a 7-days trial of the Nintendo Online sure affected how I used my hobby time these last days. But nevertheless, I could do some homebrew coding, and it was for the level editor.

You may recall that I'd like to introduce 'direct flags tiles' in the engine. The idea is to enable any combination of some very basic properties like "can be swum through", "can be climbed on" or "can be fallen through" within the level by dedicating 64 tile types where the 'type identifier' part is used as a direct set of flags for those properties.

Une des idées avec la révision du monde de Bilou, c'est de pouvoir permettre à certains tiles de définir directement les propriétés physiques à appliquer. Dans Apple Assault et School Rush, chaque numéro de tile fait appel à un lookup dans une table de correspondance pour connaître les 'flags' à utiliser dans cando(): ça, c'est l'encodage indirect. (ça vous rappelle vos cours d'assembleur ? c'est normal). Un quart des types de tiles seront maintenant dédiés à ce fameux encodage direct, qui permet notamment d'exprimer n'importe quelle combinaison de 6 propriétés fondamentales comme "permet de tomber", "permet de nager", "peut être escaladé", etc.

Yet, that's only efficient if you don't have to come with 64 custom editor art for them. And that was only possible with a few changes to my MetaFlags widget and the surrounding code:

  • paint color for 'environment type' tiles 
  • on/off switches for those tiles in MetaFlags
  • auto-generate combined tiles for combined environment (e.g. CAN_SWIM + CAN_CLIMB)

"auto-generation" works by painting the the 'pure' tile with the highest bit, then painting over the lower-priority bits. So if you swap the order of  all-blue CAN_SWIM and some-green CAN_CLIMB, you won't see that you can do both anymore.

Jusque là, c'est bien beau sur papier, mais dans l'éditeur, comment représente-t-on que le bit 4 est utilisé pour l'eau et le bit 3 pour l'escalade ? Eh bien à travers le fichier .gam, bien-sûr. Celui qui contient déjà des commandes "block {}" pour tous les blocs spéciaux (bonus, clés, portes, etc.). Comme leur nombre a été réduit à 64, je peux utiliser une partie des numéros pour décrire 6 graphismes de base (un par propriété fondamentale). La chaine hexa sert toujours à définir l'image à afficher, le nombre qui est derrière la couleur à utiliser (le noir pouvant servir à 'effacer'). A partir de ces images de bases, l'éditeur générera les combinaisons possibles.

It's far from perfect, especially because I still have to override that for the tile that says "plain air here, sir". But I realised it was merely an optimization over the 'indirect' tiles, and premature optimization is the cause of so much bad things ...

*but* I can manage to get some clean output if I define 'flags' in the .gam file. Especially, knowing that meta-tiles are alpha-rendered, meaning that any black color turns transparent, whatever their palette indices. 

*edit* And the reason why so many levels I edited lately would have buggy 'empty' tiles rendering is that this "rush.gam" file I modified for the snapshots is only used in two levels so far.

Wednesday, October 07, 2020

Other perspectives

I should possibly call them 'projections', because a perspective is something where distances shorten coherently when things are further away, and typically will never have parallel segments to depict things that are parallel in the 3D world. 

And I don't have to make the height of the front face shorter than the width of the same cube. If I do, it will be a stylistic choice of mine. 

cyangmou: Really depends on the type of projection you use. You can use foreshortening, but you don't have to, as long as it is consistent between the objects you are using. I mean it's more about the consistency of the general ruleset which is applied. e.g.:
I'll have to keep that in mind before setting the pixel sizes into stone tiles.

 (There's more about isometric pixel art tutorials in Cyangmou's "Pixel Art Knowledge" collection, of course) 

edit: more of Cyangmou's projection tutorials on ko-fi.


Thursday, October 01, 2020

Ori et le Langage Retrouvé

 J'ai finalement terminé Ori & the Will of the Wisps hier, soit 13 jours après son achat. Pourtant, je pense qu'il est dans l'absolu plus difficile que son prédécesseur, mais je suis nettement mieux rôdé à manipuler le p'tit bonhomme.

"Est-ce qu'il est dans la continuité" demande ma collègue 'Sparkling', fan de la série ? Eh ... difficile de répondre. On est dans un jeu qui débute son histoire après l'histoire du premier jeu, mais qui en rupture avec le jeu précédent puisqu'on commence en échouant sur une île inconnue.

D'une certaine façon, "The Will of the Wisps" est autant dans la continuité de "The Blind Forest" que "Link's Awakening" n'est dans la continuité de "A Link to the Past".

La grosse "nouveauté" dans le jeu, c'est cette société de personnages non-jouables qui tiennent la bavette ça et là, que ce soit pour nous renseigner sur le fonctionnement de l'île, nous envoyer dans des recoins pour des quê-quêtes à la Guilde Noob ... ou pour nous soutirer des crédits.

Eh oui, c'est l'autre "nouveauté": les orbes de lumière spirituelles sont sur cette île une monnaie d'échange pour payer le cartographe (qui arrive toujours sur les lieux avant nous, hmm), le guru des arts martiaux et le type louche qui deale des éclats d'esprit pour nous permettre d'être mieux défendu ou de faire un 3eme saut. 

Vous l'aurez compris, je ne suis pas convaincu. Et si j'ai systématiquement mis "nouveauté" entre guillemets, c'est parce qu'il ne s'agit ni plus ni moins que de réinjecter des mécaniques conventionnelles du jeu vidéo dans une oeuvre qui jusque là n'en avait pas besoin. 

Ori and the Blind Forest n'avait pas besoin d'armes, pas besoin de crédits. Le lien empathique entre Ori et le monde qui l'entoure suffisait à entrer en phase avec les souvenirs, permettant du coup de raconter l'histoire sans avoir besoin d'un vieux barbu qui nous explique que "ah... oui, mais tu ne connais pas toute l'histoire à propos de X". 

Ce lien permettait aussi de faire monter son personnage en puissance grâce aux orbes spirituelles. C'était à moitié direct (il fallait quand même retourner à un point de sauvegarde après avoir reçu assez de lumière). C'était suffisant. ça collait avec le personnage. Mais c'est fini.

ça ne ruine pas le jeu, évidemment, mais je ne peux m'empêcher de regretter ce manque d'ambition. Ca me rappelle un peu la difficulté à faire une suite à Another World après avoir fait un jeu-culte qui avait su casser les codes du genre en ne nécessitant ni score, ni barre de vie, ni 1-UPs.

Touche finale, les personnages proposent ici une sorte de chaîne de l'échange qui m'avait si bien plu dans Link's Awakening. Je vais avoir du mal à être objectif ici parce qu'un plantage à l'arrivée dans la clairière aux Mokis m'a empêché de recevoir le 2eme objet lors de mon premier essai, et que, craignant de provoquer à nouveau un plantage en reprenant la manette, j'ai évité comme la peste le Moki qui permet de commencer cette chaîne. Je n'avais donc jamais l'objet dont aurait eu envie les PNJs rencontrés au fil de l'aventure.

Pour l'amour du jeu, j'aurais bien fait la chaîne quand-même, avant de retourner affronter le boss final. Malheureusement, l'idée n'a pas été super-bien exécutée. Me voilà avec quelqu'un qui me file un sac. 

"Ah ouais, j'me souviens d'un Moki qui voulait un sac pour devenir aventurier". Seulement, lequel ? Eh oui, 80% des PNJs du jeu sont des mokis, à peu près aussi reconnaissables les uns des autres que ne le seraient des écureuils. Parfois ça n'est pas trop dur: "cherche quelqu'un qui a froid" ou "cherche quelqu'un qui a besoin de lumière" quand il y a un territoire des glaces et un territoire des ombres, c'est dans mes cordes. Mais quelqu'un qui a besoin d'un sac ? ou d'une longue vue ?

Certains sont amusants à retenir. le moki qui veut un chapeau est à côté du vendeur qui a un chapeau. Mais comment deviner qui va nous filer un chapeau ? Au moins, sur Koholint, l'alligator qui ne veut plus de ses bananes est entouré de bananes. Le type qui file du miel est à côté d'une ruche, etc. On peut essayer de remonter le fil depuis un personnage vers celui qui peut nous débloquer. Dans Ori, ça semble la plupart du temps impossible à deviner.

edit: Les mokis de la chaîne de l'échange ne sont pas les seuls PNJ avec lesquels on peut faire des mini-quêtes, mais à part quelques unes, je les ai trouvées très noires, et pas franchement satisfaisantes. Je m'explique: supposons qu'on vous demande de retouver doudou qui s'est perdu. Bon, c'est pas la quête la plus héroïque du monde, mais au moins vous aurez fait votre B.A. et un sprite sourira à l'écran. C'est un scénario plutôt rare dans Ori. une fois le lieu demandé découvert (mon ancienne maison dans les bois perdus), il y a de forte chance que la-dite maison soit complètement pétrifiée et que le doudou ne soit plus qu'une masse informe de graviers. "nouvelle quête: allez annoncer la triste nouvelle à Machin". Pas franchement chouette, hein ? On en regrette presque d'avoir accepté la quête.


Monday, September 21, 2020

Ori et le Lien d'âme

 J'avais du mal à y croire, mais si: Ori 2 est bel et bien sorti sur Switch, et ça à peine 6 mois après sa sortie officielle sur XBox (contre 2 ans pour l'épisode "blind forest"). Chose assez peu courante, j'ai bondi dessus dès qu'il a été disponible. Il est superbe, il est prenant, mais il y a aussi des différences assez profondes et parmi elles, la gestion des échecs du joueur.

Il faut dire que le premier opus avait opté pour une approche assez innovante. Pas de points de sauvegarde imposés: c'est au joueur de créer à certains endroits des "liens d'âme" d'où il pourra réapparaître en cas d'échec. Tous les objets récupérés, toutes les portes déverrouillées seront perdues en cas d'échec.

Sauver quand on veut, ça me rappelle ma manière de jouer à Commander Keen dans les années '90 (et sur émulateur, en fait ^^"). Mais ici, il y a une subtilité: pour pouvoir créer un point de sauvegarde, il faut dépenser un point de mana. Et pour retrouver du mana, il faut généralement briser des cristaux pas si fréquents que ça. D'une certaine manière, les cristaux faisaient office de point de sauvegarde... mais d'une certaine manière seulement.

Parmi les 'compétences' que l'on peut débloquer à l'aide de points d'expérience, on trouvera par exemple la possibilité de réutiliser à volonté un point de sauvegarde déjà créé. On peut ainsi faire une sauvegarde, aller éliminer un monstre, retourner sauvegarder, éliminer le monstre suivant, etc. (ou pareil avec des clés à récupérer). On pourra aussi débloquer la possibilité de reprendre de la vie au moment où on crèe un nouveau point de sauvegarde (mais là, il va falloir commencer à dégotter un fameux nombre de points d'expérience, hein).

Bref, tout ça était frais, unique, assez bien en phase avec le concept de 'je suis un esprit de la nature brille et qui saute dans tous les sens'. Eh bien c'est fini. Ori and the Will of the Wisps, avec son côté 'ninja-vania' sauvegarde automatiquement quand on franchit certaines 'portes' (invisibles). On ne risque plus de perdre tout d'un coup 15 minutes de progression juste parce qu'on hésitait à dépenser un des précieux points de mana (3 au départ). Par contre, on a plus non plus ce côté 'stratégique' consistant à choisir où faire ses sauvegardes.

Il reste cependant un lien entre mana et santé par le biais d'une sorte de 'sort de soin', plus convenu, mais aussi bienvenu dans les combats contre les boss qui ont l'air plus développés que dans le premier opus.

En fait, c'est tout le gameplay des combats qui a été renforcé, avec une palette de mouvements d'attaque dignes de Kirby en mode 'épéiste' et un arsenal d'armes secondaires qui n'ont pas à rougir de Link between Worlds.


Tuesday, September 15, 2020

makechar(BG_GFX, digit[i])

Bon, j'avais des affichages curieux dans LEDS. "où sont passé les pentes et les blocs jump-through" disait mon calepin. Eh bien ils étaient toujours bien là. Simplement pour les voir, il faut qu'il y ait quelque-chose au bon endroit dans la mémoire vidéo de la DS. Et jusque là, le code d'initialisation n'avait pas suivi l'évolution de la branche "newmap". Le niveau était donc bien converti mais les codes 0x81 pour "est une pente, type 1" n'avaient droit à aucun dessin.

Mais je n'ai pas sucé ça de mon pouce. Pour y voir clair, j'ai bricolé une p'tite table de caractères hexa en 3x7 pixels qui sont ensuite combinés pour faire 256 tiles dont le dessin indique le numéro.

I started getting weird effects in LEDS on the 'newmap/newmeta' branch. Special blocks and plain blocks seemed to work fine, but everything in-between (shadows, slopes, jump-through) was missing. Or so it seemed. They were actually still present, but invisible because the pixels to render them was still on the 'old codes' rather than on the new ones. I got it confirmed once I introduced a small loop that primes all the tiles used by the meta-layer with two-digit hex codes stating explicitly who's who.
 Unlike the legacy 0-3 codes, these are not meant to be shown to the level designer. As soon as we load the level, effective tiles will be filled, for instance using the 'symbol' statements.

Contrairement aux anciens codes, il n'est pas prévu ici de les conserver à l'écran: pendant le chargement du niveau, tous les codes utilisés seront remplacés par les symboles définis dans "rules.gam". Seuls restent affichés à coup de codes hexa les types de tiles "inconnus" -- ici les 00 qui servaient à "pousser" les personnages par-devant tous les plans de tiles et la pointe de crayon inversée.

Par contre, du coup, les "méta-boutons" deviennent beaucoup plus vides ^^"

Et comme maintenant je suis en mode multi-palettes pour tous les rendus de graphisme du jeu dans l'éditeur de niveau, j'ai les coudées franches pour redéfinir la palette principale, toujours utilisée par les plans "16x15 couleurs". C'est fondamental vu l'affichage du meta-layer en alpha-blending: utilisez une couleur non-définie (donc noire) et le truc est invisible. Prenez du blanc, et l'alpha blending sature.

Ok, c'est à peu près aussi passionnant que l'avancée des négotiations fédérales belges. Mais si je ne me remets pas ce genre de chose au frais en tête, je n'ai aucune chance d'avancer sur du homebrew. Et si je le fais, il est 23:37 quand j'ai fini ^^". 

C'est pas terrible pour la lisibilité des méta-boutons, par contre. Je vais leur donner une palette rien qu'à eux avec des couleurs bien EGA pour qu'on ne les loupe pas, du coup.  Puis j'irai jeter un oeil à la page du projet "Méta-Boutons" aussi, pour voir ce que j'avais envisagé pour passer les valeurs "inutilisées", parce que là, ça serait assez désagréable à utiliser (1 à 2 tiles utiles par "page" de boutons ... bof)

Friday, September 04, 2020

Les alliés des étoiles

J'avoue qu'on a pas tenté les vacances en mode corona. Par contre, j'aurai passé pas mal de temps cet été sur Kirby Star Allies dont la démo avait déjà bien accroché les enfants, et qui s'en sont donnés à coeur joie une fois la saison des camps & stages passée. (un peu trop, peut-être : J.L.N semblait

incapable de nous parler d'autre chose que des techniques de meta-knight avec l'épée des vents)

Bref, sans parvenir  aller détrôner le légendaire Labyrinthe des miroirs, cet opus est tout de même une belle réussite. Bon, ne cherchez pas du challenge pour les oldschool gamers, hein: pour ça, on s'orientera vers une autre boule rose plus indépendante: Whipseey (dont il faudra que je vous reparle vu que j'ai aussi acheté le jeu). Sous le couvert de "magie de l'amitié", le principe de base de ce Kirby est de pouvoir se constituer une équipe de quatre personnages pour traverser les niveaux, les joueurs humains pouvant "recruter" n'importe quel adversaire qui possède un pouvoir.

Les laboratoires HAL n'en sont pas à leur coup d'essai là-dessus: Kirby Amazing Mirror permettait déjà de faire intervenir 4 protagonistes sur un seul écran (utile surtout pendant les boss) et Kirby Squeak Squads -- une fois le mode fantôme débloqué -- permettait de son côté de prendre le contrôle de n'importe quel personnage du jeu. Oui, vraiment en prendre le contrôle, pas juste lui voler son pouvoir façon mégaman. Je dois bien reconnaître que depuis que mon frère m'avais parlé du mode "debug" de Sonic, j'avais rêvé de pouvoir faire ce genre de chose (allez, Jill of the Jungle nous en avait donné un avant-goût). Là, c'est chose faite.

On remarque au passage que pas mal de pouvoirs "classiques" des Kirbys précédents sont passés à la trappe -- notamment Kirby-roue, presqu'un incontournable depuis le premier épisode sur NES -- et je soupçonne fort que ce soit lié au besoin de garder les 4 joueurs à l'écran. Du coup, tout ce qui va trop vite reste au placard.

Il y aurait pas mal à redire par contre sur la lisibilité de l'action. Quatre personnages qui font la baston sur le grand écran contre un boss commun, on finit par ne plus retrouver le sien que grâce au petit "J1" qui pointe dessus. HAL a eu le bon goût de donner une couleur unique aux personnages secondaires (oui, je peine à dire 'les amis') et c'est très bien la plupart du temps, mais dans le feu de l'action, c'est insuffisant. Et les combinaisons du genre "épée de feu, lasso de glace, lance électrique", etc. rajoutent une couche qui n'aide pas. Ajoutez à tout ça un ou deux personnages légendaires (comprenez, un boss d'un jeu précédent aux attaques surpuissantes et tape-à-l'oeil), et vous comprendrez que le combat contre un boss dans ce jeu n'a plus grand chose de tactique: c'est surtout une sorte de gros défouloir familial.