Showing posts with label crumbling floor. Show all posts
Showing posts with label crumbling floor. Show all posts

Tuesday, December 20, 2011

The missing BlockAction

Here's a scan that discusses a missing abstraction in my model so far, to carry on a "thread" on a map location (as compared to a tileset location). I figured out I was missing it when I tried to implement crumbling floors for the "nut's'blots" intermediate project, in june 2010. It remained a draft sketch all that long.

An amusing fact: despite this is still missing from the *model*, there is actually creation of a GameObject derivative (BlockArea) so that you can proceed with evaluation of the "block:on hit" expression ... so all it would require would be to capture this derivative for longer than just a collision. I just realised that while investigating why the new collision system no longer works with interactive blocks...


Un vieux scan de Juin 2010 avec, en Français, le détail des "BlockAction" qui manquent encore à mon modèle de jeu. D'une manière assez amusante, la manière dont les interactions sont gérées vont déjà dans ce sens même s'il n'y a rien au niveau du "gobscript" qui permette d'en exploiter plus largement les possibilités.

A less amusing fact: this was all coded before we had dynamic gob lists, and it's now trying to de-register a Gob from the game engine several times every frame (especially when the interactive block is not de-activated by the collision). That could explain some performance issues observed in early AppleAssault prototypes.

edit: finally implemented as MapAnim

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.

Friday, March 12, 2010

Crumbling Floor ... revisited.

Alors quoi ? Si c'est si simple de faire un sol qui croule dans Manic Miner, pourquoi est-ce la prise de tête ici ? Me suis-je trop compliqué la vie avec mon moteur de jeu et mes scripts ?

L'état est entièrement encodé dans le graphisme

Willy ne tourne qu'à 25Hz, Bilou à 60. A chaque frame, le sol de Willy est dégradé d'un pixel de plus si Willy est toujours dessus. Si je veux faire un autre style d'animation ou si je souhaite quelque-chose comme des morceaux de pont qui balancent quand on marche dessus puis tombent dans le vide après un bref délai, la "technique Willy" n'est plus appliquable. Bien sûr, en 1983, Matthew Smith ne s'était pas encombré avec "mais, on pourrait vouloir faire disparaître le sol un peu différemment plus tard dans le jeu" ^^"

J'ai une approche "bottom-up"

Le programme de Carles est contruit en divisant le problème (coder Jet Set Willy) en sous-problèmes (déplacer Willy, gérer les collisions), etc. Dans mon projet, j'ai une machine (la DS) et un objectif un peu difficile à réaliser directement sur cette machine (Bilou). Du coup, j'essaie de me construire une machine virtuelle (moteur de jeu, langage de script, outils d'édition de maps, etc) dans laquelle le problème serait plus facile à résoudre. Cela se prète mieux à la généralisation à un "game maker" par la suite, mais ça veut dire aussi que tant que je n'ai pas trouvé le bon jeu d'abstractions, les solutions sont bancales.

J'évite de sur-utiliser les sprites
Je pourrais ajouter quelques "actions externes" à mon langage d'expressions qui altèreraient le contenu de la map, et tout gérer avec des sprites. Je marche sur un pont ? hop, le fond disparaît et est remplacé par un sprite du même morceau de pont qui bascule. Si je ne suis pas resté trop longtemps, le sprite "réécrit" le bloc sur la map avant de disparaître. Ce genre d'approche risque d'introduire trop de sprites sans qu'on puisse contrôler combien il devrait y en avoir. Vous vous souvenez du "spinning block" de Mario World ? Imaginez un peu qu'il ait fallu animer un sprite pour chaque block qui se mette a tourner parce que vous l'avez touché ... bonjour l'horreur!

L'idée est donc de rajouter quelques abstractions de base, telles que "une animation liée à une position sur la carte" (pour les ponts, le spinning block, etc.) et "une portion de la map dont je peux changer le contenu" (pour les passerelles que l'on fait apparaître ou disparaître à coup d'interrupteurs comme dans Keen). Les cogitations sont en bonne voie. Le code suivra ... comme les autres éléments de mon énorme "todo list". Derrière la façade de "vous aimez le nouveau look du site", il y a donc une sorte de "bouillonnement" de choses difficile à décrire qui avance dans le bon sens dans les slots de temps libre qu'il me reste. J'espère parvenir à en dire plus long prochainement.

A+

Wednesday, March 10, 2010

B_CRUMBLINGFLOOR

Somehow, I stumbled upon this re-implementation of the Manic Miner / Jet Set Willy engine in Visual Basic. I'm unsure on how I should implement crumbling ground in Bilou (or any block animation in response to character's presence). Let's see how a +20 year old game handled it...

Bon, je l'avoue, je suis intrigué par la quantité d'"éléments spéciaux" présents dans un jeu aussi vieux que "Manic Miner" contient, et la difficulté que j'ai à trouver une manière convaincante de réaliser la même chose dans mon moteur de jeu actuel. Du coup, j'ai mis la main sur une ré-implémentation du jeu en Visual Basic. Voyons donc comment les blocs-qui-disparaissent-quand-on-reste-dessus ont été gérés ...

' block type constants
Private Const B_CRUMBLINGFLOOR      As Byte = 2
Block types are encoded in a separate array, with one byte per 8x8 tile. One such type is "crumbling floor". Other block types include B_AIR, B_FLOOR, B_WALL, B_CONVEYOR and B_NASTY (two of them) and B_SPARE (for switches). Jet Set Willy only has one B_NASTY type, and the other one is converted into B_SLOPE. This is consistent with my own engine.

Carles a construit son moteur de Willy de manière à réutiliser les données du jeu telles quelles -- sans être le code original sous Z80, ça donne malgré tout une bonne idée de ce qui aurait pu être fait. En l'occurence, par exemple, la structure de chaque niveau est donnée par un tableau de la taille de l'écran, indiquant quels graphismes utiliser, mais aussi le type de chaque bloc entre 0 et 7.

B_CRUMBLINGFLOOR est celui qui nous intéresse. En cherchant "crumbling" plus loin dans le code, je tombe donc sur la fonction DoWilly (extrait ci-dessous) qui gère toutes les interactions entre Willy et le monde qui l'entoure. DoConveyors ne fait qu'animer des blocs, de même que DoGuardians se contente de déplacer les monstres. Ce sont les sous-fonctions de DoWilly qui détectent les collisions et altèrent le déplacement du personnage. Exactement le genre d'approche que j'utilisais dans Calimero et Bilou en QuickBasic.

What's interesting (for me :-) in Carles' approach of redoing Willy's world is that he operates directly from the tape file of the spectrum, so not only it has the "readability" of modern BASIC (i'm not that much into Z80 assembly ^^") but it still explains the logic of the original game (how switches, witches and stuff are encoded).
If (.mode = [eWalk]) Then
  If Not (WillyCheckFeet()) Then
    ' code for falling stripped out ...
  End If
  Call WillyCheckConveyor(keys)
  Call WillyCheckCrumblingFloor
End If
The DoWilly() sub shown above proceed step by step, handling interaction of Willy with every item "present" in the game. That is, we have DoConveyors or DoGuardians as well, for sure, but they merely perform animation and movement job. WillyCheckConveyor makes sure conveyor pushes Willy. That's the real job.
Let's thus have a look at WillyCheckCrumblingFloor just below ...


Voyons donc WillyCheckCrumblingFloor dont le code est ci-dessous. Après s'être assurée qu'il y a bien un bloc friable sous les pieds de Willy, elle va utiliser FXCrumblingBlock pour procéder à l'animation (décalage du tile d'un pixel vers le bas) et transforme les propriétés du bloc donné en "B_AIR" si FXCrumblingBlock lui dit de le faire à travers la variable f.
o = .x + (.y \ 8 + 2) * 32
For c = 0 To 1
  If (m_RoomBlock(o + c) = B_CRUMBLINGFLOOR) Then
    Call FXCrumblingBlock(m_DIBBack, 8 * (.x + c), .y + 16,
                          CAPaper(m_RoomData(o + c)), f)
    Call FXCrumblingBlock(m_DIBMask, 8 * (.x + c), .y + 16,
                          I_BLACK, False)
    If (f) Then
      m_RoomBlock(o + c) = B_AIR
      Call FXRect(m_DIBBack, 8 * (.x + c), .y + 16, 8, 8,
                  CAPaper(m_BlockCA(0)))
    End If
  End If
Next
FXCrumblingBlock
will not be shown here, because it's a pretty dirty function that mixes up game logic, tile animation and rendering engine commands. What I can tell you is that everytime it is invoked, it scroll downs the data of that specific tile, and insert a "blank" line at the top. Once this is done, it scans the whole tile again and sets the "cleared" flag (variable f) to false if it found any non-blank pixel. That's precisely what triggers transformation of B_CRUMBLINGFLOOR into B_AIR.

As the tile "crumbles" exactly one pixel per frame and Willy walks one pixel per frame, it means if you simply walk on crumbling floor, it will be completely crumbled when you're done walking.


Pour moi, c'est là que le bât blesse: FXCrumbblingBlock mélange allègrement rendu vidéo, manipulation des animations et logique du jeu. Je ne la reprend donc pas ici, sachez juste qu'elle décide si oui ou non l'animation est finie en parcourant les pixels qui viennent d'être édités. Si tous les pixels sont "transparents", c'est qu'il n'y a plus du tout de sol et on peut remplacer B_CRUMBLINGBLOCK par B_AIR.

Là-dessus, je vous laisse bras-dessous: il est temps que je prépare ma pitchounette à aller rechercher ma fée à Belle Ile. Ciao.

Sunday, March 18, 2007

Great Giana DS

L'annonce sur Drunker Coders m'a épaté. Après "Rick Dangerous", c'est "Great Giana Sisters" qui déboule sur la nintendo DS. Que tous ceux qui ont un jour eu une ame d'enfant et un commodore se ruent sur ce titre-culte! Des heures de fun portable garanti.

Giana, c'est le bras de fer entre le géant nippon et une bande de programmeurs de garage qui se sont vu interdire la vente de ce qui reste pour nombre d'entre nous _le_ jeu numéro 1 sur micro. Même s'il faudrait être aveugle pour ne pas remarquer l'énorme repompage sur Super Mario Bros., Giana bénéficie d'un gameplay propre, introduisant plus de variété dans les tirs (rebondissant sur les murs, à tête chercheuse, etc.), dans les obstacles (plateformes mortelles, ascenceurs, passerelles qui s'effacent quand vous marchez dessus, feu, etc).

Même si les niveaux 1 et 2 font figure de clin d'oeil énorme à SMB1, les auteurs du jeu n'en sont pas resté à un "bête plagiat": dès le niveau 3, ceux qui croyait que leur casquette et leurs moustaches allaient les tirer d'affaire dans ce monde dépourvu de carapace de tortues en seront pour leurs frais. De nombreux passages nécessitent une maitrise parfaite du saut, par exemple pour sauter d'un tuyau enflammé à l'autre, et une connaissance non moins parfaite du déplacement de certains vicieux ennemis qui vous tueront la-même où vous vous croyiez en sécurité!

Oh, et pour info: ne cherchez pas de 1UP. Pas de ça ici. Vous voulez une vie sup'? ramassez 100 diamants sans mourir. Point-barre.

Rick Dangerous was on of the first homebrew port i put on my DS. It kept me entertained for several hours. Today i found and installed Giana Sister (which -afaik- hasn't been announced on Drunken Coders), which promise hours and hours of portable fun: the soundtrack, the gameplay, the colors... The game is the exact one we had on the C64.

Giana Sister, this is also the duel of the Japanese Giant vs. some german lads in their garage who dared to release a jump/run game stating "brothers are history!" on the cover. And if you ask me, it's a shame the game has been withdrawn as it is one of the best side-scroller game ever on the commodore. Okay, i have to admit: the first two levels are a lame rip-off of SMB1, but as soon as you get to level 3 (which will require you some skill nonetheless), you'll meet the true giana sister experience! Flaming pipes, deathly disappearing platforms, and vicious foes. Watch your steps, tune your jumps and learn quickly.

Beside the absence of koopa shells, you will also notice that there is no such thing like a "1UP mushroom" in Giana Sister, but several flavour of shots (homing shot, bouncing shot, blast-them-all, etc). You want an extra life? grab as much diamonds as you can. period.

So you own a homebrew-ready DS and found New Super Mario Bros. damn too easy ? No problemo: Giana Sister DS will keep you happy for longer that you've thought.