Showing posts with label climbing. Show all posts
Showing posts with label climbing. Show all posts

Wednesday, April 16, 2025

climbing ... manuscript notes.

Quelques notes qui datent de février 2013 et qui refont surface pendant les habituelles chasses de paperasse de début juillet: comment s'y prendre pour que Bilou puisse se balancer aux signets de la school zone.

J'y note la recommandation que les morceaux de signets soient passifs dans la collision et un peu de math pour déterminer si une zone de collision classique croise ou non une "ligne" de collision, qui conviendrait mieux pour les cordes qui pendouillent.

Par contre, je ne sais pas trop dire si j'avais prévu que le signet soit fait d'un seul Gob avec une zone de collision pour chaque élément ou de plusieurs gobs ... la pages avec les lapins vont plutôt dans le sens "un seul gob", chose que le moteur "Dreamland" ne saura pas encore gérer, je dirais.

On y trouve un

state% : 3D.% {
  using RopeController;
  segment [*] F_ROPE;
}

pour un nouveau type d'objet basé uniquement sur du rendu 3D. Le fait qu'on indique des collision pour chaque segment renforce l'hypothèse d'un seul GOB composite d'un nouveau genre. On lit d'ailleurs, sur la première page

foreach (@segments):
   if (b.ymin > s.ymax || b.ymax < s.ymin) continue;
   if (s.dx * s.dy >= 0) {
     // depending on the rope's direction, there's 2 corners of the bbox to check
   } else {
     // test the other two, I presume :P
   }
   

Et une observation que "bah, peut-être qu'une verticale plutôt qu'une ligne oblique, ça ne gènerait pas tant que ça dans la plupart des cas. 

Bref: c'est confus, même pour moi, mais je veux l'avoir sous la main dans le même tag que les autres

Hi English readers. These are manuscript notes from about 12 years ago, when I first tried to figure how to deal with swinging bookmarks that you could catch and climb to. They're a bit confused and I'm unsure even I understand what's being said there. But I've got bookmarks and climbing goal revived for Bilou's Dreamland, so I'd rather have these notes around when I'll think about it. The code snippets I typed above suggests that bookmarks were intended to be a new type of segmented 3D object, which has been dismissed for the Dreamland engine

Saturday, February 13, 2021

Higher Order Blog ...

Of course, it's been a long time since I first read the guide to implementing 2D platformers on the Higher Order Fun blog. I believe it's been part of my research on how people implement slopes together with the MC Kids talk on implementing sophisticated platformers on NES. So somewhere around 2007.

Un tout bon blog, qui continue à nous proposer des conseils pour implémenter un jeu de plate-forme 2D depuis facilement 2007, époque où j'ai dû le rencontrer pour la première fois. Mais en repassant dessus il y a quelques mois (magie Twitter), je me rends compte qu'il y a encore un bon nombre de fonctionnalités discutées que je n'ai pas encore implémentées dans mon moteur à moi (échelles, plate-formes dont on peut redescendre), et d'autres qui sont en cours de révision (pentes, plate-formes uni-directionnelles). Je repasserai dessus dans les jours à venir (j'espère)

There's still a number of topics I haven't implemented in GEDS that are discussed in that post, including ladders, refined slopes and one-way platforms. So I finally printed it all so I could take the time to read it quietly and take notes on what was neat and what needs more thinking. That was over 6 months ago.

So unfortunately, the toughts aren't fresh in my mind anymore. I'll have to read them back *too* before I can talk about it more.

The blog post presented different ways to implement a platformer. Tiles-based, of course, as it was de-facto technique used on virtually all 8-bit and 16-bit consoles that used tiles-based hardware (and still an efficient technique on page-flipping hardware), but also vector-based levels (only mentioned, though) and bitmap-based. I wish there was more being said about the techniques used with bitmap-based level modeling, as I believe it was the technique used in Fury of the Furries. 

Mais une particularité de l'article de Rodrigo Monteiro, c'est qu'il ne se limite pas aux jeux basés sur des tiles: il discute aussi le cas des niveaux modélisés par des vecteurs (Braid), à positionnement forcé sur des tiles (Prince of Persia, Flashback) et basés directement sur un bitmap (Worms). Et là, je trouve qu'il a peut-être été un peu léger en oubliant de mentionner Lemmings. Bon, d'accord, l'article est bien plus ancien que le talk de Mike Dailly présentant le fonctionnement (et l'éditeur de niveau :P) de Lemmings 1 et 2. Bon, on est d'accord: ni Lemmings ni Worms ne sont à proprement parler des jeux de plate-formes, mais ils restent en vue latérale avec de la gravité, et à voir la physique du personnage dans Fury of the Furries, je dirais qu'on pourrait bien en avoir un troisième.

I also know for sure it was used in Lemmings for levels up to 5 screens-wide (that would be about half the conventional RAM available on an IBM-PC, btw). 

Since the storage space on floppies was limited, levels weren't stored as a large bitmap, though: they were stored as a set of 'paint brush A at location (X, Y)' plus a set of (deluxe paint) brushes -- think of them as 256-color stamps The level editor calls them 'rocks' and reports how much are used so far. Some brushes may even be used as 'clearers' instead of 'drawers', exactly like what is seen in the New Super Mario Bros. level editor.

A true puzzle for those who later had to port DMA Design's success title to tile-based consoles of the time, if you ask me. But it allowed complete freedom that was precious to design appealing and challenging levels. Lemmings 2 was later developed based on an editor that aligns everything on a grid to ease porting to Nintendo and Sega (?) consoles, and while it had charming new themes, I never felt them attractive the way the original Lemmings were to me.

A noter que traiter la map comme un gros bitmap n'implique pas forcément de stocker la map comme un gros bitmap. En fait, pour la majorité des machines d'avant le CD-ROM, ç'aurait été tout simplement impensable même avec des niveaux de taille modeste comme ceux de Lemmings (5 écrans). Pour faire tenir tout ça sur une diskette, les gens de DMA design ont construit leur niveaux sur base 1) d'une palette de 'brosses' (des bitmaps de taille quelconque provenant de Deluxe Paint) et une série de commande 'ajoute la brosse A aux coordonnées (X, Y)'. L'éditeur permettant d'ailleur de garder une idée du nombre de 'coups de pinceau' utilisés jusqu'ici dans le niveau.

Bon, vous l'aurez compris, cette technique bitmap pour les données d'un niveau marche surtout bien pour les jeux où l'environnement est complètement destructible (chose qui devenait moins vrai avec Lemmings 2, prévu pour consoles 16-bit) et à un style graphique plus proche d'un Rayman que d'un Mario. D'une façon assez amusante (mais foireuse), c'est aussi ce qui était utilisé pour la version BASIC de Bilou's Adventures ;-)

Wednesday, February 20, 2013

Quelle taille de crayon ?

Once again, I'm stopped at a development cross-roads. Mostly due to IRL, admittedly, but stopped anyway. I decided to move back SEDS update to "not-a-priority" level as soon as I realised that I had no gameplay idea relying on slope angles variations in the school zone.
I have a "thread" of activity that insist on bringing life to the inkjet. Pixel art is ready, fundamental parts of the behaviour "should work", but it's not operational yet.


Par où continuer ? Les pentes supplémentaires, ce n'est pas franchement une priorité. J'ai bien progressé sur inkjet, j'ai du pixel art qui est prêt, mais ça chipotte un peu au niveau du GobScript. J'ai regardé de plus près le coup de la "corde qui pendouille" et couvert 2 ou 3 pages de formules et de schémas UML, mais pour le rendu, j'aurai certainement besoin du support 3D.

I invested some time into sorting out that "animated rope" thing, and I now have about 3 pages covered with UML diagrams, mathematicae formulae, code snippets and occasionally a gag featuring Bilou and Bouli. So the model and controller aspects are mostly solved. Yet, I haven't figured an obvious way to view the bookmarks that Bilou will hang on, so it starts depending on 3D layer as well, which in turn asks for pendats to come to live.

Alors, quitte à se taper la partie "3D", autant en profiter pour enfin amener le crayon-soldat sur le terrain, non ? Le hic c'est que mes dernières tentatives pour animer côte à côte Bilou et un de ces crayons n'ont pas franchement été convaincantes. Au point que j'hésite même sur la taille à donner au crayon. 40 pixels de haut, Bilou pourra sans trop de problèmes passer par-dessus. 48, c'est peut-être mieux, mais aussi peut-être trop haut pour les capacités actuelles de Bilou

So I converted gbatek into an epub and started studying the options offered by NDS 3D rendering yesterday evening. That opens the door to some pendats, the long-awaited monsters that took over the Owl School. Meanwhile, I did some 2D attempts to animate a pendat, both in AnimEDS and later in flipnote studio, and I realised that I had no clear idea of the size pendat should have compared to Bilou. So far, Bilou should be able to clear a 40-pixels-high ennemy with a regular jump, and I don't know about a 48-px one, especially one like the pendat who cannot be jumped on.

There are only few scenes in Bilou's Book where Bilou faces a pendat directly. And none (iirc) with the desired proportions, neither for Bilou nor for the pendat. Yet, sketches suggest that Pendat.height > 2 Bilou.height
Curieusement, je n'ai pas énormément de croquis de références. Dans tous, un pendat fait entre 2 et 3 Bilous de haut. Par contre, s'il est possible de passer par-dessus un pendat qui charge, mais de justesse, ce qui demande un timing quasi-parfait. L'idée étant évidemment d'encourager le joueur à se servir des dumbladors pour assommer les crayons ou de profiter d'un obstacle plus haut en bout de chemin de ronde.

Bref, le mieux, ce sera encore de faire le test: combien de fois parvenez vous à passer par-dessus le crayon, à gauche de la map avant de mourir (SchoolTest.nds)

In my design documents, I clearly want that it is possible to clear a jump over a charging pendat, but also that it is tricky to do, requiring near-perfect timing when on flat ground.

So let's try it out. Can we clear a jump over a 3-tile-high static pencil ? Is it interesting to have Bilou jumping slightly higher when he walks(/runs?) like in Super Mario Bros ? If so, is it interesting to have Bilou unable to jump over a pendat unless he walk-jump it ?

Tuesday, February 12, 2013

Swinging Ropes in Pharaohs Return

I love those "dark" places of the Web where you can hear about other people's pet project and see them progressing. I developed a particular sympathy towards Lazycow's "Pharaohs' Return" project, a revival of Pharaohs Curse with state-of-the-art C64 programming.

Il paraît que les forums, c'est la "matière noire" d'Internet. Obscure, insaisissable, insondable. L'antimatière d'un blog/wiki, en somme. Et pourtant, j'adore la façon dont on peut y rencontrer des gens qui ont des intérêts proches des miens. Par exemple, Lazycow nous prépare depuis fin Mai l'exhumation ultime pour "Pharaohs Curse". De nombreuses salles, des couleurs et des décors réalistes, une pléthore d'actions, d'items et des animations à couper le souffle.
Pour sûr, son projet n'a pas à rougir des dernières sorties homebrew sur cette machine telles que Get'em, Mayhem in Monsterland ou Soulless. Superpositions de sprites, reprogrammation à la volée pour doubler le nombre de sprites visibles à l'écran, mélange entre caractères monochrome et multicolores ... tout y est! Même les boss démesurés.

Mixing multicol and monochrome tiles, swapping the color registers on horizontal bands for larger color sets, doing the same with sprites to go way beyond the 8 sprites/screen original limit...  I like it. But what really baffled me was his animation for rope action.

Mais ce qui m'a le plus épaté, c'est cette animation que Lazycow a postée où son explorateur attrape une corde au vol. J'avais toujours classé ce genre de détails dans la catégorie "sympa, mais clairement pas prioritaire". Mais s'il le fait sur C64, je me dois de ne pas être en reste sur la DS, pas vrai ? Grimper aux signets des livres fait partie des éléments de level design que j'avais explorés au moment de reprendre le travail sur Bilou ... Difficile maintenant de me contenter d'un signet rigide même si celà faciliterait le développement.

rope-actionClimbing on ropes wasn't that easy in the original game, and we used to make fun of friends as they were trying to do it with the joystick. Although functionally, the moving rope doesn't bring that much in terms of gameplay (given the limited angle it allows), it's one of those little details that makes a revamp look worth of it and show the love and care that the developer put in it.

When I asked Lazycow whether he had a tutorial on that, he keenly handed me the snippet of his source code that handles the rope action. I noted so far two sub-behaviours: the rope "above" the hanging character simply follows the shortest straight line between the hook and the hero.

for i=1 to heroheight:
    s[i]=i*herodelta/heroheight

The segments below try to align over the preceding segment with delta=s[i-1]-s[i], increasing the segment's speed so that it moves back towards the previous segment, then enforcing "integrity" of the rope by avoiding exagerated offset between segments.

Note that there's a small simplification here, as the rope doesn't shorten as it moves left or right. An alternative would be to assume that sin(x)=x and thus that it shortens by the amount it deviates from the straight vertical line (a fair estimate until you approach x=30°)

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.




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).

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é.

Saturday, February 06, 2010

grimpons, grimpons

Bon, c'est pas le tout de dessiner des pixels de lianes/vignes sur lesquelles grimper. Maintenant, il va falloir coder ça, aussi. La base est relativement simple : un nouveau type de tile qui permet l'utilisation du comportement "grimper", au même titre que le sol permet de marcher.

C'est plutôt le passage d'un autre état (à l'arrêt ou en saut) vers l'aggripage de liane qui va demander une attention particulière. Deux éléments entrent en ligne de compte :

  1. le joueur appuie-t-il sur la flèche vers le haut ?
  2. Y-a-t'il une liane à laquelle s'aggriper ?
La deuxième question revient à un test du type "cando(...)", à ceci près qu'il ne fait pas partie du comportement "normal", mais qu'il risque de devoir être évalué depuis les transitions de la machine d'état.

Of course, just having pixels for the vines is not enough: it's time to start thinking about the code that will let us grab and climb them. I have a few technical problems that need to be solved before code can be written down.

One of them is that you can climb a vine (assuming you're on the ground) only when you're exactly below it. From a gameplay point of view, this is unacceptable, so something will be required to make the vines "magnetic" so that the player is automatically placed at the right position when he attempts to climb while being "sufficiently close to the vine".

Second, to be able to grab the vine while jumping, I need to alter the behaviour of "jumping" and "falling" so that it raises an event, which forces transition towards new states to be evaluated. But I do not want such event to be raised at every frame when the player holds 'UP' dpad while jumping. I am still undecided on how I should make the fact that a vine is present available to the state machine expressions -- and potentially, same kind of info will be required for swimming in water and slippering on ice.


Autre petite difficulté technique en vue : lorsqu'on est au sol, il n'y a a priori qu'une position où il est effectivement possible de monter à une liane : quand on est pile sous celle-ci. Du point de vue du gameplay, ce serait l'horreur d'imposer ça et il faudra donc programmer une sorte de "magnétisme" qui positionne le joueur qui tente de monter à une liane juste sous celle-ci s'il n'en est pas trop éloigné. La solution s'ébauche, mais ce n'est pas encore assez précis à mon goût ...

Wednesday, February 03, 2010

Bilou Mining, donc.


Am I ready for this ? ...
Vous n'êtes pas du genre contrariant, hein ? je mets sur "papier" une série de petits jeux rigolos que je pourrais réaliser plus ou moins rapidement sur DS avec Bilou compte tenu du code et des graphismes dont je dispose maintenant, j'organise un petit vote, et qu'est-ce qui sort vaincqueur ? Exactement ce que je suis occupé à faire depuis l'an dernier. Autant pour le vent neuf de l'an dix, tiens. Voyons donc ce que donne le mockup d'arachne réchauffé à la sauce Bilou ...


Arachne's seminal mockup
I guess I'm just happy if Arachne don't kill me for this one. I'm quickly doing a mockup of Bilou in a "mining for ... stuff" minigame, using her own mockup as a base. Indeed, despite all the alternative I suggested, according to the poll, you seem to prefer that I keep focusing on the current line of demos. Since I don't see why Bilou should gather all the apples of a level to clear it, I prefer keeping fruits as "optional" bonuses and claim that the goal of "Bilou Mining" will be to recover all the nuts and bolts from the crashed Astro-cruiser.

On va donc continuer dans l'optique "ramasser les items et atteindre la sortie", mais plus des pommes cette fois-ci. Il me faut des "clés" qu'il est indispensable de collecter, les fruits servant uniquement à juger le "style" -- départager le maximum d'entre les maxima, comme disait Popo. Bin ce sera les boulons de l'astro cruiser. voilà.

Shantae, again
Mais un gameplay "à la Manic Miner" a des exigences tout de même un peu différentes d'un SuperMario. Tout d'abord, le timing est la clé du succès, plus que votre adresse à défier la gravité. Il faudra donc que je revoie l'armement de Bilou.

Ensuite, il faut que le joueur puisse avoir une vue d'ensemble du challenge, ce qui colle bien avec la taille de Bilou, un peu moins avec la hauteur de ses sauts. Finalement, il va falloir grimper à des échelles et ne pas trainer sur des plate-formes éphémères. Et là, c'est plus chaud: je n'ai toujours pas réussi à dessiner des lianes convaincantes en couleur. L'idéal, ce serait quelque chose approchant les arbres de Shantae DS (voir les images de référence en bas du post).


I expect subtle changes to happen on the current gameplay to match that objective, though. At first, jumps should be shorter so that I can put more of one challenge on the screen and have an increased "puzzle" dimension by letting the player observe the level and decide of its strategy rather than reading and reacting promptly as in a SuperMario game. This also suggest that we should have more than stomps to dispatch baddies. Collectible weapons are likely to appear. But most of all, to pack more action per screen, I'll need ropes and ladders ... that is, vines, in this green woods stage. Unfortunately, all my attempts at drawing something (even just slightly) similar to the vines found in Shantae DS is a total wreckage so far.

Je me suis donc fait un petit tour de flickr-vgmaps-f-spot pour essayer de collecter un maximum d'images de référence. Ca a un peu amélioré le résultat mais pas énormément. Je gribouille donc des lianes un peu partout sur des bouts de papier, je m'arrête au milieu d'un niveau dans SPP pour chiper les marqueurs de ma fée et redessiner les haricots magique qui dépassent des nuages dans le monde du ciel. Pour changer, j'ai dessiné d'abord la forme dans un pavé 32x32 et je lui ai donné du volume avant de la "zoomer" en 64x64 pour ajouter les détails et peaufiner le look.

I've collected quite uselessly tons of reference pictures, until I stumbled upon that magical-bean-plant-seen-over-clouds in the Glidy Sky of Super Princess Peach. I loved the simple elegance of that ?-shaped curve that renders all my previous attempts pretty obsolete. And I actually managed to reproduce it by sketching it first on a 32x32 draft (including colors and shading) before I zoomed individual quarters of that draft to a 64x64 canvas that I could further refine. Graphically speaking, I'm quite happy with the result, except that it is completely useless from a gameplay point of view. Still I've used its "curved head" in the mock-up as ladder and as anchor for the "berry-spiders".

EDIT: entretemps, le projet a été renommé "Nuts&Bolts"

Friday, February 27, 2009

World Collisions

Left alone, testpoinst are not really a satisfactory way to handle collisions between objects of a game and the world.
First they don't cover enough and cannot catch all the odd situations. Testpoints are points and they cannot detect the case where you're jumping through a corner unless you have many of them (up to one per tile your character covers).


Je ne suis plus trop emballé par les tests-points tels que je les avait décrit précédemment. En premier, ils ne capturent suffisamment toutes les collisions. A moins de les multiplier, on risque toujours d'avoir une partie du personnage qui rentre dans un coin de mur lors d'un mouvement, et en donnant à chaque état sa propre liste de testpoints, on ne fait qu'augmenter les possibilités de bugs.

Second, they are only boolean. They don't let you express that a fish can only move into water, that a bird can only move in air, and that a frog can move through both, but that only the ghost can also move through walls (and i'm sure we can come up with a negative space creature that can only walk through/over walls). This is a situation much more common that one could think. As soon as you add ladders to your levels, you want to express that climbing the ladder "is only possible over ladders tiles". That was a quite strong restriction of Recreational Game Maker where the only way you could create a ladder for a platformer game was to set gravity=0 on ladder tiles ... As a result, your character zooms through ladders if you press the 'jump' key and miserably 'fail to climb up the air' if you press the 'upwards' when he's not over a ladder.

Le deuxième souci avec les test-points, c'est qu'ils sont simplement binaires. Alumés ou éteints. Point barre. Pas moyen de préciser qu'un poisson ne peut se déplacer que dans l'eau ou qu'un oiseau ne peut aller que dans l'air, mais que la grenouille peut évoluer dans les deux milieux. Si on y réfléchit bien, ce genre de situation apparaît bien plus souvent qu'on ne pourrait le penser. Le simple ajout d'échelles dans nos niveau oblige de définir que "escalader une échelle" ne peut s'envisager que s'il y a une échelle à escalader. Le Recreational Game Maker sur lequel j'ai développé (entre-autres) la série des badman ne permettait pas ce genre de subtilité: une échelle était tout simplement un bloc sans gravité, de sorte que l'on pouvait y monter en sautant -- à une vitesse franchement irréaliste -- et on aurait vu le personnage ridiculement patauger dans l'air en faisant de petits bonds si on avait appuyé sur la touche "monter à l'échelle" alors qu'il n'y avait aucune échelle.

The approach of "the nature of a tile" is thus interesting: it can express (through flags) who can do what over that tile. This is a concept used both in Xargon and (afaik) in the side-scrolling Rayman game, where you have "monster-walls" that monsters can't cross (though Rayman don't feel them). This is imho an elegant solution to many level design problems. Let's take the walking block of "Inside the Machine", who wanders around its initial location, "guarding" a virtual spot even if it could theoretically walk further. Morukutsu relied on a "distance" counter that is increased/decreased through the animation code, which won't let you alter the 'coverage area' of the ennemy through level design, but only through implementation ... not so fun.

L'approche "nature du tile", telle qu'elle est utilisée dans Xargon est intéressante à plus d'un titre, et je soupçonne les concepteurs de Rayman (la version 2D) d'avoir suivi une approche similaire. En particulier, elle permet l'introduction de "grillage à monstres", des blocs invisibles et non-bloquant pour le personnage et les projectiles, mais qui sont assimilés à un mur par certaines plates-formes mobiles et par certains monstres. Comme je l'avais déjà précisé lors de l'analyse des maps de Commander Keen 5, je trouve que c'est une technique élégante pour construire les niveaux. Si je compare à "Inside the Machine" (l'autre jeu dont j'ai étudié les sources pendant mes longues soirées d'hiver en Suisse), l'alternative consiste à programmer les monstres de sorte qu'ils ne s'éloignent jamais de plus de n pixels de leur position initiale, en maintenant une variable supplémentaire "distance" qui les force à faire demi-tour. C'est exactement le genre de "pré-câblage de code" que je cherche à éviter. Décider jusqu'où un monstre va, c'est une question de level design, pas de programmation du comportement des monstres.

The final argument is that some testpoints are typically more important than others, and there is a strong relationship between which testpoint is triggered and which movements you can do. A problem i have with the current implementation of collisions in Bilou is that as soon as one of the testpoint checks fails, the whole move is cancelled. If you fall along a wall, you don't expect your character to "stick" on the wall because you keep pressing the D-pad in the wall's direction. Yet, that's exactly what Bilou does right now.
Instead, we'd like something like

if cando(dx,dy) then (x,y) := (x+dx,y+dy)
elsif cando(0,dy) then (x,y) := (x,y+dy)
else { 
  (x,y) := (x,align_on_tile(y+dy)); 
  trigger_testfail_event 
}
where cando(deltax, deltay) checks the whole area covered by the character at a new temptative location. But still, you don't want such behaviour for all your monsters, and it's certainly something that is specific to jumping. You wouldn't see this ever in a Zelda game : instead you'd have the character "walk around" a block if he's sufficiently near to the edge of that block. So this logic is really controller-related rather than being something that belongs to the game engine itself.

So, do we still need any testpoint ? after all, Xargon's cando() used in controller-specific code seems to be fine. Actually, there's something that cando() cannot catch: mixed situations. The controller will be able to tell the game engine that it's no longer possible to fall, but it can't tell whether we are now landing, diving, or bouncing against a corner. This is where we *really* need test-points, and you'll notice that testpoints are only used for state transitions.

I still have to figure out the best way to convert my codebase to this new approach -- the fact that i'm busy working on the real-world house not really helping -- but i think it might be what i've been looking for since the start of the project.


Enfin, certains testpoints sont clairement plus important que d'autres, et le déplacement indiqué par le contrôleur doit être ajusté en fonction de la situation. J'ai le problème dans le saut de Bilou, actuellement: quelque soit le testpoint qui détecte une collision, le mouvement complet est annulé. Résultat, si Bilou rentre dans un mur lors d'un saut, il va rester "collé" au mur jusqu'à ce que je relâche la touche de direction. Celà n'arriverait pas si je pouvais donner une priorité, ou une description plus complète du rôle des différents testpoints (p.ex. puisque c'est un test-point "mur", il n'annulerait que le déplacement horizontal, etc.)
Mais en fait, ce genre de logique est commune à tous les déplacements guidés par la gravité dans un jeu de plate-forme. Ce n'est pas quelque-chose de spécifique au comportement de Bilou, et celà pourrait sans difficultés être introduit dans le contrôleur du sprite. En tout cas, ce n'est clairement pas à introduire dans la classe GameObject elle-même, puisque si on veut faire un r-type, un boulder-dash ou un zelda, on en aura pas besoin.

Mais alors, à quoi servent encore nos test-points ? eh bien, à décider de quel sera le prochain état lorsque le contrôleur signale qu'il n'est pas possible de continuer. Ca veut dire aussi que le contrôleur devra évidemment ajuster la position du sprite de manière à respecter les "cando()" mais pour que les testpoints puissent détecter quelque-chose quand-même :P
  • [done] extract persistent state (found in map and accessible by other classes)
  • [done] iGobPubstate::cando(x,y,flags)
  • [done] manipulate tile_flags array (that translate tile type into tile flags) from the script
  • [done] controllers report "fail" when no "cando()" can be applied
  • [done] who updates coordinates ?
  • [done] update GameObject::play() and trymove()

2024 #choice reality check: cando is still there. it has allowed slopes, jump-throughs and more. And I finally have proof that it also works with levels featuring water. Pfew!

Saturday, February 07, 2009

Xargon, Jill et Nikita

Okay, pour ceux qui en nourrirait encore vaguement l'espoir, je n'ai pas l'intention de porter Jill ou Xargon sur DS. C'étaient de bons jeux dans leur temps, mais même le fait que les sources soient disponibles (pour Xargon en tout cas) ne me tente pas.

Je m'explique. Un des éléments qui m'intéressait dans l'étude du code de Xargon, c'est que tout comme notre Commander Keen, Jill et Malvineous (eh oui: Xargon, c'est le vilain pas beau et Malvineous le héros tout en muscles) savent grimper aux lianes (chaines et autres). Un des aspects qui me coince un peu dans Bilou. Or donc, grace au flag f_notvine, ces héros grimpotent grace aux éléments suivants:

• le test "y a-t'il une liane" n'est effectué que sur des frontières de tiles (comprenez, quand x est un multiple de 16)
• une fois accroché à une liane, il n'y a plus de déplacement horizontal

Maybe my last post made you believe I was about to port Xargon or Jill of the Jungle to the Nintendo DS. I'm not. They were solid games back in the days, but even with sources available, I'm not tempted. What's interesting me while studying Epic source code is that their heroes (much like Commander Keen) can CLIMB. Vines, chains, pole. Name it, you have it. That's one thing I don't know how to deal with in Bilou so far, but thanks to the F_NOTVINE flag. Things seem to work fine. The 'is there a vine' test is performed only at tile edges (x is a multiple of 16) and no horizontal motion is allowed on a vine. Fine.

But there's one thing missing: where's the code that aligns character to a vine if they aren't yet ? having to pixel-perfectly aligning before climbing is usually not something you leave to your players. And I don't recall it being so hard to hop from vine to vine in Jill of the Jungle. Almost easier than hopping from block to block, actually.

Apparemment tout ce qu'il faut sauf qu'il n'y avait apparemment rien dans le code qui permette de forcer le perso à s'ajuster à l'emplacement de la liane si jamais il n'était pas pile en-dessous ... louche, ça. Vous vous voyez jouer à un jeu où il faut être positionner au pixel près pour monter à l'échelle, vous ?

Pourtant je me souviens que ce n'était pas si difficile de sauter de liane en liane dans Jill (j'ai peu joué à Xargon, en fait). Bien plus facile que de sauter de bloc en bloc, d'ailleurs.

Bin voui. pas étonnant. Figurez-vous que Jill ne se déplace jamais que _de 8 pixels à la fois_ idem pour le scrolling. Oui, vous avez bien lu : 8 pixels. La taille d'un caractère à l'écran. Jill est soit sur le bloc gris, à moitié sur le bloc gris ou à côté du bloc gris. Point barre. Le jeu est un peu plus "souple" pour les déplacements verticaux (2 pixels) mais n'empèche. La version shareware avait beau se gausser de Commander Keen et de Super Mario, le slogan "The Brothers are History", c'est à Giana qu'il revient, certainement pas à Jill. Et toutes ses voix enregistrées et ses cuisses bien rondes n'y changeront rien!

So here's the catch: Jill and Xargon only move by 8 pixels. Same for the scrolling. Yes, 8. A full-sized letter on CGA screen. Either Jill is perfectly centered on a 16x16 grey block, or she's exactly on the edge of that block. Or she's next to it. That's it. Vertical motion is a bit smoother (2 pixels granularity), but barely. There may be a similar 'minimum walking distance' in commander Keen (4 pixels), but motion happens pixel per pixels, much more smoothly. And while Jill's jerky motion could be excused by the run animation on the ground, nothing justifies it while jumping (and it hurts the gameplay a lot).

Dans Commander Keen, cette "distance de déplacement minimale" est de 4 pixels (en tout cas, si je donne le plus court déplacement possible, c'est ce qu'il se passe), mais malgré tout Keen est déplacé pixel par pixel. Bien plus fluide. Et si ce genre de "déplacement brusque" peut se justifier pour l'animation de la course, en revanche, il est complètement ridicule (et pénible au niveau du gameplay) lors d'un saut. Tiens, à creuser par contre ... Et si j'utilisais le freinage du perso pour forcer ce genre de déplacement minimum ?

Bref, le code était instructif, je vais me replonger dans la programmation de mon p'tit Bilou (qui a appris à marcher ce matin ;) et en attendant, si vous êtes en manque d'exploration de mondes curieux à grand renfort de transformations magiques (c'était un des points-forts de Jill, je l'admet), je vous recommande chaudement Nikita, la femme-loup du jeu Inner Worlds. (merci à CJ pour l'URL et sa compil' "nostalgy power" :)

Voilà. Ma sauce bloubloute alors je vais vous laisser. A+.

Saturday, December 31, 2005

Mechanics (t.a.g.)

This is a term I borrow from Kirby Kid -- aka Richard Terrel.

Mechanics are the player initiated actions from controller inputs as designated by the game designers. These actions have effects on the gamestate in terms of the variables and dynamics of the gameplay system

.

In fact, if we consider that gameplay is the part that defines and rules interactions between game elements based on user inputs, mechanics are actually atomical element of the gameplay.

Une mécanique de jeu, ça va être un élément atomique de gameplay. Et le gameplay, c'est l'ensemble des règles déterminant les interactions entre les éléments du jeu sur base des actions de l'utilisateur. Oui, je comprends: ça paraît très formel, mais c'est justement l'idée derrière l'emprunt de ces termes à Richard Terrel: permettre de formaliser le discours sur un jeu. Dans mon cas, je fais principalement des jeux de plate-formes, donc mes mécaniques principales seront 'sauter' et 'courir'. je leur donne des tags dédiés. Je les note en Anglais et en majuscules (JUMP) quand je veux vraiment dire 'la mécanique du saut // le fait que le joueur pousse sur le bouton de saut pour faire sauter le personnage'.

I'm mostly building platformers here, so my primary mechanics are JUMP and RUN. I can modulate them with FLOAT. I don't quite have a shooting or fighting character, but it instead GRAB and THROW things.

As you have noted, I use all-caps when I want to obviously refer to gameplay actions (mechanics) within the text. I promise I won't shout too much.

Readme: KK: Mechanics & Abstractions (p.2)

Climbing [t.a.g.]

Let's try to clarify all those related tags...

HANG: a mechanics where you can wait at some places that look mid-air HOOK, a mechanics that allows you to remotely attach to place from where you can HANG or swing
climbing, a mechanics to reach higher places continuously without jumpingROPE, an interactive element that may be used in many mechanics, and involves specific computations
VINES: plants, you see. They grow, they're climbing, they're falling down. A visual that can be the form fitting many functions.