Showing posts with label scrolling. Show all posts
Showing posts with label scrolling. Show all posts

Saturday, April 25, 2026

Foreground for the underground ?

Something is annoying me with the underground section of the green zone levels: it's too repetitive. It shows in every screenshot I try to make. I have variation tiles that could make it less uniform, but they don't really work if we repeat them. I have plans for a background, parallax layer underground, but it only really works in open environments, not in tunnels, and underground areas are mostly made of tunnels. in the Green Zone.

But those funny pillars might work as foreground  layer as well! Maybe even better because they're bigger than the pebbles repeating tile of ground I have. They would focus the gameplay in a smaller part of the level just like a circle-of-light would, but with something pleasant to look at. The question is, how can I make it indeed focusrather than obscure. I don't want to make Infogramish game where you don't see where you're heading to because of the foreground.

Let's ask Bouli to make a bit of math, here: if my foreground layer advances by e.g 3 pixels everytime my regular layer advances by e.g. 2 pixels, then I just have to make a map that is 3:2 bigger than the playfield if I want to follow things properly.  

I mean, my "foreground" map would be drawn over a 150% zoom up of the main map, and that should be it. At least, that's the intuition. How to confirm it quickly ? Well, how about cutting some paper to make a live overlay and make it move around. Of course, you have to consider that only a part of the result will be shown to the player, too.

Does that mean I need a special mode or a variant of the Level Editor ? ... maybe not. At least, not more than "use the "physical" layer of gac.map (move by 2:3) and let me edit gacfg.map on top of that.

The fun trivia here, is that the initial motivation was to find a way to have VRAM for textures now that I know it does not require palette slots. But while comparing the options, I came to the conclusion that I had no real use of 3D in the green zone anyway, except maybe to render more trees in the background... but checking Case Portman's Lost in Fuzz video, I realised that proper amiga-style parallax would work better than any 3D and would be easier to make here. And yes, I'm only using 2 tilesets out of the 256K allocated to the background tiles in Dreamland, so I could fit a 3rd one and another "infinimap" in the unused space ...

Does it means textured 3D becomes out of reach ? No, but that Bilou's Dreamland will sometimes use 3D, sometimes not (plain 3D does not require more VRAM, but it consumes one layer).

Does it means Yoshi-Island-Style dual screen action should be forgotten ? No, but it would only work in levels where we have no 3D objects and no fancy lush background/foreground maps.

Does it mean having Bouli or another character "telling the story" on one screen while Bilou is "living the action" on the other impossible ? No, but Bouli may have to survive within 16K of sprite VRAM, using DKC-like live-update techniques for his animations.

edit: sidequest finding: shifting extended palettes from 64K to 16K VRAM isn't that trivial to do. (but not required unless we want to texture 3D stuff)
 

Tuesday, July 16, 2024

How GEDS scrolling works

The scrolling routines of InfiniMap weren't as well documented as I hoped. Not even when I blogged that "yeah, it finally works". And while trying to document them, I noted some undesired difference between what the code does and what I claimed it does in the comments. So here it goes. First this is the full level map, stored as a 2D array of tiles. Within them, we define an area of world coordinates (xmin,ymin)-(xmax,ymax) that is guaranteed to be present in the video memory as well. That is the "invariant", the condition that was true on the first line of a scroll_*() call and that must be restored before we leave the function.

if (py < ymin + WH / 2)
do { up_scroll(); } while (py < ymin + WH / 2);
else if (py + WH / 2 > ymax)
do { down_scroll(); } while (py + WH / 2 > ymax);
if (px < xmin + WW / 2) left_scroll();
else if (px + WW / 2 > xmax) right_scroll();

WWxWH is the dimension of the validty area. We will never let xmax - xmin < WW happen. To decide whether scrolling routines should update the contents of video memory, the scrolling code compares the position of the camera (i.e. the center of the viewport) with the coordinates of the area. If it gets too close to one edge of the 'validity area', video memory contents will be updated and that edge will be moved, possibly dragging the opposite edge along (since we have fixed-dimension video memory)

void right_scroll() {
unsigned xoff = (xmax - xmin) / TL;
// compute target position in video memory
u16 *src = dataview + xoff;
xmax += SQ; // new validity window will end 64 pixels on the right.
if (xmax - xmin > 512) {
xmin += SQ;
xview = (xview + SQ / TL) & 63;
dataview += SQ/TL;
}
// copy from src to video memory
// so we fill the expanded area with valid tiles. 
} 

Then, this is the video memory. The hardware reads it as a 2-dimensional wrapping array, that is if it cannot read more at the right, it goes back reading on the leftmost column. The (xview,yview) reference point corresponds to "where in the video memory is (xmin,ymin)" (that was the part that needed a patch).

Note that only a part of that valid area will show up on screen (highlighted here).

Note that whatever happens, xmin always shifts by 64 pixels. That's the horizontal copy granularity SQ (because it was meant to be square), and no, I never checked it led to better performance than 32. We must have ScreenWidth + 2*SQ < VramWidth, though.
 

Wednesday, December 26, 2018

virtual tilesets

How should I handle tilesets larger than the 1024 tiles the NDS hardware is designed to use? Quick maths show that with 16K unique tiles, I'm already consuming 1MB of RAM. Full 16-bit tile identifiers would address the whole 4 MB of RAM the NDS has.

Unlike in Eric's games, I cannot assume here that the RAM is just a cache for the whole game data (ROM) because the game data may only be accessed through the SD card interface, abstracted through DLDI which -- afaik - - does not support asynchronous reads. And the score-table l implemented lately suffered noticeable lag while accessing the filesystem.


So there will be only main memory and video memory. Echoing what happens on x86 CPUs Virtual memory management, I'll use "logical" for the identifiers related to the full tileset and "physical" for the identifiers related to (temporary) video memory locations.The two functions that deal with translation between the two  sets of tiles are linked to the scrolling updates: since the level map is made of logical identifiers, we need logical-to-physical conversion there. The other(new) function kicks out trees that no longer need to be in VRAM.

I haven't really found a use for a physical-to- logical map. And all my plans for a smart combine-bitmaps system to decide which tile to evict fell flat when I realised it would be smaller to just keep an integer counter for every physical tile. So I will avoid over-complicating things and just go for the array of counters.

I know the logical-to-physical map could use a hash table implementation. It would have at most 1k items present, i'd say that means the main table should be at least 2k entries large. One important thing to consider is that we will have to remove items quite often, which means resolving collisions with chained list would work better than by using the next available entry in the table. Especially given that we will likely find consecutive tiles present, for instance when we have a large structure on screen. Good thing is that since there is an upper limit to the amount of items present, we know an extra 1 k entries for the chained list with always be enough.

Now, one entry in such a table is at least 16-bit logical id + 16-bit physical id + 16-bit next pointer. that takes us close to 18kB for the table, while a plain array of physical identifiers indexed by logical id would take at most 32 kB. Granted, the diffeence is critical for SNEs deving, and likely significant for GBA deving. But here? is it really worth the extra memory lookups ? Is it worth doing divisions to get a good hash function? We'll look into that if I ever need more than 8192 unique tiles in a level.

Friday, June 22, 2018

deep blue InfiniMap

CommonMap revision changed the lookAt/scrollTo interface of background layers to take unsigned positions. After all, it shouldn't be possible to set the center of the screen into negative coordinates when the top-most corner is (0,0).

But I will need to keep internal computation of signed integers anyway. else I get blue meditation screens...

The core of the problem is that processors have two main way to understand numbers: one where the top bit of the number has no special meaning (we call them 'unsigned' numbers and they're all positive), and one where it tells whether the number is positive or negative (with some tweaks, and we call them 'signed' numbers). And among the operations the CPU can perform on number one behaves very differently on signed and unsigned numbers: division. Divide an unsigned number by two, and you'll always have to insert a zero in the top bit. Divide a signed number by two and the top bit remains sticky.

If you mess with the numbers signedness (issue unsigned operations when you should have used signed operations) and you may easily turn a small, negative number into a big, positive number during a division. That's what I did with my update ... this is what I have to fix now... hmm... tomorrow. It's time I give my eyes and brain some rest.

Thursday, March 01, 2018

The "last" map

Allez, je me suis bricolé une dernière map pour School Rush: la récompense pour ceux qui seront parvenus à grimper jusqu'en haut du "niveau secret". Il y aura une présentation des monstres, bien sûr, mais aussi une petite surprise qui m'a pris du temps à mettre au point. Au niveau de l'idée, je veux dire.

I sketched up a last map for School Rush, that will be the final reward to players who beat the secret climbing challenge. It took me some time to nail down the idea I wanted to have, but I think all I have to do now is some pixels and some scripting. And making sure I can restrict the part of the level that the camera can show. I'll have to keep the todo list off-line, though so that you have a real surprise ;-).

Côté réalisation, je vais avoir besoin, pour la première fois, de restreindre les mouvements de la caméra. Il me faudra aussi une petite variante de la gomme, quelques graphismes sur tableau vert et un mode "calmos" pour les encriers... Pas facile de se faire une todo liste pour un truc qui doit rester secret >_<

edit: since many of the monsters' behaviour is slightly different here, how about #ifdef LAST_MAP in the .cmd files that can lead to e.g. inkjet.cmd vs. inkjet_last.cmd ?

Tuesday, December 19, 2017

Refactoring de dingue!

J'hallucine. J'ai pris une de mes plus vieille classes -- InfiniMap, responsable à la fois du scrolling et des collisions sprites/map. J'ai renommé ça en "CommonMap", appliqué les changements partout sauf aux sites de construction. J'ai ensuite déplacé le code utile dans un nouvel InfiniMap, déclaré l'une ou l'autre méthode comme purement virtuelle dans CommonMap ... et recompilé.

I can hardly believe it. I picked of my oldest classes -- InfiniMap, that controls  scrolling and  -sprite-vs-world collisions -- and renamed it common map, everywhere but on lines of code building some instances. I then moved the "real" code into a new InfiniMap, mentioned a few ."pure virtual" markers in common Map, and rebuilt...

Et ça marche ! C'est du délire à l'état pur. Ok, j'avais une classe iWorld mais je ne m'attendais pas à ce que le truc ne réclamme aucune autre intervention. Nada.
Allez, demain, je déplace le maximum de variables membre.

And it works! I can't beleive it! (dott). I knew I had some interface class already, but I wasn't expecting it to work that easily, not requiring any fix or whatever !

Sunday, December 03, 2017

Far ground

Je tente d'intégrer mes bouquins-totems comme décor de fond du niveau vertical ... après quelques essais/erreurs pour faire le bon montage, qui ne consomme pas trop de mémoire vidéo, quelques corrections pour que le moteur de jeu puisse utiliser effectivement les 256KB dont il dispose plutôt que de s'auto-brider à 128K, je commence à avoir quelque chose... Enfin presque. L'état du code pour la gestion du décor en parallaxe n'est franchement pas terrible

I'm trying to integrate the tiki-books as the background of the secret vertical level. it took a few trials to get something that fits in the renaining video memory, which is much easier after I grant access to the full 256KB allocated. well, sort of ... Unfortunately, the code for parallax scrolling is carrying lots of legacy, hard-coded settings suited for 512x256 -picture, while this new level needs it the other way round. The wale also picks camera coordinates directly, leading to a. weird offset on screen.

  • le code qui effectue le chargement de l'image ne supportait que la taille de 512x256 pixels alors que je veux maintenant utiliser le système en 256x512.
  • le code de scrolling utilise directement les coordonnées de la "caméra" en les divisant par deux, de sorte qu'il me décale le décor de 64 pixels sur la droite
  • on dirait que seul un des deux "écrans" est utilisé, en boucle, plutôt que d'avoir un décor deux fois plus haut que large ... à l'exception de certains endroits où le décors est sans dessus dessous.
Il va y avoir un peu de travail pour corriger tout ça.
plus, l have only half the picture showing up, rather than two sets stacked onto each other. And at some place, the scenery is completely messed up. it will take some work to get all that fixed. Maybe if I hack some forced, auto-scrolling, the defects will become clearer.

edit: je devrais essayer de mettre un auto-scrolleur sur le plan de décor, tiens... ça simplifierait les tests.
edit2: en effet, ça simplifie.
  • [done] le coup des décors sans dessus-dessous vient probablement du fait que je ne chargeait que la moitié de ma map (eh oui, il faut 2 bytes par pavé, pas un seul)
  • [done] par contre il y a clairement quelque-chose qui annule l'effet du réglage "32x64" (l'ordre d'appel des fonctions, en fait). 
  • [done] Et pourquoi ai-je un VBL handler appelé deux fois, pour deux maps différentes, et qui modifient les registres des deux plans ? 

Monday, March 06, 2017

Au coeur de runMe

Okay, basics of getting runMe to run game scripts on emulator is restored. Now let's repeatedly launch script and hit the 'back' button to figure out what's working and what isn't in the mechanisms of the switching.

Bin, puisque j'ai récupéré un émulateur capable de faire tourner runMe, essayons de réparer ce mécanisme de gestion de la config de l'écran, alors. Histoire de pouvoir enfin comprendre pourquoi les boutons se bloquent pendant qu'on joue au jeu ... et de pouvoir à nouveau travailler sur les maps (oui, il y a eu tellement d'interruptions imbriquées que c'est un miracle qu'on ait pas tous été téléportés sur StackOverflow ;)

  • have a color for top screen's backdrop in 'pickWindow' and 'storWindow'
  • [wish] have an 'open' button on storWindow (not only the obscure L+A)
  • [done] reset the scrolling position when returning to GUI windows. -- implies disabling the onvbl handler of InfiniMap.
  • [done] invoke GameLayers::apply() when entering game parsing mode
  • [done] have translucent log in game mode.
  • [done] don't forget to turn off 3D when you're leaving the game mode.
  • [done] restore system colors in extended palettes.
  • [done] replace the digscreen() system of runMe's MetaWindow.
  • [done] make sure I still see logs through the digged screen.
  • make sure InspectorWidget don't try to apply default LayersConfig ^^"
And then, it would be nice if I could force exit ... wait ... isn't "SELECT" bound to that ?

    Sunday, May 24, 2015

    The Ultimate Scrolling Analysis.

    Huge thanks to Itay Keren for having written his essay that creates a clear nomenclature of camera techniques in (mostly) platformer games, ranging from Pac-land's position locking to Mario's platform snapping to linear interpolation and beyond.

    Grâce au développeurs de Frogatto, j'ai pu découvrir l'existence d'un excellent article sur le scrolling des jeux de plate-forme publié il y a quelques jours sur Gamasutra. Eh oui. C'est ça, l'après Google Reader. Je ne vais pas repasser en revue toutes les techniques qu'il présente, du premier platformer à nos jours -- pour ça, il y a l'article d'origine, mais j'en profite pour mettre à jours mes propres références.

    Lerp in action. (C) Itay Keren.
    Back then, when I started researching how to move Bilou's camera, my colleague Cyril suggested "an elastic string that would draw back the camera to Bilou's position". One close match is Donkey Kong Country's linear interpolation technique. It still has some "wobbly" effect but much less nausea-inducing than when you lock to the player's position. But this is far from being the only camera mechanic in DK games. Anyone who played the game has noted that some areas of the level are apparently "scripted" with cameras behaviour and that entering some hitbox may suddenly allow the camera to move past some artificial barrier, revealing a hidden area. More subtly, this can also be used to enforce "bottom-locking" in some part of the level, or change the horizontal tracking to the type of gameplay (rush, explore, climb...) of a specific area.

    Commençons par une technique que j'avais laissé sur le côté quand elle m'avait été proposée par Cyril -- une "sorte d'élastique qui ramènerait la caméra vers Bilou" -- que j'avais tenté d'implémenter avec le code de poursuite des BerryBats. J'aurais mieux fait de procéder comme dans Donkey Kong Country avec une "interpolation" linéaire qui déplace la caméra d'autant plus vite qu'elle se trouve loin de son point de destination.

    When I tried myself to analyze the horizontal scrolling of Super Mario Bros, I thought that there was two 'push-the-screen' positions, depending of the speed at which Mario moves. The reality is a bit different.
    two triggers in SMB. (C) Itay Keren.
    There is indeed two trigger positions, one -- walking barrier -- that forbids Mario from entering the rightmost part of the screen, and a second that smooths camera movement when Mario starts running. The "early-scroll" trigger doesn't try to keep Mario at its left, though, so he eventually "escapes" to the walking barrier.


    Passons ensuite à SMB1, avec son interdiction de revenir en arrière. Ici pas de soucis pour faire demi-tour, mais Miyamoto a quand même pensé à nos jeunes estomacs et a ajouté un démarreur de caméra deux blocs avant la position 'naturelle' de Mario. On y gagne pas pour autant en visibilité pendant la course comme je le pensais au départ, mais on évite un départ trop brusque de la caméra si on revient en courant.

    This is what smooth out the movement of the camera by reducing the instan(aus)eous acceleration of the image. I'd be tempted to say screen will move at walking speed until the real barrier is hit. I guess with more CPU cycles and memory, miyamoto's team could have even tried to linearly over time in that region rather than having two-steps, but I doubt most of us would notice the difference, so it's not bad to keep it simple. But no, you don't really have more headroom when running in SMB.

    Finally, Itay's model of Super Mario World's camera nicely complement the video document I already found (and not yet re-blogged so far). The camera here clearly has multiple mode, that Shaun categorizes as "platform-snap", "bottom-locked" or "free-moving". I tried and mapped these as an UML state machine, but it lacks one component: the fact that in some levels/parts of the level, some transitions are forbidden -- e.g. in some levels, you will not enter platform-snap and stay bottom-locked.

    Les différents mode de suivi vertical de Super Mario World, j'avais déjà étudié par l'entremise de Shaun. Le code est assez sophistiqué pour mériter une machine d'état à lui tout seul. En plus de ça, certaines transitions sont interdites dans certains (morceaux de) niveaux, forçant par exemple la caméra à rester au niveau du sol à moins que Mario ne s'envole dans les niveaux plats. 


    What Itay adds to that, is a clear illustration that the camera in SMW has a direction state of its own (moving leftwards or moving rightwards) distinct from Mario's movement. In each direction, there is one barrier that will make you push the screen if you try to go past it, and a trigger that will switch to the other mode if you touch it. When the camera is "heading right", the two yellow lines are active -- Mario is confined within 2 blocks. As soon you hit the dashed line while turning back, the camera switches to "cyan mode", and then you have the screen adapting as quickly as the camera's max speed tolerates because you're about 64 pixels away from the push barrier for that direction (still picture shows a point in time where such catch-back occurs).

    L'analyse de Itay est plus précise en ce qui concerne le scrolling horizontale. Il illustre parfaitement le mécanisme des deux "poussoirs horizontaux" décentrés (un pour chaque direction de caméra) et les déclencheurs qui forcent la caméra à changer de direction quand Mario a fait demi-tour de plus de 2 blocs. Il semblerait qu'on ait ici aussi utilisé une "interpolation linéaire" pour adoucir le mouvement de la caméra quand elle atteint à nouveau la position de Mario.

    With this scheme, the player always have at least 1/3rd of the screen in the direction he face and half-a-screen-plus-one-block in most of the cases. That works quite well with exploration games like Commander Keen, imho.


    If you're doing game design in some way, I strongly recommend you to spend some of your "research points" reading Scroll back : the Theory and Practice of Cameras in Side Scrollers.


    Wednesday, May 07, 2014

    Game scripts todo list

    Beside the current "moving ink" target, there are a number of things that don't (or no longer) satisfy me in the current School Zone prototype:

    • [now] One can land on a stunned blador, but can't walk on him.
    • [todo] 1/3-2/3 for the hero position on screen gives more room to anticipate, which is great when running, but a center position is nice when you have monsters all around you. Using the (R) shoulder to "look ahead" (direction-dependent) should be investigated.
    • [todo] the "chalk" gob is crying for being polished, both art and behaviour. Having the chalk-gob being the only thing able to break the chalk-tiles would likely be the best approach to avoid curious behaviour.
    • [done] when thrown in pencils, dumblador should stop slightly above "the ground".
    • [done] update maps make pencils spikes reacting to ennemies too.
    • [check] granted, we cannot attach or repell them, but can we allow line-up operations against BLOCKs ?
    Ça comme à faire un peu trop de choses qui ont été testées mais qui n'ont pas vu leur potentiel pleinement réalisé et qui réduisent la qualité du prototype de la SchoolZone au lieu de l'augmenter. On voit que je ne fais plus assez souvent de démos auprès de mes collègues ^^".

    Saturday, November 16, 2013

    Fine-tuning.

      Raw as raw can be: here's a collection of "todo items" related to the "20 years anniversary level" that has staid draft since my first re-contact with the BilouCorp. It's not very sexy, but at some point, gameplay fixing is also those kind of fine-tuning.
    • [done] BIGFALL Camera: a maximum vertical speed of 7 for the camera is a minimum as Bilou's maximum vertical speed is near 6 (pixels/frame). It feels better when the camera is controlled by the DPAD (holding down when falling) rather than activated automatically when reaching a specific velocity. With those settings, the player has 0.5 second between the time pencils appear at the bottom of the jump-of-(fai|dea)th and contact with the ground. half that time is required to manoeuvre Bilou away by 16 pixels, that leaves ~0.25 seconds of reaction time to the player.
    • [done] Spongebops appearing on the bottom of the screen due to wrapping of the Y coordinate by the DS hardware (?) mislead the player into believing that there's an invisible sponge that will reveal if they jump into endless pits.
    • [wish, AskTheTeam] Bonus room with a "hidden exit" should better be replaced with a room that offers a limited time to collect all the items and brings you back to the level when completed (as in DKC). Until the engine can support that, make sure the room's exit is as close as possible from its entry, so that realizing that you can't come back through the path you picked doesn't prevent you from going further with the game.
    • [done] Chalk do break, much more easily than pencils. Use some chalk picture for the break-through platform on the desktop.
    • [done] Add an 'onscreen' controller that triggers an event when an object gets offscreen, so that 'stunned' animations can be completed and items no longer "magically disappear".
    • [done] with a horizontal top speed of 540, running becomes enough to clear the pencil-pit area: no more bouncing-on-bumpers or grabbing-sponges is necessary. with momentum limited at 480, it is still feasible to clear the pencils, but it requires to jump when Bilou's first feet is already out of the safety area, so the bumber is "safier", and it could be made more in the middle of the platform as initially designed, so you don't necessarily fall into the pencils if you miss it.

    Croyez-le ou non, mais j'ai réussi à recontacter la "Bilou Corp", et j'ai donc une toute nouvelle toudoulisse pour le niveau-anniversaire. C'est un peu brut, vous m'excuserez peut-être un jour. Plein de petits règlages à faire: les vitesses de caméra quand on tombe, le remplacement du crayon-qui-casse par une craie-qui-casse, etc.

    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

    Wednesday, October 23, 2013

    Some bugfixes in progress

    After a couple of days checking the stats, I opened the editors again. I wanted to experiment alternative collisions for Spongebop and improve the readability when falling down. I updated camera control so that UP/DOWN DPAD directions can be used to adapt camera (that was quite simple)

    I think I tracked down an unpredictible crash on level loading. The crash only occured when reseting the level just after some droplets (the only object that turns into nil) gets deleted. Engine::delanim() should remove the object from the deleteme list in that case, not from the todo list. I also fixed another potential source of silent random crash linked to the lack of dedicated "you're dead / level clear" tracks :P .


    Allez, quelques petites modif's avant d'aller au lit. Le nouveau comportement des collisions avec l'éponge, pour commencer, suivi d'une meilleure gestion de la caméra pendant les chutes (Morukutsu appréciera ;) puis la possibilité de regarder en haut et en bas quand on est à l'arrêt ... c'est toujours sympa, dans un jeu d'exploration.

    J'ai du débugging sur la planche, aussi. Certains effets de glissés de la musique ne passent pas, les notes en questions restant du coup silencieuses et une sorte de condition de course logicielle pouvait planter la console si on avait le malheur de changer de niveau juste après qu'une goutte d'encre n'ait été retirée (à quoi ça tient, quand-même!)

    I could also point out that the inconsistences in the music comes from module effects to be ignored. They should explicitly be supported! that's a task for ddd and --arm7gdb=7777 ... As soon as I got that sorted out and get the confirmation by early downloaders that the game can be launched, I'll post a fix.

    All this reminds me, of course, of the "last minute panic" I got when I tried to enable throw-bladors-anytime (3 days before the release) and observed  curious effects: parsing the second level would then corrupt memory (most likely) and make the level loading impossible. On one of my machine, that made the std::map that holds BlockInfo to have an invalid pointer.
    Hopefully, once that bug turned "stable", identifying the root cause was a mere "sherlock holmes game": list all the possible causes for one more state transition to corrupt memory, rule out those that are incompatible with the observed behaviour and you get pointed at a "owned" bitfield that has incoherent value (and still rules which transitions are deleted when).

    Thursday, August 30, 2012

    Prêt pour la rentrée ?

    Il m'aura fallu du temps, mais j'ai enfin un décor intéressant pour la school zone ! Basé sur un dessin au trait puis converti à la dure (comprenez, avec Gimp, une souris standard et un calque "hue") et lui-même inspiré d'éléments de décor de Pinoccio et Blanche-Neige du Grand Walt.

    Between engine re-factoring and Bilou animation upgrades, I've tried to find things to fill the background of the library level while keeping a "intimate" tone. I think I've got at last some ideas, thanks my little daughter watching Snow White and Pinoccio movies :)
    I'm not very convinced by the sketch-to-pixel-"art" conversion process yet, but at least I've got something to fill the emptiness of the former mock-ups.

    Now, I still have things to fix: the background layer is (for some odd reason) loaded as an InfiniMap as well, which means the game engine tries and update the map as if it had to stream in new tiles. That could explain some odd behaviours I noted with Apple Assault. I still hope I'll have a running demo for September 3rd so that kids all around the world can recover from their first day at school with a Bilou minute...


    Il me reste à en faire le rendu de manière convenable, et ça, c'est pas encore gagné. Le décor (512x256 pixels) est pour l'instant chargé comme s'il s'agissait d'une couche "map" classique, et le moteur de jeu tente du coup de la faire scroller "normalement" aussi... sauf qu'elle scrolle 2x moins vite, parallaxe oblige. Du coup, les savants calculs destinés à garantir que le morceau affiché à l'écran soit toujours bon donne lieu à des "téléportages de hibou" plutôt étonnant.

    Maintenant, il serait temps que ma DS rentre elle aussi de vacances, que je puisse finaliser tout ça.

    ... flawless victory ^_^

    Friday, August 19, 2011

    Scrolling issues: done.


    Oh, btw, horizontal scrolling issues are now fixed -- it was about time!. Hope you enjoy it.

    Juste pour vous tenir au courant: le scrolling horizontal marche maintenant aussi bien que le vertical. Ca ne faisait finalement que presqu'1 an qu'on attendait ça ... ou depuis le mois de février 2010 pour Morukutsu :P

    Et il m'en reste encore pas mal, des vieux 'todo' comme ça ... la plupart visant l'éditeur de niveau (qui n'a toujours pas eu droit à une release officielle), d'autres sur des extensions des capacités du moteur de jeu ou de l'éditeur de sprite. Affaire à suivre.

    Wednesday, August 03, 2011

    now to the horizontal scrolling ...

    Hello, there. If you missed the english translation on my former post, Sonic Camera Management, it's now done. The new scrolling is implemented and works fairly well for the vertical direction. Unfortunately, it doesn't work as well for horizontal scrolling.

    The reason is that Bilou is not moving at the speed of 1px/frame but rather 2px every 2 frames, to match the animation speed. Former platformers would typically have running characters instead, since they are more flexible. When running, it's easier to make it so that (animation) frames where a feet is in contact with the ground only last for 1 (screen) frame. Well. Anyway. The result is that right now, the horizontal scrolling is not smooth anymore, but rather "pushed a bit" at every step, then it sits back, then pushed again. Ugly. I need a mixture of the two techniques, which means a bit more code hacking.


    Youpie. J'ai donc un chouette scrolling vertical bien plus professionnel. Hélas, trois fois hélas, le scrolling horizontal en a pris pour son grade. Que je m'explique. Bilou se déplace de 2 pixels tous les 1/30eme de secondes alors que le jeu tourne à 60Hz. Il reste donc 2 "coups" de jeu au même endroit bien qu'ayant une vitesse moyenne de 60px/seconde. Le hic, c'est que si j'applique la politique "le personnage pousse l'écran en quittant la zone neutre du scrolling", eh bien, mon scrolling ne bouge plus qu'à 30Hz, 2 pixels à la fois. Et ça, c'est assez moche et nauzéeux. Bref, il faut que je passe à une approche hybride qui combine le nouveau scrolling vertical et l'ancien scrolling horizontal ... soit encore un peu plus de bricolage sur iCamera :P

    ... and well ... I will need to build a place where I can test things with the full-quality pixel art ... not restricted to that "open-source 8-bit" color reduction thingy :P

    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, September 26, 2010

    Better scrolling

    DAns un épisode précédent, Morukutsu pointait du doigt le scrolling vertical sub-optimal de mon moteur de jeu. Je n'ai pas encore eu l'occasion de m'y atteler, et le problème est sans doute moins visible dans Apple Assault, mais je garde à l'esprit qu'il faudra que j'y retourne. J'ai d'ailleurs scanné mes cogitations (à savoir les différents cas de figure possibles et comment on souhaite que la caméra réagisse) ... je reviendrai dessus prochainement.

    Previously on this blog, Morukutsu was pointing out sub-optimal management of vertical scrolling in my game engine, that makes some hazard hard to avoid. I haven't really developed that aspect of gameplay, but here are some thouhgts I scanned a while ago ... I hope I'll get some time to discuss them in more detail later on.

    edit (18/8/2011): enfin, c'est fait!

    Saturday, February 27, 2010

    Tu (d)'chus, il chût

    morukutsu says: Le scrolling bouge un peu tard quand le personnage tombe, ce qui pourrait être délicat pour les scènes de plateforme avec du scrolling vertical.

    Bigre! Il a raison, le bougre! Evidemment, je commence à connaître mes niveaux par coeur, donc je me promène dedans sans me rendre compte que la visibilité est insuffisante, ou que Bilou est presqu'en train de tomber hors de l'écran.

    Il faut avouer que je tâtonne pas mal avec le scrolling. Ce serait assez simple de garder Bilou en permanence exactement au milieu de l'écran, mais je ne le souhaite pas. En particulier pas pendant un saut. Mais ça, je vous en avais déjà parlé, vidéos à l'appui. J'avais donc fait en sorte que seule la vitesse horizontale soit immédiatement prise en compte: les contrôleurs indiquent à la caméra la vitesse exacte de Bilou et la caméra s'y adapte. En plus de ça, j'ai toujours un "garde-fou" qui force la caméra à se recentrer sur Bilou si celui-ci est trop loin de l' écran (en gros, comme un BerryBat se rapproche de Bilou).

    Morukutsu pointed out that it was pretty hard in my last release to fall down safely. The camera management tends to let Bilou get really close to the bottom of the screen when falling ... it may even let it "out" of the screen from times to times. I was shocked to realise how true he was. I guess I'm so used to my own game that I barely needs to read anything from screen and I can safely reach any area of the game "blindly". So I tried to sort it out.

    It wouldn't be much of an issue to simply keep Bilou in the middle of the screen at all time, but that's definitely not what I want. It leads to very disturbing camera moves when you hop from platform to platform. Plus, it means that you loose track of what you're jumping over during the jump -- as I already said previously.


    Mais du coup, dans certains cas, Bilou peut atteindre une telle vitesse que lorsque la caméra "réagit" pour tenter de le suivre, il est déjà trop tard et il se retrouve fort au bord de l'écran. Je corrige le tir avec une règle qui force la caméra à suivre la chute de Bilou dès qu'il va descendre plus bas que la hauteur d'où il a sauté.

    Il me manque une rime en "eutre" ...

    ... euh pardon. Interférence. Il me manque encore une règle dans les contrôleurs "walking" et "idle" qui indiquerait à la caméra "recentre-toi sur Bilou verticalement, tant qu'à faire". Parce que pour l'instant, quand Bilou s'arrête dans les branches à la fin d'un saut, il peut parfaitement rester "fort au bord" (haut ou bas) de l'écran malgré tout. En attendant, j'ai modifié le "StopperController" pour qu'il permette au joueur de regarder en haut ou en bas avec le DPAD. C'est toujours ça.

    I just missed that, if I don't update camera's position during a jump, it may be too late to track Bilou back to the center of the screen when he falls down. I thus adjusted so that we follow Bilou's speed again -- even when falling -- as soon as the "landing speed" is reached. By landing speed, I mean "the opposite of jump-off speed", and it is reached when you come back at the vertical position you're jumping from. It's not yet fully Commander Keen's Magic Scrolling, but it's getting close. And I added look up/look down in the "idle" state so that the player can force Bilou to get back in the center of the screen.