Showing posts with label sidescroller. Show all posts
Showing posts with label sidescroller. Show all posts

Wednesday, August 04, 2021

In a cubical world ...

Clay-Zulah did what I had dismissed: a side-viewed, ortho-thing-ic 3D rendering of a 2D game. With a fairly nice result, I must add. The selection of objects is quite well done and there's some Kirby's Adventure vibe in the color and "textures" that manage to make us forget they are all cubes.

The perspective effect is a bit excessive to my taste, but once in motion, I must admit the result is one of the best I've seen so far for such things.

Dans la série des jeux indés dont je suis le développement sur Twitter, il y a le titre de Clay-Zulah, qui a justement opté pour un rendu orthochosique d'un monde 2D en 3D avec des objets très cubique. L'option que j'avais écartée pour un Bilou 3D à la fin du siècle dernier, donc. Et je dois dire qu'avec sa palette et son style "Kirby's Adventure", il s'en sort assez bien.

Sunday, December 03, 2017

cando grow?

Not so easy to fix the state machine bug about Bilou entering ceiling And that is mostly because it is not in the state machine itself. It happens because Bilou has two sizes, and the "HIT" state is one where he is big. Since"HIT" is a state that you can reach from almost any other state, we can't really "fix" the problem by conditional transition.

So I took my code back and started looking around the call to CompoundGob::setbbox() for inspiration.
1. the "grow'shrink." mechanism can be nicely separated along axes. I shall try it on the vertical axis alone so far.

2. I should use cando() function to detect potential issues with virtual movements before I actually change the size. That should be much easier to have something where we check whether we could move up by dy (actually grow upwards) and align coordinates if we can't.


Corriger le problème dans la machine d'état de Bilou pour lui éviter de se manger le plafond se révèle plus compliqué que prévu. Et pour cause: le bug n'est pas dans la machine d'états. Du point de vue du moteur de jeu, Bilou a deux tailles (de bounding box) différentes, et l'état "touché" est un des états où Bilou est grand. Du coup, puisqu'on peut se faire toucher dans à peu près tous les états, il n'est pas vraiment possible d'éviter un changement de taille par une transition conditionnelle.

Il faut donc que je révise plus en profondeur le système de changement de taille (setbbox). Heureusement 1) je peux traiter les axes horizontal et vertical séparément; 2) je peux me servir du système "cando()" pour sonder le terrain avant de procéder au déplacement. 3) si je sais corriger jusqu'à la prochaine frontière de tile, je peux itérer pour étendre à des redimensionnement plus conséquents (à vérifier plus tard).

3 . That will work for small resizing, and .can be extended to duck/stand for.human-sized characters  with a simpe - iteration. I haven't tested that, because all shrink/grow changes in Bilou change size by a mere few pixels. And I presume it wouldn't be completely satisfying for something like granting mushrooms for Super Mario. For one thing, the code assume that it is possible to grow. It won't catch the situation where small Mario would get a mushroom in a narrow corridor of bricks.

Tout ça m'aura demandé pas mal de gribouille pour m'assurer que je comprends bien tous les cas de figure et éviter de devoir mettre un grand nombre de tests excessifs pour traiter plusieurs micro-cas (parce que certaines valeurs sont nulles dans certains cas). Peut-être même que je n'ai plus besoin, désormais, du système qui transmet des consignes d'alignement (avec le centre, le bord supérieur ou inférieur) ... mais ça, ça demande à être prouvé, et on verra plus tard.

It took quite some sketching to find the right adjustments and avoid ending up with tons of tests to find all corner cases, but instead do the right computations, taking advantage of the fact that some terms are just zero in some cases. I think I might even no longer need hints about which side we should align against, but I prefer keeping them at the moment, until I get the proof that they indeed turned useless.

fix

Friday, April 14, 2017

splashers

Quelle sympathique façon de découvrir un nouveau jeu que ce match de splasher entre Usul, Ben et Leo.  Mais il y a mieux: la présence de Romain, le dévelopeur principal du jeu qui nous présente un peu son histoire et celle de son jeu.

There are days were you're lucky if you speak French. Because if you do, you can get all sort of advices on gameplay tuning and interesting relationship between Rayman: Origins and Splasher explained by the game designer himself. 

Le Notuto dans splasher

"Notuto", c'est mon mot à moi pour décrire le fait de construire son jeu pour qu'il n'y ait pas besoin de tutoriel spécifique.  Puisque toutes les actions importantes du joueur passeront par des tirs d'un des liquides impliqués dans le jeu, les premiers niveaux auront recours à des "canons" de l'encre la peinture correspondante. La bonne idée, c'est que ça permet de mieux montrer le côté dynamique (il va falloir peindre) que d'avoir la peinture déjà placée à un endroit donné. ça montre aussi certaines interactions que de la peinture statique n'aurait pas eu. Autre truc "notuto", les ennemis fuyeurs, qui partent en avant quand ils nous aperçoivent et du coup déclenchent des pièges qui les exterminent, nous montrant le fonctionnement de certaines mécaniques de jeu.

Romain took advantage of the primary mechanics of his game (shooting) to present all the variants it could have. Because it is quite easy to have something within the level that shoots too (a cannon) and thus you can have the player watch the new variant before she actually has to do the new variant. 

This is even reinforced in the "free-the-dude" not-so-hidden rooms, where sometimes the simplest winning move is not to move and let the room do the work for you. A nice way to avoid written tutorials, if you ask me.


Puis il y a les "warp zones" où il n'y a parfois rien à faire, pour donner au joueur un moment où il est invité à analyser la situation et trouver ce qu'il convient de faire plutôt que de devoir enchainer des manipulations techniquement exigeantes, qui sont ré-inspirées des "maps-cage" de Rayman Origins.

Le tuning

Parce que Splasher, c'est aussi 3 ans à peaufiner les détails pour que l'expérience de jeu soit celle espérée par le dévelopeur. 
La distance entre l'avatar et la caméra, très dé-zoomée contrairement aux Sonic des années '90. Une grande attention apportée aux déclencheurs d'évènements en fonction de l'avancée du joueur (comme dans SMW), même si apparemment c'est plus "checkpoint par checkpoint" que "écran par écran", sur le coup. Et je n'ose même pas imaginer le travail que ça a dû représenter d'ajuster les zones bloquantes autour des scies pour que le joueur n'ait pas besoin de calibrer *chaque* saut.

Les mécaniques de jeu

Le contrôle en l'air, où on discute sur le contrôle en l'air, conditionnée sur le temps de saut (quasi nul au moment précis de quitter le sol, et prise de contrôle au fur et à mesure que le saut atteint son appogée puis que la descente commence.

Puis il y a le shoot "assisté": on indique une direction et l'avatar tir vers la cible détectée dans cette région-là, par "aimantation de la visée" grâce à une zone d'attraction centrée sur chaque cible potentielle. Cette dimension-là sera plutôt développée dans les phases de "boss".

On va un peu voir dans les prochaines semaines ce que je peux en apprendre pour mon jeu à moi ...

Saturday, September 10, 2016

La guerre des Mascottes

Ça y est : j'ai enfin reçu mon tome 2 de l'Histoire de Mario. Chiffre de ventes à l'appui, William Audureau et Oscar Lemaire passent au tamis les années sabbatiques du plombier, à savoir la période de 1990 (lancement de Super Mario World) à Juin 1996 (fin du développement de Mario 64). Je dis "années sabbatiques" puisqu'entre les deux, les amateurs de fleurs de feu n'auront que Mario Land II à se mettre sous la dent.

C'est pourtant l'époque où tous vont tenter l'aventure de la plate-forme dans le sillage de celui qui tente de faire vaciller l'idole, à savoir Sonic (1991). Bien sûr, il y aura eu d'autres jeux de plate-forme avant et il y en aura d'autre après, mais durant cette période, ils représenteront le gros des ventes de jeu sur console.

Chose peu surprenante, c'est avec la sortie de Sonic que coïncidera l'envie de faire mon propre jeu de plate-forme avec d'abord Calimero de '91 à '93 puis avec Bilou sous Basic entre '94 et '96.

Pendant ce temps, à peu près tous les détenteurs de personnages enfantin forts vont cesser d'"ignorer" le jeu vidéo et attaquer le dangereux Mario sur son terrain : celui du jeu de plate-forme. Ce sera "castle of illusion" avec Mickey, "duck tales" puis les jeux Infogrames qui ratissent autant de personnages de bande-dessinée francophone que possible mais aussi le bestiaire de la bande à Bugs Bunny -- avec plus ou moins de succès. En réaction, les acteurs du jeu vidéo vont aussi miser gros sur les personnages d'animaux antropomorphiques ayant le potentiel de devenir des mascottes, comme le Mr. Nutz de Philippe Dessoly chez Ocean, la chauve-souris acrobatique chez Sun Soft et le controversé Bubsy chez Accolade (que je ne connaissais jusque là que sur PC pour ses simulateurs de course)... et bien d'autres encore qui n'auront atteint ni l'émission Luna Park ni les planches de Midam. Même les robots de combats spatiaux prennent des allures de braves mascottes et tentent de se faire passer pour des abeilles avec des noms comme "twinnbee".

Oh, well. There's been another book by William Audureau, joint by Oscar Lemaire, about years '91-'95 where platformer was the king of video games, and where it looked like everyone could come with a mascot-like hero that would be the next Sonic since Mario was Missing... So I've been reading and reading. And no code has progressed. More luck next week ?

De notre côtés de jeunes ados, on fait la chasse aux magazines, on rève à ce que peut bien être tel ou tel jeu avec un personnage plus ou moins probable. Il semble qu'il y ait un nouveau venu tous les trimestres. Dans quelques rares cas, on aura l'occasion de s'y essayer mais le monde du PC est tristement dépourvu de ce genre d'exotisme. Au mieux, ce sera James Pond II sur Amiga à la maxithèque, ou la surprise de découvrir Moktar reconverti en Titus the Fox. Ils ne sont pas tous des sonic-like tels que Zool, mais ils cherchent clairement à plaire au même public. Et il semble bien que le succès de Sonic décomplexe tous ceux qui hésitaient jusque là à faire des chat-tout-mignons comme personnages de jeu: il suffit de leur coller un élément vestimentaire de jeune, une attitude cool-et-frondeuse, et en avant. Sur micro, on le prendra avec une dose de dérision, et j'ajouterais bien "Super Frog" (PC, Amiga) à Jazz Jackrabbit & James Pond ... mais le plus souvent, on avait droit à un gros raté du genre "Skunny the Wild West".

Le tandem William-Oscar gratte donc derrière les couvertures de magazines et effectue un impressionnant travail pour rassembler les interviews, les mettre en contexte ... Car si l'un va titrer "la nouvelle mascotte de XXX", ce n'est pas nécessairement l'avis de la société qui l'aura publié, ni du studio qui l'aura créé. Et si les personnages humains (Commander Keen ? Duke Nukem ?) sont assez peu présent dans l'analyse, les "héros/mascottes" improbables tels que Plok ou Cool Spot eux, ne sont pas oubliés.

Il met aussi en perspective les travaux de l'équipe de Miyamoto -- qui n'est évidemment pas restée les bras croisés pendant 5 ans -- qui sans parvenir à donner un deuxième jeu où l'on saute vers des blocs-questions à la SuperNES va se frotter à toutes les technologies de pré-3D afin d'avoir le meilleur Mario 64 possible quand sera enfin prête la console 3D de nintendo.

Il y aura finalement peu de suites parmi les "héros fabriqués spécialement pour l'occasion" ... et aucun ne parviendra à survivre à l'environnement des 16-bits où il a vu le jour, que ce soit pour des raisons de fusion/acquisition/license, par incompatibilité technique entre la vue 3D et les mouvements du jeu de plate-forme, ou simplement parce que les artistes d'animations qui donnaient vie aux personnages se retrouvent privés de tout repère devant les logiciels de modélisations polygonales.

Vous l'aurez compris, même s'il y avait beaucoup moins de matière pour le game-designer-amateur que je suis, le livre m'a malgré tout tenu en haleine. Bon, évidemment, avec tout ça, le travail sur l'amélioration de SEDS et LEDS, mes éditeurs de jeu sous DS, n'ont pas beaucoup avancé ^^".

Sunday, May 15, 2016

En direct de Leilani's Island

Dans son petit coin de web, Ishi (Craig Forrester, auteur de Johnny biscuit et Princess Chardonnay entre-autres) nous prépare un adorable jeu en pixel art dont le gameplay rappelle assez bien celui de son jeu favori: Wario Land. Bien qu'étant un jeu de plate-formes, le jeu s'articule surtout sur la "roulade" de cette charmante protagoniste. Du coup,

  • la roulade permet d'aller plus vite que si on courait,
  • la roulade permet d'attaquer certains ennemis de face, plutôt qu'en les écrabouillants. En fait, tout comme dans SML3:WL, sauter sur un ennemi ne l'élimine pas. Faire une roulade bien.
  • le saut est volontairement limité (3 blocs, 4 en rebondissant sur un ennemi) pour qu'il soit plus intéressant de se servir de la roulade que de l'éviter.
  • Certaines plate-formes (les cordes) ne peuvent être traversées qu'en roulade. 
  • C'est en poussant sur ROLL en l'air qu'on lance l'attaque spéciale de la fleur de feu, et parce que ça fait bizarre que le bouton ne fasse rien dans certains cas, Ishi ajoute un "annulateur de saut" pour celui qui fait "ROLL" en l'air sans avoir ce power-up.

Hats off to Craig Forrester (Ishisoft) for his brilliant work on Leilani's Island. I hope he won't mind that I keep note here of the good design decision he took to have the game focus on one rich, interesting and funny mechanic: the island girls' ROLL move. If you really don't read French, I suggest you randomly click links in the French text to be sent to some of Craig's updates that I found especially interesting. I hope I'll be able to make Bilou's Adventure as rich as this. Btw, have you noted that Craig selected the 400x240 resolution of the 3DS ?  

Décision sympathique, c'est en ajoutant une fleur dans ces cheveux que Leilani augmente sa force. Et oui, elle peut aussi utiliser une fleur de feu. Mais ici il s'agira d'une attaque-roulée plongeante, capable de détruire des blocs. La combinaison de l'attaque-rodéo de Mario et le bouclier de feu de Sonic. L'utilisation de la diagonale lui permet de rendre les choses plus prévisibles (plus de timer "chéri, ça va couper"), plus faciles à viser (qu'à l'horizontale, en tout cas), et moins génant pour celui qui voulait simplement faire une roulade en atterissant. Bien vu.

Avec son mécanisme de "j'te roule en boule", le jeu permets plein d'aspects-puzzle, renforcé par les effets de réactions en chaîne sur les blocs. Oui, parce que -- contrairement à Bilou jusqu'ici -- le jeu assume pleinement l'héritage de Mario avec des blocs-à-bonus que l'on peut frapper verticalement ou latéralement, et d'autre blocs qui se fractureront si on les frappe assez fort. Cette histoire de réaction en chaine est encore renforcée par des séquences d'objets. Bref, côté éléments à coder, Ishisoft n'est pas en reste.

C'était déjà riche comme ça, mais Ishi nous rajoute encore les fruits, éléments interactifs un peu comparables aux carapaces de koopa, sauf que je n'en ai pas encore vu blesser le personnage. Et pour s'assurer que tout va bien, rien de tel qu'une map-unit-test qui montre en un écran toutes les interactions possibles entre les différents éléments du jeu.

Ishi nous dévoile aussi un truc que je ferais bien de réutiliser dans le développement de Bilou:  l'enregistrement de la trajectoire lors d'une scéance de jeu qui peut servir par la suite à placer des bonus précisément sur la trajectoire proposée au joueur (c'est très KirbyKid-esque, ça ;)

Il est aussi fréquent qu'il teste ses idées de jeu (ennemis, éléments spécifique à un environnement) dans un décor de blocs colorés tout génériques ... le graphisme vient alors plus tard.

Il me reste un gros morceau à lire: le système d'interaction entre les objets.


Object-to-Object collision has been recently revamped in Leilani's engine. In most collision, one object sends several "collision probe", to which the other object replies with either "NONE" or with a custome message indicating how the originator (typically Leilani herself or a rolling baddie) should react.  I think I keep preferring my own approach combining the active/passive roles of Out'm'Up with the CAN_xxx flags of Xargon Engine.

In my engine, I'd have

  • Leilani.walk { test F_COLLECT ; area F_HIT }, 
  • Leilani.roll { test F_COLLECT|F_ROLL } as well as Baddie.roll { test F_ROLL|F_COLLECT }. 
  • Shells would be passive and have only {area F_COLLECT }. Possibly you could need a second flag for F_COLLECT_PUP, so that only Leilani gets flowers. 
  • Spiky.walk would have { test F_HIT; area F_ROLL } : it actively hurts leilani, but may be rolled into.
those "test" and "area" commands may correspond to distinct hit boxes, allowing e.g. spiky to be rolled in the back, but still hurt in the spike.

Friday, November 15, 2013

horizontal position.

What if one reason for players failing to clear the large-pencils-pit was that they can't predict what's ahead? With the 'G88' release of the anniversary level, Bilou was tightly centered on the screen (horizontally). So tightly that you could barely see a few pixel of the other side even though you dangerously adventured over the first pencil.

Cette fois, j'en ai, des retours de beta-testeurs. Au point que je ne suis plus la cadence pour le blog lui-même ^^". J'ai passé un certain temps à faire des ajustements sur le système de caméra, notamment pour faire en sorte qu'on ait une meilleure vision sur ce qui nous attend. Cette rangée de crayons, à droite de Bilou, saura-t'on la passer en sautant ? Faut-il courir ? Faut-il chercher un autre chemin ? délicat à décider si on en voit pas la fin, hein?

L'occasion donc de refaire un tour d'horizon et de voir où sont positionnés les héros dans les jeux de plate-forme qui me servent de référence. Commençons par New Super Mario Bros et ses variantes: Mario est (du point de vue horizontal) au centre de l'écran. Dans SMB3, c'est l'arrière de Mario qui est au centre: il tire véritablement la caméra derrière lui, ce qui lui donne l'occasion de faire un demi-tour sans à-coup de caméra qui donnerait la nausée au joueur. Simple, donc mais aussi paradoxal: le joueur voit mieux les obstacles qu'il vient de passer que ceux qui restent à venir.

But what is the behaviour of canon platformers ? It looks like NSMB always center Mario and it feels fine. True, but NSMB can zoom out when you will need more vision of what's going on. Plus, I'd bet you could beat any level without running. Large leaps with the RUN button held down are on alternative paths only. For the record, SMB3 was even weirder: Mario litterally pulled the camera behind his back! Granted, that allow for smooth turn backs, but that somehow kills visibility. Hopefully, the Racoon suit can save you from unforseen pits ^^"

À l'opposé, Rayman PSX se situe presqu'à 1/3 de l'écran, ça donne bien au niveau de la composition d'image (disent les artistes) et ça dégage la vue. En revanche, ça fait un fameux travelling chaque fois que le joueur se retourne. Si ce n'est pas trop délicat dans la majorité des niveaux, en revanche, ça rend les combats contre les boss particulièrement agaçant puisqu'on les perdra de vue presqu'immédiatement après avoir essayé de s'en écarter. Il faudra se retourner à nouveau pour savoir quelle attaque ils préparent (ou retenir l'enchainement par coeur).

Rayman goes a bit extreme when placing the hero almost on the 1/4 boundary of the screen. True, you'll get good preview of what's ahead (and that's very welcome), but if you have to move back and forth, it will quickly annoy you with wavy behaviour. And you'll have to move back and forth *a lot* when fighting bosses. Even worse: your position on screen is not based on your state (staring left or right) but on your (last) speed. When swinging or on mobile platforms, the camera may suddenly shrink your vision of what's ahead by 50% at critical instant. Donkey Kong Country (which also has the character near 1/3 of the screen) solves this my centering your Kong perfectly when he's on a swinging rope.

Autre hic, le système de caméra ignore en réalité dans quelle direction Rayman regarde: il ne connaît que sa vitesse. Du coup, sur une plate-forme mobile qui fait demi-tour, votre visibilité devient tout d'un coup réduite de moitié sans que vous ne puissiez rien y changer >_<.

Un qui m'a surpris, en revanche, c'est Super Mario Bros. sur NES. Bien sûr, le jeu n'autorise pas la marche arrière, et on pourrait donc "fixer" Mario à 1/3 de l'écran pour avoir une bonne visibilité sans souffrir des défauts de caméra de Rayman. Pourtant, à vitesse de marche ou à l'arrêt, Mario se situe au-dessus du 8eme des 16 blocs que l'écran affiche. 1/2 écran entier devant soi, en somme.
En revanche, dès que l'on se met à courir, l'écran se centre différemment et ramène Mario d'un bloc en arrière, libérant un peu plus le champ de vision.

I've been quite surprised, however, to see the behaviour of SMB on the NES. Since the game always moves to the right, I'd have expected Mario to be somewhat near 1/3 of the screen. But it's not. It's almost centered (it pushes the screen center with his nose, rather than pulling it with its back as in SMB3) *unless you run*. As soon as you gained significant speed with the RUN mechanic, you've been moved backward by 1 block.

Bien sûr sur SuperNES, l'habitude était de proposer au joueur de regarder en avant et en arrière avec les boutons L et R, mais j'aimerais garder ces boutons pour faire tourner Bilou dans tous les sens. Le coup de SMB1 m'a donc donné l'idée de laisser continuer la caméra pour qu'elle se centre en avant de Bilou lorsque celui-ci s'arrête. Le joueur n'a donc qu'à marquer une pause s'il veut savoir ce qui l'attend ^_^

Since I want to keep L and R for later purpose, I came up with the following idea: why wouldn't I use the "idle" state to change the ideal camera position ? Do you want to see more of what's ahead ? just relax, wait a little bit and that will be shown to you ^_^. I adapted the camera system so that it become feasible, and tweaked the parameters so that you don't get jerky camera motions when doing funny things like "turn back while jumping before the camera settled on your idle position", but I think it's now working nicely. I hope it will pay off for the future beta-testers. There's something similar in DKC, btw: when entering a barrel, the view is shifted somewhat more towards the blast's direction

Thursday, June 20, 2013

DpadController::timeout

Back in 2010, I had introduced a tweak to the DPAD reading so that you wouldn't bounce again and again by just holding the JUMP button down. That seemed efficient enough. Whenever a button (DPAD excluded) was pressed, a timer was started, running for 30 frames, and as long as this timer hadn't reached zero, the transitions of your state machine would read the button as "pressed". That allowed players to do special bounces when bopping on applemen wihtout requiring 1/60sec. precision. That's called "input buffering" anywhere else in gamedev documents.

Comparé à un clavier ou à un joystick de PC, la saisie des mouvement du joueur sur le DPAD de la DS est une vraie partie de plaisir. Pensez un peu: un emplacement mémoire qui contient directement l'état de chaque bouton de votre console !
Celà dit, s'en servir pour alimenter la logique d'un jeu de plate-formes comme Bilou demande un tout petit peu de subtilité quand-même. Selon les situations, la question n'est pas uniquement "est-ce que le bouton de saut est enfoncé" mais plutôt "depuis combien de temps le bouton de saut a-t'il été enfoncé ?"

Shortening the "time window" (::delay) to 10 frames actually reduced the maximum height for jumps! After rising for 10 frames, the game logic is indeed notified that the key was released, and switch to "end-of-jump". Annoying. I already had the feeling that the "action" button may need to be held and thus be "timemask-free", but the issue is actually deeper. It means whether you use the timer mechanism or not depends on the state you're currently in.

Eh, c'est que rebondir sur la tête d'une tortue pour aller plus haut, c'est bien rigolo, mais s'il faut enfoncer le bouton précisément dans le 60ème de seconde où la collision a lieu, ça devient franchement trop exigeant. En revanche, voir son personnage faire un deuxième saut spontanément en arrivant au sol, c'est perturbant. J'ai donc depuis un moment déjà un mécanisme qui décompte les "images de jeu" depuis que le bouton (croix directionelle exclue) a été enfoncé, de sorte que la logique du jeu regarde surtout si ce décompte est arrivé ou non à zéro. Mais pour que Bilou puisse s'accrocher aussi longtemps qu'on le veut aux éponges, il faut en plus que je puisse définir, état par état, quel(s) bouton(s) ont le droit à un "décompte infini".

While moving up in a jump, you want to check simply whether the button is held or not, and keep pushing up as long as the button is pressed. When going down, however, the timer mechanism is applied so that you only get your special bounce if you hadn't pressed the button too much in advance. Similarly, the "action" button uses the timer when you're falling down, but as soon as you switch to the "grabbing spongebop" state, it just checks whether you're still holding it down. Same would go for mario-like running, for instance.

Friday, June 07, 2013

walking on platforms

I was somehow 'home alone' Wednesday evening. But my eyes were stabbed by my laptop's backlit. Perfect mood for some thinking on game engine features with some pens & paper. Theme ? How to enable Bilou walking on platforms. I initially hoped that a GOB reference would be sufficient to "walk on a platform", but that would restrict us to "platforms that have just the shape of the object's bounding box, while there is much more I intend to do with a generic "dynamic path" abstraction!

Cette fois, je pense que je tiens enfin le bon bout. J'ai réussi à fusionner la notion de "chemin" modifié dynamiquement (pour les cordes qui se balancent, entre-autres), et de plate-formes.Tout ça en prenant le temps, pour une fois, d'y réfléchir en cherchant quelles sont les questions auxquelles il faut apporter une réponse plutôt que d'essayer de construire une solution en partant d'une page blanche. Un système efficace qu'il faudra que je réutilise plus souvent.

And for once, I didn't started building a solution, but rather by writing down the questions that need to be answered. Once again, it proved being a powerful exercise. The questions were:

  • Is the "path" object permanent ? sometimes
  • Is the "path" object redundant ? only in the basic case
  • Could a GOB walk on more than one path (at once) ? no
  • Who 'own' a path ? usually, a GOB.
  • How many path can be owned by an owner ? I don't want to limit.
  • Can we be both 'on path' and owning a path ?  Yes (see picture above)
  • How could the owner of a path force objects on that path to lose their reference ?
Now, it's time to be more precise. The path is redundant with collision box in the very case of an horizontal platform. Yet, collision boxes (GobAreas) are not easily accessed from a GameObject reference. For once, I recall of Super Mario World's slanted platforms in the Chocolate Zone. It's still linked to a GameObject, but it will require a dedicated y=f(x) function.

La clé, c'est d'arriver à la formule "l'objet GPath est redondant avec la GobArea -- les zones rectangulaires utilisées dans la détection de collisions entre sprites -- dans le cas précis où l'on veut que le chemin aille de (gob.x+area.left,gob.y+area.top) à (gob.x+area.right, gob.y+area.top)". En d'autre termes, GPath est une abstraction générique, et le GobArea contient les données nécessaires pour cette abstraction dans un cas précis, mais on ne souhaite pas que le code utilisateur soit exposé à ces données. L'exemple-type d'une classe implémentant une interface ^_^. Il me faudra bien sûr d'autres implémentations si je veux des plate-formes inclinées, rotatives, basculantes, et tout ce que NSMB a apporté aux jeux de plate-formes ... mais le code de base "marcher sur une surface" restera là.

I also think the "path" we walk on must be potentially dynamic, that is, manipulated by a controller, for swinging ropes (example of a vertical path) or those NSMB dancing giant mushrooms. Writing it down as "only in the basic case (GobArea), but as a function of what I already have" made the bell ringing: GobArea is a specific implementation of the GPath interface. Virtual methods and inheritance are what I need to avoid cluttering controller's code with interpretation of coordinates array.


It also nicely solves the "ownership" (and thus allocation) issues. I know that things like huge mushrooms would have their Path allocated with level-scope, and then manipulated through a controller. The Gob that runs that controller is likely to be permanent as well.

Path for a platform, on the opposite side, are required only as long as a character interacts with the platform. By making GobArea ISA GPath, and stating that all coordinates resolutions are relative to the owner's coordinate, it means that all the platforms in a current state may share the same "path" information (offsets to their local coordinate) and  function implementation. Nice. They stop being "transient/temporary" structures and get level-wide scope as well: the allocation problem disappears ^_^. It do mean, however, that the "gobs" that control movement of multi-segment, dynamic paths will not be able to be themselves on a path, as they'll need their "path" reference to define what path they're altering ... unless I find a better solution, I can live with that.


L'autre bonne nouvelle, c'est que celà règle également les problème de "responsabilité" entre objets. Je trouve cette notion de responsabilité fondamentale en C++: une fois qu'on a pu définir qui est le seul et unique responsable d'un élément, alors on peut gérer beaucoup plus facilement son allocation, surtout lorsque les durées de vie coïncident. "Un chemin pour marcher sur une plate-forme", à priori ça a une durée de vie assez brève: du moment où Bilou entre en collision avec la plate-forme jusqu'au moment où Bilou s'en détache (de son chef ou de celui de la plate-forme, d'ailleurs). Un vrai cauchemar, surtout si on commence à se dire qu'il serait sympa qu'un autre ennemi arrive à la rencontre de Bilou sur cette même plate-forme!

En revanche, dès que GPath n'est qu'une façon de regarder la zone de collision (GobArea), tout s'arrange. Les "GobAreas" ont une durée de vie identique à celle du niveau et sont sous la responsabilité des états des machines d'état (et donc partagées par tous les objets d'un même type). C'est tout à fait satisfaisant si on considère qu'elles définissent des fonctions y=f(x) dans des coordonnées relatives à l'objet auquel Bilou est attaché.


All I still need in addition to the existing Attach, Detach and AttachToPath 'interaction opcodes' in GobExpressions is a 'IsAttached' test that will allow me to craft "force-detach" collision boxes that won't detach objects from other platforms ^^".

Friday, May 24, 2013

Un grand pas en avant ...

Pas évident d'avoir des pentes correctement intégrées dans le déroulement du jeu.

Souvenez-vous: dans Apple Assault, si les pentes fonctionnaient presque correctement, il me restait une certaine probabilité que Bilou se "bloque" arrivé au sol, et ce n'est qu'avec la révision du moteur de jeu en Septembre dernier que le bug fut corrigé. Mais on était pas tiré d'affaire pour autant...

A force de refaire des tests pour m'assurer que Bilou ne puisse plus se bloquer dans les murs suite à un atterissage en catastrophe (en mode "pas à pas"), je finis par me rendre compte il y a quelques semaines que lorsque Bilou arrive au bord d'un livre (terminé par un tile pentu en bordure), il oscille quelques fois entre "marcher" et "attendre" avant de finalement se décider par sauter. C'est la plupart du temps presqu'imperceptible pour le joueur qui ne notera peut-être qu'un temps de retard, mais je me suis mis avec ce projet d'avoir un moteur de jeu irréprochable. Exit l'à-peu-près et les excuses bidon: si je ne peux pas être le moteur candidat pour Super Mario World 3 sur SNES, alors le côté "documentation de comment on aurait sans doute pu faire les choses avant de passer à la 3D" perd sa raison d'être.

My nephew had pointed out that Bilou could get stuck in the "School Zone" quite a while ago, and while I was checking that I fixed that properly, using step-by-step mode in Inspector Widget, I realised that Bilou would also temporarily "stick" to book corners before falling down. In stop motion, one could have noted that it flickers between walk and idle 2 or 3 times before actually jumping off the cliff. I want a rules-perfect engine, not a "we can play it out", so I invested several evenings figuring out what was actually wrong.

As in many engines, I handle slopes using a 'hotspot' pixel that must stay on the 'curve' defined by the slope. The rest of the character (the dark box) may enter slope tiles or be in the void, what it doesn't cando() is entering those black, solid tiles (which is checked separatedly). Making sure this looks nice is the level designer's problem, not the engine's. Within a tile, when the horizontal coordinate is changed by the 'walking' behaviour, we retrieve the ground height for the corresponding target pixel and align the hotspot there. With that approach, we may end up in a tile that has no ground at all (gh=0) when switching to the next (horizontal) tile. In that case, the alignment is performed on the tile just below.

Commençons par un rappel du fonctionnement des pentes dans mon environnement découpé en pavés (les "taïlze/tiles"). Bilou n'y est qu'un rectangle qui doit pouvoir naviguer sans rentrer dans les tiles solides (noirs). Il possède en plus un point de référence (hot spot, en rouge vif sur l'image) qui doit rester en contact avec le sol lorsqu'on suit une pente. Pour avancer d'un pixel vers la gauche, le hot'spot passe d'abord dans un tiles complètement vide (gh=0) où il n'y a pas de sol à suivre. La fonction do_slopes détecte ça et teste du coup le tile situé juste en dessous. Son pixel le plus à droite correspond à une hauteur gh=-8. On se retrouve ré-aligné sur le prochain pixel ... tout va bien.

Le problème apparaît seulement lors d'une transition pente/trou, comme j'en ai ajouté sur le bord des livres. Ici, lorsque'on regarde sous le tile vide, il y a ... un tile vide. Pour do_slopes, celà signifie qu'il n'y a plus de pente à suivre.  Idéalement, on devrait donc juste se retrouver "le long de la ligne bleue" inférieure, qui empèche Bilou de tomber jusqu'à ce qu'il l'ait complètement quitté. Mais voilà, à ce moment-là, on est pas encore sur le sol! Du coup, lorsqu'on teste s'il est possible de tomber d'un pixel, la réponse est "oui" et le contrôleur envoie un FAIL.

Now, when we instead have a sloped edge, as with books, both tiles are AIR and have no "ground" to align on. The do_slopes function then consider there is no slope to follow and let the walker::think behaviour function to adapt accordingly. Walker's behaviour is then to walk as long as possible, testing whether Bilou cando a move downwards (meaning he can fall). That would be all fine if Bilou was aligned on the blue line by then, but he isn't. he's still one pixel above, because that's where the slope ended.

Would have it implied that Bilou started falling earlier, I wouldn't have minded. But that's not what the state machine decides. from its perspective, the backward testpoint is still on the ground and thus the FAIL even is translated into a transition to idle state rather than towards fall.

Seulement, voilà, l'échec du contrôleur n'implique pas forcément une chute. C'est à travers les transitions du comportement de Bilou que les choses vont maintenant se jouer. Tomber d'un pixel ne serait pas impeccable, mais celà nous conviendrait. Seulement, pour celà, il faudrait que le point-test placé au sol indique du vide ... et étant décalé sur la droite, il est toujours dans la pente! Du coup, c'est vers l'état "do_slopes. C'est ainsi qu'on parvient finalement à quitter le livre après ce qui semble être un instant d'hésitation.
à l'arrêt" (idle) que Bilou passe. Mais puisqu'on a toujours le DPAD incliné vers la gauche, on quitte dès l'image suivante cet état pour tenter à nouveau une marche... qui échoue encore. Heureusement, à chaque échec, on avance d'un quart/demi de pixel qui correspond au "mouvement entammé".

Une fois que l'Inspector Widget est devenu assez précis pour faire ce genre d'analyse, il devient assez évident que la solution est de forcer le personnage à s'aligner sur le sol quand on quitte une pente, et de ne considérer qu'on chute que s'il est possible de descendre alors que le personnage est déjà aligné sur ce qui devrait être du sol.

The actual solution is of course to ensure that we're aligned on ground when there's no slope. Only if we cando the move downwards *while being on a tile boundary*, we will claim it a FAIL move that should switch to some other state. But to realise that, significant upgrade on InspectorWidget's precision was required. I even was tempted to turn this post into another "Inspector Widget's novel" post, but the implication on the game engine and behaviour coding was too high, and I'd rather went for a tutorial shape.

Pour faire bonne mesure (et pour éviter que Bilou ne se retrouve en suspens sur un bord de livre parce qu'il n'a pas sauté assez haut), j'ajuste enfin le saut à travers une plate-forme à sens unique (les branches de Apple Assault): on ne peut plus atterir sur ce type de plate-forme que lorsqu'on vient d'au-dessus de la plate-forme.

Tuesday, February 05, 2013

Rope it up!

Paul's tutorial on ladders was on my "readme" list for the Cybook last night. I liked how he motivated them as a way to introduce discontinuity in control mechanics and physics response. It sounded "Eureka" in my mind and I wanted to go further, so I asked Bilou and Bouli to illustrate the other concepts of the article.

In my game engine, such discontinuity can be handled naturally as I can attach different control chains to the different player states.
(Note that I will consider that ropes are just an visual alternative to ladders, that do not bring significant gameplay difference -- i.e. you can't swing ropes yet).


J'aime beaucoup la façon dont Paul Firth introduit les échelles dans son tutoriel. "Rompre la continuité du gameplay". Forcer le joueur à utiliser temporairement d'autres règles de déplacement que celles du platformer, et donc l'obliger à se défaire d'une part de son "confort" de marcheur. Rien à voir, donc, avec le grillage ou Mario se déplace librement dans le château d'Iggy.
La bonne nouvelle, c'est que ce genre de dualité est parfaitement prévue dans mon modèle de "machine d'états" pour la gestion des personnages. Pas besoin, donc, de rajouter des booléens dans tous les sens et des tests tous côtés.

En outre, dans un niveau largement fourni en "plateformes à sens unique" (p.ex. un empilement de livres ;), les cordes et échelles peuvent aussi être un moyen d'offrir localement au joueur la possibilité d'aller "à contre courant". Une seconde bonne raison de ne pas se contenter du moteur de jeu actuel, donc.

Another think that ladders/ropes bring is that they introduce platforms that can be "climbed down". Platforms that let you jump through but not fall through is pretty common in platformers, and they let you build levels where the player is denied to move backwards. A rope is an escape path in that way.

Now let's move to the technical part. The walk/climb transition is not so obvious to set. In Paul's approach, it involved the introduction of several sub-states and sub-tiles type to be processed properly. This is typically the kind of thing that I've learned to be bug-prone and that rather quickly limits the addition of new mechanics to your character.

Ideally, it must be possible to let the game engine align the character to the rope/ladder so that climbing animation works. As mentioned in a former post, this require the combination of the cando(F_LADDER) property on the tiles occupied by the character and dpad&KEY_UP guardian expression.


Il me faut donc un "micro-contrôleur" de personnage capable de s'aligner sur une échelle (align_flag), un capable de créer un évènement lorsque le personnage passe à un endroit où un nouveau mouvement est possible (detect_flag), et évidemment, un comportement pour monter/descendre à l'échelle. Le reste n'est plus qu'affaire de mettre le bon contrôleur au bon endroit, et à filtrer les évènement générés par detect_flag en fonction de la direction prise par le joueur.

It may also happen that you insist on your player to release DPAD left/right before he can climb. This is more likely to be the case to climb down: pressing DOWN will first force Bilou to duck. Only in that "duck" state, we check for ladders. The "align-to-[F_LADDER]" behaviour controller can then be affected to the "getting down" non-cancellable animation.




Tuesday, September 04, 2012

Smooth Slopes at last!

After so many tests where I had to jump slightly when approaching the bottom of a slope, having flawless, smooth moves in the school zone almost feel magic!

Funny enough, the doslopes() function that I crafted carefully was already flawless, but the defects were in the glu code (the walker controller) that interfaces that with the animation replay. As I expected from the start, the step-by-step movements system was the root of the problem. It essentially nailed down to 2 things, that occured when leaving a slope:

  1. in that case, I need to check whether the character could fall. Bug #1 was that I wasn't completely taking care of the horizontal adjustment in that case, and it resulted in "no, you won't fall at coordinates (99,60). you can safely move and stand at (100,60)"
  2. when falling down, the controller actually FAILs to keep walking, but that means (for the animation replay subsystem) that the defined speeds are cancelled. The problem is in the case of walking off a cliff, the horizontal move has been validated and it should *not* be cancelled. Only the absence of vertical move changes.


I updated the demo link accordingly in the "back to school" post ^_^

Sunday, July 08, 2012

Best-of Pix'n'Love : Nutz

IMG_0337
C'est sans aucun doute un des articles que j'ai préféré dans l'ensemble des pix'n'love. Plusieurs testeurs de Bilou: green zone demo ont noté une similitude avec le Mr Nutz "de Ocean" dans les années nonantes. En fait, il s'agit de l'oeuvre de deux personnes, un graphiste (Philippe Dessoly) et un programmeur (Pierre Adane), avec pour objectif principal de se faire plaisir... une sorte "d'Indie Game" avant l'heure, mais à une époque où ce genre de délire d'artiste pouvait finir en couverture de magazine et en version cartouche devant un grand présentoir en carton... Vous imaginez ça pour Spelunky ?

The interview of the team behind Mr Nutz is one of my favourite Pix'n'Love entries. The game started as the masterpiece of 2 people, one graphist and one coder who wanted to make the game they'd love. An indie title before indie was a thing at an era where it was everything and you could pitch a publisher with your demo and eventually have the game burnt into a cartridge, shown on the front page of the monthly magazines. It was an unprecendented era where some talented artist could get involved into game making without having to learn odds of graphical processor programming first. Mostly thanks to the drawing software of the Amiga.

C'est aussi une époque-charnière, où un graphiste/animateur formé pour le dessin animé pouvait enfin se mettre à faire du jeu vidéo sans nécessairement devoir d'abord apprendre en détail le fonctionnement du circuit graphique qui allait faire le rendu. Entre-autres sans doute parce que l'Amiga pouvait assez facilement réexploiter au niveau software les graphismes qui avaient été réalisés avec ses outils de dessins.

The interview has everything you could dream of: direct talk with the developers, screenshots and original design documents, focusing on "what we had in mind while we worked on the game", spiced up with trivias about what it was to work remotely when long-distance calls where neither cheap nor reliable and that you'd rather put floppies in a postal package after you checked the weather.

IMG_0334

Au-delà du charisme de ce jeu (auquel je n'ai pourtant presque jamais joué), l'article reprend tous les éléments qui me tiennent à coeur: une vraie interview, appuyées par des documents d'époque de design du jeu, qui va à la rencontre de "ce qu'on avait en tête pendant qu'on a travaillé sur le jeu".

L'histoire des diskettes de graphismes relayées par chronopost m'a fait sourire: nous autres, à "PPP Team", c'était diskettes en poche jusqu'à l'Athénée et on essayait de se les échanger avant de devoir s'asseoir à côté d'un radiateur, sinon c'était le "bad sector" assuré. Puis plus tard, ç'a été "démonte le disque dur de 120Mo, emballe-le dans un essuie de vaisselle, et je le mets dans ma boîte à tartine. Grouille: on va louper le bus pour aller chez Tog et TBob!"

Je serais curieux de tomber sur les sources du jeu d'origine, tiens :)

edit: Oh. On nous fait une soirée-interview, tiens.

Friday, January 20, 2012

Picking a Tile size.

Reading further through the Sonic Physics Guide, I noted that the collision mechanisms used (two "vertical sensing bars" for each feat and one "horizontal sensing bar") calls for a certain ratio between the character's collision box and the tile size. The rule is simple: your character should be able to stand on a single tile, and it should also be able to fall into a hole that's one tile wide only.

Another observation is that Sonic is 2 tiles high, which makes it more convenient to push items, but which also makes the 1-tile-high obstacle more convincing. Let's think about it this way: if there was a boulder that's half your size high (let's say almost up to your belt), would you have to do a special action (e.g. jump) to go over it? How about an obstacle that comes only up to your knees ? And halfway on your tights ?

My feeling is that, visually, an obstacle that's only coming up to your knees can be simply stepped on. Something that comes up to your belt is a real barrier. That's what a tile should be.

And well, unfortunately, Bilou isn't quite following those guidelines so far, but Bilou is quite far away from the Vitruvian Man (despite equally being an alien ;-)


2 tiles de haut contre 1 de large. Pour un personnage bipède, c'est l'idéal, si je tire les conclusions qui s'imposent de la lecture du Sonic Physics Guide. Attention, je parle ici de la zone de collision. À aucun moment celà n'implique que l'on doive caser tous ses dessins dans un rectangle de 20x40 comme dans le RSD game-maker, hein ?

En revanche, il est indispensable que le personnage puisse "tenir debout" sur un élément constitué d'un seul "tile" sans que ça ne paraisse bizarre au joueur. Idéalement, il devrait aussi pouvoir tomber dans un trou qui ne fait qu'un seul tile de large.

Difficile de dire si c'est le cas ou non pour Bilou, par contre. Ok, il est loin d'avoir les proportions de l'homme de Vitruve, et sera plus proche de 16x24 pixels dans la school zone qu'autre chose. Difficile aussi de lui appliquer la règle "un obstacle doit plus ou moins arriver à la ceinture pour avoir l'air un rien costaud"... Mais je garde ça en tête pour la révision de Badman...

(ces 2 croquis Biloupométriques datent de 2005, quand je m'étais mis en tête de faire une version 3D de la school zone en utilisant OGRE ... et que je me suis rendu compte que je ne parvenais plus à dessiner un Bilou correct qu'une fois sur 4 :P)

Saturday, January 07, 2012

Climb up, and start the ro .. nevermind.

Voilà bien le genre de "mini-cave" cachée dans le monde de Shantae qui m'aura fait souffrir ... (et qui renforce mon impression que le jeu tient presqu'autant du "zelda" que d'un jeu de plate-forme classique, au passage). Pourquoi ? parce qu'il va falloir sauter de chaîne en chaîne jusqu'au coffre ... et retour. Et assez curieusement, dans Shantae, s'accrocher à une "corde" verticale en cours de saut est assez délicat.

Grab a "rope", climb up, hop, grab the next rope, climb down a bit, hop, grab, hop, grab, climb ... This is sure nothing new. I think even Pharaoh's curse had a screen that was designed along that rule. And you'll sure face it a couple of time in the armaggedon machine as well. So why is it so tedious to perform it right here ?

Pour s'accrocher, il faudra que le joueur presse le DPAD en direction "haut" pendant qu'il saute (vers l'avant, de préférence). Et on dirait bien que sur la DSi, ce genre de manipulation est assez peu pratique. On passe un tout petit peu trop facilement de la diagonale "haut-droite" à la position "juste vers le haut", auquel cas Shantae s'immobilise presqu'immédiatement et tombe si le joueur n'a pas bien estimé la largeur de la zone de collision de la chaîne.

Well, first, I'm playing Shantae on the DSi, with a DPAD, while I mostly grow my platforming skills with a keyboard, where there's no such thing like a "diagonal" position. And apparently, holding the DPAD in a diagonal position is not so easy. As Shantae quickly loses her horizontal velocity if you release the "right" direction in-air, you're better have a very precise understanding of how wide the collision area for those "ropes" is, or you might end up to instruct the game to "climb" when that cannot be done (not yet), and just start falling where you are. I'll have to keep that in mind when I'll implement vines-climbing in Bilou.

Keen demande lui aussi que l'on presse vers le haut pour s'accrocher aux "barres verticales". Mais ayant majoritairement joué sur clavier, ça ne me posait aucun problème.

edit: Super Princess Peach, de son côté, à une étape d'alignement aux échelles bien visibles et progressive (donc, au départ, on se déplace en diagonale puis verticalement).

Sunday, July 31, 2011

Sonic Camera Management

Le suivi de Sonic par la caméra fonctionne donc sur le principe d'une "zone" de focus dans laquelle le centre de Sonic est confiné. Selon qu'il est au sol ou non, la taille de la zone change, mais surtout, dès qu'il en sort, la caméra se déplace d'autant qu'il faut pour y ramener Sonic (avec tout de même une vitesse limite qui permet parfois à Sonic de "larguer" la caméra... et le joueur).

La grande différence avec le code dans Bilou, c'est que jusqu'ici, quand Bilou sortait de la zone de la caméra, j'accélérais le déplacement de la camera, pour ne le décélérer que si Bilou débordait à nouveau de l'autre côté, ce qui amenait des "oscillations" particulièrement gènantes en cas de saut, car l'écran allait continuer à monter de plus en plus vite alors que Bilou commençait déjà à redescendre.

Voyons un peu si ça colle avec mes "désidératas".

A state-dependent "allowed onscreen window" and a speed limit. That's all you need to get sonic-perfect scrolling. That is, the area of the screen where your character is allowed to appear vary depends on whether you're on the ground or on-airborn. I cross-checked with my requirement list for an ideal scrolling, and everything is there (further translation to come soon).

Centré au sol et sur la chute
Presqu'automatique si la zone de tracking est "applatie" à une seule coordonnée lorsque le personnage est au sol. La caméra enchaînera "presqu'immédiatement" pour suivre la chute si le bas de la zone autorisée pendant une chute est très proche de cette position de référence au sol.
My first requirement is that the camera tracks precisely Bilou (vertically) when he's walking so that climbing slopes happens smoothly, but that it starts scrolling down quickly when a fall starts. This achieved by a very narrow Y windown for "on-ground" state, and keeping bottom limits close to each other when falling.

garder un oeil sur ce que l'on évite en sautant
Ce sera le moyen n° 1 de se sortir d'une situation délicate dans un "platformer": sauter par-dessus. Ce mouvement doit pouvoir se faire sans déconcentrer le joueur. On doit pouvoir passer de plate-forme en plate-forme (alignées horizontalement) au-dessus d'une mare de lave sans attraper le tournis. Simple aussi : il faut qu'un saut tienne en entier dans la hauteur de la "zone de non-scrolling" à partir de la position de repos (au sol). Ce n'est qu'en enchaînant les sauts que l'on parvient en haut de l'écran (et donc que l'on active le scrolling), mais dès qu'on retombe d'un de ces sauts, le scrolling cesse de monter jusqu'au saut suivant (objectif #5).
Jumping is the #1 action in a platformer like Bilou (that is, where the hero has no weapon). It must be possible to hop from one platform to the next one without having the scrolling "bounce over and over" as well (which would give the player nausea). That's achieved with a fairly high "top limit" when the player is "on air". Yet if the player is "climbing up", he'll be kept on-screen. always.


Recentrer sans à-coups
De nouveau, ça tient au fait que le scrolling va ajuster la position de la caméra à la position du héros mais avec une vitesse limitée. Quand Bilou arrive au sol, on "rétrécit" à une ligne la zone de tolérance verticale de la caméra. Celle-ci va donc recentrer Bilou, mais en donnant une vitesse verticale maximale relativement basse (de 6px/fr pour Sonic alors que la limite horizontale est de 16px/fr), ce recentrage semble plus naturel.
Now, that's okay to have the scrolling "keeping an eye on the danger from below", but when the action "moves on" on the new platform, it's annoying to press UP or DOWN just to move yourself back in the center of the screen. This can be safely achieved by a narrow "on-ground" Y window, but a slow speed limit on the camera (in my case, "slow" will be 1px/frame).

Chouette. Tout y est. Plus qu'à coder tout ça. GravityController ou WalkingController auront donc la responsabilité de définir la "fenêtre autorisée" et la vitesse maximale, la caméra s'occupe du reste. Andiamo!

Tuesday, July 26, 2011

Sonic Physics Guide

ça faisait un moment que je n'étais plus tombé sur de la lecture chouette comme celle-là. "pentes & blocs à pousser", "collisions", "gestion de la camera", etc. Ca va me faire de la lecture ... Attendez-vous à ce que je vous en dise d'avantage dans les prochains jours.

A neat pick: the Sonic physics Guide starring handling of slopes, curves, camera movement ... knowledge likely generated from years of hacking the good'old Sonic 1 and Sonic 2 roms (for SEGA Genesis). Expect some more detailed posts when I'll be done with my readings. 

TODO: make a small executive summary of it. You may use https://twitter.com/bigevilboss/status/1164309035270754306 as a starting point.

Sunday, February 06, 2011

platforms (at last ?)

1. The platform must be passive
This is due to the fact the platform could be carrying several objects and must remain "unaware" of this.

2. Having a "reference GOB" is fundamental
Not only walking on a platform involves Bilou (or other "character" GOBs) to have controllers that look at the behaviour of other GOBs. It also happens with any other kind of vehicles, with homing shots that have per-instance (as opposed to class-wide) target, or to carrying of objects/monsters. Moreover, it is linked to a collision area of the GOB rather than to the GOB itself.



Bion. Refaisons d'abord le point sur les faits:
  1. les plate-formes doivent être passives;
  2. un GOB peut toujours avoir un GOB de référence
  3. le script ne doit être nécessaire que pour les changements d'état.
  4. l'état propre aux contrôleurs est partagé par tous les personnages qui utilisent ce contrôleur.

3. Collisions are only needed when we start/stop being transported.
We simply need to exit the "falling" state when a platform is hit and to leave the "walking/idle" state when the platform stops being solid. To "keep walking" on an established platform, no "event" is required, and no "scriptable action" must take place.

4. It is preferable not to mess with controllers chain
Although it was my initial idea to have collision with platforms to prepend a "walk-on-platform" micro-controller on Bilou, it only make things harder to work with. For a start, controllers are essentially class-wide resources (as the whole state machine), meaning that it would be hard to have e.g. applemen properly walking on platforms this way. Second, it requires that we identify the location in the controllers chain where the new controller should be added, which we currently have no support for. Finally, it would be impossible to insert controller-specific event for "on-platforms" micro-controller, because it is unknown at the "script compilation" time.


Pour pouvoir implémenter proprement les plate-formes mobiles, il faut d'abord:
  • que les plate-formes se soient toutes déplacées avant que l'on ne commence les calculs de mouvement des personnages succeptibles de marcher dessus.
  • que les flags de collisions permettent d'indiquer "conserver ma référence après la collision" et "accepter une référence suite à la collision"
Si tout ce passe bien, une fois ces éléments en place, il sera non seulement possible de créer des plate-formes mais aussi tout autre type de "déplacement aligné" simplement par ajustement du script (quelles collisions, à quel moment, par rapport à quelle zone, avec quel effet sur les contrôleurs, etc.)

The only modifications required on the engine should thus be 1) that GOBs acting as mobile platforms are "animated" prior to GOBs that walk on them (to avoid zool-lags) and 2) allow collision flags to indicate whether a reference to the passive object should be kept and whether the active object is willing to change its current reference.

It is still unclear, however, to what extent platforms require their own collision cast (that is, beyond HERO and EVIL).

Saturday, October 23, 2010

F_LADDER

Me voilà reparti à réfléchir à "comment permettre la présence de vignes, d'eau, de glace, de neige, etc ?", va savoir pourquoi! Le système de micro-contrôleurs enchaînés joue toujours un rôle important, mais plus comme je l'avais prévu initialement, idem pour les "cando".


L'idée serait d'avoir un des éléments présents dans la chaîne de contrôleurs qui définissent le comportement d'un état qui soit capable de détecter qu'une certaine condition (en l'occurence "est-une-échelle") est entièrement valide, et de générer alors un évènement pour que les transitions écrites en gobscript soient évaluées. On vérifie donc par exemple que la direction "vers le haut" est enfoncée au moment où l'on croise la vigne plutôt que de tester s'il y a une vigne tant que le bouton vers le haut est maintenu enfoncé.

I think I've found the way I will implement rope/vine/ladder climbing in my tiled game engine, but it's a bit tricky to explain. You may remind how I sub-divided the behaviour of characters into "micro-controllers" that can be chained to achieve the desired effect ? Well, that allows me to insert such a "controller" that would passively scan the tiles below a character and raise an event when all the tiles have a given property (e.g. "is a ladder"). Inverting the logic -- testing whether the 'UP' direction is pressed on the D-PAD when crossing a ladder rather than the other way round -- should help keeping things simple and efficient.

L'alignement automatique sur la vigne/liane/échelle à escalader et les balades aquatiques ont l'air de s'adapter aussi à ce genre de fonctionnement. La glace/neige et les tapis roulant, là, il faudra une autre approche... mais j'en rediscuterai un autre jour.

Prochaine étape, donc, permettre à ces différents contrôleurs d'avoir leur propre liste de test d'évènement de même que les zones de collisions ont leur propre liste de transition. C'est codé.

Monday, May 17, 2010

Marble Fire Madness ...

La médiathèque du coin me permet d'emprunter des jeux DS à un coût de 2€ par mois ... alors je ne me fais pas trop prier. En attendant mon vol pour Uppsala, j'ai pu m'essayer un peu aux Sonics auxquels je n'ai jamais vraiment eu l'occasion de jouer étant gamin. La MegaDrive étant squattée par les "grands" à la maxithèque, je me rabattais sur la version "Master System" (où j'arrivais fièrement à passer le boss de la zone de la jungle).

Ce devait donc être la première fois que j'affrontais la "Marble Zone" pour de vrai, et là, le parallèle avec ce que mon frère tentait de faire dans la "fire zone" de Calimero, dont j'ai retrouvé dernièrement le niveau 1 devient évident ... le tout premier niveau dessiné par mon frère qui me le tape sur ma planche à LEGO en disant "tiens, code moi ça sur C64, plutôt"...

Les mouvements de Sonic sont clairement mieux adaptés aux pentes et arrondis de la Green Hill qu'aux escaliers de la Marble Zone, chose que l'on observe pas tant dans les Mario. j'avance avec prudence ... ça aussi, ce n'est pas "naturel" pour Sonic. Je suis aussi impressionné de voir que, si tôt dans la série, Sonic tirait sa force non seulement de sa vitesse, mais aussi du réalisme de son moteur physique. Ecrabouilleurs, des pans entiers du niveau qui s'écroulent ou s'enfoncent ... On est clairement à un niveau différent d'un Super Mario où les "objets" sont généralement d'un seul bloc.

Du point de vue d'un programmeur, Sonic restera un exemple impressionnant. Je serais vraiment curieux de mettre la main sur le code Genesis de ce jeu ... ne serait-ce que pour la gestion des plate-formes mobiles... et des loopings, combinés au sol qui croule et aux blocs destructibles...

PS: avant de conclure que "la marble zone n'est pas vraiment Sonique, mais pourrait se retrouver dans n'importe quel jeu de plate-forme, je vous invite à regarder ce speedrun où la plupart des séquence "sur un bloc flottant sur la lave" sont court-circuitées en prenant de la vitesse et en enchaînant les sauts avec précision... Ou en choisissant de se faire toucher par un écrabouilleur-à-picots pour sauter un peu plus haut.