Showing posts with label inkjet. Show all posts
Showing posts with label inkjet. Show all posts

Saturday, February 17, 2018

Histoire d'encre

Eh bien, le fait de se déplacer dans un encrier n'est décidément pas intuitif pour le joueur lambda de School Rush. J'en prends pour témoin les réactions des membres de "e-magination" à mon screenshot:

Le pot d'encre dans lequel sauter, tu l'amènes comme ça dans le [Level Design] ? Parce que j'aurais pas envie de sauter dessus personnellement, il ressemble trop à un piège  ...

Peut-être qu'il faudrait rendre l'encrier plus amical ? Perso avec ce regard, je lui ferais pas confiance. ^^

Another person commenting on the fact that jumping into an inkjet to use it as a bumper/platform is far from straightforward. They aren't wrong, of course. The secondary question was 'how is that introduced in the level design'. I've got a good answer for that one: a not-yet-aggressive inkjet is featured on the intro screen, and the player is invited to jump on/into it to start the game.

Ce serait une approche assez classique du problème, c'est vrai. Mais l'encrier n'est pas amical, sans être pour autant fondamentalement méchant.
Il s'agit d'un gardien, et d'un gardien face à une invasion. il ne sait pas de quel côté est Bilou. Il ne cherche pas à l'aider quand il le projette, juste à s'en débarasser. Il est dangereux (à cause de ses gouttes d'encre plutôt toxiques), pas franchement engageant (parce que entrainé à être gardien), mais peut être utile si on sait s'y prendre. C'est une dimension que j'aime bien (les carapaces de koopa, notamment) et que j'ai envie de développer dans mon jeu.

The easy way out would of course to make the inkjets look friendly, but they aren't. They aren't "evil" either. They're warders. Guardians facing invasion times (from the pendats). They don't know which side Bilou is. They don't try to help when they throw him up, just to get rid of him. Inkjets are dangerous (ink is rather toxic), not welcoming nor appealing (but well, they aren't stewards), but if you manage to work around properly, they can prove useful. I hope this echoes the harmful/useful duality of the koopa shells, which is one dimension of gameplay I especially enjoy and want to dig deeper.

Thursday, December 21, 2017

Refactored, but freezing

ok donc, j'ai eu du code qui compilait en un rien de temps, malgré un refactoring plutôt osé. Par contre, plus moyen d'atteindre la fin du premier niveau: le jeu freeze, à peu près tout le temps au même endroit, juste avant de m'afficher les premiers "inkjet" mobiles.

Good joke! How useful is it to get refactored code compiling if you cannot reach the exit of level 1 anymore? The game now freezes every time roughly at the same spot, just before the first moving inkjets. I will need my mercurial time machine...

Je prends donc ma machine à remonter le temps (comprenez mercurial) ... le bug semble aussi se produire avant la refactorisation ... j'évite donc de passer pour un clown qui fait des effets d'annonce sur son flux twitter, mais je n'ai quand même pas du code qui marche. J'ai noté que A. avait réussi à rejouer aux premiers niveaux après avoir fini le niveau vertical, donc il existe un point pas trop éloigné dans l'espace-temps où j'ai du code qui n'a pas ce problème.

"Good" news is that the bug wasn't introduced by the refactory -- at least, my twitter-honor is safe. But honor does not make code run. I know that A/S-team could beat levels 1 and 2 during the last playtesting session, so the bug must have been introduced fairly recently. If I could find the last working commit, that would help understanding what went wrong and how to fix it.

Reste à le trouver pour comprendre ce qui cloche. Pour ça, j'ai maintenant mon programme automatique de "unit-testing" qui simule un va-et-vient dans les niveaux.
Et le programme de test en question crashe, lui. Un beau gros "segmentation fault", dû à un débordement de pile. Et la fonction "backtrace" capable de m'indiquer où s'est planté le programme et comment on en est arrivé là prend un plombe à s'exécuter (en fait, j'ai intérêt à l'interrompre):
  • CompoundGob::collide(#288)
  • BlockArea::collision(#1934)
  • InfiniMap::getflags(#350)
  • GameObject::cando(#1786)
  • CompoundGob::loadAnim(#178)
  • CompoundGob::setstate(#52)
  • CompoundGob::collide(#288)
  • BlockArea::collision(#1934)

Hopefully, I now have an automated test that moves back and forth through the levels. And that test program crashes (big segmentation fault) when running one failing build. The backtrace function of my debugger takes ages to point out where the crash occurs (and how the program reached that state). When I interrupt it, I see no memory reference on the "call" instruction. All registers have valid values, no invalid opcode to be spotted around. The only suspicious thing is the fact that there seems to be a repetitive pattern in the function calls.
Then I checked the value of the stack pointer and Captain Obvious knocked on my head.


Oui, vous avez bien vu: on tourne en rond. Et le code fautif serait apparu pendant que j'essayais de corriger le problème des personnages qui jouent à Philadelphia Expérimental avec le plafond.

Mais comme j'ai une release à assurer demain au boulot, je vais pas la faire trop longue. On sait où chercher. On cherchera pendant les congés entre les paquets de Noël et les cotillons ;-)

This is a stack Overflow, caused by something in the new code that enforces alignments when resizing bounding boxes. It is obvious because the stack pointer has the lowest allowed value, given the area allocated as stack according to /proc/self/maps. It is too late to start searching what and why, but at least I know what to look for and roughly where.

edit: trouvé en 20 minutes de "cybook" pendant que *deline travaillait sa danse. Corrigé en à peine davantage. On va pouvoir reprendre le travail sur les plans de scrolling ;-)

got it located while *deline was having her dancing lessons, fixed in about half an hour. I thought it would take me at least a week-end. Good. I'll be able to go on with the rest (todo: figure out what still has to be done)

Saturday, October 21, 2017

drop your weapons

One of the most vexing gameplay bug I can think of in School Rush is that you can't enter inkjets when carrying a dumblador. That can easily lead to moments of panic for most reactive players and frustrating death for others.

I now have it fixed, by dropping the requirement of NO_WEAPON when entering inkjets, adding a "THROW" test area when being in the inkjet and ensuring that we DROP_WEAPON if this area ever gets triggered.

C'est probablement un des bugs les plus agaçants de School Rush: impossible d'entrer dans un encrier avec un taille crayon dans les mains (ouais, essayez donc vous-même, vous verrez). En phase de playtesting, ça donne lieu à des moments de panique frustrants pour les joueurs. Je corrige donc en retirant une contrainte sur une transition et en ajoutant un nouvel effet de bord.

What took me a bit too much time to figure out is that the impulse to drop an inkjet must be define as you enter the state with a F_THROW test area, and not on the found-matching-object transition expression (likely because the blador-side of the expression evaluation happens before the bilou-side expression).

Friday, May 26, 2017

SaturdayScreenshot

Et voilà. J'ai un petit effet sympa pour attirer l'attention sur les boules bleues redonnant de l'énergie au joueur. Ça aura été un peu de chipotage pour intégrer les nouvelles animations dans les 4 niveaux existants, par contre. Pour la suite, il va vraiment falloir que je veille à ce qu'on puisse inclure les déclarations de bloc spécial de la même façon qu'on inclut les machines d'état pour les personnages.

Demain, je pourrai mettre ça sur Twitter et participer au micro-évènement "postez un screenshot de votre jeu en cours de développement".

Don't you love that blinking effect on the healing bonus ? Not as hypnotic as bouncing on a pink eraser, but i'm quite satisfied with the result. I'll have some work to do to allow such things be used in multiple levels without having to rely on manual copy-and-pasting across multiple script files.

Sunday, May 21, 2017

shell to cybook

I got the z-list issue fixed. The error was what I suspected, but what is more interesting is that I have been able to write a test case that reproduced the bug systematically, and thus that demonstrate that the problem is gone with the fix.

I had to change my approach for investigating that because I've been doing so much on-line activities these last days that my eyes started to "panic". So rather than staring at my laptop top understand the outcome of a test, I pushed it into a .html file that I could browse with my e-ink cybook.


python -m SimpleHTTPServer 8000 & # http.server if you're on python3

(echo "<html><body><pre>" ; 
  ./testme ; 
  echo "</pre></body></html>") > /tmp/html/out.html

(echo "<html><body><pre>" ; 
  grep -h -C14 prepare libgeds/source/* 
    | sed -e 's:&:&amp;:g;' 
    | sed -e "s:<:\&lt;:g;" 
    | sed -e 's:>:\&gt;:g;' ; 
  echo "</pre></body></html>") > /tmp/html/code.html

Bon, ça n'a pas été une semaine simple, mais j'ai réussi à pouvoir prouver que le bug d'affichage de Bilou est corrigé tout en reposant suffisamment mes yeux qui criaient "au secours" la semaine d'avant. J'ai notamment utilisé assez abondamment ma liseuse pour passer en revue les résultats des tests (puisque oui, j'ai choisi l'approche "test automatique plutôt que l'approche "debugging interactif raffiné", la faute aux yeux précédemment cités). Celà dit, je vais rester prudent et laisser les détails techniques uniquement en Anglais pour cette fois-ci. Dès que j'aurai compris pourquoi l'encre refuse de s'arrêter à la hauteur demandée, je pourrai faire une release améliorée de School Rush.

The test itself is actually fairly simple conceptually: I just drag Bilou around in the level, back and forth, emulating the camera and the game logic after each displacement. As the camera moves through the level, some game objects freeze and unfreeze, recycling the hardware sprites, and inkjets use the top-layer sprites so that ink drops look to come from within it.

On the first round, the bug did not happen, but I had programmed a "trap" to report what I thought to be the precondition to reproduce the bug (having the inkjet frozen while it had one hardware sprite at top priority). The test then showed me that this happened, but less often that I thought. Actually, it only happened with one inkjet near the end of the level.

Then, I extended the test so that I would make an increased number of scrolls through the level. There I got the bug appearing systematically on one of the levels. I had to filter out some of the events reported during the scroll (I reported every change in the zlist's size as well as any arrival/departure of hardware sprites): inkjets throwing ink corresponding for instance to 4 correlated events. Making sure that the camera coordinates are reported (instead of Bilou's coordinate) helped as well.

Wednesday, August 31, 2016

Plummet (2)

Et si le fait d'avoir une plume changeait fondamentalement l'humeur des encriers de la School Zone ? Au point qu'il ne leur vienne même plus à l'esprit de lancer des gouttes d'encre.
Et si ces plumes, Bilou pouvait les transporter d'un encrier à l'autre profitant d'un vol plané d'encrier à encrier.

Techniquement, ce ne sera pas pour School Rush, mais j'aime bien l'idée...

The recent chat about techniques that could extend the number of sprites the GEDS engine could support on the DS opened some new paths and led me to funny ideas such as "what if Bilou could use quills to move from one inkjet to the next one ?" and then "how would an inkjet feel (and look) when he's got a quill in ?".

That might not reshape the SchoolRush game, but I love how it turned out

Thursday, March 24, 2016

Bon pour le son!




Ok les gars: accrochez-vous bien à vos baskets, voici toutes les captures animées dont mon frangin aura besoin pour me faire la "palette sonore" de School Rush, ré-appliquant le procédé qu'il a mis au point avec Lazy Cow pour son jeu "PowerGlove" récompensé au concours de RGCD.

I tried several ways to get the right sound effects for Bilou: School Rush, and I ended up with the following observation: it must be tested both against the background soundtrack and against the in-game timing (and possibly the look) of the action. On the other hand, I'm not convinced that "playing" it is actually needed. So, following the advice of my brother, I captured an avalanche of animated gifs to be used as basis.








On va dire que ça compte comme "release d'anniversaire", mais j'espère avoir pour le courant des vacances de Pâques une release stable avec un vrai menu de sélection du niveau de difficulté.

Given the real-life interference of the last days (Brussels attacks seems to have damaged my laundry machine), this will be my birthday-gift-to-the-Internet for this year... but I now have all the pictures I wanted to implement the "difficulty selection" bottom screen, and I should have that built somewhere next week.

edit: quicklink to the latest download if you enjoyed this


Saturday, October 10, 2015

School Rush Story

Bon, mon jeu n'a pas la reconnaissance de Rick Dangerous, mais il y a une ressemblance amusante avec les croquis de Simon Phipps.

The idea of "turning off the ink" starts to get real. With some details on the level design, I hope to be able to explain "why is there so many ink here", and "what happened to turn something normal into something dangerous. Time for some more Pixel art ...

edit: Got fair art drawn, but unfortunately, I'm using the few 16 colors (same as the inkjets), which happen to be trashed by the background art in the current code. There is no good reason for this to happen, given that we have now extended palettes (16*256 colors for every individual plane). I'll have some code-digging and potenially refactory time ahead.

Edit: ok. Cork switch closes the level. It doesn't let you see ink draining away from the pipe, though.

Saturday, September 27, 2014

Kirby Kid's Advice: Inkjet interplay


Here's another one stripped out from Kirby Kid's precious feedback:

the double ink jar obstacle could be tuned better so that the player waits less. the rhythm/timing challenge here is pretty complex (two objects moving and attacking at different rate). Also when the ink rises jumping into these jars is difficult when they go under the ink.
Pas évident, hein, les doubles encriers ? Selon Kirby Kid, ça vaudrait la peine d'en ajuster le rythme pour que le joueur ait moins besoin d'attendre. Effectivement, si on essaie de passer en force ou en vitesse ce genre d'obstacle, ça se finit généralement dans une mare d'encre. Même pour moi. Dommage pour un jeu de course ?

Yeah, that's quite true, I have to admit. Whenever I fail myself at *deline's level, that's in the only part she has not been involved in: the double inkjets. Same for the later level. I hadn't bother this far because I'm not that good at video game, so it sounds natural to me when there's some place where I often fail.

Now, there's one easy way I could increase the chance the player goes through such challenge: allow him to undermine it. If only Bilou had the opportunity to stun inkjets by throwing him a dumblador, that would ease moving through. You wouldn't need to time your jumps because inkjet would stay in-place.

Mais je coince un peu: je ne vois pas bien à quels ajustements procéder. Permettre de simplifier le challenge, ça oui. Il me suffit de permettre au joueur d'assomer les encriers qui resteraient alors gentiment sur place, sans plus jeter d'encre. On redescend à un mode plus simple avec un encrier immobile et un mobile, une seule source de goutelettes. Mais est-ce bien à ce genre de solution que Kirby Kid pensait ?



You wouldn't have to fear droplets either. Of course, when there's two of them, only one would be disabled that way, but that would still be better than trying to hop here and there to dodge droplets.

L'autre explication possible, c'est qu'avec leur façon de monter et descendre depuis le début du niveau, mes encriers se trouvent dans un état trop imprévisible au moment où le joueur les rejoints. Le moindre petit retard accumulé et il n'y a plus moyen de se fier à sa mémoire: il faut obligatoirement observer les encriers, repérer le rythme de leurs tirs (qui dépend de la distance qu'ils parcourent) et se faufiler entre les gouttes.

 
Now, the point I cannot solve is whether that would be solving the "tuning" issue mentioned by Richard. But what could I tune better ? Inkjet's speed doesn't seem too fast, they typically throw once moving up and once moving down. The moment when they'll prepare their blow is constant related to the moment where they turn back, so you *can* learn it from observing, but it will be harder to use this knowledge from one inkjet to the next, since the position of your platform compared to their turn-back position is variable.

Comparativement, tous les Marios sur 8 et 16 bits n'auraient activé le comportement des encriers qu'après que Bilou s'en soit suffisamment approché. En dosant la vitesse à laquelle il avance, le joueur peut alors "manipuler" leur comportement et les forcer à adopter un schéma qui est plus à son avantage. J'avoue, c'est surtout une technique de speedrunner, et j'aurais tendance à la trouver plus perturbante qu'amicale, mais au moins ça donne une possibilté de contrôle bienvenue dans ce genre de situation.

One thing that differs from typical Mario games, is that inkjets are active as soon as the level starts. In comparison, all 2D Mario games built before 1995 were technically limited to a dozen of active sprites. Anything that was moved offscreen from a sufficient distance was "deactivated" and monsters -- but also moving platforms -- start activating when the screen approach them. Here, the player will see them at a random initial position because their position depends on the number of frames spent to get there. Comparatively, in Mario, you'd see them at a position that only depend on how fast you were moving when approaching them. Is this what I'm missing ? 
The ink is interesting to avoid in the air. Once it hits the ground, the player has successfully dodged. If the ink hurts on the ground, the player just waits around for the coast to clear.
This has been easily fixed. Now the ink only hurts in the air, no longer on the ground. For the "rush" type of game, this is definitely not deconstructing any of the challenge.

Thursday, February 20, 2014

Vieux coups de crayon...


2005
 En vrac, quelques petites illustrations bilou-esques qui s'étaient glissées parmi mes documents de doctorant, et qui correspondent justement à la "zone creuse" de Bilou: L'encrier en 2005 pendant que je reluquais surtout les graphismes de petitcarreaux.fr pour améliorer mon trait,

I think I mentioned that idle timeslice between 1998 (Badman III) and 2006 (the pencil and the sharpen-her), where I mostly focused on operating systems design. While cleaning up my office, I dug a small collection of easy-to-date sketches of Bilou-related characters. 
2006
We see an inkjet from 2005, while I was attending a conference on grid computing, some pendats covering empty space between some IXP microcode in March 2006 (PhD years, just before starting the comics, afaik) and some standalone emotions of Verso-the-eraser which I would date from 2002 (or possibly late 2001 when I was finishing my master thesis ?)

2006
Un de ces crayons qui peuplait les ébauches de level design dans l'ambiance "bibliothèque 3D" de 2006 (pendant ma phase BD-couleur-photoshop). En mars de la même année, j'avais essayer de l'imaginer se déplacer en 3D avec du "tilting" pour la marche et de la rotation pour la course.
2002
Plus vieux (à mon avis vers 2002), quelques réactions de "recto-verso" dont les gags ne voulaient pas prendre, marquant ainsi la fin du "Bilou's Book".

2003
2004 ?
2003
Et pour clôturer, malgré leur arrivée tardive, voici enfin quelques gribouilles de Bilou et d'autres personnages de la School Zone datant avec précision de 2003. Curieusement, Bilou se remet à faire des grimaces qu'on ne lui connaissait plus depuis les années '90.

Plus délicat à dater, une tentative de mise en page du retour-éclair de Bilou dans la Green Zone où il devra "recharger les pouvoirs de la gemme dans le deuxième monde". Rien que ça. Le croquis est tracé au dos d'un document présentant Reiser4 (paru en '2004, et j'ai des raisons de penser que je suis tombé dessus assez rapidement après sa sortie). Côté scénaristique, ça ne marche pas suffisamment, et je reste donc calé du point de vue "Bilou's Book".


Saturday, September 28, 2013

2 days left

Inkjet throwing Bilou up finally works fine with corrected animations. I wish Bilou would lower by 3 or 4 pixels when the inkjet prepares the blast.
Tonight, I shall upgrade runME and the .cmd files on the DS so that I can try all those new objects in their real target environment. I also added some turn-back transition for pendats ... they should be able to join the game soon.
I still need some blocks for the "end-of-rail" tile and some horizontal
I need to make RectoVerso vulnerable to thrown bladors
I have to check inkjet-on-rail do work
I need to make sure the engine in RunME allows me to keep grabbing sponges.

Bien. Les animations pour projeter Bilou fonctionnent. Ce serait pas mal que Bilou s'abaisse de 3-4 pixels pendant que l'encrier se prépare. Reste à mettre à jour runME et transférer les .cmd sur la DS pour faire quelques tests en situation réelle. J'ai aussi rajouter une animation de demi-tour pour les pendats. On devrait pouvoir les intégrer prochainement.

Manquent encore des blocs pour la "fin du rail", les rails horizontaux, rendre les gommes vulnérables au lancer de taille-crayon, vérifier que les encriers-sur-rail fonctionnent correctement et que le moteur de jeu permet d'attraper les éponges dans runME.

Friday, September 27, 2013

3 days left.

Not so much achieved yesterday, but this day is off, so I can fix inkjet's behaviour. Some state command adjusted, and I have Bilou thrown up for the first time with a little thrill ... Now I have to find the tuning that makes the animation work fine.

Hmm ... something wrong with transanims, but it's getting to late to get that sorted out >_<

... oh, wait ... I'm not parsing :anim%u tail in transitions on 'done' or 'fail' but only on 'event' and 'found' in very specific situations ?? wth? 

Le J-3 est un jour de congé, et ça tombe bien, parce que je n'ai pas avancé autant que j'aurais voulu hier. Quelques commandes state à ajuster et voilà Bilou qui se fait projeter par un encrier pour la toute première fois. Petit frisson. Reste à ajuster l'animation pour que ça marche correctement. Et corriger le parser pour qu'il prenne les animations de transition en compte dans tous les cas, et pas seulement quand la transition est le résultat d'une collision.

Friday, August 23, 2013

Sheets for AnimEDS.

The set of animations for the school zone is quite full now (here, you don't see the spongebop, for instance).
Some of them could be dropped in specific levels, but I just don't want to lose things I've crafted so carefully, especially if I know I might use them later on.

So, just like you have "sheets" of sprites in SEDS, there will be some "sheets" of animations in AnimEDS asap. I love thinking of "sheets" for that because i) the DS display is too small to show them all and ii) scrolling through linear large set has never felt comfortable when working with RSD game-maker.

On dirait bien que j'ai quand-même rempli le jeu d'animations auquel AnimEDS me donnait droit. Je vais donc introduire des 'planches d'animation' tout comme il y a eu des 'planches de sprites' dans SEDS. J'aime bien penser en terme de planches. Ca s'adapte assez bien à l'espace limité de l'écran DS et c'est plus confortable que les interminables listes déroulantes de l'éditeur RSD.

Ce n'est pas forcément la chose la plus urgente à faire là-maintenant, mais le fait que la page soit pleine n'aide pas à ajouter des choses comme "Bilou-dans-l'encrier", "la gomme tournée dans l'autre sens" ou "le crayon assommé". Du coup ...

RSD map editor: you had to scroll
in a flat list to get another tile.
Random thoughts:
  • there are 8 columns per sheet, and less than 8 lines. That suggest using octal numbers for animations in game script could mean 226 is natevly translated into "page 2, row 2, column 6".
  • [done] We'll need a way to move things around pages. It would be useful to consider the last two lines as belonging to a sticky page (e.g. page 7) that can be used as buffer space to move things between "structured" pages.
  • [done] We'll need an input to dismiss one animation completely.
  • [done] preserve ongoing animation while switching page
  • [done] keep an "undo" for deleted animation, recall them pressing "DELETE" again.
  • [wish] sticky page remains sticky across loads (implies content wouldn't be saved :-/)
  • [done] avoid additional issues with LEDS' monsters rendering.
  • [done] some random replacement still occur, apparently when coming back from the editor window
  • [fixme] restoring deleted animation on another slot randomly makes source slot show an animation again.
  • [wish] find some way to flip to the next/prev sheet (preferably without the stylus). 
  • [wish] I can live with pendat's hands not having pendats colors on the thumbnail, but body's color reflecting the real choice could be important for level editor.
  • [wish] flipped limbs rendered flipped on the thumbnail.
It might not be the most critical thing to do to progress on the project, but it might also be that none of the monsters have progressed this summer because this sheet is full. No room for Bilou-in-inkjet... No room for swapped bopping eraser ... No room for stunned pendat ...

Monday, June 17, 2013

Spongebop Rodeo

I now have a (partly-)working prototype where Bilou can grab a Sponge bop and stay hooked while swinging, but I have to hard-code the offset between Bilou and the Sponge as arguments of the copycoords controller. Not so elegant. Plus, if I also allow to grab on Bladors (granted, that's a silly idea, but it helped for debugging :), those offsets are no longer correct and we're rather grabbing some point in the air over Blador's top-right corner >_<

Bien. Bilou peut maintenant s'accrocher aux éponges en balance. Il y a encore des soucis non résolus avec l'animation prévue à cet effet (d'où l'absence de démo jusqu'ici) et un désagrément mineur: il m'a fallu ajuster à la main et préciser dans les paramètres du comportement "accroché à X" la position relative de Bilou et de l'éponge. Au moment d'ajouter le comportement "assis dans un encrier", ça me démange un peu.

I initially had plans for making those "grabs" act on an are, and it would make sense to actually state "copycoords(a.bottom=b.top ; a.center=b.center)", but I've just said that accessing GobAreas within a controller isn't practical.
Expressions handling a collision have access to some extra-context variables (wc-wf) which were just involved in that "repel" behaviour that made inkjet "solid".


  • xcontext[0] - wc -- collision flags
  • xcontext[1] - wd -- unused (0)
  • xcontext[2] - we -- X-axis center-to-center distance
  • xcontext[3] - wf -- Y-axis center-to-center distance
  • xcontext[4] -- not in GobScript - X-axis area overlap
  • xcontext[5] -- not in GobScript - Y-axis area overlap
 The idea would be to use some GobScript to compute/force the desired location, possibly record it in some GOB variables and have the CopyCoords controller simply enforce that offset from the GOB variables.

Il y aurait bien des solutions techniques pour automatiser ces coordonnées relatives en "alignement vertical, centrage horizontal", à la façon des éditeurs de diagramme ... il y aurait même un "chemin de moindre résistance" pour construire ça dans le contexte actuel. Mais soyons honnête: ce n'est *pas* un élément nécessaire pour le programme. J'ai un seul objet auquel Bilou puisse s'accrocher de la sorte (l'éponge) et je dois de toutes façon utiliser une autre animation pour Bilou-dans-l'encrier (donc, autre état et autres paramètres). Ce serait donc de la généralisation intempestive et prématurée! Caramba! Ça le ferait pas!

I could thus extend the "interaction opcodes":
  • A[p]: attach [with path] evaluating object to context object (works in hit and found)

  • D: detach evaluating object (works in any transition)
  • R[xy]: repels context object away from the evaluating object (works in hit and found) [only along x/y axis]
  • L[xy]: line up the evaluating object with context object (mirrored repel)
  • C[xy]: center the evaluating object with context object (wish)
  • Now, let's be honest. That's a "wish", not a "todo". I only have one grabbable ennemy so far, and only Bilou grabs it. "hard-coded" offset are just fine in that context, and alternative are "premature generalization". I thought about all this because I'll also need a "copycoords" when Bilou sits in an inkjet, but that will be another animation and another state, so other copycoords offset is just fine.

    Wednesday, May 01, 2013

    Inside the Inkjet

    Pas si simple de mettre Bilou dans un encrier, même une fois le résultat à obtenir défini. Il serait sans doute bon de reprendre les évolutions de la semaine qui se sont agglutinées dans une "todo list" qui n'était pas initialement prévue pour ça.
    En premier, il me fallait un moyen de forcer les sprites à clignoter de manière sélective, et dont la définition se ferait au niveau des scripts. C'est pour un test, je ne fais pas dans la dentelle et j'introduis simplement un nouvel opérateur dans les expressions de changement d'état qui modifiera cette propriété de clignotement. En quelques essais, je peux rendre Bilou semi-transparent lorsqu'il s'est fait touché. Encourageant.

    It wasn't supposed to be that long. With the desired rendering defined, I'd have thought I could implement the flickering-translucent-inkjet in one sunday afternoon at most. I started with a couple of simple checks, like blinking Bilou when hit, and then selectively blink only some limbs. That was all neat and sleek. I had forgotten, however, that 'pulling' some limbs worked only "locally" by rearranging limbs within a sprite (although 3 distinct, globally ordered OAMs lists were introduced).

    Mais je ne veux pas que l'entièreté de Inkjet clignote: seulement le "patch" destiné à masquer Bilou lorsqu'il est à l'intérieur. Je change donc la sémantique de cet "opérateur-clignotant" pour qu'il reçoive plutôt des bits de contrôle et laisse le rôle de "compteur" à une variable accessible depuis les expressions du script. Je peux du coup faire clignoter seulement le corps de Bilou ou une de ses mains ... tout va pour le mieux.

    Par contre, le code permettant de modifier l'ordre d'affichage des composants d'un sprite (les OAMs du hardware, donc) n'offrait jusqu'ici qu'une modification interne au sprite, faisant passer une main devant le corps, etc. mais sans permettre de placer un composant devant Bilou et un autre derrière. Or, c'est essentiel pour "entrer" dans l'encrier.
    C'est le comportement "global pull" qui utilise les mêmes commandes "pullmask" qu'auparavant, mais qui force maintenant un changement de zlist pour les composants tirés vers l'avant-plan. Le code du moteur de jeu n'était pas tout à fait prêt pour ça.

    Once invariants for pulling limbs into list 0 on demand were ready, I realised the path to victory was cluttered with unrevealed bugs dating from z-ordering and even per-controller-events introduction. It's all fixed now, but it leaves a kind of annoying "not-quite-professional-coding"... I guess I should have known this from the start, this being a hobby project, I can't always afford being professional :P

    That being said, I definitely want to take the time to clean up the interface and provide some coherent way to define the (pullzero?, flickermask, pullmask, flickertime) variables in a cleaner way.


    Il m'aura encore fallu un ou deux temps de midi pour comprendre pourquoi ce damné encrier refusait de tenir compte de mes commandes pour continuer à clignoter. En fait, il restait un bug datant de l'introduction des évènements-par-contrôleur. Qu'un seul contrôleur voie sa liste d'évènements prise en compte lorsque deux (ou plus) disent simultanément "évènement", je pouvais m'y attendre. Qu'un "évènement" et un "impossible" se traduise en "réinitialisation", franchement, je ne l'avais pas vu venir. Il aurait été plus "pro" de concevoir des cas de tests suffisament riches au moment où cette nouvelle fonctionalité a été ajoutée. Seulement voilà, un pro code aussi en-dehors des temps de midi :)

    Sunday, April 21, 2013

    translucent ?

    I managed to have some translucent effect through fast (60Hz) sprite flickering. That's mandatory if I want sprite-versus-sprite transparency. So if I want Bilou to look "inside" the inkjet, I need an extra patch of glass that will flicker over Bilou to partially obscure him.

    J'étais tombé par hasard sur l'épisode "Spécial Disney" du joueur du grenier, dernièrement.  Après une bonne tranche de rire avec ma fée sur la partie "La Belle et La Bête", l'analyse (nettement plus grossière) de Fantasia par Infogrames me rappelle à quel point il est important de soigner la communication des règles du gameplay à travers l'aspect visuel. Le livre géant et menaçant qui est en réalité un bonus (et non un ennemi comme son aspect le suggère) et l'espèce de rond dans l'eau qui est en réalité une plate-forme.

    Mais maintenant que j'ai le moyen technique de rendre les sprites transparents les uns par rapport aux autres, est-il intéressant de rendre l'encrier transparent ? C'est plus réaliste, sans aucun doute mais ça n'est pas forcément mieux pour autant. L'aspect d'Inkjet doit transmettre au joueur "solide, dangereux, mais pas blessant", et pas "fantôme immatériel mélangé à l'arrière plan". J'ai donc fort probablement commencé l'ajout des sprites rectangulaires (pourtant attendu depuis longtemps) sans que ça n'ait aucune utilité immédiate.

    That being done, shouldn't the inkjet itself be translucent (against the background), and if so, how do I achieve that, given that the ink itself must remain opaque ? Basically, the only way is to separate the "glass" of the inkjet and the ink itself. That puts enormous stress on the vram as inkjet animation takes almost 1/4th of the spriteset so far. doubling it ? aouch. Hopefully, the ink only takes 16 pixels high, so that would be worth an update of SEDS to support wide (and tall?) in addition to square sprites.

    Although its in progress, is it really wise to go that way ? Does the translucent inkjet on the right look better than the non-translucent (except for the patch) on the left ? Or does it rather look ghost-like rear object which you wouldn't expect to be solid and ride-able ? After all, form-fits-function is crucial in video games, and the only way to allow the player to have "eureka" feeling rather than progressing through frustrating trial-and-error.


    Bref, c'est l'occasion de rajouter le terme "Form Fits Function" au tagtionaire... ce lien entre l'aspect et l'effet si cher à Miyamoto et qu'Infogrames a systématiquement ignoré.

    PS: the DS also has 16-color sprites, and obviously, the inkjet shouldn't need more. Converting the whole sprite page into 16 colors could do the trick ... but that's not supported neither by the Game Engine nor by the Sprite Editor at the time of writing. At best, it's a wish.

    PPS: pour ceux qui voudraient essayer le jeu, c'est par ici.

    Friday, March 29, 2013

    Floating or non-floating ?

    J'étais donc arrivé à vaincre les premiers défis techniques liés aux encriers et j'avais une animation assez convaincante. Suite à une demande de Lazycow, j'y ajoute une capture vidéo montrant les 2 "inkjets" qui bombardent Bilou à l'écran...

    S'en est suivi une discussion assez animée sur pixelation qui est partie beaucoup plus vers les choix de gameplay que vers le côté "artistique" pur et dur, ce qui n'était pas forcément pour me déplaire.
    Mais on touche à un élément "sensible": les encriers peuvent-ils ou non flotter dans les airs sans support apparent. Ce ne seraient pas les plate-formes mobiles les plus incongrues qu'on ait vu, mais ça représente un "décalage" par rapport à tout ce qu'un encrier est supposé pouvoir faire. Or, ça fait un moment que je me suis convaincu qu'il est primordial de faire en sorte que le monde virtuel dans lequel le jeu se déroule soit cohérent de façon à ce que le joueur y reste impliqué et qu'il continue à s'identifier au héros (fût-il une balle bleue :)

    It's a fairly long story that all started on "way of the pixel" as Lazycow asked for the droplets to complete the inkjet animation. So I showed up a byzanz record of my on-going level and everyone stared at those floating inkers, suggesting that they rather feel ground-borne. But floating inkjets is a pretty well established design decision that has already been used in several maps. Still, I don't want the fiction to fall apart just because of some detail that looks too-odd-to-fit-the virtual world.

    Quand Helm dit
    I would never think to use them as platforms and even when I would figure it out I would say 'well... this is weird' and it would take me out of the game.
    "Il ne me serait jamais venu à l'esprit de m'en servir comme plate-forme. Et si même j'avais fini par trouver, je me serais dit "c'est ... bizarre" et ça m'aurait ~sorti du jeu lui-même~".
    La fin (entre ~) n'est qu'une traduction approximative, mais j'y lis une rupture du vortex reliant l'esprit du joueur à l'univers du jeu. Le genre de "glitch dans la matrice" qui fait que l'esprit se persuade qu'il est impossible qu'il soit dans la réalité. La frontière entre une bonne fiction et un délire où le lecteur ne parvient pas à rejoindre l'auteur et le regarde se bidonner tout seul.

    Clairement, ça clashe. J'ai mis le temps pour re-penser à tout ça: les encriers-volants étaient un des premiers élément de gameplay que j'ai introduit moi-même quand j'ai commencé à faire du "level design" pour Bilou en 2007. Ils figurent sur la bannière de ce blog. Ce n'est pas rien. Mais oui, je suis le Grand Conteur de l'aventure (pardon pour les majuscules) et je peux trouver mieux que cette solution "peu chère" même si j'y suis émotionnellement attaché.

    Quite some time ago, I planned and kept secret the addition of a "cork lid" being a sort of organic key that Bilou carries along to change the behaviour of inkjets. The idea is that the height Bilou could reach would be higher when he's using the lid. The ground-based and the airborne inkjet thus co-existed in level designs, with little attempted to harmonise that. Of course, it would still be possible to ride an inkjet with no lid, but that wouldn't throw you as high.

    Parmi les solutions envisagées, il y avait la possibilité de faire en sorte que Bilou soit "propulsé" vers le haut en lieu et place de gouttes d'encre, s'il saute dans un des encriers. C'est une autre façon d'atteindre les hauteurs, et je pourrai donc l'exploiter à certains endroits où je retire un encrier-flottant-verticalement.

    J'avais aussi prévu depuis un moment qu'on puisse rajouter un bouchon par-dessus un encrier, pour l'empècher de bombarder d'encre, mais aussi pour pouvoir être propulsé encore plus haut ...

    Dans l'exemple "lancer le taille-crayon", je jouais sur le fait que Bilou arrivait dans un encrier pour motiver le fait qu'il lui était impossible d'emmener un taille-crayon. Celui-ci est facile à adapter: il me suffit de descendre un brin l'encrier (vide) de façon à ce qu'il flotte dans l'encre. Rien d'anormal ici.

    A first use case featuring the inkjet was the "bridge" that brings Bilou to the blador-and-pencil area. Here, Inkjet is different from any platform by the fact that Bilou need his hands to grab the inkjet and avoid falling. Therefore, he cannot bring a dumblador along. It's fairly easy to adjust, though: an empty inkjet could easily float in the ink, so I just need to raise the level of the ink swamp by one tile and I'm done.

    Le "niveau de rémi" me bloque beaucoup plus. Je voulais combiner les 2 propriétés du taille-crayon (solide et transporteur) pour lui faire bloquer l'entrée d'un passage vers la gauche. Cette entrée n'aurait été débloquée qu'une fois l'encrier en route vers le haut (avec Bilou à son bord). Seulement voilà: une fois engagé dans le conduit, pas moyen de sortir de l'encrier. On devra pour ce faire attendre d'être arrivé à l'étage au-dessus, et on aura donc à combiner un bon timing tout en évitant Bangbash et la rangée de crayons pour entrer  dans le passage sans pour autant se faire écrabouiller par l'encrier qui redescend.

    My nephew-drawn level brings a tougher challenge. The inkjet here is moving vertically, only when triggered by Bilou's landing. When idle, it blocks the way to a secret room. Without that room, Plummet -- the scribble feather -- could have been used, but I specially designed around the presence of a moving block that push the player into a narrow vertical pipe. You can't escape that pipe until the inkjet has reached the ground level, with a Bangbash to take care of.

    S'il n'y avait pas eu ce passage secret, j'aurais pu faire appel à Plummet, la plume qui accompagne l'encrier bougon qui sert d'introduction à "Deep Ink Pit" Mais suspendu à une plume, on peut se détacher n'importe quand ...

    Dans un autre essai de niveau, j'avais mélangé encriers et livres-écrabouilleurs pour forcer le joueur à ajuster son timing plutôt que de foncer toujours plus vite en avant. Ici aussi, le fait que Inkjet soit solide oblige de correctement calculer son coup pour ne pas tomber dans les crayons.
    Une éponge qui monte et descend devrait pouvoir reprendre le rôle, cela dit.

    Another timed challenge that used inkjet moving up and down to force you dodging the smashing book rather than rushing forward. I guess Spongebob could easily be used instead, here.

    Ici, image d'archive (excusez la qualité moyenne du scan): le premier niveau de la school zone dessiné par Piet avec deux encriers qui montent et qui descendent. Ils ont pour rôle de mettre suffisament la pression au joueur pour qu'il soit tenté de minimiser les risques et du coup "loupe" la clé nécessaire pour quitter le niveau. Mais vu leur côté ascenceur, on pourra si nécessaire refaire un essai en faisant demi-tour une fois l'erreur constatée.

    And last but not least, here comes ancient scroll where my brother depicted the first school zone level. First inkjet ever, and they weren't floating on their own, but were rather standing on "magically floating erasers" ... not much better. They were used to intimidate the player and make her miss the key among the bonuses, while offering the option to move back upwards and eventually grab it. Would it work if I had some bouncing erasers on the ground with the inkjets bopping up and down ? it's fairly high ...  

    Les encriers sont-ils sur des gommes volantes dans le dessin de Piet ? sans doute. Est-ce une meilleure idée ? J'en doute.
    Assez rapidement j'ai voulu "habiller" ces deux encriers, par exemple avec une grosse poulie et des cables: ils se retrouvent dans le matériel prévu pour le cours de physique et montent/descendent accrochés l'un à l'autre. Sauf que si c'était réellement le cas, Bilou devrait pouvoir s'accrocher lui aussi à la ficelle, non?

    Ce n'est qu'en commençant ce texte et en voyant les lattes côte à côte que mon cerveaux embrumé par mes 34 ans tout frais à suggérer l'interprétation de "ce sont des flacons du cours de chimie accrochés à ces saloperies de statifs universels gradués, et ils sont maintenus par des pinces qui montent et qui descendent" ...

    I was staring at those two-decade-old inkjets and suddenly, the rulers started looking like those graduated rails that the chemistry teacher used to build goldberg machines featuring erlenmeyers and test tubes. They would perfectly grip on an inkjet, wouldn't they ? you can move the grips up and down at will, too ... and the rail itself is too slippery, so Bilou cannot grab it on his own! Eurèka!

    J'ai enfin fini les corrections des TP de mes étudiants, donc je chope un microfin et je fais un test ... Hmm ^_^
    Oui, ça j'aime beaucoup mieux. ça ne sera pas utilisable partout, mais des classes de chimie, il y en a aussi. La tige sur laquelle la pince est montée est suffisamment glissante et large pour qu'intuitivement on puisse admettre que Bilou ne parvient pas à s'en servir seule. Reste à ajuster la perspective pour qu'il n'y ait pas trop "d'espace mort" entre l'encrier et la tige (qui fait office de mur).

    Je crois qu'on y est. Coder ça, ce sera l'affaire de quelques pixels supplémentaires ... rien à voir avec "la plume en 3D" ou "une grosse poulie avec des cordes et tout ^_^



    Pendant ce temps, sur Way of the Pixel, ça ne chôme pas. Chacun y va de sa petite proposition.

    J'aime assez bien l'approche d'Ymedron (ci-contre) pour un "passage imposé" où il faut ajouter un bouchon pour passer. C'était le genre de petites scribouilles que Julien, Piet où un autre membre de PPP Team m'aurait suggéré il y a 20 ans quand le projet venait de commencer. On aurait pu rêver meilleur cadeau d'anniversaire ? ^_^

    Habemus Atramentarium. And thanks to Ymedron's alternate solution, I now even have the perfect scenario for introducing the cork lid without involving some boring text-based tutorial ^_^.