tiled milestone

tiled [t.a.g.]

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJVUquWMaLvVjfnHr4bL5xXX5aKH5Ion5U1Ej0vYIx3UrWXaKFYwHF8p-Hz-yzEJTQB3OkU1zC6ZoORarZ7257P-rigLsM_o2-J-zFo9ORPVpbTH-TmmKGz0b873LOG6F9wunG/s320/cando.png ; cando.png
Great. You've read through all the posts related to the management of a tile-based level and how the game logic uses it. The basis is also covered in the tutorial branch through the 'cando()' function that filters contents of the map to say whether we're green to do some kind of move or not.
(2005-12-31) [tiled][tagtionary]

J'ai une DS

Pour l'instant, elle ne me sert qu'à jouer à Mario & Luigi: Superstars Saga, mais j'espère bien pouvoir faire plus ... Avec l'annonce d'un New Super Mario Bros, d'un nouveau Zelda et d'un nouveau Yoshi's Island, ça devenait nettement plus tentant qu'avec un Nintendogs ou un Mario 64 contrôlé au stylet...

(2006-01-01) [game][milestone][surDS][thisblog]

J'attaque la DS

Ce coup-ci je m'y met: je me lance dans le développement sur nintendo DS. Bon, ne vous attendez pas à du sensationnel genre "Bilou en 3D" ou "Badman IV" ni même un portage de Clicker (bien que ce serait fun).

Finis les grands projets még-à-l'eau: j'attaque par la base. Petits "sprites editors" et autres qui serviront de base. Ce serait déjà bien fun si je pouvais créer et animer des persos depuis mon fauteuil, transférer tout ça sur PC et le ramener dans un jeu plus tard.
En plus, d'après mon expérience sur PC et C64, c'est encore par là que c'est le plus facile d'attaquer: pas besoin d'avoir une tonne de texture et compagnie pour s'y mettre ... Puis je ferai tourner le "tracker" pour DS dessus et je prête la bête 2 semaines à mon frère pour qu'il me fasse une zik ou deux, et c'est parti pour "Bilou Sky Quest DS" :)

Let's go! i'm starting DS development. I don't bother doing large projects such as Badman IV or a 3D Bilou game. This time, let's make it simple first. Small editors for pixeling and animating characters from my armchair would already be a nice starting point. Maybe our "Bilou Sky Quest" shoot'm'up could be a starting point after i integrate a modplayer...


http://www.aaronrogers.com/nintendods/wifime.php
http://www.devkitpro.org/
http://www.double.co.nz/nintendo_ds/
http://www.dsdev.org/ -last updated in 2005. See https://web.archive.org/web/20100505045923/http://www.dsdev.org:80/
(2006-06-14) [3D][coding][devkitpro][skyblog][mybrew][choice][hardware][milestone]

Premier Bilou sur la DS

CA y est, les gars. Le matériel de GameLand-Shop.fr est arrivé ... supercard, superpass et lecteur de cartes SD en USB, tout y est! Et bonne nouvelle, mon sprite editor marche presqu' impeccablement (évidemment, avec un design aussi minimaliste, je vois mal ce qui aurait pu foirer :P)

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZO7P_bomC48xZ76jnu0R97PzcKMi5PZMflAZnHXTXhWv15_BJcrlOKVWR3e18oNoSN64rOo0OwZbah8m6NMujORPJQwOtGJC1cdxqTEam-UutpznD7-tK64EbAzFATsOZRWnE/s1600/555387425.jpg ; 555387425.jpgHahaa! My homebrew dev'er hardware has arrived. Supercard, Superpass and SD card readers. I gave my Sprite Editor a real try and it works! Here it comes : the electronic millimetric sheet for drawing things ^_^. Only one sprite and no saving at this time :P
"Ah, si tu mets Bilou dessus, je veux bien regarder", me disait mon e-papou l'autre jour. Bin voilà, en arrivant chez eux, j'ai redessiné un p'tit bilou sur cette grille-là et je lui ai montré ... "Tu retournes aux sources, là", répond e-papou en voyant le même genre de grille que celui que j'ai utilisé il y a près de 10 ans pour tous mes petits jeux... Bin oui, c'était l'idée ... sauf que je ne suis plus obligé de démolir des claviers en faisant "flèche, espace, flèche, espace, flèche, espace" pour remplir un carré :)

"C'est encore plus un retour au source" que je lui dit, "c'est un peu comme si j'avais une feuille de papier millimétrée intelligente qui pourrait retenir tout ce qu'on dessine dessus ... enfin, sauf que j'ai pas encore programmé les sauvegardes, donc si je l'éteint, j'ai perdu mon Bilou".
(2006-08-23) [coding][milestone][supercard][skyblog][mybrew][photo][screenshot][bilou][dslinker][sprite editor][gmaba]

SpriteEditor DS

Les choses prennent forme. Je peux éditer un sprite avec un outil 'crayon' ou 'block', et grâce au code de la "libfat" de chism & dragonminded, je peux charger et sauver mes sprites sur la carte SD. J'ai rajouté hier une fonction "copier le sprite" en utilisant un truc venant de SCUMMVM (le moteur de jeux pointer-cliquer de Lucas Arts).
Un pression sur l'écran correspond à un clic simple, alors qu'une pression pendant que le bouton "L" est enfoncé correspond à un "clic droit". Pour la grille, celà correspond à prélever la couleur comme couleur en cours, et sur la table de sprites, à enregistrer la zone de travail.


PS: avant ce post, il y avait mon skyblog. Les messages relatifs à la programmation DS ont été rassemblés dans ce post-anniversaire
(2006-09-08) [desmume][milestone][libfat][mybrew][bilou][spritesheet][user interface][sprite editor][thisblog]

Bilou .. l'ancien et le nouveau ?

Bion, il y a évidemment déjà eu un jeu Bilou, qui était programmé en QuickBasic pour DOS et qui a finalement fait usage d'une bibliothèque SoundBlaster (oui, m'sieur), même si ce n'était pas du grand délire (juste un son "hihoo" au début du niveau, un "uh!" quand on est touché, et encore).
Alors en grand, vous avez un aperçu de ce que ça donnait ... et en petit de ce que ça pourrait donner avec les nouveaux graphismes (pixelisés sur la DS).

J'ai encore du boulot pour les "feuilles" de mes nouveaux arbres, notamment parce qu'il me manque des couleurs compatibles dans ma palette pour l'instant (elle vient du jeu "Tyrian", qui ne s'est pas embarassé de teintes vert/jaune :P) J'ai essayé d'appliquer les techniques de Dan, mais il y a encore un peu de boulot avant d'avoir un décor vraiment convainquant.
Oh, et j'avais fait marcher la pomme, aussi, mais ça, c'est pas encore top (et je l'ai effacée par erreur hier, donc je pourrai en refaire une nouvelle :P)
Cette fois encore, le "mockup" fait appel à un zoli (?) dégradé pondu par The GIMP ... 'faudra que j'intègre qqch de similaire pour mon SEDS ...

edit : Vous notez l'appleman primitif et un "bubblebat" endormi dans l'arbre.


(2006-10-30) [gz1ac][screenshot][greenzone][history][evolution][appleman][mockup][berrybat][adventure][pppteam][y95][milestone][y96][msdos][basic][bilou]

Project started

http://sourceforge.net/projects/dsgametools/ is now officially started, and will be used to synchronise and distribute the outcome of my activities.
(2007-01-09) [milestone]

Screen Template

Congrats to Bigs and his "xmas dash" (a clone of Boulder Dash) who wins the xmas compo at Drunken Coder. I haven't got the time to check the game so far, but i've been visiting his homepage nonetheless, and i found an interesting document he wrote up: a sketch of VRAM usage for his program.

nice.

that's something i'm always missing when i'm to introduce new items in a game or new widgets in my GuiEngine for DS. So i decided to take the lunch time today to write myself a "template" of such document that one can happily print, fill and keep along for deving. In addition to Bigs' scheme, i added various information i always wish i had at hand when i'm doing that kind of low-level VRAM programming, such as how much memory each bank has, and what it can do.

If you prefer to have an editable version, feel free to grab the XLS (office 97) or the SXC (open office 1.1) file instead of the PDF.

Bravo à Bigs pour son "XMAS Dash" (un clone de Boulder Dash) qui remporte le concours de Drunken Coders. Honte sur moi-même: je n'ai pas encore testé le jeu, mais je suis passé voir sa page web, et j'y ai trouvé un chouette document où il esquisse l'occupation de la VRAM par son programme. Sympa.

En fait, c'est quelque-chose qui me manque chaque fois que je veux introduire des nouveaux éléments dans mes embryons de jeu ou dans le GuiEngine utilisé par SpriteEditorDS. Du coup, j'ai décidé de prendre le temps de midi pour me faire un 'modèle' à remplir et conserver comme référence pour la programmation.
(2007-02-13) [english][mybrew][coding][homebrew][tiled]

Vous courriez ? J'en suis fort aise! Eh bien, Sautez, maintenant...

Je discutais DS et bilous avec Dider, mon beau-frère informaticien, et je me rends compte que des techniques que j'ai apprises "sur le tas" avec mon Bilou's Adventure en QuickBasic peuvent parfois être pas si évidentes que ça pour des personnes qui ne baignent pas dedans depuis 15 ans ^_^

Outre les aspects techniques qui font que les images du jeu s'affichent convenablement, une question-clé était "mais comment programmes-tu les murs, les sauts, etc." Rappelons-nous tout d'abord que sur une console de jeu, l'écran (en tout cas pour les modes 2D) ressemble plus au carrelage d'une salle de bain qu'à n'importe quoi d'autre. Vous avez de jolis pavés (parfois appelés "tiles" ou "blocs" selon les cas) sur lesquels vous avez amoureusement dessiné des bouts de livre, d'encrier, de crayon, etc. Chacun porte un numéro et il suffit d'inscrire son numéro dans une grande grille pour construire l'image voulue.



Bion. Maintenant qu'on sait ça, on voudrait pouvoir détecter s'il y a ou non un sol en-dessous de Bilou, histoire de s'avoir s'il doit tomber ou rester sur place. Rien de plus simple: on va calculer les coordonnées d'un "point-test" situé juste en-dessous de Bilou et regarder le numéro du pavé au-dessus duquel il se trouve. S'il s'agit d'un crayon, d'une latte, etc. on ne bouge plus! Sur PC, j'avais traduit ça en une division des couleurs du jeu en deux sous-ensembles: les couleurs "solides" (pour dessiner les livres, etc) et les couleurs "de fond" (pour dessiner le fond. warf.), mais sur une console comme la DS, on a généralement plusieurs plans de décor, et pour commencer, on peut tout à fait décider que tout ce qui n'est pas "solide" set sur un autre plan: lors du calcul du "point-test", on verra soit le pavé #0 (du vide), soit un autre pavé, qui indique qu'on a affaire à du sol.





Bien sûr, ce que je fais avec Bilou et ses points-test peut être généralisé à tout le reste du jeu: les éponges, les crayons, les gommes, les gouttes d'encre et tout le tintouin. Il suffira de programmer les routines de déplacement de chaque élément du jeu pour qu'il fasse ses propres tests et réagisse en conséquence (passage de l'état 'sur le sol' à l'état "dans le vide", par exemple). Avec ça, vous ne devriez pas avoir trop de mal à vous construire un petit perso qui tombe quand il n'y a pas de sol et qui avance quand il est au sol.

Maintenant, quid des sauts et compagnie ? Bon, si vous avez déjà suivi un petit cours de physique, vous savez qu'un objet qui bouge a un vecteur-vitesse. En clair, si Bilou avance vers la droite, son vecteur-vitesse vaut p.ex. (5,0), c'est à dire qu'à chaque "tranche de jeu" (ou 'tic'), il sera 5 pixels plus loin sur la droite mais qu'il ne monte pas et qu'il ne descend pas. A l'inverse avec un vecteur-vitesse (0,5) Bilou descend comme s'il était sur un ascenseur. Pour donner l'impression qu'il tombe, il suffit d'augmenter la vitesse verticale à chaque tic. Mieux, même, si je démarre avec (0,-5) et que je garde la politique "augmente la vitesse verticale à chaque tic tant qu'il n'y a pas du sol en-dessous de Bilou", il va faire un gentil saut sur place.

Avec un petit calcul niveau secondaire-sup, vous pouvez même calculer la vitesse initiale à donner à Bilou lorsque le joueur appuie sur le bouton de saut pour qu'il puisse (par exemple) faire un saut suffisant pour grimper par-dessus un obstacle de 64 pixels de haut. Facile: il faudra au moins une vitesse initiale de 11. Et c'est là que le bas blesse: on vient de dire que 8 était un maximum :-/ Résultat,


En pratique, si vous regardez sauter Mario, vous vous rendrez compte qu'on a pas vraiment respecté les bonnes vieilles lois de Newton dans les sauts, et pour cause: le joueur doit pouvoir doser son saut, et la manière la plus naturelle de le faire, c'est de relâcher plus ou moins tard le bouton de saut. Dans la réalité, bien sur, ça ne correspond à rien: une fois que vous êtes lancés, vous ne pouvez plus décider que "oups, non, finalement, il faudrait que je saute un peu moins loin si je ne veux pas me tordre la cheville en retombant".

On pourrait faire comme dans ninji & zarbi et demander au joueur de laisser le bouton enfoncé d'autant plus longtemps qu'il veut sauter loin (mimant alors une "accumulation d'énergie" avant le saut) et ne faire le saut que lorsque le joueur relâche le bouton, mais je vous laisse imaginer sauter de passerelle en passerelle sur ce principe.
Non, ce que l'on va faire, c'est considérer que l'énergie dont notre Bilou dispose pour le saut n'est pas consommée complètement en un instant pour lui donner la vitesse (0,-11), mais plutôt que pendant une première phase du saut, Bilou conserve une vitesse verticale plus basse, mais n'est plus soumis à la pesanteur (en gros, il monte à vitesse constante) aussi longtemps que le joueur garde le doigt sur le bouton de saut. Avec un bon dosage de la durée max de cette "phase ascenseur", on pourra atteindre la hauteur souhaitée sans dépasser la vitesse qu'on s'est fixée.

Reste le coup du saut pendant la course. Le premier jeu bilou était assez déroutant dans ce sens. J'avais voulu obtenir un effet "à la Sonic" ou le personnage saute d'autant plus haut et loin qu'il avait pu prendre de la vitesse. L'ennui, c'est que je passais simplement de (v,0) à (v,-v) au moment du saut. Si vous faites le calcul, ça veut dire que au moment où le jouer appuie sur le bouton, c'est comme si l'énergie de Bilou était subitement doublée ... d'où un saut qui n'a rien à voir avec la vitesse de Bilou à ce moment-là. Idéalement, j'aurais plutôt du prendre quelque-chose comme (sqrt(v),sqrt(v)) pour conserver sa quantité d'énergie ...

On testera tout ça...

Sorry non-frenchy folks, this one is a big too large for inline translation. i might come with a dedicated post with translation when i'll have a bit more free time... and implemented the stuff ^_^ Meanwhile, i suggest that you read Gregg Iz-Tavares and Dan Chang's article on M.C. Kids for the NES, which basically covers the same kind of topic.
(2007-03-05) [game][tiled][sidescroller][collisions][mario][mechanics][JUMP][mockup][coding][school zone][tileset][physics][bilou][tutoriel][vram][gmaba]

Let's Rumble !

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3lQSfqEyIJ98PRcACLIIoz7tpcxUcRMCTRtI7Z-v0ZM2oxoNJg67nTn2TuXjbLa3VBFPPC2DaT44cIR1Ia5gjovZP_Zy8dNpAsUPY7r2wY_EZJMEWooJxKsZxxqZLe50r5Tab7w/s320/v01-rumbling.png ; v01-rumbling.png
Here you are, folks: my first homebrew game ever: Apple Rumble v0.1. Get it here, unpack and place the /rumble directory with media files at the root of your flash card.

How to play: hit the apples with the stylus when their eyes are open. The sooner you touch them in the game, the more points you'll score. My own best score is around 19 seconds for clearing the woods and around 970 points. If you manage to get at least 1000 points, post a comment ^_^

Mon tout premier jeu homebrew est enfin disponible: Apple Rumble v0.1! Téléchargez-le, décompressez l'archive et placez le répertoire /rumble (les musiques/sprites) à la racine de votre carte flash.

Comment jouer: touchez les pommes du stylet quand elles ont les yeux ouverts. Plus vous les touchez tôt dans le jeu, plus vous gagnez des points. Mon meilleur score est aux alentours de 970 points. Qui arrivera à passer les 1000 points le premier ?

SFX: V. Boigelot and S. Martin
GFX: S. Martin
Code:
S. Martin and Sten Larsson (TetAttDS)
Thanks flies to the maintainers of devkitpro, yopyop and the desmume team, Miodrag Vallat and supporters of the mikmod library for the nds, TONC and people maintaining GBA/DS technical documentation, Natrium42 and many others i might have forgotten including everyone working on making nds homebrew possible.

(2007-03-25) [download][game][milestone][english][mybrew][apple-rumble]

Sprite Editor on the DS: the SEDS approach.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrmJdqD4TsDXjUEb5TfARM3acMKmkKzsDjMe0_Kt4N_Rm_TNJsl3wLJOvmQjLJ7yXGlHCkeWqMiqQSmcMVfYOkCR9OcFlzBqnXpgdc6ReAy_qHvBL3jrYpG6C1Kt4TJjxy-Jh6/s320/540878759.jpg ; 540878759.jpg
Let's advertised it a bit: i've started a sourceforge project for the game development tools for the DS.
To many aspects, SEDS philosophy is quite different from the other sprite editors i've shown you in my previous post.

First of all, it is not using bitmap rendering. I oriented most of the rendering techniques towards tiles-oriented rendering that is so specific to console hardware. This is mostly possible thanks to the huge amount of individual tiles available on the DS.

As an example, the grid where you draw your pixels is actually made of tiles, that is, each individual pixel you paint is a 8x8 character that is programmed to be a 8x8 square of a single color. Same goes for the grid lines and the palette on the left. I also integrated various test of DS features in the editor, such as the ability of modifying the grid lines' opacitiy (through up and down arrow), thanks to the fact that widgets are rendered on a separate layer than background and your colored artwork.

Another great feature it enables is fast rendering at any zoom level. So far, the grid is rendered 1:1, but i have already tested a 32x32 grid with smaller pixels (which wasn't working as expected probably due to DMA problems). I could even potentially use 24x24 grid (scaling 8x8 tiles to 6x6 to keep the same area occupied) by just reprogramming two registers. Welcome to 2D hardware acceleration goodness ^_^.

J'ai enfin uploadé mes démos et sources sur mon projet "dsgametools" sur sourceforge. Entre-autres, SEDS, l'éditeur de sprites pas comme les autres, qui s'appuie principalement sur le hardware 2D de la console pour accélérer le rendu de la grille, etc. Le niveau de transparence de la grille, le zoom plus ou moins fort sur la zone de travail, autant de petits tests des possibilités de la bête... Ca demande un peu plus de boulot et de debugging que d'utiliser une bibliothèque de widgets sur un framebuffer, mais le projet gagne en intérêt ^_^

Bon, les sources ne sont pas encore génialement belles (je débute en C++, quoi qu'on puisse en penser), mais c'est assez fun d'utiliser pour ce genre de projet les techniques de développement OO, l'UML et tout ...
/* reprogramming the background layer 3 (colored artwork)
* so that it is 50% zoomed and still appear at (xbase,ybase)
*/
SUB_BG3_CX = (-xbase*2) <<8;
SUB_BG3_CY = (-ybase*2) <<8;
SUB_BG3_XDX = 2 << 8;
SUB_BG3_XDY = 0; /** XDY and YDX useless in that case. **/
SUB_BG3_YDX = 0; /** see TONC tutorial if they puzzle you **/
SUB_BG3_YDY = 2 << 8;


Feel free to download the demo or browse CVS sources.

Well, I'm not very proud of the sources. I'm still learning C++ and certainly haven't a good style atm. Plus, most of the code depends of libraries i've hacked for proper interoperations (such as the libnds that integrates anti-stylush-jumping code from PadrinatoR)
In other words, expect hard time if you try to compile the projects from its sources right now. I'll publish the modified libraries in the project too ... when i'll find time for this :P

And yes, the development of the editor is somehow freezing these last days, because i have met a point where data storage and organisation need to be refactored. And my thesis do not let me allocate sufficiently large time slices to do things like that ... so i'm just writing small perl scripts for converting old .SPR files to the new (anticipated) format -- which gets highly IFF-inspired if you ask :P
(2007-06-16) [english][mybrew][download][milestone][sprite editor]

.: easy :: normal :: hard :.


Suite au commentaire de CJ sur "armageddon machine", j'ai cherché davantage de niveaux de Commander Keen 4 & 5. Je suis tombé sur une véritable mine d'or: les niveaux tels qu'ils seraient vus dans TEDEDIT 5, l'outil d'édition de niveaux de Apogee/ID Software, réalisés par "pleinair123". Le layout même de ces niveaux suggérait que pleinair123 avait accès pas uniquement à des screenshots réassemblés, mais bien à une reproduction de ce que donnerait un éditeur. J'en veux pour preuve les flèches transparentes, qui servent de guide aux plateformes mobiles et surtout, ces curieux blocs gris avec un B que vous voyez à gauche de l'image et qui, selont la légende, servent de "frontière" pour les objets qui rebondissent (étoiles à pointes, passerelles, etc.)

Intéressant de constater que, bien que les éléments du jeu soient nettement plus sophistiqués que ce qu'il y avait dans le GameMaker, ce simple "plan" supplémentaire contenant les ennemis et ce genre d'objets de contrôle invisible permet des fonctionnements bien plus riches en se prenant nettement moins la tête.

Déçu, par contre, par l'absence de map équivalentes pour "Secret of the Oracle", j'ai cherché tout ce qui pourrait m'aider à reverse-engineerer les fichiers .CK4. Bin j'étais pas le premier : http://files.keenmodding.org/mobydoc.txt

Tout est là. De quoi se faire son petit éditeur ou viewer pour Commander Keen. Maintenant, que ceux qui pensent que celà veut dire qu'on est à 2 doigts d'un KeenDS s'arrêtent tout de suite:
1. Commander Keen est toujours la propriété intellectuelle d'ID software
2. Son inventeur serait ravi de refaire des Keens s'il récupérait cette propriété intellectuelle
3. Tout utilisation non-privée des infos dans "mobydoc.txt" (comme un homebrew) constituerait une violation des droits d'auteurs de Apogee
4. Il resterait quand même le plus costaud: reconstruire le comportement de tous les monstres, la physique du jeu, etc.

Bref. Je pense que ça n'intéresserait pas grand monde un keen sur DS qui avance mal, qui saute de travers et où les robots roses ne montent pas aux barres. Donc, je vais rester sur mon Bilou et ses éditeurs de niveau (non, la structure des niveaux de Commander Keen - même si elle est source d'inspiration - n'est pas géniale au point de vouloir utiliser TED pour Bilou :P)

Oh, et pour ce qui est du titre, je prends le niveau "security" de Armageddon Machine (le 2eme du jeu), au pif.

Mode easy: 6 Sparky, 3 Ampton et 2 SliceStars.
Mode normal: 13 Sparky, 5 Ampton et 5 SliceStars
Mode hard: on rajoute 4 Sparky, 1 ampton et une SliceStar qui se balade horizontalement au milieu des écrans bleus ...

Alors imaginez dans les niveaux plus loin, là où il faut commencer à rester sur les plateformes volantes pour ne pas mourru sous un feu crépitant de lasers, vous comprendrez vite que l'expérience n'est pas du tout la même.
Idem pour le niveau final. Ce que j'ai dit à propos des ennemis rebondissant dans un espace limité ne tient évidemment que s'il y en a (et il n'y en a aucun en mode easy dans cette partie du jeu). Le Shikadi Master est lui aussi réservé au mode "normal", et seule une rangée de lasers est activée, ce qui laisse au joueur le soin de passer à l'aide du pogo du côté d'où les lasers viennent sans être inquiété...

Donc, non, frérot: si t'as pas re-terminé les Commander Keen au moins en mode "normal", t'as jamais essayé plus que la "grande foire au bonus" réservée aux moins de 14 ans. Désolé.

edit: oh, et on ne sauvegarde pas au milieu d'un stage, hein ?
(2007-09-05) [difficulty][level editor][keen][featured][game][tiled][nostalgy][platforms]

SEDS Multipage

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGbwTPkSUCMWzRnGTU-FodWdTvjBlqo6gskIu9SL5D7_hU98K9qLDOd0ByMkMGQ3orFyz8gTQY4SUF5kfP6R3S3uyl-pBFEEs5g-EM9aPKQ-pTuoJgeBPUTffL0uW3m78AtXmfyA/s320/class-sprites.png ; class-sprites.pngah, y'a pas à dire: c'est agréable d'avoir un environnement de développement capable de mises à jour rapides ... En quelques coups de cuiller à pot, j'ai pu, hier soir, goupiller la première version de SEDS capable de gérer des fichiers .spr multipage. Enfin la possibilité de dépasser 48 sprites en un fichier (ça devenait vraiment problématique) et de réorganiser mes petits dessins par thèmes (un seul fichier pour toute la forêt, avec une page contenant les blocs de terre, une pour les arbres, une troisième pour les pommes, etc.)

Wow, needless to say, it's really a good thing to have software update to speed up application development. Just a couple of edit-compile-update loops were enough to brew the first version of SEDS that can manage multi-page .spr files (which had been tested in runme a couple of weeks ago). That means i can at last break the "48 sprites per file" limit and reorganize my own tiles theme-wise, e.g. grouping all the forest-related tiles with one page for dirt blocks, one for the tree trunk & roots, anoter one for in-progress tree tops, one for the apples, and so on.

C'est aussi un premier pas vers la possibilité de mélanger des blocs 16x16, 8x8 (pour les pieds et les mains de bilou, entre autre) et 32x32 (l'encrier).

Bon, ceci dit, pour l'instant, les réorganisations sont pénibles au possible, mais c'est juste parce qu'il me manque une interface pratique pour ce genre de tâche :P

Et il a fallu faire tout celà sans que les aventuriers qui avaient téléchargé la release d'hier ne se retrouve temporairement avec un programme inutilisable suite à un update malencontreux... ce qui n'a pas été sans mal :P

This is also the first step towards the ability of mixing 16x16, 8x8, 32x32 (and other sizes coming) resolutions in a single editor/spriteset, which will be crucial to go on working with Bilou's world. Well, right atm. "reorganization" is as tedious as moving files using MS word, but that's still better than no reorganization at all :P


Allez, ça mérite bien une "0.2"
(2007-10-16) [mybrew][milestone][uml][sprite editor][SpritePage]

tiles extraction ...

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCYhpAx20xJAcmq2lWVqZLMF6s901THkDCRcfbjUGCo2OGSKCZUxiqhda4PwaWKeH-NOs6gHqP29sSSXVW2mX6g7bYBfXQ3RZr9iNfkSVsA9BTR42VhkfGM10d5N93oG8BfiZcyg/s320/brewing-oct26.png ; brewing-oct26.pngUn autre petit outil en Perl (basé sur la bibliothèque de manipulation d'images Imlib) qui décortique une image et identifie les tiles uniques (8x8) et le nombre de couleurs utilisées...
Il ne fallait pas grand chose pour en faire un convertisseur .gif->.spr un peu plus automatisé. Je m'y suis attelé ^_^. L'outil en question s'appelle "imlib2spr.pl" et est disponible dans le CVS du projet 'runme'.

I've been working on a new small (PERL) tool for SEDS/runme. "imlib2spr.pl" is using the "imlib" package to open your .gif, .png ... pictures and identify uniques tiles and colors so that it can then convert them into .spr files.
It also builds a map of how to reuse those tiles to get the initial image back.

Mais pourquoi chercher à transformer une image .gif en un tas de tuiles, me demanderez-vous. Okay, certaines images contiennent des zones un peu répétitives et pourront donc prendre moins de place en VRAM... et c'est tout ?

Ooh non! Notre DS est effectivement capable d'afficher directement des images 'bitmap' (c'est ce que je fais quand vous envoyez à runme un fichier .pcx), mais avec une taille maximale de 256x256 ou de 512x512, selon la configuration d'écran choisie. Impeccable tant que vous voulez une image fixe, mais imaginons que je veux faire scroller horizontalement une image de 320 pixels de large, je fais quoi ?

Je passe à 512x512 ? le bitmap fera alors 256K, presque la totalité de la mémoire vidéo!
Je tronque à 256x256 et je redessine une colonne chaque fois que je me décale d'un pixel ? Bonjour le code!

Maybe you wonder why i'm trying so hard to split a picture into small tiles while i've shown with runme that it was fully possible to display a .pcx (and thus .gif and .bmp aswell) image straight on the screen. Well, the reason is scrolling. You very well can show a 256x256 image on the DS screen (which is 256x192) and side-scroll it again and again (using the 'scrolling wrap' hardware option). That will take you 64K worth of VRAM. Now if you want instead to side-scroll a 320x200 image, you'll get into trouble unless you're agree to devote 512K of VRAM just for your background image.

On the other side, once you have 'tiled' your background, you can easily repeat it as many times as you want: it's merely a matter of a few KB, and you can easily rewrite offscreen parts of the map as the scrolling goes so that you keep showing the right stuff at the right time, with a 64:1 reduction of the stress on VRAM.
Since we are running on gaming hardware, i think we should make the best possible use of it, shouldn't we?

Well, demo and code for that will follow once the 7.11.7 day is over.

Sous GBA, pas tout ces soucis: l'écran faisait 240 pixels de large et le mode bitmap 256x256 aussi, donc on avait tout loisir de redessiner des blocs dans la partie complètement masquée de l'écran, puis de scroller un peu, puis de redessiner, etc.

Eh bien, si l'on prend la peine de convertir notre bitmap en "tiles", on peut continuer ce petit jeu: une fois les tiles en mémoire, une "carte" peut très bien contenir deux fois l'image initiale sans nécessiter d'avantage de mémoire vidéo (allez, quand-même 1 ou 2K de plus, mais c'est quand même mieux que de passer de 64 à 256K, non?)

Bref, c'est Cyril qui sera content. Lui qui me proposait y'a pas 48 heures d'ajouter un mode "construisons notre map" dans SEDS ... On en est plus très loin ;)



à la base, c'était ça:

#!/usr/bin/perl
use Image::Imlib2;

$image = Image::Imlib2->load($ARGV[0]);
print STDERR "$ARGV[0]: ".$image->width."x".$image->height."\n";
while ($ty<$image->height) {
$tx=0;
while ($tx<$image->width) {
foreach $y (0..7) {
foreach $x(0..7) {
($r,$g,$b,$a) = $image->query_pixel($tx+$x,$ty+$y);
$r=pack("C1",$r);
$g=pack("C1",$g);
$b=pack("C1",$b);
$colors{"$r$g$b"}=$ncolors++ if !exists $colors{"$r$g$b"};
$tile.=$colors{"$r$g$b"};
}
}
$tiles{$tile}.="($tx,$ty)";
$tx+=8;
$tile="";
$ntiles++;
}
$ty+=8;
print STDERR ".";
}

print scalar(keys(%tiles)) . "unique tiles (/$ntiles) detected\n";
print scalar(keys(%colors)) . "unique colors detected\n";

exit 0;

note: il nous faudra installer le package libimage-imlib2-perl pour faire fonctionner le tout.


rem: pendant ce temps-là, Globoeil nous faisait une release de son "virtual game maker DS" ...
à découvrir sur globoeil.fr/vgdms ...
(2007-10-22) [level editor][coding][tiled][english][mybrew][perl][tools]

2D sur la DS : quelques chiffres ...

Plus de 640K de mémoire vidéo sur la DS -- c'est presqu'autant que la mémoire vive dont on disposait sous DOS sans les extensions. Mais comme je vous le montrait dans un de mes posts précédents, il faut répartir cette mémoire entre les deux écrans, les fonds, les cartes, les sprites et éventuellement, les palettes et les textures. Bref, pas mal de monde.

Pour un jeu de plateforme comme Bilou et Badman, le plus raisonable serait de partir sur 256K pour les décors, 128 à 256K pour les sprites (tout ça sur l'écran principal) et de garder les 128K restant pour gérer l'écran secondaire (map, inventaire ... peu importe). 256K de décors ... avec mes blocs qui font 16x16 pixel, ça veut dire que j'ai droit à un bon millier de blocs différents conservés simultanément en mémoire. Soit près de 5 écran de DS. C'est déjà honnête ...

Bien sûr, rien n'empèche de changer le contenu de la VRAM au fil du jeu. C'est notamment ce que j'ai l'intention de faire pour les blocs animés (pensez à la pièce d'or de SuperMario ou au bloc-question). On leur attribue quelques tiles sur lesquels on ira recopier systématiquement l'étape d'animation suivante au bon moment (depuis nos 4Mo de mémoire de travail, donc). Ainsi on gagne du temps et de la place. On pourrait aussi essayer d'éliminer certains blocs non-affichés pour les remplacer par d'autre en fonction de la progression du joueur dans le niveau, par exemple si l'on voulait faire un traveling continu sur les écrans d'Another World... mais il y a peu de chances que je me serve de quelque-chose de ce genre.

Dans un niveau ou le scrolling est libre dans toutes les directions, on choisira de préférence une map 512x512, de manière à pouvoir toujours modifier les "bords" de la map pour avancer dans le niveau sans que le joueur ne remarque quoi que ce soit. Il y a aussi des map 512x256 et 256x256 que l'on utilisera dans des jeux ou le scrolling suit un seul axe (les shoot'm'up, par exemple, ou des niveaux spéciaux dans un jeu de plate-forme).


Evidemment, on pourrait se dire que c'est du gâchis de prendre une carte de 512x512 alors que 256+16 aurait suffi à un scrolling fluide (réfléchissez un peu: pourquoi le GBA a-t-il un écran de 240 pixels de large, selon vous?). Mais ce serait compter sans le fait que la "carte" des tiles peut aussi nous servir directement pour savoir si notre personnage (et tous ses adversaires) ont affaire à un mur ou à un trou. Chaque "tile" est encodé sur 16 bit dans la carte (cf cet autre post précédent) et on peut choisir parmis 1024 "tiles" différents, les autres bits permettant de "retourner" les blocs horizontalement et verticalement.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOHQZXv8a_0i67MQwnRGFmy06bWYGLzt8evwi_EB9R_qp3Uvad8-yIUNjNoNJV9DrBwBV7U0-ea1rr21ZP2lUABewPcum4bKXkF0qlJS5mJixXD-P9cxigxMkDbxCTp5_ve0GLuQ/s400/mapformat.png ; mapformat.png
single tile encoding, from LiraNuna's tutorial


Restent 4 bits inutilisés qui pourraient se révéler bien pratiques pour encoder directement le type de bloc: creux, plein, "montée" à 45°, "descente" à 45°, "montée" à 22.5% ...
http://www.kmgassociates.com/rayman/images/typall.gif ; typall.gif

Dans Rayman Designer, il y a 24 types de blocs différents, y compris le bloc semi-solide (on peut passer à travers en sautant, mais pas en tombant), les blocs glissants (de nouveau 7 inclinaisons différentes), des blocs qui blessent, qui tuent, qui noient, qui font rebondir, escaladable, etc.

<obsolete why= "si les bits "palette" sont actuellement effectivement utilisés, c'est en les combinant par blocs de 4 tiles que l'on étendra le nombre de propriétés disponibles.">

Bien sûr, avec 4 bits de libre, c'est un peu juste pour proposer les 24 types de Rayman, et pourtant, dans Bilou, il nous faudra bien tout ça. Mais dans notre cas, il y a peu de chance que l'on se serve du "retournement" de tiles. Le plus souvent, ça fouterait en l'air tous nos efforts d'éclairage sur les blocs. Résultat, on pourrait s'arranger, par exemple, pour stocker certains blocs "à l'envers" et pour pouvoir se servir du bit "miroir horizontal" pour faire la différence entre les montées et les descentes ... L'alternative, ce serait d'avoir une des combinaisons pour indiquer que le bloc est "spécial", et de se servir à ce moment de son numéro pour choisir le comportement approprié, sachant que ce sera un peu plus compliqué à traiter... L'idéal, ce serait de garder ça pour les interactions que seul le personnage fera (grimper, se blesser, etc.) et d'avoir les effets sensibles égalements pour les monstres directement encodés sur la map...

</obsolete>

Enfin. 'faudra tester tout ça. J'espère que ça ne vous a pas paru trop imbuvable: j'avais besoin de mettre les idées au clair avant de me lancer dans le code de gestion des niveaux ...
(2007-11-15) [tiled][sidescroller][translate me][slopes][level design][cheat sheet][vram][jump-thru]

Ideas for smooth scrolling on the DS...

Bien sûr, la DS est capable de faire un scrolling fluide à travers un grand niveau, mais ce n'est pas nécessairement une mince affaire. Je cogitais sur les méthodes possibles l'autre jour et j'ai pris mes notes dans mon blog.

Je rafinerai et traduirai plus tard ...

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8AOBdIMnRN3Sw3XohVSOPZZ8xeLBZlE0MA8oKVbdWoC26I4WhVFFaFxyf4i9-y7ygHwVmfqms7iulxmAWGSPsgOio4AluBl20c2LES_Hg7rVHPvntnLHARH0S42jBXOzpl6PKfg/s400/liranuna-mapvstiles.png ; liranuna-mapvstiles.pngThe hardware (from Liranura's 2D tutorial)
Map bases always have 32×32 entries. To create bigger BGs (Like 64×64) you need to use several map bases. As for tile bases - If you want to make use of the full tileset (1024 tiles), you will have to use several tile bases - 4 Tile bases for 256col full tileset, and 2 Tile bases for full tileset of 16col mode. Since the Map bases and the Tile bases are located on the same region in VRAM, they can overlap. Since a map base is 2Kbytes and a Tile base is 16Kbytes, each Tile base contains 8 Map bases.
Une surface affichable sur la DS est constituée de 32x32 tiles (l'écran en fait 32x24) et occupe 2KB dans la mémoire vidéo. Pour construire des plans de décor plus larges (p.ex 64x64 tiles), il nous faudra plusieurs 'morceaux' de 32x32 mis côte à côte pour former une surface plus grande. On retrouve le même phénomène avec les tiles (pour utiliser l'entièreté d'un jeu de tiles (1024 tiles), il nous faut 4 sections de 16K en mode 256 couleurs). Notez que c'est au programmeur de choisir s'il va stocker 16K de tiles ou 8 maps dans une région donnée de la mémoire vidéo.

La console nous permet de positionner l'écran librement dans la surface définie (pour chaque plan séparément, hein, ) et -- contrairement aux carte VGA -- par défaut la surface 'boucle' sur elle-même (si la zone affichée déborde par la droite, c'est la gauche de la surface qui sera réutilisée).

We can have hybrid technique ...
At some point we have to alter parts of the map to keep scrolling smoothly. Nothing forces us, however, to have a unified technique that accomodates both horizontal and vertical moves. The fact that the screen isn't a square, that memory stores lines continuously and columns discontinuously and similar consideration -- not omitting the fact that our game may have a side-scrolling or vertical-scrolling action (shmups ;) -- may suggest that we have two distinct mechanisms for updating the map after a vertical and a horizontal movement of the "camera".

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUtuQLV9e99n64j_pUG7ifZoc-VaWqXKaauskzwkqCWgp6syroi0ejfmraR_h-ujzYQDv2DnsQykOYyUqKpAYwcDS2lf6LoQMmL4crr9ocfZ2WYtnoA1T7RPACWxIy3FOFEqsQGw/s400/DS-level-scrolling.png ; DS-level-scrolling.pngLe système de scrolling va forcément mélanger software et hardware. Le côté hardware, c'est le choix de la portion visible de la surface en VRAM (on l'appelle "onscreen surface" -- litéralement 'à l'écran' en anglais). Le côté software consistera à modifier des portions de cette surface (de préférence qui sont actuellement invisible pour le joueur) afin de donner l'illusion d'un décalage continu alors qu'en réalité, nous somme piégés dans un carré de 512x512 pixels.
Avant de ce lancer dans le code, il serait bon de se rappeler que rien ne nous oblige à avoir une technique unique pour les scrolling horizontaux et verticaux. Les uns pourrait parfaitement s'opérer à grands coups de DMA sur des tranches entières alors que les autres se feraient "bloc par bloc" gérés entièrement depuis le CPU.
  1. we can't have smooth scrolling in a 64x64 area if we reprogram 32x32 entries (dma copy) at once (<-- cyril contests this, see next post).
  2. we could do the "John Carmack" trick, using hardware scroll in the 64x64 area and then "jump" to a second 64x64 area when we're about to move out, but that would kind of be silly on hardware that allows to "wrap around" the area with our viewport (which the PC hardware couldn't do properly).
  3. doing "double-buffer" of the map will involve a burst of up to 8K memory transfer (through DMA), potentially leading to gameplay lags
  4. we have better things to do with the other maps (e.g. additional planes)
  5. DMA copy for the map might be interesting to save CPU (well, it is actually frozen during the move), but it requires that the offscreen map is a verbatim copy of what's used on screen. manual copy of the map parts instead allow us to use more bits for tiles meta-data and wipe them as the tiles are moved on screen. That would give us 64 types of block, more than we need to encode "slipperiness", identify bonus, etc.
thinking again ...
Nothing forces us to use 64x64 ... since the height of the screen is smaller than 32 tiles, we can very well work with e.g. 64x32 instead. This is not only nice because it halves the amount of work without loss of functionnality (maybe a bit less effective "caching" of vertical scrolling), but also because it means we now can do the "carmack jump" thing effectively: Suppose we are working with maps 0 and 1 initially (side-by-side 32x32 areas of the level map) and that the viewport is getting close to the edge of the currently displayed area ... rush! we dump another 32x32 chunk of the level map (and now we can just ask for a DmaCopy of the whole data if it is properly stored offscreen) into map #2. When it then appears that we are about to scroll out of the current 32x32 area, we then cheat the video hardware, reprogramming the map base to be map#1 (instead of map #0) and the X scrolling register to show us in the new area (most likely x=x-256 or x=x+256 depending on the movement).

Autre petite constatation: rien ne nous oblige à utiliser du 512x512 pixels! en fait, ce serait même l'inverse (en cas de scrolling horizontal, ce mode nous oblige à faire plus de mises à jour et ne nous offre pas grand-chose en contrepartie). Au passage, ça nous permettrait de faire un "scrolling à la John Carmack" plus efficacement (enfin, au moins une fois de temps en temps...).

Mais entretemps, je suis nettement plus sceptique sur l'interêt de la technique Carmack (rendue célèbre par la série des Commander Keen) sur le hardware de la DS.

I'm not sure we could keep it smooth forever with that technique, unfortunately: there would be no way for us to tell the hardware that map #N-1 and map #0 should be shown as a continuous 64x32 area...

see also captain Apathy's tutorial
voir aussi le tutoriel de Edorul (GBA)
Sonic the Hedgehog 2 (Emerald Hill) from soniccenter.org

(2007-11-19) [coding][tiled][scrolling][sidescroller][sonic][english][mybrew][cheat sheet][hardware][tutoriel][vram]

Scrollons encore

On discutait scrolling avec Cyril hier midi, et il m'a fait remarqué assez justement que je m'inquiétais inutilement pour les scrolling à grande vitesse. Bin oui, tant qu'on ne scrolle que d'un pixel à la fois on peut s'en sortir très bien avec seulement 512 pixels de large dans la mémoire vidéo. Au cours du décalage, on finira bien alors à se retrouver avec un morceau de 256 pixels appartenant à un seul bloc de VRAM à l'écran et on a les mains libres pour changer le contenu du deuxième.

example of what concerns me
Mais si la vitesse devient trop élevée, on risque de se retrouver à passer d'un 'bloc' à l'autre mais en gardant toujours plus d'un bloc de VRAM à l'écran, ce qui nous empèche de mettre l'image à jour sans prendre le risque d'un affichage inconsistant. Mais c'est là que Cyril est intervenu: rien n'empèche d'arrêter le scrolling plus tôt que prévu juste pour ce 1/60eme de seconde... On a alors de nouveau les mains libres pour copier le bloc suivant en VRAM, et au coup suivant, on scrollera un peu plus. L'un dans l'autre, ça devrait être invisible (edit 26.11) J'ai testé sur le temps de midi: c'est indécelable.

types de blocs pressentis pour Bilou, et leur encodage sur 4 bitsReste un autre problème: l'encodage des "types" de blocs. Si je faisais une copie élément par élément à la main (jouable si on remet un bloc de 8x8 pavés à jour d'un coup), je pouvais chiper les bits "miroir" pour encoder les types dans la carte "offscreen", et les remettre à zéro avant la copie dans la surface "onscreen".
Mais pour remettre tout un bloc à jour (2K), il serait franchement préférable de passer par le DMA.
Mais bonne nouvelle, on peut s'en sortir avec un encodage un peu plus subtil. Imaginez: on a besoin d'encoder si chaque tile est solide, traversable, incliné, etc. mais aussi s'il s'agit d'un bonus, de pics, de lave, etc. Trop pour 4 bits ... sauf si on encode que 12 types de tiles et que l'on se sert des numéros 12 à 15 pour des blocs plus "spéciaux", par exemple ceux dont seul le personnage du joueur doit s'occuper.

Alors, quel est le truc ? Eh bien voilà. Notre niveau n'est pas construit à partir de tiles 8x8 mais à partir de blocs 16x16. On peut donc supposer que la lave prendra bien 16x16, et ce n'est pas juste 2 bits (de 12 à 15) que l'on a pour faire la différence entre les picots, la lave ou les bonus, mais bien 4x2 bits (2 dans chaque tile faisant partir du bloc 16x16). Soit 256 types de blocs spéciaux possibles. De quoi voir venir...


(2007-11-22) [coding][scrolling][tiled][sidescroller][special block][translate me][choice][tutoriel][vram][jump-thru]

Yes! Ca scrolle!



C'a été un drôle de combat, reprennant les bonnes vieilles habitudes du cours Algo I (invariants, etc) pour parvenir à faire scroller le niveau de Sonic sur ma DS. Faire un scrolling vertical, c'est simple. Le scrolling horizontal m'a déjà donné plus de fil à retordre, mais pour s'assurer qu'ils n'essaient pas de s'assassiner dans les coins, j'aime autant vous dire que ça ne va pas sans mal.

J'ai laissé tomber les transfers DMA pour la plus grande partie du code. L'idée maîtresse ici était une "fenêtre de validité" qui indique quelle portion de la map est effectivement présente dans la mémoire vidéo, et à partir de quelle position. L'ennui, c'est que pendant tout un temps, le scrolling "vertical" modifiait des zones que le scrolling horizontal tenait pour acquises. Bref, on se retrouvait avec de gros blocs de terre au milieu du ciel, de l'eau dans le sol, des hybrides guèpes-singes, etc.

mais ça y est. Ca marche. Pour les curieux, le code est sur le CVS. Et au passage, j'en ai profité pour commencer un petit interpréteur de scripts pour ce genre de tests (histoire de pouvoir réutiliser un fichier .spr transféré préalablement). L'ennui, avec ce genre de méthode, c'est qu'il vous faudrait 5 minutes pour mettre en place le test à partir de runme.nds ... D'où la vidéo ;)

Pas de musique sur la vidéo, donc si vous voulez vous mettre dans l'ambiance, jetez une oreille à "Oil Ocean (WT-40 mix)" qui m'a accompagné lors de tous ces tests ^_^

edit 2024: Le CVS, c'est fini, et le travail sur le scrolling arrive d'un bloc dans le repository mercurial. Entre les deux, il y a eu un SVN où on voit le travail évoluer jusqu'à l'étape ça marche (4 décembre).


(2007-12-04) [coding][scrolling][sidescroller][milestone][sonic][gobscript][mybrew][video]

faire et défaire ...

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg15NVgFIfTW0dKjk83DtpKlopAL8xDD25IzleYNxROVxXSbwq6FYmPalEJQqWaVsccXJ6AAbYkVbzj81J-Czyk-JZAO81hreYkMJ7ritBh_I2X_c7nSY1KRRKIxKeXkChMP7sH/s320/level1-draft.png ; level1-draft.png

autre bonne nouvelle: les animations marchent! enfin, quand je dis "marchent", je devrais plutôt dire "rampent", puisque pour l'instant, seul le "petit ver jaune" de la forêt a été animé.
Je suis pas mal fier de mon coup, je dois dire. J'ai gardé un code tout à fait générique, qui est paramétrisé par un petit script de commandes. Petite astuce, les déplacements du ver sont intégrés dans la séquence d'animation elle-même, ce qui permet d'avoir un contrôle plus fin du déplacement (pour vraiment donner l'impression que le ver rampe, et pas qu'il glisse sur le sol pendant qu'il se tortille, comme on le voit si souvent dans les jeux amateurs).

En revanche, si je commence à être assez rôdé sur les std::vector<GameObject*>::iterator, je suis encore un peu perplexe sur les destructeurs virtuels. L'environnement d'exécution du "petit script" en question doit être "renettoyé" chaque fois que l'on veut relancer le script, et pour l'instant, ça se traduit encore trop souvent par un écran rouge de la mort. J'aime bien la méditation, mais toutes les 5 minutes, ça devient lassant. (quicklink: l'assembleur ARM par TONC: http://www.coranac.com/tonc/text/asm.htm)

D'un autre côté, j'ai un peu relooké mon script qui traduit une image (comme celle ci-dessus) en un tas de tiles et les données pour la map, de sorte qu'on puisse lui indiquer quelle couleur doit être considérée comme "transparente", et il s'arrange tout seul pour que les tiles entièrement de cette couleur soient considérés par la toute nouvelle routine de "testpoints" comme étant "EMPTY", tout le reste étant de type "BLOCK"...


edit-PS: la première version du level editor (sans sauvegarde) n'arrivera qu'en avril de l'année à venir. Là, on est donc toujours dans une "composition" de niveaux à coup de Gimp suivi d'une conversion avec détection des tiles redondants par un script fait-maison.


(2007-12-14) [adventure][coding][cxx][woodworm][tiled][gz1ac][collisions][milestone][gobscript][arbre][mybrew][greenzone]

*bounce*

Un nouveau pas important pour la réalisation de Bilou a été franchi: j'ai mon évaluateur d'expressions, et son intégration au moteur de jeu est quasi-parfaite. En clair, cela signifie que je peu maintenant indiquer via mon scripteur de niveau que lorsque Bilou arrive sur le sol, il doit:
Avant la DS, j'avais essentiellement testé deux mode de développement de jeux: le BASIC et le GameMaker de Recreational Software.

Côté BASIC, c'était la liberté totale pour les algorithmes et les comportements des monstres, mais les possibilités graphiques restaient restreintes -- même sur Pentium '90. Côté GM, c'était le constat inverse: scrolling dans des niveaux relativement grands, un nombre d'animation et de monstre présent à l'écran quasi illimité (au point que Pascal s'est même servi de monstres pour faire les bonus de notre remake de Pop'n'Twinbee). En revanche, le GameMaker était totalement incapable de gérer un saut un peu potable. Le simple fait d'avoir un sprite différent pour la montée et la descente du saut était impossible. Alors faire faire une cabriolle au perso quand il arrive au sommet de sa parabole (comme dans Bilou sur Basic), vous pensez bien ^_^.

About 10 years ago, i decided that neither QuickBasic nor recreational software's GameMaker could still fullfil my needs for creating games. I wanted parallax scrolling, compound sprites (think of rayman, but i already had it for Bilou in QB), and most importantly, more flexibility in creating monsters attack patterns.
I don't want to have to program them at the lowest level of machine code, i want their behaviour to be part of the game data, not part of the game engine.
When restarting game development on the DS, i decided to opt for something that would be state-machine inspired, but capable of reacting to the level map, the hero's position, etc. How to actually make it working came up later while reading the "making of Another World" .

Bref, à part des fioritures comme le parallaxe ou des sprites composés (à la Rayman), mon projet "Ultimate Game Maker" devait surtout permettre une plus grande souplesse de programmabilité : un scripting des actions : ne pas se limiter à des transitions "d'un état à l'autre" pour la gestion des monstres, etc. mais permettre plusieurs transitions depuis un état en fonction de l'état actuel du monstre, et une modification de certains de ses paramètres. Comme vous pouvez le voir sur l'image, je vous concocte déjà un petit 'appleman' bien particulier grâce à ce nouveau mécanisme.

C'est en lisant un making of du jeu Another World que l'idée est revenue au premier plan pour la DS. Dans Another World, Eric Chahi a choisi de disposer d'un environnement de développement pour son jeu qui ne nécessite pas de recompilation entre deux tests successifs, mais aussi la possibilité d'écrire toute la logique du jeu indépendamment de la machine considérée. Le jeu étant développé sur Amiga500 et constitué exclusivement de polygones rendus 'à plat' (à partir d'image filmées, il n'y a donc aucun calcul 3D), il n'est pas possible de s'en tenir à un "BASIC" traditionnel, trop gourmand en temps de calcul. Eric nous concocte alors son propre petit langage, mélange d'assembleur et de BASIC (oui, quand-même) dans lequel il va exprimer toutes les réactions du jeu (genre "quand le laser entre en contact avec la base du rocher, le rocher se décroche et s'incline en oblique").

Aucun élément compliqué n'intervient (pas de chaînes, pas de structures de données complexes): Eric utilise uniquement 256 variables entières pour représenter l'état du jeu, et le plus souvent, il ne les nomme même pas.

Même le maniement du joystick est géré de cette manière.

Another World was coded by Eric Chahi on an Amiga 500. He wanted cross-platform game logic for a game whose logic is *much* more complex than a shoot'm'up, and he also wanted to avoid recompilations between two tests. He thus naturally opted for some scripting language -- a mix between BASIC and assembly -- through which he controls animations and game variables (just integers).
Well, that's more or less what i'll do for my sidescroller game engine, except that you'll have per-object (monster, hero, switch...) variable in addition to the global (per-level) variables. In my case, i can even make the scripting simpler than Eric's "bassemblic" as it will essentially be used in predicates and actions of a state machine. So no control flow is needed at all.

Eh bien, je me suis dirrigé dans la même direction avec mon Game Engine, mais en donnant plutôt 16 variables par personnage (oh, il y aura aussi des variables globales comme dans Another World, rassurez-vous). Je me suis évidemment inspiré de mon interpréteur WASP qui m'a valu mon doctorat pour le bytecode, mais en simplifiant encore un coup: il me faut des expressions, pas des programmes ici. Donc exit toutes structure if-then-else ou les boucles, qui peuvent se coder par la structure de la machine d'état. Reste à inclure quelques instructions supplémentaires (p.ex. créer un nouveau monstre ou jouer un son), mais la base est là, même si mon 'langage' est encore plus moche que le bassemblic de Eric Chahi.

# gestion de la chute de Bilou.
state4 :anim0 {
   using gravity
   testpoint off (4,16)
   testpoint off (12,16)
}

state5 :anim0 {
   using stopper
   testpoint on (4,16)
   testpoint on (12,16)
}
# si la vitesse est trop élevée, on rebondit en la réduisant de moitié.
state4->state4 on fail [v1 $40 >=] (v1 2 / ~ :1)
state4->state5 on fail [t]


En avant. Essayons de voir si j'arrive à fixer la caméra sur Bilou pour le promener dans le niveau. Et en même temps, je vais tenter de faire un petit .nds de démo pour que vous puissiez tester ça sans devoir comprendre le fonctionnement de mon 'runme'.


(2008-05-02) [coding][sidescroller][milestone][collisions][uml][gobscript][state machine][testpoints][english][mybrew][choice]

gedsdemo : get it!

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbkPFdkhLFQT58804331gkyPgBpO2lllcDOOiSEMgsZQHqR-b7SlRa1wEqmy6ynlMRrxfuh7AMUohedSKrojnkWQFwDImJxKgvPQwyWtGqNUvzAd6_EXYG19P5RBqWduBgoZ8l/s320/gedsjump.gif ; gedsjump.gifAvec un petit desmume intégré à ubuntu, plus "byzanz" pour la capture vidéo (en .gif ... y'a mieux, mais c'est plus cher), et voilà un petit aperçu du rendu de la greenzone ...

vous pouvez télécharger la démo ici.

Okay, time for a demo. Here's what my Game Engine for DS (geds) looks like with a greenzone tileset and some sprites for the Bilou game ... captured out of desmume rendering using "byzanz".

Sorry for lacking time to translate former posts that describe my work. Hope i'll be able to do that soon.


PS: le moteur de jeu est et restera Open Source, mais en revanche, les droits d'auteurs habituel s'appliquent aux graphismes intégrés dans la démo.
Please keep in mind i spent hours on the art, and that unlike code, it is not open for reuse.

vu sur wayofthepixel et dev-fr.
(2008-05-05) [adventure][woodworm][desmume][download][sidescroller][pixels][milestone][blockanim][mybrew][greenzone][video][bilou]

Bilou par Wifi ...

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH4D1DgtWK5TdyKMM6GJyzAzQtzwUWfsQVoBZvye2uESUas-WI5MrNESGkSx0QpEn3yf1St3tEq2NyUkTGrfbFqnZNupymuflk-a2Uu3xO1iVF-aI_KNK9rGK7i5ncH6nepZbUug/s400/newbilou.png ; newbilou.pngHehe. Je vais me faire enflammer avec un titre pareil. Non, on ne joue pas encore à Bilou par Wifi, mais j'ai transféré les couleurs de mes tests sur Pixelization vers SEDS histoire de pouvoir essayer un p'tit Bilou (mais alors vraiment tout petit, là). Ce qui veut dire que les réorganisations de couleurs dans la palette, c'est fait aussi. Je me ferais bien un petit "publier le sprite courant par Wifi" avec conversion immédiate en .png à la réception sur le PC, tiens ;)


https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXuuGtqqoscYXn-68CHyZAxahJRWf1I3-Q34bRZfMzkE3qgvRq0Ln1vjF8FPFf9uJe8WLr4zHdd1LbUTezXqCTB3XNMaJyLqgp1fLYX_U4NOKrvtA5ZuS7DTZMq-dh3TTSTjqHeQ/s400/newbiloubuggy.png ; newbiloubuggy.pngAaargh. sur ma lancée, j'ai essayé de faire un deuxième Bilou un peu plus grand. Puis je l'ai animé pour donner l'impression de "respirer" et j'ai refait des balles de formes diverses (plus applatie et plus ronde) sur la même base. Puis j'ai joué à faire marcher mon p'tit Bilou et donner quelques expressions au plus grand.

Ouais. Bin j'aurais mieux fait de finir le debugging de mon éditeur, pas encore capable de gérer correctement les longues animations qui s'en sont suivies. Au moment de sauver tout ça, il m'a montré des pages de sprites de plus en plus louche ... Pas dupe, j'ai voulu recharger : bardaf : Guru Meditation.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_19TK2s5CqdIPiVeK4UCW7097FC5RTpjbqjDlH-EQXyizuEatHebHRQPv6Yf3yGNJip4VpnRuKEAlZ_f0AHbQxVcf7Imzty4dVvV-BsHoN-tT6XuGROGXzL5jQtRZ64srJtyOiQ/s400/bilou-newbase.png ; bilou-newbase.pngComme vous pouvez le voir, la plupart des "tiles" seront récupérables (à la main dans Gimp, j'imagine), mais les infos qui disent quel bloc utilise quel tile, là, c'est irrémédiablement foutu >_<

edit: comme je m'y attendais, c'est plus que probablement dans la gestion des animations que se trouve le gros bug. C'est du vieux code d'avant que je ne me mette à la bibliothèque standard du C++ (vecteurs, maps, etc) qui est encore plein de malloc(sizeof(x)*n) et qui manque de if(i>n) return; si vous voyez ce que j'veux dire

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTfXNG_ZtuuJNZI6KUNbYNjJGTaG1KAfrgtDIBLlIg1sW3UZzKqnKgrCLMiXAlUCJzyz0A4BqaxLP6yc8DIJNrvmfi7QibH95ug4oyLkAYzQnfL4emR9J0uL86hzVgYwEQxAZ2gQ/s200/newbilou.png ; newbilou.png
(2008-06-06) [wifi][allocation][pixels][milestone][data recovery][mybrew][bilou][spritesheet][sprite editor]

Cursor for picking tiles ...

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ0tRi2yipA1iJagBoN3xiDQ5od8nBfaxhyphenhyphen2yFdSPDJYX667vj6i46FqNG0V8z_Hs_xf-cSq2c9LZohLdyNn3nYRZ_KKqHNb6xmd2ItsuOy3LmEg-qXZlBRcXvtetSs479NqqzZQ/s320/cursor.png ; cursor.pngHmm ... j'ai un peu bricolé quelques nouveaux tiles pour la forêt, et plus j'avance, plus le côté 'édition bloc par bloc' me cause des soucis. J'ai une technique assez simple pour m'assurer que les objets de plus d'un bloc aient une forme correcte : le scrolleur.

Je dessine la gauche de mon champignon, je sauve sur un bloc, puis je le décale de moitié, je garde la moitié droite à gauche et une moitié vierge à droite. Reste à construire le début de la droite de mon champignon. Ce bloc (central) ne sera évidemment jamais sauvé : une fois la "droite du centre" dessinée, je re-décale pour la ramener à gauche en tant que "gauche de la moitié droite".

C'est tordu, pas vrai ? et le plus casse-pied, c'est que du coup, c'est pratiquement impossible de venir ré-éditer l'objet plus tard (à part chipoter à gauche ou à droite, mais plus au centre). D'où l'idée de rajouter à SEDS un widget "curseur" qui permettrait d'aller chercher n'importe quel groupe de tiles dans la SpriteTable (y compris à cheval sur plusieurs blocs) pour l'éditer. Ce curseur permettrait aussi de réécrire rapidement le sprite en cours d'édition là d'où il vient (par un R-R, par exemple), ou d'éditer 4 blocs 16x16 dans une matrice 32x32 ... Bref, il y a du boulot.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdMybKedipsLUu_rm8qK92rLcZ2dOuj-dVNU65h1KyrzCtDRdo0WkYpJrAsTeH3GgozwVyTeKIAXQ4U9hMOiuTdwH15Hkvife0HT0VdLaomPiJmhj-8W5kruSU8W07m2uRJp_tbQ/s320/more-grid.png ; more-grid.png Oh, je n'oublie pas non plus mon fameux "éditeur de dégradé HSv", ne vous inquiétez pas ;) Et tiens, puisque j'ai la ligne de commande sous la main, je vous fais un snapshot de l'évolution dans desmume. Pas encore super-utile, mais j'ai la fonction "charger un ensemble quelconque" qui marche. Allez, je m'ferai le retour vers la SpritePage un autre jour ;)

edit : status
disons, vu les changements que ça amène dans le coeur du software que ça marque le début de l'ère "0.3"
(2008-06-12) [coding][widget][milestone][mybrew][screenshot][translate me][done][user interface][sprite editor]

Bon anniversaire, Bilou

Eh oui, ça fait maintenant deux ans que je bricole sur ma DS. Et figurez-vous que en voulant retracer l'historique, ma mémoire m'a fait défaut. Elle n'a apparemment retenu que les évènement "vie réelle" (achat de maison, mariage, conférences, changement de voiture, etc) et éventuellement greffé les bouts de développement DS qui s'y rapportaient.

juillet 2006 - octobre 2006 : Balbutiements
Les débuts de SEDS, qui commence sur émulateur uniquement, puis reçoit la libfat pour stocker les fichiers sur la carte SD. Et en deux ans, je n'ai toujours pas fait sauter la "limite" de 4 fichiers, même si la quantité de données autorisée sur un fichier, elle, a considérablement progressé.

Fin octobre, j'ai mon premier petit "tileset" hivernal et Mr Noël récupéré du PC, de sorte que je peux envisager un Rick Dangerous like avec mon papa noël de 2000. Faute d'avoir retrouvé le pingouin de Badman III, le projet n'ira jamais plus loin que ce petit "mockup".
Novembre 2006 - Mars 2007 : Rumbling
http://photos1.blogger.com/x/blogger/5640/3676/320/154026/runME.png ; runME.png Entre la thèse et le déménagement, j'avais apparemment trouvé le temps pour coder un petit "whack a rat" nommé "apple rumble", partant des sources de Tetris Attack. C'est aussi pendant cette période que mon lecteur de carte SD m'a laché, et que je me suis rendu compte de l'ampleur des lacunes du Desmume (l'émulateur DS) de l'époque. D'où le démarrage du projet "runme" permettant des transfers "over wifi"

Et si les tiles de la "bibliothèque" de Bilou sortent dans leur première version, c'est toujours à coups de SEDS émulé que je les convertis en "mockup". En revanche, beaucoup de fêtes en famille, donc beaucoup de level design pendant cette période-là ^_^
Avril 2007 - Juillet 2007 : Rédaction

Calme plat ... il fallait s'y attendre :P

Aout 2007 - Octobre 2007 : L'odysée du Wifi
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFlmQVzHwIBBh0A1eyU-3NLypRZF71XTcfI1zglYHIw9MC5MZvURd5b_gNva_L8fDCttCjMiHz3E7FA0iBZZZqRBneGXgOYZi6_MPqQTXHZW92NQ-R5HHf7SpuPy7sgzbPy5qbAw/s320/out71.jpg ; out71.jpg

C'est la grande reprise de "runme", qui jusque-là pouvait télécharger des fichiers par wifi, voire en afficher certains (.pcx, .spr, .it ...) mais c'est tout. Deux petites lib' releasées au bon moment (l'attente de ma thèse relue) vont permettre la pierre d'angle de mon développement DS : l'auto-update par wifi, ou comment un programme va récupérer une nouvelle version de lui-même et la démarrer sans autre intervention qu'un clic de l'utilisateur.

Suivra une ré-écriture de SEDS pour qu'il puisse gérer plus de sprites (multi-page) et "sortir" vers runme (qui sera aussi en mesure de lancer SEDS), qui sera annoncé sur les forums (à partir de Player Advance) vers la mi-octobre.

Novembre 2007 - Février 2008 : Objectif LEDS
Quelques scripts bien placés et je m'attaque maintenant au débuts de mon moteur de jeux de plate-formes: le scrolling. Théorique d'abord, puis pratique via une petite modification de runme (qui me sert une fois encore d'homme à tout faire) Ensuite, je m'attaque a un éditeur de niveau "autonome", ce qui amène son lot de nouveaux "widgets" et à la création d'une bibliothèque de fonctions utilisées par les trois programmes, j'ai nommé "libgeds" (pour Game Edition on DS).

Avril 2008 - Juillet 2008 : GedsDemo
Après cette petite pause musicale, je reprends le développement de mon moteur de jeu. Collisions, animations, déplacements ... Tout ça prend peu à peu place. La première animation postée sur le forum pixelation va aussi être à la base d'une révision quasi-complète du look de Bilou et de sa forêt, ce qui ne se fera pas sans pas mal de bricolage autour de SEDS (de nouveau) notamment pour la gestion et l'import/export des palettes.

Le tout sur fond de "R4volution", afin d'améliorer la compatibilité de mes programmes avec d'autres linkers que mon Super Card...
(2008-07-15) [coding][level editor][wifi][sidescroller][milestone][mybrew][sprite editor][skyblog]

"Use the Source, Luke"

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnit4ImJzvDls20aKYsqkXn5FUNxmgIX8Sd4w327DtsmLcPDm70oJSBNWnbsH45lQNukaGpGm-x_wubbZ5gKTSpyVJ5Y9g5jnDAgQMedu-VJeYNceA8zuYGtfCnZoCRXrZsC8C_w/s320/download.png ; download.pngLa nouvelle structure de l'éditeur de palette commence à prendre forme dans mon esprit, mais avant de tout casser, cette fois, je vais profiter pour faire une petite "release sources" du sprite editor : version 0.3.2x32. Eh oui, c'est quand-même un projet Open Source (j'ai finalement opté pour du LGPL+GPL), donc il faut que je fasse une release source de temps en temps ;)

Pour mon frère et les autres qui ne pensent jamais à cliquer sur les images de mes articles (et ils ont bien tort), c'est ici, et pour ceux qui n'ont pas besoin des sources mais qui veulent quand-même essayer la dernière version, c'est (md5sum ba88e6b898297d5fe99a918f70c47f8e).

Combo release, with both sources and binary version of SpriteEditor for DS, version 0.3.2x32 with eased edition of large regions. This is of course motivated by the fact that the current palette edition 'window' is completely messy and is the next big thing to be revised. As the new interface is getting clearer in my mind, i found it was about time to release what's working before breaking everything into puzzling pieces again.

(2008-08-28) [coding][download][open source][milestone][english][sprite editor]

montre moi ta VRAM et je te dirai qui tu es ...

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPwBZo1c3mCpkqVLuyPv0fIpVSKSwBSFGJ063Le5XG68mHb23svcSPc6FiczxP6B44F_6rKOYyYQQ_R6erXOn3XS2kQf2YN88Rq8abn5OFo2372Bq_8yr-WXK9_Yi_ojk2fWSJzA/s320/charset.png ; charset.pngSans doute juste une curiosité pour vous, mais de plus en plus important pour moi : voici le contenu de la mémoire vidéo de mon SpriteEditor, vu sur un plan "16 couleurs" (1KB par ligne) à gauche et sur un plan "256 couleurs" (2KB par ligne) à droite.
Du temps du DOS, j'avais refais et plastifié sur un carton de 16x16 centimètres la table ASCII pour mes programmes en BASIC et en assembleur. J'ai d'ailleurs eu droit à du "oh! great! Can i borrow you your mouse pad ? please ?" en pleine démoparty parce qu'un gars qui passait par là avait bigrement besoin de ces infos pour continuer son intro 4K.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8TRsW_MzMwJS6xdxUN9epYLkVawx10ykrA6k_3NmtYTdCpkrkHbqv8Nb27N5Tylks5QhPZ3-z1qZr2dYMUsGwoduR1HsHblspI7BL4AKIcnr_ARfjg33jOHe7TUj8afPqiseT_Q/s320/charset256.png ; charset256.pngLes vieux de la vieille reconnaîtront pas mal de ce jeu de caractères, d'ailleurs, même si j'ai remplacé les symboles "coeur, pique, trèfle, carreau" par une animation de pacman qui me sert de 'scrobber' et que vous reconnaitrez à partir de la 4eme ligne quelques éléments de l'interface de SEDS (accessibles à l'aide de YOUR_CHARSET(0), et programmés à grand coups de codes hexa ... ça rappelle des souvenirs de CPC, ça, hein ;)

Version 256 couleurs, évidemment, ça ressemble furieusement à ma palette, puisque -- souvenez-vous -- j'avais reprogrammé un caractère par couleur pour pouvoir redessiner facilement ma grille ...

Il y a des curieux qui se demandent ce que peuvent bien être ces 8K de n'importe quoi entre les caractères et les couleurs ?

Allez, je vous aide: il y a quatres plans sur un écran DS et chaque écran peut contenir 32x32 caractères encodés sur 16 bits ...
(2008-08-29) [coding][tiled][cheat sheet][vram][sprite editor]

analysis paralysis ?

Près de 3 mois loin de chez moi, maintenant, et toujours pas de petit homebrew à vous mettre sous la dent. Okay, mon laptop est un char à boeufs comparé aux PC que j'ai à la maison. Okay, je n'ai pas de Wifi dans mon k0dek et le laptop n'est pas configuré pour faire base station pour la DS mais il y a autre chose.

Je sais qu'il y aura pas mal de choses à mettre en place pour parvenir à réaliser Bilou sur DS ... je veux dire par là, "le jeu de plate-formes tel qu'il avait été prévu dans les années '90 et prototypé sur BASIC", mais revu et corrigé pour la DS, bien sûr.

Par exemple:
J'accumule les idées sympa sans vraiment avancer dans le développement. Je sautille d'un projet de shoot à une reprise de Seafox à un "bubble bobble - like" etc. Et bien sûr, comme j'aime le pixel art, j'ai tendance à explorer les aspects graphiques à tort et à travers avant de me lancer dans un jeu.

Je vais devoir me fixer une "roadmap" jallonée de petits projets intermédiaires, et attaquer les difficultés techniques une à une, sinon je vais finir par recommencer à programmer sur Clicker :P

Bonne résolution 2009 #1: on garde Bilou. Quelque soit le petit jeu envisagé
Bonne résolution 2009 #2: un nouveau thème graphique si et seulement si un jeu est produit.
Bonne résolution 2009 #3: s'il n'y a pas d'image de fond (ou si l'image est fixe, etc.) ce n'est pas un problème pour l'instant.
Bonne résolution 2009 #4: faire la vaisselle ce soir

edit: côté "base station", j'ai au moins pris la peine de recompiler le module de mon stick WiFi. M'en vais aller manger une soupe et tester ça @home, tiens.
edit++: toujours pas de connexion Internet au k0dek, mais au moins, j'ai su modifier runme pour qu'il puisse démarrer un programme 'runme-compatible' après l'avoir téléchargé.


3 monthes in Switzerland and still no updates. I'm not focused enough and therefore I'm missing the #1 golden rule of game development : *release*. Having no Internet access in my Swiss flat doesn't help, so I modified runme so that it can launch the last compatible .nds it received from a WiFi transfer. Using my laptop as an access point, it allows ad-hoc development.

Allez, je vais essayer de me faire un petit "ramasse toutes les pommes pour passer au niveau suivant". Ce sera déjà un bon début. Après tout, c'est fort le principe de base de Qwak, Bubble Bobble et même Still Alive DS :P
(2009-01-20) [coding][wifi][milestone][bilou][bordures][animeds]

un autre mot sur la VRAM

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEig9DOu2Pq8FvbXW9PM6Gf6WtyTw9TeAHGi-gQHxnF2qB2tLavv7X5ZCfjjpe7HbG7UvHgex6o5rSGrfh-ejBcVjJG6i4RVlTXgftgp3j96CAXIq2NDcqv_8JpDPz1x2ht87_cPmQ/s320/koswood.gif ; koswood.gif Ouaip. "un petit jeu tout simple où il suffirait de trouver toutes les pommes pour passer au niveau suivant" disais-je donc. Pendant les préparatifs de SeafoxDS, j'avais ajouté la possibilité de demander le chargement d'un fichier .pcx (une belle grosse image bitmap, quoi) comme image de fond. Sympa.

Histoire de tester ça, je bidouille un peu hier soir, mais pas moyen de sortir le décor de Donkey : King of Swing (qui n'est là qu'à titre temporaire, hein) sur mon écran: je me retrouve à la place avec un tas de tiles bleu suivant un motif improbable et quelques pixels aléatoires ça et là.

So, the next milestone should be a very simple "grab all the bonuses and head to the gate" kind of platformer, where i can gradually introduce tests. I just wanted to add a fancy background, since i added support for .PCX loading when "working on Seafox DS". I just couldn't make it work, while runMe can happily show .PCX files for at least two years ... I just forgot that SUB_BG0_CR register is not the only guy who matters here. Whether you have bitmap or tiled background is defined by the video mode, which in turn tells the graphic hardware how to interprete the content of SUB_BGx_CR.

J'avais beau fixer les lignes "SUB_BG0_CR = BG_BMP8_256x256|BG_BMP_BASE(1)|BG_PRIORITY(3);", identiques dans le mode "télécharger un .pcx et l'afficher" de runMe et dans le moteur de jeu ... rien n'y fait.

J'ai fini par me rendre compte ce matin que changer les attributs d'un fond particulier ne suffit pas à faire de lui un fond bitmap sur la DS. Il faut d'abord s'assurer que le mode vidéo supporte bien ce type de plan, mais aussi qu'il peut s'appliquer au plan choisi. En clair, les seules possibilités sont renseignées dans gbatek:
BG Mode
Engine A BG Mode (DISPCNT LSBs) (0-6, 7=Reserved)

Mode BG0 BG1 BG2 BG3
0 Text/3D Text Text Text
1 Text/3D Text Text Affine
2 Text/3D Text Affine Affine
3 Text/3D Text Text Extended
4 Text/3D Text Affine Extended
5 Text/3D Text Extended Extended
6 3D - Large -

Le mode "bitmap 256 couleurs" est un des modes étendus (de même que les plans avec rotations et 1024 tiles, d'ailleurs), et donc disponible uniquement sur les plans 2 et 3 dans le mode 5. Vous suivez ? Ce que nintendo appelle le "mode texte", c'est en réalité le mode "tile" qui effectivement s'apparente au bon vieux mode texte des années 80 à ceci près que vous avez 1024 caractères (et non pas 256), 16 palettes de 256 couleurs et que chaque "caractère" peut combiner comme il veut n'importe lesquelles de ces couleurs (il y a aussi un mode 16x16 couleurs, pour les nostalgiques de la GBA, bien sûr :)

Only those combinations detailed in gbatek are possible. E.g. 3D + two text + one of the "extended" (DS-only) modes. But then, only "BG0" can handle 3D and only BG3 can be an extended mode. What i need for PCX (256 colours bitmap) is extended, clearly, which make me stumble into trouble as the Game Engine i've got so far is hard-coded to use BG2 and BG3 for maps, so that i could zoom in the front layer. Somehow, it was a bad idea >_< . It's not much a dead-end, just a reminder that DS hardware comes with constraints and that a "you just have to ..." idea must always be checked against those constraints...

Y'a un hic, évidemment: j'avais pour ainsi dire "hard-codé" mon moteur de jeu pour que la map utilise les plans 2 et 3 (histoire de bénéficier des effets de zoom, par exemple ... ça m'avait paru sympa). Mauvaise idée, comme dirait l'autre, hein :P

Oh, rassurez-vous, ce n'est pas un problème insurmontable. En soi, le "bitmap" tiendrait sans difficulté en mode "texte". C'est juste que ça me rappelle ma lecture de ce matin dans le bus, selon laquelle les druides théorisent que "l'univers, pour sa bonne marche, dépend de l'équilibre de quatre forces : le charme, la conviction, le doute, et l'envie d'emmerder le monde".
(2009-01-22) [coding][tiled][english][cheat sheet][hardware][vram]

Xargon : may the source be with you ...

Vous ne connaissez pas Xargon ? pensez à Jill of the Jungle avec un chromosome Y et vous ne serez pas loin... Vous ne connaissez pas Jill of the Jungle non plus ? Ah. Bin probablement que votre PC n'avait pas encore de carte SoundBlaster ou d'écran VGA en 1992. C'est vrai que ça coûtait un peu cher, à l'époque.

Quoi qu'il en soit, si je vous en parle, ce n'est pas parce que les 3 épisodes de Xargon sont disponibles sur classicdosgames.com. Non, c'est parce que le code source de Allen Pilgrim est également disponible. C'est du code C, mode réel pour le DOS, mais suffisamment propre pour que tous les aspects "hardware" soient extrait de la logique du jeu -- et croyez moi, sur PC, c'est un exploit majeur.

Ce n'est pas la bibliothèque d'abstraction du hardware qui m'intéresse, bien sûr. Même si c'était impressionnant à l'époque, le scrolling des jeux de plate-forme Epic ne pouvait concurrencer celui du moteur de John Carmack (commander Keen & autres), le player de fichiers CMF (adlib/midi) était bien connu, mais je n'ai jamais vu d'éditeur correspondant, et si l'on se laissait impressionner par un "yeeaaah" en ramassant un gros bonus, le mixage des effets sonores était en réalité peu convaincant (voire absent).

I'm currently studying the game logic of Xargon from Allen Pilgrim's sources. I hope that giving a look on someone else job will help me to overcome that "analysis paralysis" in my own game engine. I know i tend to overcomplicate things ... The management of objects-to-world collision has already shown enlightening... more to come. And, by the way, if anyone of you is interested into porting Xargon to the DS (or whatever other system), you may want to give a look to information gathered on the game modding wiki at shikadi.net in addition to the source code. Personnally, it's not in my to-do list :P

Non, ce qui m'intéresse c'est la logique du jeu. Et quelque-part, cette logique me crie le maître-mot de Mollusk: "ne vous posez pas de question: codez". C'est vrai quoi. Je me prends la tête avec mes test-points alors qu'en fait, ce n'est qu'une optimisation bancale que je traîne depuis l'age du BASIC, renforcée par l'étude d'un jeu NES. La gestion des collisions perso-monde dans Xargon est bien plus simplement basée sur les possibilités de l'ensemble des tiles recouverts et l'affectation de propriétés sur chacune de ces tiles.

int cando (int n, int newx, int newy, int ourflags) {
 int x,y,temp;
 int flagor, result;
 int startx, endx, starty, splity, endy;

 startx=newx/16;
 starty=newy/16;
 endx=(newx+objs[n].xl+15)/16;
 endy=(newy+objs[n].yl+15)/16;
 splity=(objs[n].y+kindyl[objs[n].objkind]+15)/16;

 flagor=f_notstair;
 result=0xffff;
 for (y=starty; y<endy; y++) {
       if (y>=splity) flagor=0;
       for (x=startx; x<endx; x++) {
         temp=(info[board(x,y)].flags|flagor)&ourflags;
         result&=temp;
       };
 };return (result);
};


Comme disait Colomb en quittant le Portugal "Il suffisait d'y penser": le tout est de concevoir les propriétés des tiles de manières à ce qu'elles "s'additionnent" bien. Un personnage ne peut se déplacer vers un nouvel endroit que si tous les tiles possèdent les bonnes propriétés ("pas un bloc", ce que Allen appelle f_passthru. Celà demande parfois un peu de jonglage mental. f_water est évident, f_climbable aussi. f_not_stairs un peu moins...


int trymove (int n, int newx, int newy) {
 int ourflags;
 ourflags=f_playerthru;

 if (newy>objs[n].y) ourflags|=f_notstair;
 if (cando (n,newx,newy,ourflags)==ourflags) {
    moveobj (n,newx,newy);
    return (1); // successfully made it to new location.
 } 
 else if (cando (n,objs[n].x,newy,ourflags)==ourflags) {
    moveobj (n,objs[n].x,newy);
    return (2); // could only move vertically
 }
 else if (cando (n,newx,objs[n].y,ourflags)==ourflags) {
    moveobj (n,newx,objs[n].y);
    return (4); // could only move horizontally
 };
 return (0);    // couldn't move at all.
};


J'aime bien aussi la manière dont il a réussi à capturer les comportements de déplacement simples Il faudra que je tente d'en faire autant. Bion. Je vous en dirai sans doute plus. Malgré tout, la routine de gestion du personnage principal fait quand-même 7 pages, et je n'ai pas encore tout lu.
(2009-02-05) [coding][open source][tiled][y92][sidescroller][collisions][physics][english][nostalgy]

World Collisions

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


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

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

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

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

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

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

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

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

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


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

Mais alors, à quoi servent encore nos test-points ? eh bien, à décider de quel sera le prochain état lorsque le contrôleur signale qu'il n'est pas possible de continuer. Ca veut dire aussi que le contrôleur devra évidemment ajuster la position du sprite de manière à respecter les "cando()" mais pour que les testpoints puissent détecter quelque-chose quand-même :P


(2009-02-27) [core][coding][tiled][sidescroller][collisions][testpoints][english][choice][iGobController][climbing][done]

BBL metadata.

Voilà. Une fois qu'on dispose de tout un jeu de .BBL avec les tileset correspondant, c'est bien plus simple de reconstituer le rôle des 20 bytes de contrôle ... C'est ce que fait de son mieux ce petit outil "bblmeta.pl" que je vous offre également.

Chaque ligne rappelle le numéro du bloc (en hexa) et sa position dans l'image générée par bbl2png (le premier, par exemple, r02 c12 correspond au premier canon, tourné vers la gauche sur la 3eme ligne de l'image). Suit ensuite les "flags" tels que lus dans le fichier .BBL puis l'interprétation de ces flags par le script bblmeta.pl

J'ai repris la technique des répertoires UNIX: un '-' chaque fois qu'il n'y a rien à signaler, une lettre sinon. Ainsi "B--a-K" serait un bloc solide (B) animé qui interagit avec une clé (probablement une porte). "--g-+-" est un bonus qui rapporte uniquement des points, etc. Pour être exhaustif, je dirais que le programme reconnait:
  1. Bloc, Floor, Wall ou ciel (-)
  2. Pickme : l'objet peut être ramassé pour l'inventaire
  3. g, l ou r : gravité normale, vers la gauche ou la droite. Les autres combinaisons ne sont pas reconnues.
  4. a : bloc animé,
  5. t: réagit au contact
  6. bonus/malus : H=hitpoints, x=kills, + : score
  7. L = 1UP, K=clé/porte.
En plus de ces "flags", certaines valeurs sont indiquées dans une liste entre parenthèse, comme la succession des blocs pour une animation, le nombre de hitpoints ou de clés, ou de points modifiés lors d'un contact , le numéro du monstre tiré (pour les blocs qui tirent des monstres), etc.

Here comes a second funny PERL script. It extracts meta-data from .BBL (Background BLocks), .CBL (Character BLocks) and .MBL (Monster BLocks) produced by RSD Game-Maker. If you used to write games with that editor, feel free to use that tool to retrieve all meaningful elements and port your old funware to some new platform. If you do so (or just plan to do so), please share the joy and post a comment.

This tool is a kind of "preliminary" reverse-engineering tool. It can tell you roughly what are the properties of individual blocks but detailed information may need to be looked up in the 40-digits hex string. Each line describes a block. Right to left you'll have the following information :

1c (r01 c13): 400100000000000000ffff1b64001c0400010000  --ga-x-  (a1b,100)(h-1)
^    coords   |--- complete hex dump of meta-data ---|  |flags|  |---details--|
+- block number
On the right side, "flags" tell you roughly what are the properties of your block. here you see an Animated block that has downwards Gravity and that hurts the player (x) on contact. Details tell you that it animates to block 1b after 100 ticks and that hitpoints are reduced by 1 on contact. On the left, you have block number (block #x pixels are located at bytes x*420..x*420+399 in xBL file) and the row/column coordinates on the picture generated by my former bbl2png.pl script.
Bref, ce n'est certainement pas aussi souple que l'éditeur du game-maker (et d'ailleurs, ce n'est pas un éditeur, juste un outil d'inspection), mais ça capturera la plus grande partie des cas que l'on retrouve dans un jeu de plates-forme comme les Badman.

Hope it Helps ^_^
PS: 1st byte is the index of the generated monster (0x40 = no monster generated), thus byte 2 is likely the delay between two such generations.

(2009-03-26) [tiled][special block][tools][game maker][coding][pppteam][badman][keys and locks][y96][english][perl][scripts][level data]

Le Bilou Nouveau est arrivé...

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf0TKwl5FK7o23uq-reC1yU8wGZnh8azrH4EARkltUcsl32yIi527bvc2W6ji1cqKhq0x9zN8fk-DTeYLm2dkNAjcJ3EJNlJF81dTq-zKeGaaa7PU-vL-QQ8IXUyYjb7eYaGyNnw/s320/gedsdemo-20090519.png ; gedsdemo-20090519.pngComme promis, voilà la nouvelle démo de mon moteur de jeu. Ce n'est pas encore parfait, bien sûr, tant au niveau technique qu'au niveau graphique ou gameplay, mais ça vous permettra de voir faire une meilleure idée de ce sur quoi je travaille.

L'objectif est de récolter toutes les pommes du niveau, et un petit "GREAT" vous félicitera si vous en trouvez 16. Vous pourrez vous faire "blesser" (aussi souvent que vous le voudrez) au sol, mais pour l'instant, vous êtes invincibles en saut. Et il me manque toujours un fond convainquant.

Bref ... Work in progress.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9MMeevPvzzAuLac8Qj_1hoU987Na_I1DAdLClWHvS2z4YlkF559t5FiS9DlU1ol72UBXiFjrvQKzE_xTALgfSl2WBulgMD62BYLicPKanYV_Hd8LeSdG7SG6r9ZGmTcgFxLOwMQ/s320/gedsdemo-20090519b.png ; gedsdemo-20090519b.pngHere you finally get it: a new demonstration of my game engine with my most up-to-date pixel art. It's not perfect, of course. Neither graphically, technically or in regards to gameplay. But at least it gives a better view of what i'm working on.

So far, your mission is to collect as much apples as you get (and you can get all of them in one row), a message "**GREAT**" will show you you've got 16 of them. Note, too, that you'll never get hurt while jumping. And yeah, it'd be much better with a background of some sort.

download gedsdemo.nds



PS: dans cette version, il vous faut toujours appuyer quelques fois sur "Y" au démarrage de la démo pour lui forcer à "lire" le script du niveau. C'est une de mes priorités de retirer ça pour la prochaine démo, bien sûr.

PPS: last update: 2009/05/20: Kram reported a bug on real hardware. Fixed.

Greetings fly to: NODA (efs lib), OxTob (ntxm), the devkitpro team, Kram (DS2DS), CJ (R4), Pierrick & Tbob (music), lackey, victorX, pixelaroo, arachne, zeid, Helm and many more pixel pushers at Pixelation for artistic advices, sourceforge & blogger for project hosting.

http://farm3.static.flickr.com/2472/3627988819_4cf424525d_s.jpg ; 3627988819_4cf424525d_s.jpg Suivre le développement du projet ...
Read progress reports

(2009-05-19) [download][game][funky funghi][sidescroller][pixels][milestone][english][mybrew][screenshot][greenzone][bilou][firstDemo]

parallaxe ... foireux.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA6Phq-fy5jO7H-sbOjT2bmMHjvMNzrqB3hRwMmav5MJW1BHYZs5CpbYyqDJ0OZzCN-pniuPzmT-NH3tDBcphGrMoGfv3dQ0at9OAYWFo_3bYqhyphenhyphenZBQZnNG0_ZEEY9RWVrDNhF5Q/s320/maps-test.png ; maps-test.pngPetit test de scrolling parallaxe ce matin (entre vidange du garage et achat de papier peint) qui est encourageant sans vraiment être satisfaisant. C'est ma première tentative de charger plusieurs tilesets différents en mémoire, et je dois maintenant combiner une "infinimap" (dont l'image est modifiée au fil du scroll) avec une "wrapping map" (dont l'image reste fixe mais "tourne en boucle").

Les pommes sur fond blanc témoignent d'une petite réorganisation de la VRAM. J'ai réglé tout ça un peu vite à mon goût et il faudra que je prenne le temps d'ajuster le code pour qu'il fonctionne correctement sans dépendre d'effets curieux du genre "if bg==2 ...".

I wanted to bring the real (parallax) background in my woods this morning, but it didn't came as 'fluently' as i hoped in the code. Things were not quite ready for mixing wrapping maps and large maps, not quite ready either to host several tilesets in vRAM or to load an odd number of colors. I had to put ugly patches here and there to show the feature. A proper way to "split" SpriteRam in several banks is required in the future, as well as a real "WrappingMap" class and an update of the map-related script parsing functions. Well, anyway, even though my camera isn't as neat as Kram's, it's more "sexy" this way than with the dark-red background.

PS: since the demo is now released, now, it's time for a new "todo list", reusing wishes from the former one.

Note: le parallaxe figurait dans mes "todo list" depuis décembre 2007 quand même ...
(2009-05-23) [coding][tiled][scrolling][english][mybrew][screenshot][greenzone][done][firstDemo]

bilou.cmd

Ca y est. Une petite classe abstraite "InputReader", deux sous-classes BufferReader et FileReader et un peu de bricolage, et je peux ranger tous les éléments relatifs à un personnage dans un fichier séparé, inclus depuis le "script-maître" du niveau.

Ca fait plus propre ... je suis prêt à rajouter des niveaux dans tous les sens.
Mais j'ai aussi pas mal de fonctionnalités à béta-tester:
Three tiny classes added, a few edits, and i can finally store everything related to Bilou in bilou.cmd, the bouncy logic of Funky Funghi in funghi.cmd, etc. Those files are then 'included' from the level script, and can thus be reused in as many levels as one wishes. Hooray. That's a major step towards a multi-level game, despite the actual coding is still a bit crude (e.g. you can't #include with blocks, and you *must* have 'end' statement in every file, including included files).

Am i going to do a release right now ?
Or am i going to toy a bit with chained controllers (useful for the appleman), dynamic Game OBjects (useful for shots and the like) and external actions invoked from the state machines (useful for sound effects) ?

(2009-08-13) [coding][flower-power][milestone][gobscript][state machine][english][bouli][done][level2]

Sound Effects

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2eaMhNV9uHj9z9iaqOqRl6gE9MhyphenhyphenD31BTJfoTlJo-znQO90RWtrktSoFf7syefSq_h_1zjiasn2dqncJPyDHZ501VWFHAyg4Z54tX8Fx8aUjhr-OBbgtmKM3d5OYSBn7ca4RRiA/s320/playnote.png ; playnote.pngBon, il est temps de faire du bruit. Voilà le bout de code de la libntxm qui traite les nouvelles notes lors de la lecture du pattern. Le reste du temps, le player se contente d'ajuster le volume et de traiter les effets définis par une "cell" (une case du pattern).

Pour pouvoir faire des effets sonores, il faudra en quelques sortes que j'appelle ce même code à la demande depuis le processeur ARM9, probablement en réutilisant la technique d'IPC qui a servi à indiquer que le module devait être lancé ou arrêté (cf. NTXM7::updateCommands et le fichier command7.cpp)

It's been roughly 1 year that my game engine is waiting for sound effects. Let's see how to proceed, and add them to the ARM7 NTXM player that is the core of sound playback on the DS. This post is a sort of "exploration mission" to see how i'll proceed with programming them.
Primo, if i want to issue sound effects, the first thing to do is to ensure that I can invoke the "playNote" function (and surrounding code) on request from the game engine running on ARM9 . The most likely approach will be to mimmic the IPC approach 0xtob used to instruct the ARM7 to start or stop playing the whole song.
Funny enough, all the "commands handling code" always look the same. PLAY_SAMPLE and PLAY_INST commands already exist (i guess 0xtob needed them for the nitrotracker), but the actual stubs are missing. On the other hand, the "proxy" functions at the ARM9 are already present in command9.cpp ; they just lack an API in ntxm9.cpp ...

It should be running in a couple of evenings. It's really a shame it took me so0o long to check it out. It sounds that most of the effort will be to make GobExpression invoke ntxm9::playNote(), after all.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA0DU0Lfvus6gtNtnbLMVp5veZGhFi2ctuTaz-BYqOBh86Bl0wVN3NhGCwboGWissZXPZc2IJwOplKGGdxNYrfBzWS5lRZm0vM13QDMSWqmmBfPm1Xu2krNtCIe_FM6z2FJw84Sw/s320/processcommands.png ; processcommands.png Tss. Même après l'an 2000, tous ces codes de "gestion des commandes" se ressemblent. PLAY_SAMPLE et PLAY_INST existent déjà, j'ai même déjà struct PlayInstCommand. Ils ne sont juste pas encore implémentés, mais Oxtob a bien préparé le terrain, pas de doute. Eh bien on va y remédier.
Cerise sur le gateau: CommandPlayInst et CommandStopInst sont déjà là dans command9.cpp ... Il reste juste à ajouter ça à NTXM9 et à faire en sorte que ce soit appelable depuis le GameScript et confrères.

edit: okay. Ca marche. Les pommes font "bzing!" quand on les prend. Il a fallu un peu plus de code que prévu du côté du game engine: c'est la première fois qu'une GobExpression du script appelle du code C++ ;)
(2009-09-03) [modplayer][coding][music][milestone][gobscript][arm7][sound][ntxm][english][mybrew][tracksequence]

95% done.

J'ai repris ma petite todo-liste que j'avais fait après la release de ma dernière démo pour cocher les derniers développements. Bonne nouvelle: il ne reste rien à faire.
Ensuite, il sera franchement temps que je me remette au boulot sur l'éditeur de niveaux. Il est à la traine, le pauvre, avec des "fix" qui attendent depuis ... houu ... un an ?

Right after I released my the last demo, I came up with a little todo-list of things to be done before a new demo was worth to get out. Good news: they're all flagged as "done" right now. I still have non-technical things to finish, such as the trees' art or Appleman and BerryBat's behaviour. Then I'll have to ensure levels are playable and contain no "dead ends". It is just a matter of day before you see "grab-the-apples-and-find-the-exit-2.0-new-and-improved" (aka. gedsdemo). Some packaging will have to be done, as usual: i guess you don't want to bother with installing small files all over the place, or tap "B A R R Y L" to see the game starting so I actually build a separate binary that shares the game engine library.
The next goal: improve the level editor. The poor thing is waiting for an update for roughly one year now. It's getting too easy to screw up a level and too hard to fix the same level.


Bon, comme d'habitude, il y aura aussi un peu de "packaging" à faire: reprendre le moteur de jeu, les graphismes, la musique, tout ça, et l'intégrer dans un petit .nds prêt à la distribution. Avec l'EFS de Noda, ça devrait passer sans trop de problèmes.
(2009-09-04) [english][milestone][level2]

Un Bilou tout neuf.

Level 2 is merely there to demonstrate we can now have multiple levels.
Voilà. Je vous livre mon travail de vacances: la forêt mystérieuse de Bilou, revue et corrigée. C'est une démo jouable de mon moteur de plate-forme toujours en cours de développement, où vous incarnez Bilou (la balle bleue) et récoltez les pommes pour progresser dans les niveaux. Nouveautés dans la release 0.999:

En cours de jeu, sautez avec X ou Y et dirrigez le personnage (la boule bleue, faut-il le répéter) avec le Dpad. Start passe le jeu en mode pause debugging, L+START revient au mode normal.

The sign points to the left: you haven't collected enough apples to access the second half of the level.

(2009-09-09) [download][funky funghi][scrolling][sidescroller][milestone][english][screenshot][greenzone][appleman][bilou][level2]

Sprites à Priorité Dynamique

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXiB_sNuXsPueAHYcnpex1dVoehU0D8xuEVOOw6zAMeWO4jCweHdGhXj_lr21ETURaSl2ZISHbpxC6rqP2ARJPvCqbvml4izxjxLxbMvirxypS3cDhBBKJoR9Ytj-B-H-amntkxw/s400/bushes.png ; bushes.pngVoilà typiquement le genre d'environnement qui était pénible à construire avec l'ancienne version de LEDS et qui devient simplissime avec le curseur de copie et autres nouveautés.
Mais c'est aussi le genre d'environnement qui pose problème au moteur de jeu dans sa version ".999" parce que j'utilise les deux plans de tiles comme arrière-plan alors qu'à d'autres endroits dans le jeu (p.ex. quand Bilou est dans un arbre), il se situe en fait _entre_ les deux plans.

Bushes like these were typically the kind of background that was a real nightmare to build with the previous release of LEDS. And with the "copy cursor" and "pull to foreground" modes of the new prototype level editor, it's really easy and funny. On the other hand, it was also the kind of background that challenged the game engine. It is acutally built by "flattening" the two layers in such a way that i never need more than two tiles at a place, and yet simulate much more planes. Unfortunately, as i wish some elements to hide Bilou (such as walls and trees in secret places), Bilou actually stands "between" the two layers i'm using here, while in this specific case, he should be on top.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9MMeevPvzzAuLac8Qj_1hoU987Na_I1DAdLClWHvS2z4YlkF559t5FiS9DlU1ol72UBXiFjrvQKzE_xTALgfSl2WBulgMD62BYLicPKanYV_Hd8LeSdG7SG6r9ZGmTcgFxLOwMQ/s320/gedsdemo-20090519b.png ; gedsdemo-20090519b.png Le résultat, c'est que souvent, les pieds de Bilou étaient masqués, comme sur l'image ci-contre, soit parce que j'avais oublié de repasser l'herbe en arrière plan, soit parce qu'il y avait déjà un autre élément de décor par-derrière l'herbe.
Quand j'avais lu les spécifications techniques de la console Genesis, j'avais été plutôt étonné de voir qu'il n'y avait que deux plans de tiles. Or, Sonic est parfois devant le décor et parfois derrière (sans compter l'image de fond, bien sûr, qui occupe le 2eme plan). Le truc, c'est que contrairement aux console de Nintendo, la Genesis permettait de définir pour chaque tile si les sprites avait priorité ou pas pour l'affichage.

As a result, it is common to see Bilou's feet hidden by the grass in the latest demo, either because i forgot to move the grass to the bottom layer, or because it has to be on the front layer due to some other object (e.g. vines or bushes) in the background. I'm trying to address this by reproducing in software the technique used in the SEGA Genesis, as illustrated in Sonic II.

Je vais donc tenter de reproduire cette approche en software: puisque je dois tester les "flags" de chaque tile lors du déplacement de Bilou, je peux assez aisément en ajouter un qui force Bilou (et les autres sprites) à "passer par-devant le décor" quand ils sont au moins partiellement en contact avec ce tile-là. Ca risque bien de compliquer un rien l'édition de niveaux, mais ça devrait valoir la peine...

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUtuQLV9e99n64j_pUG7ifZoc-VaWqXKaauskzwkqCWgp6syroi0ejfmraR_h-ujzYQDv2DnsQykOYyUqKpAYwcDS2lf6LoQMmL4crr9ocfZ2WYtnoA1T7RPACWxIy3FOFEqsQGw/s400/DS-level-scrolling.png ; DS-level-scrolling.png
Despite the Genesis had only two "scroll layers" (against 4 for the DS), it dynamically evaluated tile-to-sprite priority: while all the tiles involved in the "tunnel" on the picture above were on scroll layer A, Sonic can be hidden by the "front pillars" and still seen in front of the dark checker tiles. I'm unsure whether this implies that rings in Sonic were sprites, though. I cannot change the DS hardware, but i can mimmic this technique by having some of the tile attributes (F_RAISER) that forces any sprite that hits it to appear above all the "scroll layers" rather than between "F scroll" and "B scroll" for this specific frame. It's still to be tested.
(2009-10-20) [level editor][coding][tiled][sidescroller][depth][sonic][english][mybrew][screenshot][greenzone][hardware]

Handling of slopes.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCYQunSfpdENhwah1AOJDBv83poe1jrLpUI-OQYga453OxD47ePaGku-iVGpPucgFyCIBkluT0eoeYQy5n80qnTX4xIvTkGjV8mUd-Nr3z-J0YzpQXRINTL6B5WNr0FDCjLFJUVg/s320/sloping-0001.png ; sloping-0001.pngOkay. It might be a little pathetic ... I've spent some time figuring out an algorithm for properly handling slopes in my platformer, but i didn't found the time to properly inject it into code, so I just speed-typed it in a draft post. One of the key ideas is that you won't try to adjust frame t's horizontal speed to the slope you have to cross, but instead defer the effect of climbing dy pixels to the next frame's horizontal speed. This allows a one-pass while all my previous attempt had to iterate until they find the position you'd actually take given the slope you have to climb.
Since we don't know how the slope "continues" to the next horizontal tile, we have to "pause" at the end of each tile in order to compute the Y coordinate we'd have then. When dx < TILE_SIZE
new_x = x + dx
while (tile(new_x) != tile(x)) {
gh = ground_height(end_of_tile(x,dx),y);
if (gh!=0) y = end_of_tile(y,1) +gh;
x = next_tile(x,dx);
}
Now, we know what height we have when we enter tile(new_x). We just have to compute where we'll end in that tile and we've finally done.
if (ground_height(new_x, y) == 0) {
new_y = end_of_tile( next_tile(y,1), 1) + ground_height(new_x, next_tile(y,1));
} else {
new_y= end_of_tile( y, 1) + ground_height(new_x, y);
}
Quick Note : the 'x' and 'y' are copies of the object's hotspot position, and the result of the algorithm is the new_x, new_y position at which the GOB's hotspot should be moved. I still have to figure out where cando(new_x, new_y) should be applied to ensure walking slopes do not allow one to move through walls, etc. I also have to figure out how to integrate this properly with the OO model I have so far : what is under the responsibility of iWorld, iGobController and GameObject.


C'est par manque de temps que ce petit algorithme de gestion des pentes se retrouve sur ce blog plutôt que dans le code. Une des idées simplificatrices de base (par rapport aux essais précédents) est qu'il n'est pas nécessaire de traiter immédiatement l'effet de la pente sur la vitesse horizontale (je ne sais pas vous, mais moi, je vais généralement moins vite en montée qu'en descente). A la place, je peux utiliser l'élévation du sprite à l'instant t-1pour ajuster sa vitesse horizontale à l'instant t... Le résultat, c'est que le calcul de la position actuelle peut être effectué en une seule passe, se basant exclusivement sur la fonction ground_height() qui retourne pour chaque position horizontale dans un tile pentu la hauteur de la pente depuis la base du tile.

ancien post-scriptum: je ne vous ai pas oublié, mes lecteurs francophones (près de 50% d'entre-vous). Vous aurez peut-être compris que ce billet fait office de "pseudo-code retapé en vitesse et commenté". Le temps de loisir est distillé au compte-goutte ces temps-ci, entre les dents de *deline et les grands rangements de la maisonnette qui en a bien besoin.

(2009-12-02) [traduis-moi][coding][tiled][english][slopes][sketch]

Enfin, des pentes qui marchent !

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg78ifU0GOXugaaxs78x11xPaOIS0hR3s6RuzO7uOsExR6q9_grFrsKiCjsLlbOfRctbW6a0zJ4ATbj2G8DlpDRgyzonVqs4UnTYd9kNaLpZ6i9h1SNirONx257rW8Rs2EqUXAW/s320/appleman-sloping-0.png ; appleman-sloping-0.pngC'est encore un peu mystérieux, mais ça commence à fonctionner! Petite démo téléchargeable (non-jouable, par contre) de mon "cas d'étude pour le débugging". Je vais tagguer le CVS pour qu'on puisse retrouver les sources correspondantes. Je dis "mystérieux", parce qu'au départ, l'appleman semble "hésiter" à prendre les pentes, chose qui n'a pourtant pas été programmée comme telle. Je soupçonne un effet de bord des vitesses inférieures à 1pixel/frame, sans avoir pu creuser complètement. Howdy! It starts working (though still subtly mysterious). Rather than trying to shoot you a full-blown Youtube Video, i used byzanz-record and some javascript to provide you a nice "video" teaser (hover the picture, you'll see ;). On the other hand, you're welcome to grab the running .nds and try it on your favourite emulator or linker.
(2009-12-10) [download][tiled][milestone][english][mybrew][slopes][video][appleman]

Slopes, Cont'd.


limitations of Tony PA's engine
Initially, I thought handling of slopes would be well-documented and tutored on the Web. The reality is that it is still a poorly-covered subject, that often puzzle hobby game programmers. I remember of discussions where developers (i.e. Gregg) claimed "think twice before adding slopes to your game. If you can go without them, do it without them". And I wasn't quite satisfied with the implementation proposed by Tony Pa in "Tile Based Game Tutorial" series, either. Tony listed a number of slopes that are not allowed (i.e. anything that isn't a 45° straight line) and arrangement of slopes on the map that lead to bugs or glitches.

I intended to overcome these limitations in my own implementation, and I'm in the process of cross-checking to which extent I got it working. I'm still sticking with 45° items right now, despite adding other shapes should merely be a matter of pushing more data[] in the engine and extend iWorld::groundheight() so that it looks for those new shapes.


SMB3, un des premiers jeux de plate-forme à introduire des pentes, va doucement sur ses 20 ans. On pourrait s'attendre, du coup, à ce que la gestion de terrains pentus soit un sujet largement traité dans les tutoriels, mais c'est loin d'être le cas. Quand j'ai attaqué la question, même le tuto de Tony PA "Tile Based Game Tutorials" ne m'avait pas satisfait. Il ne prenait en compte que des pentes à 45°, mais en plus, certaines combinaisons conduisaient à des bugs ou des "glitches" désagréables. Pour construire mon petit algorithme, je me suis donc appuyé sur un tableau "groundheights[]" pouvant être étendu avec n'importe quelle forme de terrain : marches, dunes, pentes de degrés divers, etc. Notre seule limitation sera le nombre de bits disponibles pour indiquer de quelle pente il s'agit. Et pour trouver l'algorithme correct, j'ai appliqué les fonctions élémentaires que je m'étais données (ground_height, next_tile, etc.) sur chacun des cas qui peuvent être rencontrés et que j'ai maintenant reproduit dans un recoin du niveau 1 de la greenzone. C'est presque fonctionnel, à l'exception du cas "e" (la pointe) où Bilou se "coince" et ne peut être débloqué que par un saut (l'appleman, lui, a déjà trouvé la parade et "saute par-dessus" l'obstacle !)
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijDyEEDlLk5LdDHeABXDY7ljQ4BsdfTOdgLpZBznHwAsDnEH8STG5oJRp1Jstb9e3rBdkw_bM7Q8K2uadRIhm7zRfpOFgiPQDHoNQJHTHF5PgcAbH0YoKkodjXkA90EZ7clrhSGAT6ZH3N13YfyeFH7qhGn45EDDzpBf15Z_JZpyg0rGmiqSis1w/s1600/Screenshot%202023-11-29%20at%2009-52-50%20Bilou%20HomeBrew's%20Blog.png ; Screenshot_02023-11-29_0at_009-52-50_0Bilou_0HomeBrew_7s_0Blog.png
The reason why I want slopes is level design : they allow a regular "walker" ennemy to find itself in a better tactical position (above you -- "in your functional blind box", would say Kirby Kid), as anyone who played Commander Keen knows. Until a "sloped level" is properly built, I altered the part of my level 1 that features appleman with all possible slope combinations. Walking right-to-left, you'll encounter (g), then (h) and (e) near the wall. So far, only (h) causes coding trouble: Bilou just stop at the top of that "spike" and refuses to move any further. The Applemans happily work around this situation by either turning back (if Bilou is not in sight) or jumping over the spike to attack Bilou. Cases (f) and (h) are automatically covered by the cando() tests that complement hotspots in my engine.

The algorithm I presented a few weeks ago is still mostly unmodified, but it had a major defect: it only moves you along a slope. The fact is that it should also inform the caller whether 1) we are on normal ground (and thus will fall if we can) 2) or on a slope (and thus don't fall) or 3) if we just couldn't move because there's something in our path. A bit more critical thinking is needed here to lay things down properly.

Encore un peu de patience, donc, et je vous livrerai l'algo revu et corrigé. La principale difficulté est qu'il avait été pensé uniquement pour suivre une pente existante, mais que j'ai aussi besoin de savoir si on est toujours bien sur la pente ou si les tests de chute habituels peuvent à nouveau être appliqués.
(2009-12-15) [english][coding][tiled][slopes]

Tracking Memory Bugs

http://farm3.static.flickr.com/2535/4206769834_163f0dce71_m.jpg ; 4206769834_163f0dce71_m.jpgmalloc et free sont des outils formidables, mais quand on s'est un peu embrouillé dans son code, ça devient vite une plaie. Je m'explique: le système d'allocation dynamique ne fonctionne pas "magiquement": il conserve autour des blocs libres et occupés des informations : taille de la zone, prochaine zone libre, etc. Elles sont évidemment importantes lorsqu'une zone libre est allouée ou qu'une zone occupée est libérée, mais elles servent aussi lors d'opérations de "compaction" (pensez au defrag du disque windows, vous n'êtes pas loin). Si on dépasse l'espace alloué pour une zone A, on peut facilement aller écraser les informations de contrôle d'une zone B. Du coup, on perd le lien entre la cause de l'erreur (le code qui gère A) et ses conséquences (erreur lors de la libération ou de l'allocation de B).

Dynamic memory allocation is a key aspect of programming that both open new horizons and puzzle newbie programmers. Unfortunately, it can also become a real nightmare for the seasoned programmer who has overestimated his skills, even just temporarily. malloc and free are not built from magic out of the void*, of course. They are algorithms that use small memory headers to maintain internal information about which block is free, how big is what, etc. This information is used when allocating/freeing blocks, of course, but also in the process of coercing small, contiguous free blocks into a larger one to avoid excessive memory fragmentation.
The problem is, that if code responsible for block A trashes information about block B (e.g. due to a buffer overflow bug), the error remains latent until block B is used again, and by then, you completely lost the knowledge that A is the faulty guy.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoYWfRLIdFn2ZwywKR6cfQ8srvsMKBr2zZtWu64K6K19MQeo376dWBU_r9IluhTLCyr3rkpITkxWIr9PIN9EHUDL_YJvR11BKQ2VrMBTcXulktI1JolmScA8DW9nGh5uF6QAm7Zg/s320/NastyBug.png ; NastyBug.pngCa fait un moment que je traine un bug de ce genre dans runme, sans trop savoir si c'est mon code qui est en faute ou celui de NTXM, le module player que j'y ai intégré. Bug plus ou moins facile à reproduire d'une révision à l'autre, mais que je sais être lié à une erreur de gestion de mémoire grâce au "crash code address" indiqué sur l'écran "guru meditation". Ces dernières semaines, j'ai pas mal avancé dans la gestion des erreurs et j'ai maintenant une fonction die() qui peut reprendre la main en cas de guru meditation ou d'exception C++ non traitée. Elle peut à présent tenter de retourner au moonshell, mais aussi afficher le contenu de n'importe quelle zone de mémoire de la DS. De quoi étudier la situation de manière un peu plus méthodique.

I know that I've got such a bug in runme (hence the lack of releases and the extensive use of gedsdemo). It's reappearing now and then and then hides again for a few releases. I've already proceed to a few code sanitization steps, but it doesn't look like i've been effective. With my recent findings (__cxa_terminate) and the introduction of a die() loop that replace main() after a guru meditation has been notified, I've given myself a memory inspection tool that let me follow "valid blocks" (starting the list from entries in __malloc_av_, the entry point of free lists) up to a faulty block that precedes the one where malloc/free() triggered an exception due to a wrong size.

Now, the goal is to trace back the owner of this memory block ... to be continued.
Un papier ... un bic ... pas mal de patience et la DS branchée sur chargeur ... C'est parti.
(2009-12-22) [guru meditation][coding][allocation][milestone][english][tools][runme][NastyBug]

FileWidgets

http://dsgametools.sourceforge.net/pixs/runme-reloaded.png ; runme-reloaded.pngLet's welcome FileWidgets.cpp in libgeds and appropriate DirShow + TypeWord widgets on the beam-file-out-of-DS page of runme. Snapshot will come out later : it's past my bed time, already.

Bin voilà. Finalement j'ai pu transférer les FileWidgets depuis le LevelEditor dans libgeds, ce qui m'a permi du coup de les utiliser dans runme pour le choix du fichier à exporter. Mais là, je vais aller dormir :P
(2010-01-04) [english][wifi][milestone][runme]

Monsters & Levels.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhECNh4ZSkxSEspXnn5yqn2ATIZMzY8YHfc4f2BN2hw3VuY0SSQXP2jixrKjHIpAv9sChDXZ7IdEaKm-zKo8ta3mCiTqsxd8ktiQp9Cik0Q6aYt5uxLR-Ox1G3T73YBGDsjaLvUyg/s320/Scan0001.png ; Scan0001.pngLe week-end s'achève, et c'est une semaine plutôt exigeante qui se profile à sa suite. Du coup, je fais l'annonce ici et maintenant, plutôt que de passer mon lundi à essayer de ne pas la faire pour ne pas me laisser distraire dans mon travail.

Ca y est, la lecture des fichiers .cmd et l'édition de la position des monstres a été intégrée au "véritable" éditeur de niveaux. Comprenez: celui qui me permet de manipuler les fichiers utilisés par le moteur de jeu, pas juste un .nds créé pour les besoins du débugging.



here you go: cj-leds.nds
special "Bros. Birthday Release"


C'est une belle étape, qui -- moyennant envoi de quelques fichiers "template" vers la DS -- me permettra de construire des p'tits niveau avec monstres incorporés en "ambulatoire", quand je peux, ou je veux. Comme vous avez majoritairement marqué votre préférence pour "Bilou Mining" (c.à.d. le prolongement de la démo telle qu'elle existe actuellement), ça sera des plus appréciables.


(2010-01-31) [level editor][milestone][gobscript][english][mybrew][sketch][pendat]

grimpons, grimpons

Bon, c'est pas le tout de dessiner des pixels de lianes/vignes sur lesquelles grimper. Maintenant, il va falloir coder ça, aussi. La base est relativement simple : un nouveau type de tile qui permet l'utilisation du comportement "grimper", au même titre que le sol permet de marcher.
C'est plutôt le passage d'un autre état (à l'arrêt ou en saut) vers l'aggripage de liane qui va demander une attention particulière. Deux éléments entrent en ligne de compte :
  1. le joueur appuie-t-il sur la flèche vers le haut ?
  2. Y-a-t'il une liane à laquelle s'aggriper ?
La deuxième question revient à un test du type "cando(...)", à ceci près qu'il ne fait pas partie du comportement "normal", mais qu'il risque de devoir être évalué depuis les transitions de la machine d'état.


Autre petite difficulté technique en vue : lorsqu'on est au sol, il n'y a a priori qu'une position où il est effectivement possible de monter à une liane : quand on est pile sous celle-ci. Du point de vue du gameplay, ce serait l'horreur d'imposer ça et il faudra donc programmer une sorte de "magnétisme" qui positionne le joueur qui tente de monter à une liane juste sous celle-ci s'il n'en est pas trop éloigné. La solution s'ébauche, mais ce n'est pas encore assez précis à mon goût ...
(2010-02-06) [tiled][sidescroller][greenzone][berrybat][coding][NutsnBolts][english][state machine][vines][sketch][iGobController][bilou][climbing]

C'était bien ça ...

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimgosu3yFaCBGaGCZRh95Ww3-06MCdnF65S2667UIaeSfLkkkn9v4UrYOSXoSUZ1R3plLWIdXSVQtopIZ9SmahGthJe5JhsifQIq-_2VFGMvepCol7wb7pjKGEEWsXdOZ-bxENvw/s320/level-shoot.png ; level-shoot.pngJ'avais pris une approche un peu trop "frileuse" en choisissant d'exécuter l'expression accollée à un changement de niveau avant le changement de niveau lui-même. Cela signifie en particulier que l'action "changer le niveau" aura le dernier mot quoi que l'expression puisse tenter de faire, rendant impossible des construction du genre si (vies=0) alors gameover() sinon réessaie(ce_niveau).



En réalité, exécuter setNextLevel() en premier est correct parce qu'il s'agit d'une opération qui se déclenche à retardement. Pour raisons techniques, il n'est pas possible de changer de niveau (ce qui inclus une destruction de tous les objets en cours pour reconstruire le nouveau niveau à partir du script donné) pendant la phase "animation/détection de collision" qui provoque en cascade l'exécution des actions.

L'important, c'est que le problème est réglé: on peut donc être "game over" dans Apple Assault.

PS: En général, j'évite de m'étendre sur ce genre de graissage d'engrenages, mais peut-être que ça permettra de me l'ancrer un peu plus définitivement dans la caboche. Quelqu'un a une cheville de 8 à me prêter ?
(2010-08-09) [game over][coding][milestone][gobscript][english][mybrew][apple assault][level2]

Vuoi una mela ?

EDIT: {{Oh, wait ... final version is one click away}}


https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLlL_rP6eLIQgUh-UQRKKw_ZMucLJ-b4YT5UHyfgGl4Om5Rc4twY5MqPm3-wl_0lqmqeI2xgvU5EdDDCZYXMwJMZAxdb5U7NNqH7Jp94ybAF1UCOFf-Fdz7jRQ4vCn93E4kQhw6w/s400/aa-it-shot.png ; aa-it-shot.pngAllez, un peu d'upload avant de retourner me concentrer sur le Distributed Interference Minimisation de Matt'. Eh oui ...

Voilà donc la version "à l'italienne" de Apple Assault, avec un vrai écran de statut dans le bas (voilà qui fera plaisir sur gbarl.it ;) et des p'tites pommes sur le menu pour choisir son niveau de difficulté. J'ai aussi ajouté les manoeuvre d'évasions et ajusté le gameplay des tableaux 1 et 2.


E meglio cosi?

[.es] Personajes y Controles (nds.scenebeta.nds) [/.es]
mirror on FileTrip
backstory, instructions and tips
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvbAVKz9-9H19aJmuzgNQkxOSwqG_KgeiigHUxsfSne6ovelIaIF8NBc9vz58JU0AvKZCGfHjNGDBPtGppF1Zn4phnlhyphenhyphenN30QqtIOBNJaNludmNz2qrKvBGJ_lDDYq-Og242zl2w/s320/aa-it-dl.png ; aa-it-dl.png
(2010-09-05) [download][milestone][english][mybrew][greenzone][appleman][apple assault]

TrackSequence : public Animator

Ce coup-ci, c'est fait: j'ai enfin la possibilité de programmer des séquences d'actions en réutilisant la partition musicale comme "séquenceur". Ce n'est encore que moyennement utile vu le petit nombre d'actions disponibles dans le "dictionnaire" de guns.cxx, mais ça me permet par exemple de faire tourner une petite musique "Level Clear" avant de lancer le démarrage du niveau 2. A terme, je devrais pouvoir y insérer fade-in, fade-out, etc.


Au passage : nouveau petit sondage sur le blog : combien selon vous vaut "Apple Assault" ? Perso, je le vois comme une démo un peu plus aboutie ... une sorte de "teaser shareware" pour un jeu complet qui n'est pas encore là, mais vous, là, qui téléchargez des oeufs de Zerg sur votre iPhone à la pièce, vous en donneriez combien, sur DSiWare ? (je parle d'une version achevée, bien sûr, avec les effets de transition terminés)
edit: résultats du poll.
(2010-10-12) [modplayer][coding][milestone][gobscript][ntxm][english][mybrew][poll][sketch][done][tracksequence]

Small step for me, Giant leap for Badman



Alors que je tentais d'expliquer à Aderack que "non, je ne cherche pas à porter les jeux Game-Maker sous DS", je me rends compte que le principal obstacle technique à une version anniversaire de Badman -- les tirs -- est maintenant résolu. Alors vu que j'étais trop naze pour réfléchir la semaine dernière, j'en ai profité pour bidouiller du script Perl de-là de-ci histoire de peaufiner la conversion des fichiers .BBL en .SPR. On ne s'emballe pas : ça reste hautement expérimental et artisanal, mais à force d'ajustement, j'ai fini par pouvoir sortir les sprites du jeu dans un setup "un sprite par pavé de 32x32 pixels" mieux adapté à une conversion vers le format SEDS.


Je dis "mieux adapté", mais rien n'était encore joué. Mon bon vieux script "imlib2spr.pl" avait en son temps été conçu pour produire des maps destinées à tester mon scrolling, absolument pas à remplir des pages de sprites avec un nombre réduit de blocs 32x32. Il m'a donc fallu un brin plus de chipotage pour parvenir à refaire un fichier qui soit accepté par l'éditeur, mais ça y est, photo à l'appui !
On verra bien s'il finit par en sortir quelque-chose :P
(2010-10-14) [pixels][milestone][badman][sprtools][english][history][perl][screenshot][scripts][game maker][sprite editor]

vsnes à la rescousse...


Bion, nous y voilà: à gauche la version SNES, à droite la version GBA. Même lieu (le boss du chaudron), Dixie sélectionnée et Diddy en mode "suiveur" dans les deux cas. Ambiance sombre et dantesque sur SNES, grosse bouillie rougeâtre à droite. Qu'il s'agisse du sol, du décor de fond ou de la lave, on a l'impression que la version GBA n'a eu droit qu'à un seul dégradé ... Je pourrais refaire la même analyse avec plein d'autres screenshots, je pense.

Face to face, the SNES and the GBA version of Diddy Kong's Quest (DKC2). I'd like to find out whether there was a technical subtle difference between the video hardware of the two that would explain why the GBA version is so ugly to my eyes... something like "DKC2 used an infamous 256-colour mode thanks to an on-cartridge bank switching device" or whatever... I used vSNES to analyse the use of video resources by DKC, but I couldn't find an evidence of such a techical explanation. So my only guess so far is that the colours have been changed *on purpose* to meet the rendition capabilities of the backlight-less screen of the GBA. Hover the screenshots below for english comments.

Avant de commencer à dire ce qui aurait été faisable ou non sur GBA, voyons un peu de quoi étaient faits les jeux de RARE sur la SNES.

J'ai trouvé un outil assez ultime pour ça: vSNES, un analyseur de cartouche et de savestate ... Comprenez : je démarre la ROM dans l'émulateur zSNES, je presse F2 pour sauver l'état, je quitte, et vSNES va interpréter l'état sauvé (contenu de la VRAM, notamment) et me permettre de visualiser les couleurs utilisées, le tileset (avec les différentes palettes disponibles), le rendu de l'écran dans les différents modes (DKC en mode 7 donne un résultat assez ... inattendu)

Première observation: 64K de mémoire vidéo pour la SNES, tileset et sprites partagés, les deux travaillant avec 16 couleurs par pavé de 8x8 pixels (les "tiles", vous vous souvenez). Chaque sprite et chaque pavé sur la map peut choisir la palette de 16 couleurs qu'il utilise, ce qui explique que j'ai des bananes oranges et un donkey correct à gauche, et des bananes correct avec un donkey psychédélique à droite.

Deuxième observation, les couleurs sont bien en R5G5B5 sur SNES, tout comme sur GBA. On aurait donc en principe pu reprendre les images de DKC (et de DKC2, vu que je n'ai pas de raison de penser que cette partie-là du moteur de jeu a été modifiée entre les deux épisodes) et les afficher telles quelles sur GBA. On a 3 plans dans le jeu SNES, la seule subtilité est que la priorité des tiles (devant ou derrière les sprites) peut être manipulé tile-par-tile sur SNES (comme sur la SEGA Genesis, donc) alors qu'il faudra obligatoirement passer par un layer supplémentaire sur DS ou GBA.

J'espère trouver un outil similaire pour GBA (no$gba sous Wine, peut-être) pour faire la même analyse sur la version portable du jeu. Ma seule hypothèse jusqu'ici est que l'écran de la petite portable (sans rétro-éclairage) aurait conduit à un jeu inutilisable si les graphismes avaient été conservés tels quels. Si je remets la main sur la DS Phat de ma fée, je pourrai peut-être me faire une meilleure idée...
(2010-11-16) [tiled][gba][donkey][snes][hardware][vram]

Yahoo!

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitnNzB_FBHT9Wv6esOc6ORS-YpIFYhobym_LhoG2POJ50ZgkO-XwMO6tk_717aAKAxaOAOPpSLqvlbCly8zh0E1rJx9rP4hkO_0ElsafXXvHCbLU409k5lr1lKjE5BbzRrX2SjUg/s320/first-frameditor-success.png ; first-frameditor-success.pngHey! Regardez: c'est Rayman ... reconstitué sur l'écran de la DS. Il y a encore un paquet de choses à régler, mais c'est la première compilation de mon éditeur d'animations qui permet de positionner les différents "membres" sur l'écran! Wouhouu!


(2011-04-15) [wish][coding][milestone][mybrew][screenshot][done][animeds]

Goro mode activated

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIEKLtfiOocyEfex69FG0YqX-Io5KpFLesf7oSJX83B5Z6BRXaRp72ffyipKr96jeSTYQOP-qJVdIz1jFbSUEYBHTbJQKbVO2MdQ45efGav7rfT6q2g4uO8XxBZejqnrMgmDdzLA/s320/skeletton-updated.png ; skeletton-updated.png

Bin ça n'aura pas été une semaine très causante, sur ce blog, hein ? Que voulez-vous, c'est qu'en-dehors des "grands travaux", il y a parfois une série de petites choses ingrates qui n'ont droit qu'à une ligne dans une todo-list et une autre ligne lors de leur commit SVN. Mais ce coup-ci, les epsilon se sont additionnés suffisamment pour devenir un delta: je peux (enfin) modifier la "structure" de mes personnages (le nombre de sprites utilisés, les pages parmi lesquelles choisir les images et l'image de référence) depuis l'application DS elle-même. Il reste encore pas mal de nettoyage à faire pour éliminer les incohérences de l'application, bien sûr ... mais on a fait un bon pas en avant.

On s'approche déjà de la release 0.3 ... bonne chose.


(2011-06-29) [mybrew][screenshot][milestone][done][animeds]

deep ink pit mockup tout moche

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmapx5UGAxdKEnPFhO0nibhJdAdvvFAtkjGyI4OIdt9_xEr4cTXm7Bo1t8ja4d4GwSmdPnfArAxMpDx9kYXNBQDy7AKubjXG7ozw_paWHoEso2PSc1Na26RF8IILJn0Vqtj4oiSQ/s320/deep-ink-pit-mockup.png ; deep-ink-pit-mockup.pngJ'essaie de rendre "deep ink pit" un peu plus concret, mais j'ai du mal avec ce classeur qui ne veut pas sortir de mon stylet >_< Je devrais peut-être essayer de travailler avec une autre couleur que le violet. Les Bop'Eponges donnent pas encore trop mal pour quelque-chose de bricolé en 2 minutes dans Gimp. Par contre, l'encre, clairement, il faudra que je me documente pour avoir quelque-chose de décent. Comme quoi, quand je disais que je n'ai pas encore ce qu'il faut au niveau graphismes, je ne vous racontais pas de bobards.



edit: dans la cité des images de Rayman, seuls les contours de l'encre sont colorés. Enfin, quand je dis colorés, c'est plutôt un reflet blanc qu'une coloration.
(2011-09-22) [pixels][milestone][school zone][deep ink pit][spongebop][mockup]

Happy New Year !

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpvybONODZDuhGcu0CX6qz8KO_8MLCuwQP2jUXKKviAiOCSCaY0In3dLJJ20kDT2Iipx5sUm_96xeHPypvzu3j7uRXZOht7blrMdJVvxDM9b-MW4L9PT4kX7mFPaZwkHzH8lB7/s400/timecurve-download-bis.png ; timecurve-download-bis.png
En guise de carte de voeux, une "fractale du temps" de toutes les "releases" de mon projet sur DS depuis 2006. J'espère la compléter dans le courant du mois avec les "choix stratégiques" sur le moteur de jeu, etc.



(2012-01-01) [milestone][mybrew]

Picking a Tile size.



2 tiles de haut contre 1 de large. Pour un personnage bipède, c'est l'idéal, si je tire les conclusions qui s'imposent de la lecture du Sonic Physics Guide. Attention, je parle ici de la zone de collision. À aucun moment celà n'implique que l'on doive caser tous ses dessins dans un rectangle de 20x40 comme dans le RSD game-maker, hein ?
En revanche, il est indispensable que le personnage puisse "tenir debout" sur un élément constitué d'un seul "tile" sans que ça ne paraisse bizarre au joueur. Idéalement, il devrait aussi pouvoir tomber dans un trou qui ne fait qu'un seul tile de large.
Difficile de dire si c'est le cas ou non pour Bilou, par contre. Ok, il est loin d'avoir les proportions de l'homme de Vitruve, et sera plus proche de 16x24 pixels dans la school zone qu'autre chose. Difficile aussi de lui appliquer la règle "un obstacle doit plus ou moins arriver à la ceinture pour avoir l'air un rien costaud"... Mais je garde ça en tête pour la révision de Badman...
(ces 2 croquis Biloupométriques datent de 2005, quand je m'étais mis en tête de faire une version 3D de la school zone en utilisant OGRE ... et que je me suis rendu compte que je ne parvenais plus à dessiner un Bilou correct qu'une fois sur 4 :P)
(2012-01-20) [3D][tiled][sidescroller][y2k5][collisions][bilou]

fusion!

Grand merci à sepcot pour son tuto. Mes déviations "moteur de collisions" (newcollide) et "moteur d'animation" (companim) sont maintenant intégrées sur le "tronc" de développement, là où se trouve également runme, qui intègre transfers wifi, lancement des éditeurs et petit moteur de jeu pour le prototypage rapide pendant le temps de midi. On va pouvoir attaquer la school zone plus sérieusement ^_^ A commencer par un dumblador qui marche ...


(2012-03-04) [milestone][CompoundGob][runme][newcollide]

Compound Gob: release

D'aussi loin que remonte ce blog, le 24 mars, c'est le "release day". Ca a commencé en 2007 avec la première version d'Apple Rumble, puis une version de runme capable de jouer des fichier .xm envoyés par WiFi en 2008. 2009 a vu le premier d'une belle série d'outils destinés à repomper le contenu des jeux Game-Maker.

J'ai un peu triché en 2010 avec tout juste le gameplay d'Apple Assault ... et franchement loupé le coche en 2011, avec pourtant une première version de l'éditeur d'animations pas bien loin.

Ouais ... Bon ... il est largement temps que je me rattrape, quoi.



Voilà donc la première version de mon moteur de jeu qui soit capable d'animer des sprites construits dans AnimEDS. Avec tous les outils en prime, dans une belle release source ^_^.

essayez de le voir en action


Maintenant, il me reste à reprendre AnimEDS et faire en sorte de pouvoir y définir les zones de collisions et les déplacement du personnage (en plus de son animation à proprement parler.
(2012-03-24) [coding][download][milestone][school zone][video][CompoundGob][animeds]

Where You See is Where It Is

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga_zzVQ87fAq_i4IgBYl4ezhYCo0wI6n9dumBNmaDUsafnZ5tP97_vrB0bcYlvadiwhY_0U-ROxAC7MF4NJdBW5W_YKnLv21t6AsqvbyjW_SMzLi2IKbkX-3ex8gd6ZtEbOC_E/s320/blade800.png ; blade800.pngBon, on récapète.

Là, j'ai AnimEDS, LEDS et le moteur de jeu qui sont d'accord sur la manière d'interpréter la position d'un personnage composite dans un niveau. Ça n'aura pas été sans mal.



https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5-UTONmXvdf3gUjs0wOI3HyBo0TpuWDNTjN2SN1CL1ioouXczqrjSRgOOOHn6vBhFhtx-jZ7n8tXxCZ76C9pysVjXdvmS4dJBkmTphkLLPTd2qnx86yfTwjco_x1tb7510GSz/s320/blador.png ; blador.png


J'ai même le début de la définition des déplacement, quoi que ce soit encore très "courbes elliptiques en espace discret toroïdal", si vous voyez ce que Bouli veut dire ... non ? bon, bin Dumblador reste sur place pendant presque toute l'animation, puis arrive d'un coup à une position improbable qui n'a pas grand-chose en commun avec le déplacement qui était prévu, donc:

  1. faire en sorte d'avoir en mode émulateur (sur toutes mes machines) une animation de déplacement, histoire d'éviter de re-faire l'animation à chaque test;
  2. éliminer les effets du type "la position de la tête n'est remise à jour que si la tête est déplacée (relativement) dans l'animation.
  3. garantir que l'info du type "verouillé sur le membre #3" est maintenue à jour quand on se déplace le long de la timeline.
  4. trouver le bug.
  5. Faire en sorte que les repères de positions dans LEDS restent corrects quand on se déplace dans le niveau ^^"

(2012-05-16) [level editor][coding][milestone][english][dumblador][sketch][bouli][CompoundGob][animeds]

Dumblador turns back

https://i.imgur.com/2yUdH.gif ; 2yUdH.gif Dumblador avance et fait demi-tour. L'occasion de revenir sur le fonctionnement des personnages dans mon moteur de jeu. Accrochez-vous un peu: le 'gobscript' est conçu plus comme un modèle de bytecode en ASCII que comme un véritable langage de programmation, mais comme dumblador est tout simple, ça reste lisible (j'espère ^^")
anim1 = spr:0
anim2 = spr:3
statL0 :anim1 {
using walker
selfmove
test 0 (2,4)-(8,14) 0001
area 0 (0,0)-(8,4) 000A
}
on commence par importer des animations depuis le jeu de sprites (il suffit de connaître leur numéro, ici n°0 pour avancer vers la gauche et n°3 pour avancer vers la droite) et on leur donne des identifiants locaux (anim1 et anim2, respectivement). Le comportement de dumblador va maintenant être construit comme une combinaison d'états réutilisant ces animations: L0 pour avancer vers la gauche et R1 pour avancer vers la droite.
statR1 :anim2 {
using walker
selfmove
test 0 (2,4)-(8,14) 0001
area 0 (0,0)-(8,4) 000A
}

statL0->statR1 on fail (100 :0)
statR1->statL0 on fail (100 ~ :0)
statL0->statR1 on hit0 (100 :0)
statR1->statL0 on hit0 (100 ~ :0)
end
Vous pouvez penser à un "état" comme à une action que fait un personnage: s'il est dans l'état "avancer", il fait son animation "un pas en avant" et utilise un morceau de code C++ un (contrôleur) identifié via using walker qui reprend les tests "y-a-t'il du sol? dois-je suivre une pente?, etc.". Le mot-clé "selfmove" indique que c'est l'animation qui définit de combien de pixel on avance à la fois pour une meilleur synchronisation. On reste donc par exemple dans l'état "vers la gauche" tant que tout va bien. Le contrôleur génère un "fail" lorsque le personnage arrive dans un mur. À ce moment-là il va falloir choisir un nouvel état. Les commandes du types statdepuis -> statvers on fail [condition] (action) permettent de construire les transitions qui seront testées dans ce cas-là. Ici, l'action consiste simplement à écrire une valeur constante (100 ou -100) comme nouvelle vitesse horizontale (variable n° 0). Enfin, pour compléter le comportement décrit par chaque état, les instructions test|area (coin1)-(coin2) avecqui donnent les zones de collisions (rectangulaires) qui vont permettrent d'interagir avec les autres personnages. La partie un peu "magique" se situe dans le nombre hexa avecqui. Pour chaque "type" de collision, il faudra choisir un des 16 bits disponibles et faire en sorte qu'au moins deux zones de collisions (p.ex. le corps de blador et celui de Bilou) utilisent le même bit (0001) mais dans un test pour l'un et dans un area pour l'autre, pour refléter l'asymétrie frappeur-frappé du moteur de collisions.
(2012-05-22) [download][milestone][school zone][gobscript][MyEngine][english][dumblador][video][done][CompoundGob][tutoriel]

transanims get rolling!

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDo9AjNbz1KDluLhGoFBeeJoNnNool6MnjA12fjLnn-CEgHtsY1ISeDhWqDDobjaGm9dfziFwA9IPwNNx_5TamRaK-_GRYkj1SlroKiaIsBPqVNLl-oBwEavC9rppPOvJfhBJd/s320/rolljump.png ; rolljump.pngVoilà. Après une soirée de debugging intense (entrecoupée de chasse aux bananes dans Donkey Kong Returns :P), j'ai réussi à faire "tourner" les animations de transition. C'est encore trop rudimentaire pour vous en montrer une démonstration (j'ai une seule transanim que j'applique à tort et à travers juste pour vérifier que ça fonctionne), mais c'est fait.


(2012-08-13) [coding][milestone][transanim]

pullmask working!

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIyZO5-VH3muIyE8Zea7JJVRscVaebE8fP7UeHyqHBt5VTn00R0Cvfkja6bW-BFAwRUDW_bqbApkvFSvO9Reu099-0mr8gMl8zNeenHS5HKIyF6PFgSWHzxBjsNd4bdCERvb652w/s200/stunned.png ; stunned.png

Après le décor, c'est Bilou qui - in extremis - est prêt pour la Grrande Riliize de Septembre. Il n'y a pas 14 heures, faire faire un saut-boule à Bilou le faisait disparaître presque complètement... c'est maintenant résolu. Les "transanims" sont donc prêtes à l'emploi et il me restera au plus à faire une copie-miroir du saut-boule (pour qu'on puisse aussi en faire vers la gauche ;) Mes nouveaux outils sprsplit, dumpanim et sprmerge ont été bien utiles dans la bagarre, si vous voulez savoir.

Reste donc juste à peaufiner la map pour faire un premier schooldemo.nds... et là aussi j'ai une bonne nouvelle: je viens de retrouver sous un fauteuil le chargeur de la DS "phat" de ma fée (la DSlite étant en réparation depuis sa Grande Chute du mois de juin et la DSi pas encore homebrew-ready, mais j'y travaille :)

Il me restera donc tous les aspects "collisions étendues" pour l'après-vacances.
(2012-08-31) [coding][milestone][transanim][z-order][english][bilou][CompoundGob]

First multi-palette LEDS screenshot

Si le post précédent vous a laissé avec des yeux grands comme des soucoupes, voici une petite image qui résume ce que donne le "multi-palette" hardware une fois ajouté à mon éditeur de niveau. Eh oui: les livres peuvent enfin avoir des couleurs différentes. Bon, on est encore loin du compte, parce que pour l'instant, ce sont les propriétés des objets (solide, pentu, ...) qui modifient les couleurs, alors qu'au final, il me faudra un outil de sélection de couleur à part. En plus, seul l'arrière plan (juste derrière Bilou) pourra voir ses couleurs modifiées, l'avant plan utilisant obligatoirement les couleurs de la palette "de référence".

the multi-palette .spr file I crafted on my DS phat has been beamed and (thanks to Sverx's precious hints), I've got LEDS now working in extended palette mode, so that it can natively use the same tiles data for at least two different tints of books. I still have much to fix, but it's a nice first step.
(2012-09-10) [level editor][coding][milestone][english][palette][colours]

throwing bladors

http://i.imgur.com/mpsL1.png ; mpsL1.png

De temps en temps, ça fait du bien de retourner à une "liste de choses à faire" pour s'assurer que le projet avance effectivment. Bon, des "todo lists", vous devez tout doucement commencer à en avoir une indigestion, mais je parle ici de quelque-chose qui s'approche plus d'un "planning" que des micros-tâches à effectuer sur un temps de midi. Mon dernier planning datait de mi-juin ... voyons où on en est... tous les éléments "du bas" ont été satisfaits, à grand renfort de mises à jour de SEDS et AnimEDS. Je vais donc pouvoir cet hiver attaquer sérieusement les nouveaux types d'interactions entre personnages: assomer, attraper, balancer.
On dirait que les mois à venir vont être durs, chez les Dumbladors.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFkXU1GwuK2RkkVPYo3wJwfOQifrt0HnP48JvrRd3PmQ7THne5HeFwvNnFpj3bS2UfH-CpVu0YjTrs2mikTL6uFatqnHx91XGR8neze2A2MHpeQ9mZRwMdOCtB3EICNisXsvgI/s1600/ingame.png ; ingame.png



(2012-11-05) [dumblador][screenshot][newcollide][animeds][todo][milestone][school zone][state machine][english][bilou][CompoundGob][sprite editor]

More slopes

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXiI_K_gnZNdvRirKyRI7QNlt5EXv7TCD9_BZo3vwi-gkq8D5cVEpyxisNKsG0mEKjIFiF_wLwia_xDjgsscJ4xIkfnRH2xaWl_wM7YzXFkkLqBU_TUIhuQkxygZccHt5gBlFa/s320/extra-slopes.png ; extra-slopes.pngJ'ai envie d'avoir plus de souplesse dans les pentes que juste "45° dans quel sens?". Si ça n'apporte pas grand-chose au niveau du gameplay en tant que tel (un ennemi-marcheur en haut d'une pente garde un avantage stratégique même pour d'autres formes de pentes), ça permet de construire des niveaux plus "organiques", ce qui n'est déjà pas si mal.


https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM2Z5e4l_8dDG6U8xYczIoXQg-ZKR88qF75Wt3aSamnRAx-E-PvDDOLgUEvbYtNs1BrvxcZdIkWe16eymJA6MPC6306GunnFecvyb85JkOoNLyLc7NQyGV7zRwrFMqIYby6DJw/s320/bilou-techx.png ; bilou-techx.png En revanche, j'ai déjà saturé le nombre de "type de blocs" dont je dispose vu ma technique d'encodage. L'idée cette fois serait de combiner le "type" (encodé par élément 8x8) avec la position du tile au sein d'un bloc de 64x16. Si ça reste jouable au niveau du moteur de jeu, ça demande un support spécifique dans l'éditeur de sprite pour "préparer" ces blocs de 64x16 contenant 16 tiles alloués de manière contigüe dans la SpriteRam (alors qu'ils sont normalement alloués par bloc de 4) puis de les disposer conformément à ce qui est prévu pour un des type d'obstacles souhaités.

http://imgur.com/2DXa1f7.png ; 2DXa1f7.png En comparaison, le moteur de SMW (selon Lunar Magic) offre 3 angles de pente: 'normal' (22.5), 'gradual' (11.) et 'steep' (45). Au niveau du gameplay, les pentes 'steep' étaient les seules à pousser d'office le joueur vers le bas (si ma mémoire est bonne).
Bon, je sais, ce n'est sans doute pas ultra-prioritaire pour faire avancer Bilou, mais mon petit J.l.n est né vendredi dernier, ce qui réduit un peu ma liberté d'action. Un peu de bidouille dans les éditeurs devrait donc être plus aisé que d'aller créer du code pour de nouvelles interactions avec Inkjet.

(2013-01-21) [wish][allocation][tiled][english][slopes][gameplay]

Un grand pas en avant ...

Pas évident d'avoir des pentes correctement intégrées dans le déroulement du jeu.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZRoDcPK6LNvKLTnPILCkDIXgIvhpqFfXl8a3yxzh6GvPH1aOkw2rbVhS38wLyVYO13tTOgn5DKUYM2PswtjtFhxr_E94hYprQLlz1D9K2AktJqsbV8SeSODj_4pC5pvJQQQxG/s200/glud.png ; glud.pngSouvenez-vous: dans Apple Assault, si les pentes fonctionnaient presque correctement, il me restait une certaine probabilité que Bilou se "bloque" arrivé au sol, et ce n'est qu'avec la révision du moteur de jeu en Septembre dernier que le bug fut corrigé. Mais on était pas tiré d'affaire pour autant...
A force de refaire des tests pour m'assurer que Bilou ne puisse plus se bloquer dans les murs suite à un atterissage en catastrophe (en mode "pas à pas"), je finis par me rendre compte il y a quelques semaines que lorsque Bilou arrive au bord d'un livre (terminé par un tile pentu en bordure), il oscille quelques fois entre "marcher" et "attendre" avant de finalement se décider par sauter. C'est la plupart du temps presqu'imperceptible pour le joueur qui ne notera peut-être qu'un temps de retard, mais je me suis mis avec ce projet d'avoir un moteur de jeu irréprochable. Exit l'à-peu-près et les excuses bidon: si je ne peux pas être le moteur candidat pour Super Mario World 3 sur SNES, alors le côté "documentation de comment on aurait sans doute pu faire les choses avant de passer à la 3D" perd sa raison d'être.




https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigh_ju9yxjOiMtelW0vpXxgeEn8r73rJFWyfzuVa_LIjc7vezZHSKw3o7G-Oc1UV7NBsyYP_QvQYyLYrQUkBbBXQTJC0DzHO_xLngD6vRFzBMy0_LOpG1cQM7KUPcRi0i8BRqq/s1600/slope2.png ; slope2.pngCommençons par un rappel du fonctionnement des pentes dans mon environnement découpé en pavés (les "taïlze/tiles"). Bilou n'y est qu'un rectangle qui doit pouvoir naviguer sans rentrer dans les tiles solides (noirs). Il possède en plus un point de référence (hot spot, en rouge vif sur l'image) qui doit rester en contact avec le sol lorsqu'on suit une pente. Pour avancer d'un pixel vers la gauche, le hot'spot passe d'abord dans un tiles complètement vide (gh=0) où il n'y a pas de sol à suivre. La fonction do_slopes détecte ça et teste du coup le tile situé juste en dessous. Son pixel le plus à droite correspond à une hauteur gh=-8. On se retrouve ré-aligné sur le prochain pixel ... tout va bien. https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnpunfNVGMYeVGAg336tBulR2NzzxFYoccseezpcYb6b72WNy-eO8MmIPUWAhvwsncThw4pJqBeAyM5lB-vAki-YbcZoae8hHiukh9tYWSH2X1n3vTBswRSV31_Hfhz80VHjLt/s1600/slope1.png ; slope1.pngLe problème apparaît seulement lors d'une transition pente/trou, comme j'en ai ajouté sur le bord des livres. Ici, lorsque'on regarde sous le tile vide, il y a ... un tile vide. Pour do_slopes, celà signifie qu'il n'y a plus de pente à suivre.  Idéalement, on devrait donc juste se retrouver "le long de la ligne bleue" inférieure, qui empèche Bilou de tomber jusqu'à ce qu'il l'ait complètement quitté. Mais voilà, à ce moment-là, on est pas encore sur le sol! Du coup, lorsqu'on teste s'il est possible de tomber d'un pixel, la réponse est "oui" et le contrôleur envoie un FAIL.



https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitqlyW4M0M_xbrKzAIWjKIVZMXrTySJG78M7T-PTbnfS574Fo7h80Jd6v6Hs20OwKILnVn2Ql3sRHp1P2Eqt4qZPw2T1t2Un_K6ROPTveovC_g5_JuTrlbjZn5G2diC2uRRyXQ/s200/states.png ; states.pngSeulement, voilà, l'échec du contrôleur n'implique pas forcément une chute. C'est à travers les transitions du comportement de Bilou que les choses vont maintenant se jouer. Tomber d'un pixel ne serait pas impeccable, mais celà nous conviendrait. Seulement, pour celà, il faudrait que le point-test placé au sol indique du vide ... et étant décalé sur la droite, il est toujours dans la pente! Du coup, c'est vers l'état "do_slopes. C'est ainsi qu'on parvient finalement à quitter le livre après ce qui semble être un instant d'hésitation. à l'arrêt" (idle) que Bilou passe. Mais puisqu'on a toujours le DPAD incliné vers la gauche, on quitte dès l'image suivante cet état pour tenter à nouveau une marche... qui échoue encore. Heureusement, à chaque échec, on avance d'un quart/demi de pixel qui correspond au "mouvement entammé".
Une fois que l'Inspector Widget est devenu assez précis pour faire ce genre d'analyse, il devient assez évident que la solution est de forcer le personnage à s'aligner sur le sol quand on quitte une pente, et de ne considérer qu'on chute que s'il est possible de descendre alors que le personnage est déjà aligné sur ce qui devrait être du sol.


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

NSMB Editor !

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9tFPo8TQfhZfgzXVVzftRfBq7xpbcxutbIqhyphenhyphenaEWcHWZ8K5gwTyzZuxVnOlq-923wAsD1wEmeFza_l_Kqf3r6hVaTstUHLoT0_xsQWceIBQkDAFbn4WXzEFFrNXZvxAkPS-36/s320/NSMBe-spritesets.png ; NSMBe-spritesets.png

Cette fois j'ai battu Bowser sans utiliser de Mega Mushroom (interdiction édictée par *deline). Et je réalise tout à coup que "new" Super Mario Bros a ... 7 ans. Bien assez pour que les éditeurs de niveaux aient fleuri, et j'ai même réussi a faire un peu tourner NSMBe un tout petit peu sous Linux. J'avoue que je n'ai pas l'intention de créer mes propres niveaux à NSMB. C'est un exercice qui ne m'a jamais vraiment attiré. Par contre, je suis curieux de voir ce que je peux apprendre sur la structure du jeu.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoWM_ULpp6NG4LP45XBNqH4I0ZdyVVJZZW5iA8ifrVJ5BOYmp6jvJqHSue-bIzc75rPkKI-fOS-iGZZ1f2VGUboXSQJJyLCgtX6zom0LcenKxja_58dXbz6ltCBjUMoFxK0ibe/s320/NSMBe-sprites.png ; NSMBe-sprites.png


Comme on pouvait s'y attendre, un grand nombre de plate-formes sont en réalité des "sprites" (soit avec des OAM, soit avec la couche 3D. Difficile à dire), même celles qui ne sont pas forcément mobiles, mais dont le comportement est suffisamment différent du sol. Les portes, les début de niveaux, les entrées/sorties par des tuyaux, sont eux aussi gérés avec des sprites.
Les sprites sont organisés en "bancs" que l'on peut utiliser ou non dans le niveau, certains bancs en excluant d'autres (pas de bowser et de nessie ensemble: ils sont tous les deux pour le banc n°5, par exemple). Par contre, on pourra les compléter avec des Hammer Bros ou des chomp chomps, comme on préfère.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcJv_tymRCDlS74Vfgqx6oSbsNsM_Wh9fVlC3uXtTGxi65fjqnuNZUp-AtDU3FkRG6oOzlabsEMrHKGX2AEJbLOZn7BwFOV22bwVm3QiVfLIyN98IZ45A2xdiT-eMdbtYrQszh/s320/NSMBe-tiles.png ; NSMBe-tiles.png


Les pièces d'or et les bloc-question font partie de la couche "sol". Idem pour les blocs-à-power-up. Ils sont sans aucun doute fait à partir de bons vieux "tiles". Chose assez inhabituelle, en revanche: on les édite et tant "qu'objets", pas juste en plaçant des pavés sur une grande grille. Chaque objet peut être sélectionné, déplacé, redimensionné individuellement, ce qui s'avère très efficace pour la conception rapide de niveau comparé à ce que LEDS propose. Du coup, on retrouve des éléments assez curieux comme des "pointillés de pièces d'or" qui permettent d'avoir un "damier de pièces d'or en diagonale" avec un seul objet.
Tout ça n'a pas l'air d'être juste un choix de fonctionnement de l'éditeur: les niveaux eux-même contiennent ce genre d'objets: si on clique sur un "bloc" du dessus d'une plate-forme, on sélectionne directement l'entièreté du sommet de la plate-forme. Je présume que c'est une technique pour réduire l'espace sur la cartouche: le contenu en mémoire du niveau sera reconstitué en appliquant des commandes du type "remplir (10,10)-(20,20) avec du sol" puis "remplir (10,9)-(20,9) avec de l'herbe", etc. J'y crois d'autant plus fort quand je vois des motifs "effaceurs" qui n'auraient aucun sens dans un système utilisant des textures et des polygones.





(2013-06-15) [traduis-moi][level editor][tiled][mario][level data][platforms][designclass]

School level delivered!

Enfin nous y voilà. 3 ans après 'Apple Assault', un nouveau jeu Bilou est sorti. Enfin, "jeu" est excessif: c'est une démo jouable comme vous auriez pu en trouver avec votre magazine PC-Fun préféré dans le milieu des années nonantes. Avec un seul niveau, il n'y a par exemple aucun moyen de reprendre de la vie ni de regagner des vies. J'ai pourtant d'excellents souvenirs de la démo de Prehistorik 2 avec son compteur de pourcentage d'exploration. Nous nous étions donc mis en chasse des dernières plate-formes invisibles et bonus cachés jusqu'à parvenir à un 100%. C'est ce genre d'ambiance que j'ai tenté de reproduire dans le niveau-anniversaire mis en ligne hier.


Et dire que depuis Mars dernier, il me semblait de n'être nulle part, puisque presque toutes les modifications apportées au moteur de jeu dataient de 2012. Et pourtant, du changement il y en a eu: tout ce "rush" sur le niveau-anniversaire n'aurait jamais été possible avec des outils aussi peu fiables que ceux dont je disposaient en début d'année, succeptibles de perdre ou d'écraser le travail accompli à la moindre fausse manoeuvre.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF9ZLsdbjB8dI-aULhCXN_MVSuKURkYzMrAdEkgvba9n8YP66Zy3stxin_awB7c5rV7F_EcW6-fHL22HTwl32siRvvki5QxdYk-HqMlu9H2jROA88fCKASgJe62XfLL9fOarCd/s1600/schtiles.png ; schtiles.png

Le niveau dans lequel on se promène tente de respecter le plus fidèlement possible le design d'origine (1994) créé par mon frère, mais remplace régulièrement les "clés" et les "interrupteurs" abstraits par des interactions entre personnages. Par contre, au niveau graphismes, je dois admettre que sur la fin du niveau, je tournais un peu en rond. Pour continuer à construire la School Zone, il me faudra d'autres objets. Et là, soulagement de dernière minute; je ne suis en fait qu'à ~50% de l'espace disponible. Du côté des sprites je devrais pouvoir compter sur le doublement de l'espace disponible (j'utilise 64K sur 128), mais il faudra "expliquer" ça à l'éditeur de niveau.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFonCe5r6mjtEkQHt_0vVctcVM3ZgRd2G8w42DHDAmgFCJHi-75Z0vxzgcyu91GY2ar0rRX0J543EDnf6qtZGyPGJcfa4lxBOSZXhFnRhxeYAW0087Tcch0YjeECJlu2Z3waO_/s1600/schsprites.png ; schsprites.png

Si je suis parvenu à boucler ce "niveau jouable" en 2 mois alors que je travaille sur la school zone depuis Septembre 2011, c'est entre-autres que je suis passé sur une autre approche: chaque fois que c'était possible, j'ai rusé (par exemple en trouant le sol sous les pieds des Pendats pour leur faire faire demi-tour à l'emplacement souhaité) plutôt que de chercher à étendre le moteur de jeu (p.ex. avec un mur invisible pour les monstres). à retenir.
Et maintenant ? Quand tous les confettis de l'anniversaire auront été balayés? Bien sûr il y aura un peu d'emballage nécessaire pour permettre à mes p'tits n'veux de faire leur propres niveaux: manuel d'utilisation, blocs supplémentaires pour les vies et les soins, par exemple. Sur une autre branche, proposer une réalisation de "Deep ink pit" malgré tout pourrait s'avérer sympa, encore que le concept du jeu n'était pas aussi riche que celui d'Apple Assault. Enfin, il serait temps de s'attaquer à la 3D, histoire de permettre aux crayons de poursuivre Bilou et d'introduire le fameux Bang Bash qui, en février 2006, introduisait le jeu vidéo Bilou dans la blogosphère...
Oh ... et il me faudra un écran "sound test" pour comprendre les effets curieux qui se produisent sur les musiques ces temps-ci.
(2013-10-20) [20years][milestone][school zone][finishhim][spritesheet]

Special Blocks

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_lWHKDL52f1vJCNwM1swlIv7mnOvP3o5MSS634jhTuT5uPI_JRABYklKnbR70GABSoHYpEQO_nGdKy78KMgFDo04oNoUjc9Qq2yT1TB_fDaKNTKZMu-VXVDOV2tpKWDtpzZbT/s1600/level-2-1-recup.png ; level-2-1-recup.png

(2013-11-02) [coding][tiled][StillDraft]

2D + 3D = ^_^

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj70nKtus7xgTJzPKUr85XPFHqiiH_SjfmXvionSWaK3iu9yvWaL33simeiqlnQtXPYTaQX0eOJ2U-r4clgWs97uNdEocBBczVK6im9sqQgqW3AurN-APcA0V8fTnR8w8E2uHQi/s1600/working3D.png ; working3D.png


Quelques règlages ici et là, et j'y suis: un premier polygone (non-texturé) affiché en symbiose avec le moteur de jeu 2D. Tout ça fonctionne évidemment mieux quand on essaie pas d'activer la 3D à 3 emplacements différents dans le code. Je vais devoir à nouveau ré-organiser quel-layer-est-utilisé-pour-quelle-fonction ... ça devient un brin lassant, je vais faire une couche d'abstraction, ce coup-ci.


There was activity about the controling log display this summer ... It should allow me to flip between BG and log quite transparently.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP-9I7tThN8MVYsKN_-tTarTRUiW4dlBhx6WvAzk7KiTGS-NLVYzFFufFIOL0GDbZh8q8ioG6lCPLXOUa33aqJAxhKpL-ozGIexWLx7Xg4HZERHAy6LdE8uOlEWNB5ASU2iskp/s1600/success.png ; success.png
edit: huzzah! it works!

edit: game engine fix is done. Runme adaptation will have to follow (and will likely be a bit more tricky). Real bugger will be the "fade sequence" which used BG1 (now used as "farground") to hide the screen content while re-loading the level ... I'll have to use another technique like window registers.
(2013-12-04) [3D][screenshot][milestone]

runme3D

Toujours aussi tendu dans --IRL, au point que j'ai fait les modifications il y a bien une semaine mais que je n'ai toujours pas eu le temps d'en parler. Assez curieusement, j'ai des triangles flashy blancs qui apparaissent dans tous les sens quand je m'approche de l'emplacement d'une éponge sur DS, chose que je ne parviens pas à reproduire dans l'émulateur... et qui ne se produisait pas avec la version intégrée "SchoolTest.nds" ToT


https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeFJIwuPlKwe3FELNrH0MZrsSk4N-cRrcMKTvLur413MnMIRSkmf2uoP7MysLklMpKMjvfOmpnYDnQ65KlPBIWSvcG1OjulfIw4spJmGBUi2mQLoVPDYbObLJv5DvCrCILeztE/s1600/bonus-bug.png ; bonus-bug.png

Je pense bien avoir mis le doigt sur ce qui provoque ce curieux bug de bonus-à-moitié-disparus, par contre... et à reprendre le fichier construit proprement, la 3D passe aussi dans runme. Cafouillages de téléchargements, j'imagine. Il faut dire que le "nouvel hébergeur" (le site web de sourceforge) est d'une lenteur affligeante à l'heure des CDNs. Il va falloir que je trouve un autre plan B ou que je parvienne à prolonger mon occupation du serveur qui marchait si bien jusque là.
(2014-02-13) [3D][special block][tiled][runme]

Collision avec le monde

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCL2t8LH-zLjoLpwtjjJKLLk5-o7StW6i801oOUPuD0X3zH1l7XmpzcY71iWiKryZb83Fb16wK1wZos-namW7ET5sK9YTq3F9HOvvTEtiQgI1tkfalqZSKA_xtNTIdD2bh57nQ/s1600/uml-GobCollision.png ; uml-GobCollision.png
Au milieu de ma série de scans sur le thème "Critical Link", je retombe sur un diagramme UML représentant la séquence d'action qui découle d'une collision entre un personnage et un bloc spécial. Comme il va prochainement me falloir gérer des collisions entre crayons fixes et taille-crayon, je blog en stock ...

.
(2014-04-05) [special block][tiled][collisions][uml]

pinky LEDS

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggXIxfY4_-04R7uYdpI5RGBTUCyBSwn3JdvkKjpvhPiuEZQnPkRYTnJ_18oyfrVNeyPQsdjB6fCYCFhPMm87iJBmfbsnGuugxlbW-KTas63RkKymgWxECKj0LBBYCzYnOILXm0/s1600/leds-pinkmode.png ; leds-pinkmode.png


Voilà donc le premier pas vers un nouveau mode d'encodage des blocs spéciaux: chaque bloc peut se voir assigner un "symbole" (façon CPC basic) qui apparaîtra dans une jolie (?) couleur rosée lorsque l'éditeur fait le rendu du niveau. Il faut toujours faire l'encodage "à la main" (c'est même un peu plus délicat que précédemment, puisqu'on ne peut plus loucher sur les codes existants :P) mais dès qu'on déplace la vue, l'éditeur nous confirme que les règles du moteur de jeu ont bien été respectée (numéro de bloc spécial connu, un bloc tout entier a été utilisé, etc.) ... et le petit symbole pointu ne laissera plus de doute sur le fait qu'on a encodé un picot et non pas une fin de niveau ou un bonus.
Ce n'est qu'un premier pas, mais comme ça, je peux enfin trouver et corriger le problème d'interaction avec les taille-crayons dans le "niveau de *deline". J'espère pouvoir du coup aligner 2 ou 3 autres niveaux-courses d'ici la deadline de la neocompo (s'il y en a une cette année).
(2014-07-14) [level editor][coding][tiled][english][special block][wysiwyg][done][user interface]

Les tiles ... du C64 à la NDS

http://www.biloucorp.com/images/design/logo.png ; logo.pngChose plutôt inhabituelle, après pas loin d'un an de bidouille, mon premier article sur le site de la BilouCorp est finalement en ligne. J'avais envie d'y faire une rétrospective sur ce qui a fait de certaines machines des plate-formes assez merveilleuses pour la programmation de jeux vidéos et de jeter un coup d'oeil à la façon dont leur caractéristiques techniques ont formatté les jeux qui ont tourné dessus. Le premier jet, c'est donc sur les les tiles, ces petits pavés graphiques qui m'ont accueilli sur le C64 dans "Space Mission" et que je reprogramme dans SEDS pour vous faire les jeux de Bilou. Bonne lecture.

(2014-11-22) [english][tiled]

Keen: ClipToWalls()

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqMO5BvctF_5v7ylyfyTdOl53-cDAc3vNtASNXPfDqHIaNcDJ8kRNyBZ4hyDDksUN-FkZ3WpivACa0z1mGbfjswsNCKLrSr9TRxcDuapCH2sMeea0bpKLGJfrE-gvI5bOAlwjs/s1600/KeenTiles.png ; KeenTiles.pngPour éviter que Keen ne passe à travers les murs ou ne reste bloqué en bas d'une pente, les niveaux attribuent à chaque bloc de 16x16 pixels un ensemble de propriétés. C'est la technique des "tiles" bien connue de la plupart des lecteurs. Ce qui est particulier dans le moteur d'ID software, c'est la possibilité de définir séparément l'animation, la pente de sol, le comportement en tant que bloc spécial (valeur du bonus, couleur de la clé, etc.) et la polarité du mur. Plus fastidieux à définir que le simple remplissage en tant que bloc solide de mon éditeur de niveau, mais heureusement, dans Keen, il y a presque systématiquement correspondance entre graphisme et propriétés, et l'éditeur de niveau peut automatiser tout ce qui n'est pas passages secrets.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpIj9KArYJbuz8lYe2FBxUme0jacJZZPogeXt5JlS6Icgn1ZtA5y-zb1naiEKV42j4Fn_Jaz6zhia1FiapeGFEkIU7W9XP9fPXyT20Si8G_x9Y1s6Vkon_6YEvVEDHcheuL3r4/s1600/ClipToEnds.png ; ClipToEnds.png




https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRfPostp5PvcYX2aVYsnHcKN5QjldgzQoMYbOtmEyfZcSVRjvtvVSnUZlO_GdHg_Q-xHaGDDsVUZMtUDTznx8_9xfcPaMtEaNn_hsnT8jnJg_Sk0gtB4WeMwl3AZ-BzaqwdN29/s1600/keen-level.png ; keen-level.pngLa notion de "polarité des murs" est intéressante. Lorsque le personnage se retrouve partiellement dans un mur, c'est cette polarité qui décide si Keen est repoussé vers la gauche ou vers la droite. On aura donc jamais de situation comparable au "zipping" des jeux NES où Megaman se met à traverser le niveau à vitesse super-sonique lorsqu'il rentre dans un mur simplement parce que les programmeurs se sont contenté de "si on est dans un bloc solide, on repousse Megaman sur le tile suivant". Evidemment, ça suppose que les murs font toujours au moins deux tiles de large.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiibymsS3C8Cm-F6SphgFjdaFVUznUAUpjs-2vytvuGhNTlszdE3yjWA44RgoLhNJCL1A_adByOntZmWpb6VG5fm8xKlNihU5_yyOCWhkyXfxPxgzhGvxD_xV5mhrz0y3opaP7f/s1600/megaman-zipping.gif ; megaman-zipping.gif
A Zipping technique in Megaman. Propelled at 1 tile/frame or so.



C'est intéressant de voir que ID software a choisi ici une technique radicalement opposée à celle d'Epic Megagames. Pour Jill of the Jungle et Xargon, Epic faisait en sorte que le personnage n'entre jamais dans des tiles qu'il ne peut pas traverser (grâce à la fonction "cando"). Pour Keen, think() peut potentiellement faire rentrer un personnage dans un mur, mais le déplacement via ClipToWalls() le repoussera automatiquement dans la bonne direction, sans risquer de se faire piéger par un demi-tour de dernière minute comme dans Mario Bros.
(2015-01-10) [english][keen][coding][tiled][bordures]

Air Grab

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQrkjwo3t28aAkm16BGgFQRyt6FUjAd7f0wzOMtD1_u-umgtBcf9EsvF1vYnD31MitgvXMSpCcom1jFiN-cZ7cfXEqqGUV3py-hQYjS_UTLMvnSkBMhoYEsSjsFTEgTYN-tjNE/s1600/Photo-0369.jpg ; Photo-0369.jpg
On s'approche, on s'accroche ... Les travaux sur les zones de collisions contrôlées depuis l'éditeur d'animations portent enfin leur fruits. Il y a maintenant un état dédié dans le comportement de Bilou pour "je pirouette en l'air pour attraper quelque-chose".



https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC66tVTC86kerMxOdGnIVW4ph-qOkbDrTuwueuxlz1_g2htzQkKNNQJwXLW25IosJXoZvap0rFbUyW2iuObRHAnXjSIrSPIJkcQihWb9cNGZQm6WAU7PXVUDk4Av19VkPHW_c-/s1600/OHphLKb.png ; OHphLKb.pngAu-delà de la performance technique, l'idée est d'agrandir la marge de manoeuvre des joueurs qui veulent s'accrocher à une éponge. J'ai tenté de reporter sur l'image ci-contre la marge de manoeuvre avant (en mauve) et après (en bleu clair). En rendant le fait d'attraper l'éponge moins élitiste, j'espère -- selon les conseils de KirbyKid -- les rendre aussi plus amusantes.
Une chose, par contre, n'a pas changé: Bilou est toujours centré au-dessus de l'éponge quand il s'y accroche. Du coup, agripper une éponge alors qu'on arrive à côté d'elle produisait un décalage brusque de Bilou. Je tente donc un élément inédit dans le gameplay: une transition pendant laquelle Bilou, roulé en boule pirouette pour revenir par-dessus l'éponge mais dans une forme de pilotage automatique. Il est déjà lié à l'éponge et se dirige automatiquement vers elle, même si elle fait demi-tour et s'y accroche dès qu'il entre en contact avec elle.

(2015-02-07) [milestone][english][state machine][let-s try][spongebop][bilou][GRAB]

See you, bloggers.



J'ai beaucoup aimé les années blog, que je situeraient de 2005 à 2010. J'ai beaucoup aimé l'ambiance bon enfant de dev-fr jusqu'à ce que l'engouement pour les iPhones ne le dépeuple et qu'un Androïd ne lui donne le coup de grâce. Je suivais les développement des uns et des autres via Google Reader grâce à la magie des RSS. Je laissais des commentaires et j'en recevais quelques-uns en retour. Tout celà est loin maintenant. Les blogs sont au mieux alimentés d'un "je ne suis pas mort" annuel. Au pire, leur adresse a été vampirisée par un quelconque annonceur sans scrupule. Petit message de sympathie à mes correspondants de l'époque.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjKIG7Y0KouDqNWQD5qJAx5OuuF1ZHvHcc1bqImzmscc5m16ay_gu-CJSB_ZBHsAkPHgfFIGve-QVOlRh1FqfO4i9og1u54LIVFY32xZDxAgSafZaBh3ChAcFpq1nc6cjh8KpU/s320/0xtob1.png ; 0xtob1.png

Je commence par 0xtob, à qui je dois la base du son dans mes homebrew. Je lui dois d'ailleurs toujours un rétro-portage de mon code pour les effets (vibrato, etc) dans sa nouvelle architecture... Le blog est mort. La page d'accueil lui a survécu. Le code aussi. J'aurais dû regarder de plus près à son moteur physique, peut-être ?

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivbxo1wm6wVy2PNkBd-6gqrMhyphenhyphen4MoY9bEhwifkRkwVACat0OQcG5dVLwQedKs3PTOR7CEYDigUauRqkRD_MGpG9RFO96IZPaPZ1961_jMVvvixpInxE8gBl_5Ai_Qe4xLBOsns/s320/squidi.png ; squidi.png

Il n'y avait pas que des homebrew dans mes flux RSS, mais aussi les nouvelles idées très chouette de règles de jeu. Il s'était fixé l'objectif de 300 règles, il est arrivé au résultat très honorable de 160. Bien mieux que le catalogue des Jeux Vidéos Obsolètes.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3tHb0mEQbWCEjJ2XkjCnyghThTvEeadOm461YGMvow1YBLNg5SMKU-SodE9CW2DdThxk12-HvTtNYjVUFNf3QRSW8o7VZVSWtTI-efUenldTkVZjvndvHmoBBoW3BshMAG_Kk/s320/sverx.png ; sverx.png


Les petits jeux de Sverx étaient bien agréables. Ses conseils de baroudeur des consoles Nintendo Précieux. Il est maintenant passé à une bibliothèque pour la Master System de SEGA. Github semble être suffisant par rapport à un blog puisqu'il n'y met plus qu'un bonjour par an.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7QlCU7F4f9JWDnm423TWc9ISayB5saOej-r1pQusu7cK35xEJMrDVPHAeJW29Cn4_WR8j4lCjDlvy5Umq7f1ScSL6i4sKAHvGFCDHXCiqjeFsr3Ix7eObhM8HglgKLoOJyPNN/s200/mia.png ; mia.png
J'adorais les mini-jeux de Mia. Lui a continué à blogger de temps en temps, et son blog est toujours actif. Comme de nombreux homebrewers' Mia est passé au jeux Androïd, mais malheureusement avec de "simples" jeux de cartes. Peut-être celà représente-t'il un vieux challenge à vaincre pour lui ?


Oh ... et pendant ce temps-là, Zalo nous sort quelques tutoriels 3DS et une reprise de Jumping Jack sur son blog ^_^
(2015-07-21) [milestone][android][reading][homebrew][guest star][dev-fr]

Emunit-testing

I am stuck with bugs in the two approaches I planned to use to allow shop-for-bonus in-between levels. Kind of bugs that are difficult to track with regular debugging, and that may even crash the emulator or the debugger itself.

http://problemkaputt.de/gbatek.htmSo it's time for me to start doing more professional testing on my code base, dropping rendering and things alike so that I have more control on memor allocation and objects lifecycle. For that I need that access to NDS registers can still be performed although it will be a regular x86 program running under linux. I thought I could use a custom linker map to force the declaration of a regular area where the registers are expected, which you use with -T linker-script-file. But being sure that all of C++ sections will remain in place might be harder than creating a custom layout for an operating system kernel.

http://sourceforge.net/p/dsgametools/hg/ci/c3d54a0c1b14173735513f8227cdd2f8f93d6645/Hopefully, the memory map is somewhat compatible with the default locations for a 32-bit linux process. A few mmap calls and I can have valid read/write memory mapped at the place where NDS registers are expected. That should be all I need.

I will need to track what memory area are still alive after the end of a level, to know whether some could still reference dead objects and lead to memory corruption. I'll need too, to know who allocated such block so that I can understand their nature and purpose. I remember of Tim Robinson explaining how he embedded a call trace leading to *alloc. I'll try and do the same. It's not quite completely working at the moment.
(2015-12-13) [coding][allocation][milestone][unit test]

100 bytes for a level

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmd8Xx6WaVL6tsyTa0cBq4nMWuCiLMSBqKSkOTehXtbk1tiz61uke8dBI4BvPebNA2iE5I_8vI-3IyKl7qY0cRuKj8jTfTF6YYYPAmn0rCpsMXLHVyo8gm6fnQullfjdGzLxEM/s320/SMB-opcodes.png ; SMB-opcodes.pngIl m'aura fallu me promener dans le code désassemblé de Super Mario Bros 1 pour finir par y croire. Oui, sur cette cartouche de 40KB, les niveaux sont extrêmement compacts. Oui, la technique pour en faire le rendu est à la base de ce que j'avais observé avec l'éditeur pour NSMB: bien que le hardware travaille avec des "tiles", le niveau est décrit par une série de commandes (un byte de coordonnées, un byte indiquant le type de commande et éventuellement une taille). On aura ainsi des "un tuyau de 3 blocs de haut" puis "une rangée de 5 briques" et "un escalier de hauteur 3". Voire même "un trou dans le sol de largeur 4". Pas de "patterns extensibles" derrière ces codes, mais directement du code assembleur! Les buissons, nuages, le sol sont eux décrits sur une autre couche qui est utilisée en premier lieu pour remplir la zone mémoire sur laquelle le niveau sera ensuite dessiné.




L'équipe RD4 aura profité au maximum du fait que le jeu ne fait pas marche arrière: le niveau est encodé écran par écran, et les coordonnées des objets sont données à l'intérieur de l'écran en cours. Un marqueur est ajouté aux objets qui se trouvent sur un nouvel écran par rapport à leur prédécesseur. (I AM ERROR) Il faudra attendre que SMB3 embarque une RAM additionnelle dans sa cartouche pour que le jeu puisse se souvenir des blocs déjà cassés et des pièces collectées, rendant ainsi possible une navigation plus libre dans le niveau (/I AM ERROR).
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgler9Ple1zwk4Y-Jt7eDzQO5YlPYq6U6LMjhrT1TTK-dKCrN8Qj6Um2M2cOdRiadlznBmFs8nUtGUoOKOe5tFmXLWPeW2nhepKAQn8kYJKsqPT6Oq4A_JJjWyFKW5JAeTZlvts/s320/SMB-objects.png ; SMB-objects.pngUn monde de différence, donc, avec le stockage brutal d'un tableau de MxN éléments que j'utilise dans LEDS (avec des niveaux de 32 ou 64KB. Plus gros que l'entièreté du jeu SMB1, donc), mais qui me permet en contre-partie une souplesse totale pour que les livres ne soient pas tous exactement les même. Allez, apparemment, une simple compression .zip pourrait réduire les niveaux à une taille d'environ 8KB.
(2016-01-10) [tiled][mario][asm][NES][level data]

Nathan Am Error

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXOVyqn0oRNO4xXSI1nIbHD3rFqjV6DFsC8nN_sKRRofdhqErj4jWV3g-fG298fCKm-lx9FwMkX2xji515M1Z7sBh6c13L2X-Im_yUmidy817TMVM4opKcRTdz8N4N15QG2ctN7x9MH8m-XCd4HSCU9bl4POt_kO71ihlqbF79TLno4eHtULnjrA/s320/Screenshot%202024-08-31%20at%2018-09-51%20CbCe2hyXIAE5IGY.jpg%20(JPEG%20Image%201200%20%C3%97%201200%20pixels)%20%E2%80%94%20Scaled%20(50%25).png ; Screenshot_02024-08-31_0at_018-09-51_0CbCe2hyXIAE5IGY.jpg_0(JPEG_0Image_01200_0_3_7_01200_0pixels)_0_2_0_4_0Scaled_0(50_5).png



Quelque-part entre les chroniques de la saga Zelda et "la révolution playstation", je vais bientôt ranger un outsider: "I AM ERROR" par Nathan Altice. Outsider parce que ce livre-ci a été pensé comme un ouvrage de référence universitaire par un expert d'une faculté "arts & culture" qui va étudier en détail en quoi les limites de la NES ont influencé les gens qui ont créé dessus, leurs oeuvres et les gens qui ont découverts leurs oeuvres, un peu comme on pourrait écrire un livre sur la technique des pigments dans les peintures de la renaissance et l'impact que le changement de matériel pour les pinceaux a eu sur l'oeuvre de Léonard de Vinci. Ici, bien sûr, il sera plutôt question du nombre de couleurs et de tiles, des possibilités de scrolling puis des puces et astuces que les développeurs de jeu et de chez Nintendo ont utilisé pour faire des histoires toujours plus grandes, dans des environnements toujours plus vastes .


En découvrant les maps des jeux Capcom sur NES, j'avais déjà supposé que la console imposait le choix du sens de scrolling: horizontal ou vertical. J'étais loin d'imaginer que pour faire un jeu tel que Megaman qui alterne phase horizontale sur phase verticale, il aura fallu bricoler les cartouches et leur rajouter une puce de contrôle, parce que Super Mario Bros, par exemple, a soudé le choix d'un scrolling horizontal. Toutes ces puces -- les "mappers" -- sont bien plus fréquentes que le SuperFX de la superNES, mais pourtant il n'en a presque jamais fait mention. C'est un détail pour le joueur, presqu'un secret de fabrication. Un secret peu avouable pour les développeurs qui avaient au départ misé sur le "famicom disk system" qui remplaçait la ROM graphique de la cartouche par une RAM remplie à partir du contenu d'une diskette. Pourtant, c'est bien en ajoutant une puce de RAM que Super Mario 3 est capable de retenir quels blocs ont été cassés (la NES n'ayant que 2KB!, à peine de quoi retenir le contenu de 8 écrans).
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhy2tRcGgVGWjxOKUqtS-fo7kps4IpYXgw5LJoQ7A1NvyLq_Ou_NIPcKWSFloIz-6XzfehsICdSimZeWXDI3PywH432EQ1IL7IckpW5QB_O6YlD3bhzoO9Wzhkg05Y7uTIkaF68/s320/IMG_0987.JPG ; IMG_0987.JPG

Ce n'est qu'à travers ce genre de ruse -- pagination pour passer de l'overworld de Zelda à un des donjons, copie à la volée de sprites présents dans la ROM-programme vers la nouvelle RAM auquel le processeur graphique (PPU) a accès -- que les développeurs NES vont pouvoir faire mieux et plus riche que Super Mario Bros, qui saturait déjà les 16KB de mémoire que le PPU sait utiliser. Ici aussi, j'avais soupçonné ce genre de technique en voyant tourner SMB3 dans Nesticle, mais j'étais loin de me douter de la diversité des approches, des subtilités ajoutant des nouveaux systèmes d'interruptions sur une ligne précise de l'écran (devenue partie intégrante des designs de Nintendo depuis la SNES) ou l'intégration d'une puce sonore additionnelle que la NES utilisera comme elle aurait utilisé "l'entrée micro" du 2eme contrôleur de la Famicom.
En revanche, "comment on fait tenir un niveau sur 100 bytes" restera une curiosité dans ce livre. Dommage pour moi. Heureusement - j'imagine - pour la majorité des étudiants qui commandent le livre sur MIT Press...

(2016-04-21) [reading][y98][tiled][NES][hardware]

Costumes, folks.

https://www.youtube.com/watch?v=xI3xZAn7r2AJe vais appeler "costume" un ensemble alternatif d'animations pour un personnage qui ne change pas fondamentalement le comportement du personnage. Ce sera le cas par exemple de Mario quand il grandit. Bien sûr, mario-grand est capable de faire des choses que petit-mario ne sait pas faire, mais les animations modifiées vont bien au-delà des nouveaux mouvements. Devenir Mario-tanooki, c'est enfiler un costume. Devenir Mario-feu ou Mario-Marteaux aussi. Devenir Mario-Grenouille (SMB3) change fondamentalement l'ensemble des mouvements du personnage, la physique des déplacements et ne peut clairement pas être assimilé à un costume comme défini plus haut.


https://www.youtube.com/watch?v=xI3xZAn7r2ALa question qui se pose pour le développement de Bilou est de choisir le bon moyen de réaliser ce changement d'apparence. Vu la complexité de la machine d'état, plus franchement question de doubler l'entièreté des états pour tenir compte de la disponibilité ou non d'un power-up.
Dans certains cas, un simple changement de contenu de RAM grahique suffit. C'est plus ou moins le cas de SMB3: en utilisant son "mapper" pour remplacer la page de ROM présente, les dessins de Mario petit disparaissent et ceux de Mario grand prennent leur place. A part modifier le visage de Bilou, cette technique ne me permet pas vraiment de changer d'animation parce que moi, je fais de l'animation modulaire: la mémoire vidéo ne contient donc pas d'étapes d'animations mais uniquement des fragments d'image génériques.


La version plus facile, héritée de la NES et de ses palettes séparées, c'est de changer le jeu de couleurs du personnage (demandez donc à Mega-Man, il en sait quelque-chose). Une approche que je mets de côté pour Bilou: ses couleurs font bien trop partie de son identité.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyVbs3jEJM_m_xfrZrv-6_o15Ntyc17Rrp7SrT1CGxiQ2azWMXKsR7ZDXEZPKmSun38t4e1YZvbOEMChWfA_dJiOV2cs7V1opN66P7ucFJkjO0-MIIhlwoosveA0XZexVtnJoq/s1600/thSonic---Sheild.gif ; thSonic---Sheild.gifAutre alternative possible, on se la joue Sonic et son espèce de bouclier transparent. Ici, le sprite de base et toutes ses animations restent inchangées: il suffit de faire suivre Sonic par un sprite supplémentaire suffisamment creux pour qu'on voie encore le personnage par-dessous. Jouable pour Bilou aussi, j'imagine.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnUoduO6Y_oDx82vZGUhZvt0xTX2cA4lPMeGmTnxIRQeOAQwzGho-PZFhKacrWrKs1K5H-01hCyRwTrUUUverlWJVvfHDM3vZLNR2wS5tFEZ6Z-pVM43ssFziW7QxHijdxQPPr/s1600/willpunch.gif ; willpunch.gifJe choisis un système moins rétro mais mieux adapté à mon moteur de jeu: j'introduis des sections conditionnelles dans les animations elles-même. L'idée est d'éviter de devoir modifier les infos liés à l'état -- il continue à ne connaître qu'une seule animation -- mais de profiter du fait que j'ai déjà des instructions type RISC pour les animations (déplacer tel OAM, changer l'image utilisée par tel autre, etc.). Du coup, il est assez facile d'ajouter une "instruction d'animation" qui est en réalité un saut conditionnel dans la séquence, sur base d'un des compteurs de bonus ou d'une des variables internes du personnage. Reste à construire la séquence correctement. Ça, ce sera le rôle du lecteur de scripts. Les animations elles -- et leur éditeur -- restent totalement inchangés. On se contente au moment du parsing de construire quelque-chose de plus complexe comme "if [compteur%] animA else animB".  C'est encore insuffisant pour émuler SMB3 (au niveau script, je veux dire), mais ça devrait faire l'affaire pour Bilou.



https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioW81Y9biVUhIoQwV0UFKAb-KNwcaAToxm_OKIthzAJXsP9d80TKR3oqZbuY2fIV86S2Cuc7Z9t1iRrinZ1_mUISrHzHzZiXmhlz_GYxdLrREFths1qCSpoh1lTx0c-11iR8Un/s1600/Marios.png ; Marios.png
Enfin ... le ROM mapping de SMB3 est peut-être un peu plus compliqué que ça. On voit sur la vidéo de Bisqwit qu'une seule "page" de 256x16 pixels est utilisée à la fois pour Mario, or il y en a 4 différentes par "costume" de Mario. Selon l'action en cours (marcher: +0, courir et tenir une carapace +2, voler +3), la page choisie est différente.


(2016-04-24) [PUNCH][superpowers][milestone][state machine][mario][rush][animation]

Its all sketched in the book!

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsIZ4BtAGdZFjaMEjPVwgCgITA9JCyg5zKwXPmAEDIipcYswe8Yq9fqEX2kasYPZ-SGMuk5ty3crQ5C_8HZQ2Nt2BD1sxUpmy7lJSXTNoc5rNuNcmktuuJ9c6obNY1Ptm0BJet/s320/messedup.png ; messedup.png
early bugs to be caught.




N'allez pas vous imaginer que j'utilise une autre excuse-de-BMX pour ne pas fignoler School Rush! J'attendais juste un moment un peu plus calme où je ne serais pas occupé à faire des trous dans les murs. C'est tout. Et nous y voilà justement, avec un sympathique changement d'illustrations pour guider le joueur dans son aventure et le renseigner rapidement sur les mouvements possibles.
(2016-05-05) [coding][PUNCH][FLOAT][milestone][rush][user interface]

Augmentons la Gravité ?

J'ai eu l'honneur (et un peu la chance, il faut l'avouer) d'avoir un retour de Romain Claude -- dévelopeur principal de Splashers sur mon School Rush. Un feedback assez technique et qui ne sera pas facile à prendre en compte, parce qu'on s'attaque ici au coeur du gameplay.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmVckjTWwOXYur_5aT3qiisUHRA4B1t8TqL-Qh53I3uBMOCf8E-vgn7AKCyT0MxQ0HfwEHqzzdtt6wQZz7KUpE4qTAYsdaw5rUtbClJkb-CHwIlyw1grrC_WxI6m19NcByR2Ht/s200/clauclaudr_400x400.jpg ; clauclaudr_400x400.jpgMon principal retour pour le moment concerne la prise en main, que je trouve assez raide. De plus, le fait que le jeu soit assez mou rend le tout assez hardcore, même en facile ... Côté contrôles vous devriez avoir un air control progressif (de moins souple à beaucoup plus souple), et ceci marié à une gravité plus forte rendra la prise en main plus réactive et agréable. Par contre pour retrouver la même hauteur de saut il faudra augmenter la valeur de l'impulsion.




https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGv9NUtwYtR-qDk70pVT9FpXciCnV6ZDBkDtnjuxvjtGBL9kUMvPPKicH9U0qQ7fb3eiLK_ssyUbK7NOjhysXxofG60-PPezpuY5tZ3M_mA5wXrq8aK8hyphenhyphen9_JV0KrpkXAEtTAW/s320/C9uTXJVXUAEpBqj.jpg ; C9uTXJVXUAEpBqj.jpgMais changer la gravité, c'est changer beaucoup de chose. En plus d'ajuster la puissance de l'impulsion, je dois aussi ajuster la vitesse de déplacement de Bilou puisque le temps qu'il passe en l'air, lui a été réduit. Sans celà, il faudrait revoir tous les obstacles du jeu.
En fait, une fois tous les paramètres dépendants de la gravité réajustés, on a le même jeu mais avec le temps accéléré. Ce n'est pas déplaisant, mais ça va demander aux joueurs d'être plus alerte, parce que du coup, je vais devoir aussi augmenter la vitesse de l'encre sans ça elle est complètement à la traine. Peut-être devrai-je aussi accélérer les pendats...
By increasing the walking and the jumping speed of Bilou with the appropriate factor, I can keep the levels unchanged and enjoy a more engaging gameplay. I'll have to speed up the rise of the ink: at the moment, the game has turned too easy and I might also have to speed up pendats, so that Bilou don't outrun them too easily, which will shrink the response time allowed to the player (to 86% of the current value for g'/g=4/3) ... but it still leaves 500ms+ to react, so that should work.
http://critical-gaming.squarespace.com/blog/2011/1/5/super-meat-boy-pt1.html
J'essaierai celà dit d'éviter "l'effet Meat Boy" si je le peux, à savoir d'avoir le contrôle en l'air tellement élevé que l'on finit par "glisser" dans l'air et se déplacer plus vite horizontalement que verticalement. Mais en ajustant la vitesse horizontale maximale, il devrait y avoir moyen d'éviter ça.



This happens in Super Meat Boy too, with a character that initially struggles to work against its original impulse, but that gets increasing amplitude as you maintain the joystick pushed into one direction. To be honest, Super Meat Boy isn't one of my reference in terms of gameplay. I would even consider it as a counter-example of convincing physics

Dans le "School Rush" actuel, j'ai un système qui encourage le joueur à prendre le temps de courir avant de sauter: une fois en l'air, on peut ralentir et faire demi-tour (Bilou reste tout de même un explorateur de l'espace, ça offre quelques mouvements inaccessibles aux simples humains), mais on ne pourra jamais atteindre à nouveau la vitesse maximale avant d'avoir touché le sol pour courir à nouveau.
Ma première tentative pour m'approcher du "contrôle de plus en plus souple" (que je traduis par "augmentation linéaire de l'accélération horizontale avec le temps passé en l'air") consistait simplement à autoriser une vitesse horizontale plus grande en phase descendante par rapport à la phase ascendante. Mais ça, ça n'a pas été un succès.
(2017-04-19) [feedback][milestone][mechanics][let-s try][JUMP][rush][gameplay]

Les autres pentes

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSVXUC9-NbzXCntjWfpSEoExh-RKbxVuQYOyLz6qbNhyZYljk233aK3b8ZsNBcM-o4dI5hkc3lJqcNdvCmj69Se51-1BOviEkVkIsYKtiFb8VrG69IVshoU5V_xNN_flfe5MRJ/s320/slopesWCM0072.png ; slopesWCM0072.png
Du point de vue du moteur de jeu, un niveau est avant tout une grille dont chaque case reçoit des propriétés: solide, solide uniquement quand on tombe, pente, spécial, etc.


Les "blocs spéciaux" ne sont pas compris par le moteur de jeu lui-même (d'où leur caractère "spécial") mais décrits dans les scripts qui définissent les règles du jeu.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTAl6TF8twdsisRRkGr5y3HSMyG91TZAbunvoSmfpvp4af69YLt83bxkEbebqWlIibPbIRxX-FHXAZb5x6A53VP0Cvi1X_ZYajScIIqZzpf3D8vZLu2hT3SF0270_14GeQ4Cpf/s200/special-now.png ; special-now.pngAinsi, quand Bilou touche par exemple un Bonus, le moteur de jeu récupère quelques bits d'information pour chaque pavé (8x8) de la grille constituant le bloc (16x16) et reconstruit un numéro de bloc spécial (de 0 à 255) qui permettra de retrouver les instructions à exécuter (faire un son, déclencher une animation, donner des points, etc.)


https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxXVOqi4yEG7M4MhqmpKE5krFjRkthrFcEpnE5HIAEyPKVVmeG2r0fDhpZVZEhi7O5Ub3Dj3cnGfWI2Gsy1MeLpH2RgNqPtwdytX0sEbXJfcCoj7Nhc6j5c47xVTDniOG2R1WS/s320/slopes-now.png ; slopes-now.pngQuand Bilou touche une pente, en revanche, le moteur de jeu sait qu'il doit aller regarder une petite table indiquant la hauteur de chaque pixel de la pente. A priori, la forme de cette pente pourrait être n'importe quoi. Mon éditeur de niveau connaît les pentes à 45° et à 22.5°

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNoKnP1ISlAcRmhCRV37kQNXY0_bUmCh94UeqhM_9cFr2ILl6reSRlhskmA32zEXPuGdU1s9Slb9cng6QlMJyNmyoqajqhgM86y4Zf6qY-UnfcnrudvEPz-8JbjBUHWAA6qB9y/s320/slopeWCM0068-problem.png ; slopeWCM0068-problem.pngMais voilà: j'aimerais pouvoir avoir plus de souplesse: des escaliers, des coudes, par exemple. Un petit schéma de rien du tout qui traîne depuis des années (2010?) sur un bloc de brouillon en atteste.
"Le mieux serait d'avoir deux boutons 'pente' [dans l'éditeur de sprites] qui forcent le remplissage d'une ligne de 64x16 pixels avec des pentes suivies (les modèles)"
 ajoute encore le calepin.


En effet, la technique que j'envisageais alors consistait à utiliser comme information supplémentaire la position du graphisme au sein d'une ligne de blocs dans l'éditeur de niveau (une "tranche" de 16 pavés de 8x8 successifs). On pourra alors convertir l'information de la grille "pente compliquée vers la droite" en "transition douce de 0° à 22°" parce qu'on est dans le 6eme pavé sur une tranche de 16.
Sur les dernières années, ça n'a jamais été mis en service et mes derniers tours d'horizon dans le code de l'éditeur de Sprites me confirme que travailler "par tranche de 16 pavés" serait un vrai casse-tête (le mode et le moment de l'allocation des pavés dans la mémoire vidéo n'étant absolument pas prévu pour ça).
Et cet été vient une idée qui jette un autre éclairage sur ce problème: "Les pentes douces, c'est un problème pour l'éditeur de niveaux. Ce n'est pas quelque-chose à régler dans l'éditeur graphique.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTbTslGjv-0_BcvUMopzNf3gxd1XIZWHBKkrDJUb96ta2ro8YVIiVMIlGjn7a7eealvJgXwovUaE1MGywuq47lIdWZgEC0NC2j1mPOjojHKflQ7l-1_-BNGlu0tt3pXTVlivdU/s320/slopeWCM0068-idea.png ; slopeWCM0068-idea.pngEt l'éditeur de niveau sait par contre traiter des groupes de chiffres pour montrer qu'un bloc spécial est soit un bonus, soit des pics, etc. En prenant donc un type de pavé qui dit "pente compliquée, regardez les chiffres en-dessous pour en savoir plus", je peux diriger le moteur de jeu vers une autre table de hauteurs qui définit la pente (parmi 16 pentes possibles), mais aussi éventuellement fixer le coefficient de friction (sol dur, glissant, boue-qui-ralentit, etc.)


Il me tarde d'essayer ça ^_^




(2017-08-19) [tiled][MyEngine][special block][slopes]

power-button bug

On the game design axis, I am quite satisfied with the final level of school Rush and how it integrates with the earlier levels. It took A. (from the S-Team) Some 30 attempts to beat it, but she hasn't turned mad or bored, and even enjoyed being wrapped to level 1 afterwards.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhda_dqmrIVrLAmqrbI2SFwTY5jHHeI5lYYSC6n5LIVsIEObllOPqVjFJSJD9ws52ga_44Lyt8PeJtoeuoxiIh-uYmOZ9jqQ_fVagzUFH296P_ZARxlmOti4P5kgvFlE5Vc1Tu/s1600/bugDOOCV2bWAAAFJKV.jpg ; bugDOOCV2bWAAAFJKV.jpgOn the technical side, my latest personal tests hit me with a bug I thought I fixed long time ago: getting stuck in a ceiling, There are few places where this can happen in the game, but if it happens, you will remain stuck, possibly forever unless you use the power button to trash all your progress and reboot. Would a player feel like starting the game again in such conditions? I don't think so.
 
The thing is, the basis pretty hard to track, a bit tedious to reproduce and all my attempts to fix it have failed ... so far.

What I truly need is a tool that will allow me to identify the sequence of state transitions that led to the offending state when I finally manage to reproduce it. Another debugging tool that would complement Inspector widget for cases that cannot be solved by single-stepping on setting breakpoints.

edit: let's stop rambling, let's start cracking ...

Bug is tedious to reproduce

Then let's make it easier to reproduce. Let's have e.g. a build of the game with much more lives, more hitpoints if needed, that drop you in a place where it is easy to try reproducing the bug. Let's go to that level with the DS, too, and try to get into the wall in as many ways as possible (runMe is neat for that because it let me launch any level), to get a better understanding of the conditions that make it happen.

Moreover, we're running on an emulator, here. And emulator typically have a free save-state mechanism. I'm unsure whether it works flawlessly with desmume, but it's worth giving it a try.


https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx3G81KKyN6bwCbWFCjOaycI4xaM9ARuo3b-imfCcAFeU91rtsgSOdkrb8kiOcV7MF2CIB4is1Pe_YrMKQrvDDnLugyAR8TJCFo1fPYt0EGCQU1-TSRglEtWbKmCTyzSz9-OFu/s1600/bug3-cr.gif ; bug3-cr.gifBug is hard to track

Then let's make our best to get as much information as we can from a succesful run.

Granted, the ideal would be to have a curve plotted, annotated with state changes, in readable colors and where I could get any set of gob variable at any time by just pointing at a spot on the curve. But we don't have that. Granted, last time I had to use both ddd breakpoints and Inspector widget, but that doesn't mean I cannot do better this time.

So the ideal would be a time machine that let me replay things if I ever manage to produce the bug, and view what happened in slow motion, eh ? Wait ... that tool exists already. That tool is ... recording game + Inspector widget as an animation and replaying it!
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZDDZlqcJlJTjqkYRZM6OD7nlpWrqBh35dS7o1rNmkVpXrPxvtXGZcVfMadt5NfDZTUqJILBNZw5CxLv99c7hvUxxZOFCUg14Yy_N5x6Xr0hiSqzdb2771PIQJNX4fzYzxkiva/s320/hitIMG_20171118_104446_402.jpg ; hitIMG_20171118_104446_402.jpg

Bug couldn't be fixed so far.

I thought I knew what happened by looking at the code that makes Verso bounce, because I know I had to fix the problem for Verso (the bouncing eraser). And the solution was to detect the impact's vertical speed to tell ceilings apart from floors, and prevent the 'fail [assuming on the ground]' from happening when what really happened was 'fail [on the ceiling]'.

So after I located something similar with the "HIT" state of Bilou, I thought I got rid of the problem. But since I don't have well-isolated test cases for the state machine (yet), seeing the bug again doesn't mean that the fix wasn't effective: simply that it might not be an isolated case.

To be continued ...
(2017-11-18) [guru meditation][tiled][rectoverso][done]

MMU9 write32 to undefined register 04001058h

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaXGwdq32wVPjH_PSjyrHieBkphuoJBCH2hSVQPNS3KemcZGzX0a-kD51fjBzDmw2siLA9BXqsvdgFStxqsYCepqzS33Be4mTKf_GcfBqaaFSjl3YTvMdMRtLeOyM77gGoibm1/s1600/baredebug.png ; baredebug.png


InspectorWidget est en vacances, iprintf en arrêt maladie, ddd fait la grève du code optimisé, Qui reste-t'il pour sauver la journée ? Qui, sinon 0xbadb07 !
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIXeddjkT84er5p1BU3tISO56B6sb4nj85zhybZNCTs7vb0u88rfWBX1Z4Rx6pQoIhgQ26mtP_iRD6cVVP1WxBBlgLndpDPYCd4rYlEc1Mm-5Eb0MjdjvrtX6P7hURQbxdKq3e/s320/bareterm.png ; bareterm.png
Ouaip, y'a une adresse-mémoire qui provoque un message sur le terminal quand l'émulateur la rencontre, avec la valeur posant problème, et même l'emplacement dans le programme. Alors j'ai rajouté comme un malpropre des accès direct à cette adresse pour envoyer un diagnostic d'erreur à travers le subespace de l'émulateur. Du coup, je peux corriger mon code. Ciao.

(2017-11-27) [guru meditation][tiled][done]

cando grow?



Corriger le problème dans la machine d'état de Bilou pour lui éviter de se manger le plafond se révèle plus compliqué que prévu. Et pour cause: le bug n'est pas dans la machine d'états. Du point de vue du moteur de jeu, Bilou a deux tailles (de bounding box) différentes, et l'état "touché" est un des états où Bilou est grand. Du coup, puisqu'on peut se faire toucher dans à peu près tous les états, il n'est pas vraiment possible d'éviter un changement de taille par une transition conditionnelle.
Il faut donc que je révise plus en profondeur le système de changement de taille (setbbox). Heureusement 1) je peux traiter les axes horizontal et vertical séparément; 2) je peux me servir du système "cando()" pour sonder le terrain avant de procéder au déplacement. 3) si je sais corriger jusqu'à la prochaine frontière de tile, je peux itérer pour étendre à des redimensionnement plus conséquents (à vérifier plus tard).
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj98bLk4NHFrInKrECmkToJ2gcj4mHPvwx-cs-JssGt6sxTL3reXga9lTwlQzO1T7pewn7ocbPEI_aut4Kj8ZpmzNMOQzmea7jBOaRbrnzw0htO-UUubfrlYyxAqpLED_jRi78z/s320/cangrow1.png ; cangrow1.png


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


fix
(2017-12-03) [coding][tiled][sidescroller][collisions]

Refactoring de dingue!

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ-aXAjaZHeOSm-Gp_vhueOP3KSmM0SPewdc7RllL6xx_UCZiH5njaTI_EgeQzl6Qrd5Cw6ox-lI9k9ZApxgXG6MrQ9GEobnI8DFryxUIeyv_qobFBvy-gElvny6pu0z3_y-gS/s320/21.png ; 21.pngJ'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é.


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.

(2017-12-19) [coding][cxx][scrolling][tiled][refactoring][uml]

whipseey

https://i.imgur.com/Iif7G8a.gif ; Iif7G8a.gif A lovely setting, charming character, platforming action in pixel art, and above all, a "whip/ninja rope" mechanics I'm in love with since Fury of the Furries and Mickey Magical Quest. You bet I'm following @whipseey in his quest recovering the Lost Atlas ^_^. And the fact it is drawing inspiration from the legendary Mr. Gimmick is just the perfect spice to complete the gift.

Yet, while watching I realised that one of the sceneries had an issue that also existed in Bilou School Rush and that was pointed out by Kirby Kid when he gave feedback on the early version of the game: one-block-wide pillars.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwXbRLLMDILwhk4vh0T26Nts2fuLWZAsqMNTPeVAM0dRqEjOhFWjzXdb8S8LoDPPuG9Bw-Pk3EwB_SO-yZAD-FQggr187Rx1WdW41BT89KPdoFSY5q6K-XkMvKSvTHXwk1wtLR/s200/kk-r_6ZSNj-_400x400.jpg ; kk-r_6ZSNj-_400x400.jpg
You have a lot of "one block wide" or "character width wide" platforms. I find this irritating. They put a lot of stress on the mechanics and they also slow down the gameplay a lot. Open the platform spaces up some more.

 For the untrained player, these will put strong stress on the player's knowledge of the game engine's intimacy, like how much exactly gravity and momentum there is, so that one can land her favourite pink avatar on such a tiny spot.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikouxJFbBP4jFB8SBPXaMasIun_7axp9MbaSuYSDnEqJIPm0nQrIxLFXditK8fd7sdrCarbf_c4hF4BCe0PSraJRznFAlcvVfKLz4kUXqHitan-K2aokmAUz095iGhqe-rTwxW/s320/SCAN0022.png ; SCAN0022.png
One think I like to do on Twitter is to dream how I'd approach those short video  sequences myself. Preferably in the original character's abilities set, a bit like how Myamoto and his team decided to make Popeye be able to jump over barrels in the early prototypes of Donkey Kong as it was the most natural thing to do if it wasn't a videogame.

And what would be the most natural thing to do if you barely missed a jump to a pillar while carrying a magical yoyo/whip/rope thing ? Well I bet I'd try to wrap the rope around the pillar to be safe again.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwo7D6P2LHIvpF6MvlAGgxmc8WSuSH-Bws2sfYySbSbl_d6d21jYmq5LVFIMtvCUgU17Og35F5DTuIf_kvE4sSHvs3XNEfi92lSD9bKpcB1X7IUkcGILcxK2RG51LCNdrQSemQ/s320/SCAN0023.png ; SCAN0023.pngThat in turn raised the question of "how would I do such a thing for Bilou in my own engine?"  Should the 'whip' be an extension of the player's gob (that is, the internal software element ruling the sprite's behaviour) or be a gob of its own ? Should the pillar be made of special tiles or would the whip-end object (if any) be able to detect a pattern of solid-but-small-enough area ? Both approaches would be valid in each question, but as you may have guessed from the way I ask (or read in the sketches), I'd rather opt for the second answers if I was immediately ready to introduce that ;-)




(2018-07-13) [indie][game][tiled][HOOK][ROPE]

1-ups... At last.



Enfin! Ça vaut enfin la peine de faire la collecte des lettres dans "School Rush". Rien que du très conventionnel, j'en ai peur (on prend une vie supplémentaire), mais bon, vu la difficulté du dernier niveau, quelques vies supplémentaires ne seront sans doute pas de refus. Mais cela ne s'est pas fait sans de nouveaux outils.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_NOex8SLSeXz52xlP9Qe9TyiPNC7XAHHEZUlX3jTcxfS4UOBCtlRK2GVy5-JSgUSnIIMgF4gIMsn6D9M9tA-da4DGom0yb1BwUpMuTPuZUO2ALXVrEwv2CFokb85LnNB7asyj/s320/1up.png ; 1up.png

Les vies, les points de vie, les objets à récolter, tout cela est géré à travers des compteurs dans mon moteur de jeu. Normalement, on ne sait definir la valeur d'un compteur qu'au chargement du niveau. Durant le niveau, en revanche, on ne sait qu'augmenter ou diminuer la valeur petit à petit.
Le gros intérêt de ces compteurs, c'est qu'on peut forcer l'exécution d'une action lorsqu'ils arrivent à zéro. Comme redémarrer le niveau, changer la musique ou, faire apparaître un nouvel objet. Mais idéalement, ici, il faut surtout augmenter un autre compteur (les vies) et reprogrammer pe compteur arrivé à échéance (le nombre de lettres avant la prochaine vie). Bref, ce sera le rôle de l'action "setcounters", fraîchement ajoutée à la panoplie du parfait programmeur de GobScript.
(2018-08-30) [coding][milestone][COLLECT][rush]

Retro-game mechanics explain: golden!



C'est du tout bon. Une vraie pépite. Une fois encore, "retro-game mechanics explained" confirme que même quand on a pas l'intention de pratiquer le speed-run intensif, les découvertes des speedrunners sont une mine d'or pour qui s'intéresse aux techniques de programmation utilisées par les anciens de l'ère 8/16-bit. Et cette fois, c'est Super Mario world qui s'y colle.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYnGEieGaquo_P6mfXE-IoyMne_elTXbZGFkeg_y_KL9I3sw4eCORIKJDrTRhxFs4yg5opT3arbMLgp0UXGZ09NMBLRmOWq2M-YC-WubtByiG42G-8wJTM9RBsUdzM4NI00l3H/s200/smw-blocks1.png ; smw-blocks1.png


Si vous avez déjà un peu cogité la manière dont les consoles nintendo construisaient leurs images à base de mosaïques de "tiles" et des "sprites" par-dessus, vous aurez aussi deviné que pour faire sursauter un bloc-question quand on le touche, il faut effacer le bloc de décor (à base de tiles, donc) et le remplacer par un graphisme librement positionnable (un sprite) le temps de son sursaut, puis remettre à nouveau des tiles pour le bloc transformé. C'est sympa d'en avoir une confirmation depuis l'analyse du code (et oui, j'ajouterai ça dans ma todoux-liste un de ces quatres).

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX41sT6KEASGiLpnj6NrfmLHOU_VPm_MmEOMJAzEZqtUMFk5Hm-3iBEC4uVCjG6CB70081bIF9uH6_MTVW7Vm21F8tjzjgcuW5fKvu6zgxRG16XfZVnBQnDJlQRIBO3hr9cGTK/s200/smw-blocks2.png ; smw-blocks2.pngWhich tile is activated during sprite/tile collision is determined by a point that is a mix (blue) between the the sprite's position (green) and its clipping box (red). If that point is not within the tile that was activated [...] there will be block duplication.


Un peu plus inattendu: en plus de leur zone active -- la hitbox, en rouge sur la carapace -- qui doit rester en-dehors des zones solides du jeu, les objets ont un point unique qui sert à déterminer quel bloc a été touché. Si on cogne un bloc-question avec une carapace lancée vers le haut, c'est d'abord le carré rouge qui va renseigner qu'il y a collision puis le point bleu servira à trouver avec quoi il y a collision. Chose intéressante, tous les objets subissent le traitement "repoussé par les murs" qui autorise Mario à contourner un bloc lors d'un saut plutôt que de s'y cogner méchamment comme une Giana sister.
En revanche, le fait d'avoir mis le point-test en dehors de la zone de collision m'intrigue. Quelle est la raison ? ou est-ce juste un bug ? et cette possibilité d'avoir changé de position entre les deux opérations du test de collision (boîte et point) trahit-elle une optimisation du genre "on ne teste les blocs-question qu'une frame sur 4" ?



https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhz-k4kMMXwBXplP979l09Ur0j8SwlsJYdMfJIwhD7aHCXd63J_WRlEE0EF0W_fu17cw8qoKgklY6_xZSd9Ac996zk6UMzQH1yRc5qtCocKXcu-WHVsn7MMmlxnxNMpqm6uQsn/s1600/smw-blocks3.png ; smw-blocks3.pngIn order to reduce the number of distinct objects, some power-up blocks have different contents depending on their X coordinate on screen.


Mais il reste le plus croustillant. Le truc que explique qu'un bloc supposé contenir une clé peut tout d'un coup donner des ailes à yoshi. Visiblement, je ne suis pas le seul à avoir choisi trop peu d'information par bloc dans mon format de niveau, et pour pouvoir représenter tous les power-ups et bonus possibles dans Super Mario World, l'équipe de Myamoto a choisi d'utiliser la position du bloc au sein du niveau pour choisir quel objet serait offert au joueur. Pas la position absolue, hein, mais le fait qu'il soit sur un bloc pair, multiple de 4, impair, etc.
C'est à la fois génial et complètement déroutant. Dans un commander keen, je ne me serais jamais attendu à un truc du genre "si le bonus est au 2eme étage du building, alors c'est une glace à 2000 points. S'il est au 1er c'est un donuts à 1000 points et au 3eme un nounours à 5000". Mais ici, dans un contexte où les blocs-question sont souvents présentés alignés comme les gobelets d'un jeu de hasard, le truc prend tout son sens. Il reste à considérer le "numéro" stocké dans le niveau non plus comme un identifiant d'objet à créer mais plutôt comme l'identifiant du générateur d'objets correspondant. Au moins, ils ont évité les contraintes du genre "un niveau peut offrir soit les ailes, soit une clé, soit un ballon, mais jamais une combinaison de ceux-ci."

(2018-09-07) [tiled][collisions][mario][special block][SMW][level data]

School Zone: aftermaths



Voici 5 ans, je vous faisais un jeu-anniversaire avec Bilou dans la zone de l'école. Quelques semaines plus tard, en septembre, mes p'tits n'veux me faisaient me rendre compte qu'il me fallait quelque-chose d'autre comme niveau pour introduire les mécaniques du jeu. Ce niveau non-tutoriel est depuis devenu le premier niveau de School Rush.

Download SchoolRush - JLN build.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-wSNz5Hn5jpB2LUPWbWNWze8djEcAxWv3-_GOb3QIf1KcaEbhc_WovFmezp_cZSZdtvAN_FRuT-DHDrhcRrG000QgiLF0CHZ5TsGUt9vLPGJBGgZq8ehG9GJ7J4eZksO370dn/s1600/rush.gif ; rush.gif





Aujourd'hui, le développement de School Rush prend fin. Ce fut long, parfois fastidieux, mais je voulais l'amener jusqu'au bout. Comme dans tout jeu, il y a des choses qui ont été abandonnées en cours de route. Soit qu'elles ne convenaient pas, soit qu'elles m'écartaient du but premier du jeu... soit qu'elles promettaient de devenir un gouffre de développement rendant irréaliste toute sortie tant que je serais en solo sur le développement. Que ce jeu soit mon cadeau à tous ceux qui ont écrit du code free software que j'utilise tous les jours, les musiques que j'écoute en codant, les vidéos sympa qui m'ont donné envie de continuer. Merci à tous pour votre travail.


(2018-12-01) [download][milestone][school zone][bilou][rush][star comments]

Tile Engine Revision

Bon, j'ai une grosse révision de mon moteur de jeu en cours. Jusqu'ici, les propriétés du niveau étaient conservées dans les bits "palette" du niveau, soit 4 bits par mini-bloc de 8x8 pixels (les tiles, pour les intimes. Prononcez avec de l'aï comme dans light). Pour "School Rush" et ses niveaux de 16 écrans de large pour 1 écran de haut, on parle de 8KiB de données. Un niveau de Commander Keen (mettons la machine infernale des Shikadis) avec ses 1200x1200 pixels nécessite 22500 de ces tiles.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4jp3WqhYS1mDoCCm6Mk3AEl7CTRS6yw_JyXp95IgmCC5mjGmlqBVU0WIxETH1whaPH88lFjbea3zgvHGrj4aVVWLKLjTVEawxftXRKkSq0ENgp5qLjrR8uFOnz6tzOWfDBpNn/s320/img_20181208_090441R.jpg ; img_20181208_090441R.jpg

Pourquoi tous ces chiffres ? parce qu'au coeur de la révision, il y a le besoin de faire sortir ça des bits de palette pour pouvoir utiliser librement les changements de couleurs si utiles dans School Rush tout en permettant de nouvelles mécaniques de jeu. Jusqu'ici, j'ai pu m'en sortir avec des blocs spéciaux (bonus, pics) qui utilisaient les "codes couleurs" des 4 tiles qu'ils couvraient pour encoder un numéro suffisamment large. Mais quand on commence à réfléchir à faire de l'eau, des ventilateurs ou des tapis roulant, ce système devient bancal.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_fwLuOIbwsTq0na-l4bPG-85Hv-uKQ_-AkZxt7o_F11_2VZg-QZ_-yT6bImVrbZKRcc3iigLJFuvMcAN5qQobEW3WAUcHmGvGRRMQTNARLadcsxXtZ1wqN4_CclbXINSrdeev/s320/img_20181208_090441L.jpg ; img_20181208_090441L.jpg


En particulier, il était basé sur le fait qu'un groupe de 4 tiles sont liées par les numéros de tile (en mémoire vidéo) utilisé parce que l'éditeur de sprites fonctionne comme ça. Impossible donc de définir un bloc-bumper sur un graphisme qui serait fait d'une moitié de gomme et d'une moitié de lettre. ça, c'est plutôt un avantage. Impossible aussi de rendre une pointe de crayon blessante si elle est sur 'l'arrière-plan'.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS7-ei_XPig5AFFMFMlzSvlAooOPP_VaqE6WU516gdoi3xUmfrCgZueODpbwfV9ukIqOOpXLG7eHcr-uez12PqBI8N11im4YqKb6YigFelXW027a5vZIwOyAf7SL4uoYg2AxmJ/s320/img_20181208_090441U.jpg ; img_20181208_090441U.jpg
Faut-il donc que je continue avec ce système (données 4-bit) sachant que je travaillerai maintenant sur un tableau séparé ? Puis-je me permettre une extension à 8-bit par tile ? et si oui, comment organiser au mieux les données ? Est-ce que ça m'impose d'intégrer de la compression ?
A mon avis, avec 22Ko pour une map type "Commander Keen" et sur une bécane qui dispose de 4Mo de mémoire principale, ça reste parfaitement jouable. Oui, c'est loin des techniques de trapéziste de l'époque des consoles 16-bit, mais c'est justement une des raison de choisir la DS à mes yeux: elle permet de se concentrer sur le jeu lui-même, avec des contraintes, certes, mais des contraintes simples à apprivoiser.
(2019-01-13) [tiled][newmeta][scanned][CONVEYED][palette]

Sandopolis Zone and Mega-tiles.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZGt8vAIhyXQnYBnmnSWQfyFPcNcQK3ALxHaUiTA42_8735vAUKrRUU0UJGnufpjzHyzM0PHTDSfKCpwRPG9VmL9jwUFSOvhrRErge6s52kw2MTVRAw_gVgoWcLbcbAAeVY10X/s320/many.png ; many.pngOk, au départ je cherchais des références pour les couleurs et le style de la "desert/pyramid zone" de mon prochain jeu. Et je venais de découvrir l'existence de Sandopolis, région d'un jeu Sonic jusqu'à laquelle je ne suis probablement jamais allé.



Un beau gros .zip dans lequel était supposés se trouver tous les décors, mais au lieu d'une "tilesheet" habituelle, je tombe sur une collections d'images de 128x128 pixels. J'étais resté un peu intrigué mais sans plus. Puis en revoyant la vidéo "making of Sonic 2" de splashwave, le doute n'est plus possible: il y a un niveau intermédiaire de map, et ces blocs de 128x128 pixels sont bels et biens des morceaux de puzzle construit à la main pour servir ensuite de de bloc de construction dans un niveau. On va les appeler des "mega-tiles".

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG7LxZty73VLJ0fuRndyd_bVJKm5tuTsyi5mgy1foEPxeoKEOm4k8Hg-2m7bXXVzTcb1lmOrM806wnbnWqUp510-9S3ZHSd_1xVRcT7g3DhT6DDDbyGuR2djAEnzaGfE6fh98h/s320/index.png ; index.png

Avec les mega-tiles, on peut atteindre ainsi un taux de compression proche de 100 pour 1. Les niveaux de Sonic avec leur taille surréaliste de 10,000 x 2,000 pixels tiennent en réalité dans moins de 64K de mémoire.
Et si on regarde un niveau construit avec suffisamment de recul, on peut commencer à trouver des correspondances. Commencer seulement, parce que c'est loin d'être complètement évident ... et j'aurai eu recours au mode "soustraction" de Gimp pour les mettre en évidence.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHMnLwC3-z43Sb2rE8HN9eKsjK4OE-caLhTAIFBrdT7Js954XdNO8sXe9I8ERkKVsnzJTXPbj4bPGCv8Llud8k0L1_JWHhtmj-KHcrCQg5-ifsOt-MbBgs1eEI08B26tG9JZ1E/s320/DwVccHGWsAE9DNx.jpg ; DwVccHGWsAE9DNx.jpg

Et si on ne s'en rend pas compte en jouant, c'est grâce aux différents éléments qui eux ne font pas partie de ces blocs : les télévisions, les anneaux, les ennemis ... Et parce que contrairement à un jeu "type Mario", la disposition des blocs de taille 16x16 au sein du jeu a nettement moins d'importance. J'entends par là que Mario interagit avec un bloc de brique ou un bloc-question individuellement. Et le fait qu'un saut soit possible ou non se décide à un bloc près.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY3xjPqKnBzonZPPmMM7wYQdXEL7e1MXCcsk2pvDxzEAJgFiBzNvhvwvZJZKnt9E35RxM0KYffF7faypb-aTXXK0LQsVQk8tvIvjpXXWMghxRfxHs6Px6vWNGAeGKMpPR_iGgd/s320/DwVfpozXcAAn05w.jpg ; DwVfpozXcAAn05w.jpg



https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7dXC332HyrYpjAbgnikyO3vKl4cAk6CO7IZwb3_CmKdwNrWY_MIDNZJj_qFw4vrSUPFyQHnPyuCNhtl2yPX69pSwRd6jQvxS9VYqRTsrGGoQLhLw0VRl2_gjwfcBmy-0nJZmM/w181-h200/sonic1.png ; sonic1.png Pas dans Sonic. Selon qu'on va plus ou moins vite, on passe ou non. Selon qu'on trouve le bon bumper ou non, on va assez haut. Et quand on n'est pas assez haut, il y a de toutes façons une route inférieure à suivre. 


(2019-02-28) [level editor][tiled][sonic][tileset][level data][designclass]

Level Editor vs new engine

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiFtfCsV_IwlA-u2TzHYtlGbt1foVW-d7Zv0mk53yZZD-lM-TMNJBUVK7Y5qpaLcCQHn579E1ZGUnBzSdDJ8mlwTHaKqWNFXehyphenhyphenVln0mKfai4fHkA56yevPUzboRRzKYz9PRQk/s320/tiles-types.png ; tiles-types.pngMes cogitations pour rénover la gestion des maps dans mon moteur DS commence à porter ses fruits, au point que je peux commencer à réfléchir à l'impact que ça aura sur l'éditeur de niveaux. ça me tient à coeur parce qu'avec le système actuel, je ne vois de bonne solution pour réaliser les cours d'eau souterrains que mon frère avait mis dans les niveaux historiques de la Grande Aventure.
Je me dirige vers un système avec uniquement un byte par tile de 8x8 pixels, et quatre grande classes de blocs: - les morceaux de blocs interactifs, provoquant des collisions auxquelles le personnage doit réagir (pics, bloc-question, bonus, portes ...) - les zones non-solides mais succeptibles d'affecter le comportement de certains morceaux de code (eau, échelles, courant d'air ...), dites "medium" - les blocs de "sol" (solides) qui encodent la forme des pentes - les blocs solides qui encodent les propriétés physiques (friction, déplacement forcé, etc.)
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAr75mhVzo2NttWINKTWJo4US7c8fCPHaHQqXxZnYISFzy6gYHsCzhHflIsfGbus2Oz13tAtO83sDMImO28wURcORfSDg0qu-NJRUQuDLpYbsVUNvrUDp6zNuy8ZVvXpJQFBDo/s1600/no-more-paltype.png ; no-more-paltype.png

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGUDrFWEBDyQKOqyttmoR45d74W6FZu6Umpsy-hEMCmFlNr4tIQjAD5bV2r6pU0PQq7i-WMwAg8h7XkWnQ9bFDDuO7QRZExtORBmVXTjwSo6Jcxk3KcvDLku9uUee9UGlZ9HrI/s1600/palette.png ; palette.png
ça signifie que la petite palette de blocs utilisée dans LEDS va devenir plus complexe, avec un bouton "montrer les autres options", et que je pourrais bien en avoir trois tranches plutôt qu'une seule pour éviter les opérations de navigation fastidieuses.
ça signifie aussi que c'en est fini de l'encodage de petits "0" et "2" dans la map pour former un code entre 1 et 256 en base 4: l'éditeur de niveau ne pourra plus proposer que les blocs qui auront été décrits, ce qui devrait au passage rendre les choses plus lisibles et plus faciles pour des gens qui auraient envie d'utiliser LEDS pour leur propres projets (on peut rêver, non?)


Autre truc intéressant: puisque l'information concernant un bloc spécial (mettons des briques cassables) n'est plus encodée que sur 1 tile, je vais avoir besoin de tiles qui disent "suite du bloc, cf. à droite" ou "suite du bloc, cf. en haut", etc. Chose qui devrait être plus simple à étendre à des blocs interactifs de 24x24 ou 32x32 si le besoin s'en fait sentir...
(2019-03-22) [level editor][tiled][newmeta][special block][slopes]

a + b = idea

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGtGQAktnVyCBuP3juZ4a9xNRHXWt2AFKaHugUCVhfMLvnvl10xwVD0jl_UKRH5Ipp7-lIpxyLgCJEdZuRXV3pLkVC9YPsu_Q50MqyNorLMR8KPtO9zM6WKa140psWB1auqrFG/s200/44.png ; 44.png+ https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZGt8vAIhyXQnYBnmnSWQfyFPcNcQK3ALxHaUiTA42_8735vAUKrRUU0UJGnufpjzHyzM0PHTDSfKCpwRPG9VmL9jwUFSOvhrRErge6s52kw2MTVRAw_gVgoWcLbcbAAeVY10X/s320/many.png ; many.png+ https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrTWhmOC1oMkDs6cHo4YzC5x5uLVHZteJVQlzLVYOfGz5Eija5lw2MSZ1b2z2EH70P-BvQRaBukVHDg-HqifIbVbLwBLJq2DJEhx_JR58XMDrSkI_zfhJ_p-c7viiBeuP3__Sz/s320/IMG_20170218_125616_391.jpg ; IMG_20170218_125616_391.jpg
= idea.


Il y a encore des choses dans l'étude des moteurs de jeux de plate-formes qui m'intéressent suffisamment pour me garder accroché au dévelopement de 'libgeds'. Des mouvements style "corde ninja". Des rebonds sur les murs. Toutes des choses que j'espère bien voir figurer dans 'infinite pyramid', mon prochain projet.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUJKq4uKMPCXBavBO_WIeydwzm-eaFe8So0sNA1F4XuCLwcaPa7tYVbsXhtZwHbALRHYhOJ3Maxq3PK54SjjTBOa8P5Ik2uERtPQi7y2pQVraQwFxfq6KiXuiShuRxaDhiMlFY/s1600/Screenshot_2019-08-23+Bilou+HomeBrew%2527s+Blog.png ; Screenshot_2019-08-23+Bilou+HomeBrew_s+Blog.pngIl y avait par contre un truc qui ne collait pas avec le thème de la pyramide: les zones qui forcent Bilou à avancer dans une direction précise. C'est le cas avec la rivière que j'aimerais introduire dans la version revisitée du niveau 1-1 de Bilou, à la placedu tapis roulant que mon frère avait dessiné en guise de passage à sens unique. Parce que cette rivière justifie la révision du système de "propriétés des blocs", en cogitation depuis le début de l'année.
Mais c'est bon. Je me suis retrouvé avec les méga-tiles de Sonic juste à côté de Bouli expliquant le nouveau système et ça a fait "a + b = i * d" : je n'ai qu'à mettre des rivières de sables (comme tout le monde?).
Pas oublier non plus les escaliers-qui-deviennent-des-tobogans du chateau gadget. Mais à condition que ce soit fun!
(2019-08-21) [todo][tiled][newmeta][pyramid][desert zone]

FlatWorld : public iWorld

Bon, je laisse un instant les commentaires sur Ori et Link's Awakening de côté, les pixels studies et compagnie. Les enfants commencent à me demander s'ils peuvent essayer les niveaux dans la forêt de Bilou, et j'ai une idée un peu plus claire du moteur de jeu que je voudrais avoir pour pouvoir le réaliser.
La première étape va être de faire en sorte que les propriétés du niveau soient conservées dans un tableau séparé, plus dans l'emplacement réservé aux couleurs d'une des deux couches de graphismes (une des plus vieilles fausses-bonnes-idées du projet).
Il faudra adapter l'éditeur de niveaux, mais ce sera pour la deuxième étape. Avant ça, j'utiliserai un "extracteur automatique" pour les "vieilles" maps (comme celle de School Rush et Apple Assault).
Je vais essayer d'avoir un bon design de classe dès le départ ce coup-ci, avec un type pour les données du moteur physique, l'implémentation qui reste un détail et iWorld qui est le seul élément connu du reste du code.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJJMymQ9RO97q_Is4fJSos6Mq7c7dvUrPp_TcLY5iBned65XOUAvAWr5fjIPHaVe8F7Sm0dugoWIqNQwB-h6fcht8oyNVIG7Qx3p3P5ievbiTXuOr2WXhDx3rX-oStDL12PnIJ/s1600/doh-efs.png ; doh-efs.png
J'ai voulu réessayer de faire tourner ça dans SchoolRush pour voir, mais je n'arrive qu'à avoir un écran bleu quand je compile avec le "dernier" devkitpro. Un conflit avec EFS, semble-t-il ... ou bien j'ai fini par oublier comment je devais invoquer le programme, mais Un premier problème que je parviens à identifier, c'est lseek(..., SEEK_END) qui renvoie -1. Pas bon, vu que le code d'efs va chercher à comparer la taille trouvée avec celle pré-enregistrée. Et si ça foire avec lseek, c'est apparemment parce que open("fat:/SchoolTest.nds") échoue avec un beau ENOENT ... pourtant ce nom provenait d'argv[0]. Bref, c'est de nouveau la saison des guru meditations...
Par contre, le commit précédent marchait sans problèmes sur 'grizzly', mon vieux laptop de 2007 qui utilise toujours un ancien devkitpro. Et mon nouveau code passe sans problème la découverte du système de fichiers embarqué quand il est compilé sur grizzly. Au point que j'en viens à me demander si j'ai jamais fait un build de SchoolRush sur le nouveau système... Fort peu probable, en fait vu que le système de highscores dépend du stylet (décembre 2018) alors que je n'ai corrigé le bug d'intégration du stylet avec le nouveau devkitpro que 6 mois plus tard.



Je sens que je vais archiver le setup devkitpro de grizzly sur mon nuc-à-tout-faire, moi. mais, en utilisant grizzly-desmume-cli --cflash-path=directory/to directory/to/SchoolTest.nds, je peux faire tourner le code (c'est l'implémentation pour "cartouche GBA" qui ne marche plus, apparemment). et en débuggant ce code-là, il apparaît que le destructeur d'InfiniMap se voit appelé lors du premier getflags()... c'est supposé être un iWorld, mais il a une vtable de Vblcallback ...
Et si desmume sur grizzly ne se laissait pas débugger avec ddd c'est parce que ... J'avais chargé l'éditeur de niveau dans ddd pendant que l'émulateur tournait le moteur de jeu et SchoolRush. Eh oui. Je vous en prie, balancez votre vanne préférée sur la quarantaine dans les commentaires.
(2019-11-26) [guru meditation][tiled][desmume][dldi][devkitpro]

FlatWorld.artmap

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKPX04df6qB9BEc8ayso_5wrZ9lXww1v5v9UsK9jRytxzq5ldf9UmzaHUNXnHw_GfWaDPN7sF0EvzuMvR2zzHHL5lY9OmBTrBxN-BjC2ijP3gqK-yhqeYk7kAnxhhu2tDvWl9_/s320/FlatWorld.png ; FlatWorld.png
Bon, bin j'ai finalement réussi à trouver les erreurs que j'avais glissées dans mon code et à les corriger. Je peux donc reprendre une des "maps" de School Rush et la convertir à la volée pour qu'elle tourne avec la nouvelle classe "monde" et ses données de collisions séparées des blocs de VRAM du fichier .map. Par contre, ce faisant, j'ai cassé la possibilité d'animer le contenu de l'écran en réaction à une collision avec un bloc spécial.

Je dois reconnaître que j'y vais à tous petits pas, là. Entre autres à cause de la faible quantité de temps libre qu'il reste après les transports et les opérations de maintenance domestiques ... et encore, je suis loin du compte.

Bref, on va commencer par ré-établir un lien entre la "méta-map" et les map-à-images puis il faudra ajuster les changeblock() et autres clearblock() pour que tout passe. Mais caser ça avant St-Nicolas ? Je dirais qu'on est à un niveau d'improbabilité de 3.14 ou pis.
(2019-12-06) [tiled][newmeta][uml]

Rush to Flatworld

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguCuSw0jfjBFYTudzfq0VSAOsW9Dl5zmiKz3gZpesKNQb_g2f3U_Rn7VU2s8UelqD_ZHMTVRlVdt3VTuNDk-TkWDnLDbO92uFhmQlKgeho7UGRxdqqJhK044ZS5A-VtKxf7Chf/s400/special-blocs-rushed.png ; special-blocs-rushed.png



Avec le recul, ça me fait un peu penser à un donjon Zelda où on viendrait de trouver l'objet-clé. J'ai un nouveau mécanisme pour gérer les types de blocs sur DS, conquis après une lutte opiniâtre contre les vilains bugs (pensez aux wall masters) et les émulateurs récalcitrants (grosses statues à déplacer vers une dalle-interrupteur au hasard dans la pièce).
Et du coup, je dois retrouver les différents endroits où je peux à présent reprendre le développement. Editeur de niveau amélioré ? Programme de conversion vers un nouveau format de map ? Plus de types de pentes ? chacune de ces "petites clés" supplémentaires seront nécessaires au final pour pouvoir faire une version jouable de la maquette "desert zone" que j'ai en tête, et un bon nombre est aussi utile pour débloquer une conversion correcte de la "green zone". Mais là, je suis dans la salle avec trois portes et je dois choisir la bonne.



(2019-12-07) [coding][tiled][newmeta][scanned][special block]

Pentes et JumpThru

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJV9ru8CUjewi5IDlOYL1YKkderHng-F1JzUenQtH_21h4Z3PI64-KH-UlxxcQi5PdMmKJio9UA3EhrmgkJYa694ZibbAF1sRSe5FEDKdaI8yqmsgfUsuGxEQUnFuc_n5Lr3bs/s1600/slope-types.png ; slope-types.pngJe me rends compte qu'il y a un truc à propos des pentes que je n'ai apparemment pas convenablement expliqué sur ce blog. Voyez donc cette "capture d'écran" de l'éditeur de niveau avec les types de blocs qui sont révélés en bleu transparent. Il est assez facile d'y voir les zones considérées comme solides, et même la petite pente au niveau de la souche d'arbre (allez, je vous la marque en vert flashy). Puis il y a un troisième élément qui revient assez souvent, ce sont ces lignes horizontales, notamment dans la branche (je vous les marque en rose ou en jaune, petits veinards ;)


Elles correspondent au type "jump-thru", qui a la particularité de laisser passer ce qui monte mais pas ce qui descend. Aucune magie là-dedans: c'est simplement le "GravityController" qui ajuste le test effectué selon qu'on monte ou qu'on descend. Ce type agit aussi comme du sol sans agir comme un mur: si on arrive dans la branche par le bas avec une vitesse horizontale, on la conserve.
Là où ça devient intéressant (ou louche comme une passoire sans trous), c'est pour les blocs "jump thru" qui sont marqués en jaune. Non, il n'y a pas de passage secret, et on est jamais sensé sortir de la souche.


https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1Q7pSQmBzpdkQQDyrhyphenhyphenJnI5Jk78rSuGZho0WJwIlN5khCo40SsHkR2CnNqV8ZmoR5WN22YqndVWfZpXB6LVD3laF38pxWCgPeaBcaRJqYX5qJMdt6pVUoCsJvjdQWBBrnF5XA/s200/slope-explained.png ; slope-explained.png
Imaginons un instant qu'on ait un personnage occupé à monter cette pente. Il a un point de contact (en vert flashy) qui doit rester sur la pente, et une zone de collision (en bleu). Pour qu'un déplacement soit valide, l'ensemble des blocs sur lequel la zone de collision arrive doit posséder les bonnes propriétés -- par exemple "on peut passer à travers" ou "on peut nager dedans". C'est le principe de la fonction cando() dans mon moteur de jeu.
Mais dans le cas d'une pente, on voit clairement que la zone bleue peut "déborder" sur les blocs juste à-côté des blocs-pente. Si on les rends solides comme des murs, le personnage restera bloqué en bas de la pente... d'où la réutilisation des blocs au-travers desquels on sait tout faire sauf tomber.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWwZtzOFL-hjm-U55o6b-M8AlealOfSb8ss9VQljBurCErQD5R9xKL3Mf7d73a0CfBW4phnGjLZFoosAtmjiCun_GdGraCsp7CB9xeewh11fCsrfWuCpCeDNruJeu2S2yn3npB/s1600/no-end-slope.gif ; no-end-slope.gif
(C) The UnDisbeliever why we need more than slopes & blocks.




Ils permettront aussi qu'un personnage dirigé par une "IA" qui sonde la map autour de lui ne pense qu'il arrive au bord d'une plate-forme en trouvant un tile "creux" quelques pixels sous son point de contact.
Voilà, j'espère que c'était intéressant ;)


(2020-01-09) [tiled][jump-thru][slopes]

DoSlopes

Ok. Ajouter des pentes dans un jeu de plate-forme, ça devrait ne pas être compliqué, mais dès qu'on modélise son niveau à l'aide de dalles pré-définies (toujours les bons vieux tiles), ça cesse d'être simple. J'en ai déjà beaucoup parlé (cf. le tag) mais sans jamais vraiment (reality check: si) présenter la solution que j'utilise depuis Apple Assault: la fonction doslopes.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghqLcHqtBFGnhfneDbTb5Ug83OKDkP1NaspFXlO6Ag47gMgRH94a3k_jTXp49_gAzD-A-XVXz6NIplPs4XLk4QrR0TJCx-NAnp95gkAUBhqk5OdT_af2uY7BFYVza8xNyYGTS_/s320/doslopes.png ; doslopes.png
L'algorithme derrière doslopes travaille uniquement avec le 'hotspot' des sprites, et veille à garder ce point en contact avec le sol tout en appliquant un déplacement horizontal donné (qui peut s'étendre sur plusieurs tiles). Il utilise aussi une fonction annexe -- groundheight(x,y) -- qui donne la hauteur du sol pour un tile du niveau à partir de la base de ce tile. On y reviendra.

L'algorithme est constitué d'une boucle optionnelle (en jaune) pour atteindre le tile de destination puis une phase d'affinage (en vert) qui calcule la position du sol pour la position horizontale voulue.
En sortie, on obtiendra un  déplacement vertical correspondant au déplacement horizontal donné. A chaque déplacement intermédiaire, doslopes s'assure que l'on est pas en train de s'envoyer dans un mur à l'aide de la fonction cando -- la base de la gestion des interactions sprites/niveau.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYmQmg03csF3MinAASqqPJ3emxPLUJ8P8wcUTQBk6mitLReTAqIS3zYSt9BAnewS4Ml5t9Amj8aElOC431fGuMJ_9UCsh8FlrxesBNNAaI_tF23MexeJ-JxeNFv78TWo1-qpEL/s1600/slope4.png ; slope4.pnghttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigh_ju9yxjOiMtelW0vpXxgeEn8r73rJFWyfzuVa_LIjc7vezZHSKw3o7G-Oc1UV7NBsyYP_QvQYyLYrQUkBbBXQTJC0DzHO_xLngD6vRFzBMy0_LOpG1cQM7KUPcRi0i8BRqq/s1600/slope2.png ; slope2.png
Le principe de base, c'est de regarder la hauteur du dernier pixel d'un tile pentu juste avant de le quitter. Il peut avoir une 'hauteur = -8' ce qui fait positionne le joueur juste au-dessus du tile (comme on le fait normalement pour du sol) et permet du coup de regarder le bon tile pour la suite de la pente au tour suivant.
(2020-02-01) [tiled][scanned][slopes]

Higher Order Blog ...

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXO45BXUICXVQpRQz0Q0GKYw9WswuavyQkXNp_1-Md4qAItw-flrK13it7nRSifLlxVvZvpSoFLbb5SH717JNwEo0LqOoXfMSi9g0qzCkwN_WJzEb2b35QkJN-mV-9QCZCbQEE/s320/Screenshot_2021-02-13+Pype+%2528+pypebros%2529+Twitter.png ; Screenshot_2021-02-13+Pype+_+pypebros_+Twitter.png

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

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

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkcGQLuCSzOca_32hiVjCchi24wenZF7Uw5h9Ni7Mz5h-xqqW2FashqbdO-6HbsF8njofFNzVrfaxB43wgIJDolmV4QMGcEKTZClvXnIFpKPAm8DL9pDrrQh-1xU-pY1fai63Q/s0/Screenshot_2021-02-13+Lemmings+digital+audio+playback+added.png ; Screenshot_2021-02-13+Lemmings+digital+audio+playback+added.png

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

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


(2021-02-13) [tiled][jump-thru][slopes][climbing][designclass]

3 rooms milestone.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNvDibJgZm_kcjzv76yieDFyYOcOyEeKfDlPHWCjndJAzzU36PyWH3T120zHGc7qhMfPH52sOFjHyBJHk3znlrc9QSdmbJTUhQe3ZTju3EPBD4CM2GNH3yP5oXwmpM19IwB3uI/s320/Screenshot_2021-03-29+Pype+%2528+pypebros%2529+Twitter.png ; Screenshot_2021-03-29+Pype+_+pypebros_+Twitter.png

On dirait bien que mes éditeurs sont maintenant prêts pour le travail sur Bilou's Dreamland. Support des nouveaux types de collisions et de pentes, support du choix de palette sur les deux plans. Et les spritesheets/tilesheets ont été nettoyées et prêtes à l'emploi aussi.

Il me faut donc un prochain objectif, et ce sera les trois portes salles. Une pour chaque environnement, pas trop grande, mais assez pour qu'on puisse y placer les différents éléments de gameplay critiques pour le jeu comme les cascades, l'eau qui change de niveau, le sable qui glisse, les portes, les plate-forme crocos, les branches qui plient, etc.

(Eh, CJ, ça fait penser à tes niveaux-téléporteurs du jeu d'origine, ça, non?)


(2021-03-29) [dreamland][dr21][milestone][school zone][pyramid][ThreeRooms][greenzone][sketch][desert zone][done]

3 Rooms - Release Early

 

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-jUKLkwRNDiuEqJIUPxkd_cDuAmYuvH9idXUQQmIT-yZfaxHOKLg8hKFTGAEYQBpUzDQMaxGda-wro-G3DSYdxWXgsTlSip8QkImnPvqd-h9aXnzFoYlNVzb730jcldGamujE/s16000/3rooms.png ; 3rooms.png

Download: Dreams.nds updated Dreams.nds for new year

Voici donc (enfin ?) quelque-chose de téléchargeable avec les environnements que j'ai l'intention de faire évoluer pour y amener toutes les nouveautés de gameplay de Bilou's Dreamland. Alors, soyez avertis quand-même: c'est vraiment une version 0.0.0.1 là. Pas même une ébauche, tout juste un canevas. Y'a des retouches à faire par-tout. Y'en a tellement que je n'aurais même pas le temps d'en dresser la liste avant d'aller me coucher. Mais qui sait, ça vous amusera peut-être.


(2021-12-08) [download][dr21][newmeta][milestone][ThreeRooms][mybrew][world 2]

special properties

While thinking at 'how to implement conveyer belts', I end up investigating some currently incomplete code in special blocks handling. They have correct implementation of their collision areas, but since the migration to the new tile types engine, they can no longer act as 'doors' because they all have the same cando() properties.

There's some code in the parser to change that, and some code in 'FlatWorld' to return BlockInfo::props when we encounter one ...

Wait ... BlockInfo::props is precisely what this last `siscanf()` updates ... so ... that means the code is not incomplete at all ? it just needs to be tested ?


(2023-05-28) [dr23][coding][tiled][special block]

tapis roulant!

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZIA6tZJ3IhXHdodrbYkWbOK8crnpRbqgNz0-rXII6xPxEy4lZtdVpEtL6RJpp_Yd_weTK0yqX3tGFaD6mr4xbsLl1eGQILgP8HfFglazocJWuSts-mfNYxe87EE5k3zb16Ag3U3usBA_aMtGNyOcWX1nc-GvwIyL40yct0LuHf-N0Vl-4SPDyXw/s1600/specialground2.gif ; specialground2.gif
Nous y voilà enfin! Après l'eau-qui-pousse, je peux vous présenter le sol-qui-pousse. Le point délicat, vous vous en doutez, ça aura été de mélanger ça avec des sols pentus. Ce à quoi je ne m'attendais pas franchement, par contre, c'est que être poussé pendant qu'on est immobile sur le sol se révèle plus compliqué à gérer qu'être poussé pendant qu'on avance.

C'est que pendant qu'on avance, on appelle régulièrement la fonction do_slopes, voyez-vous. Et même si le sol annonce "je te pousse de deux pixels sur la gauche" alors qu'on est sur une pente, on finira bien 2 pixel à gauche et 1 pixel plus bas si nécessaire. Mais rien de ce genre dans l'état "immobile sur le sol". Et notre fonction do_slopes est prévue pour aller directement corriger la vitesse et les déplacement retardés du personnage, or l'idée du "sol qui pousse", c'est justement de manipuler la position dans un premier temps et de laisser le code qui traite la vitesse tranquille. Sans ça, sur un tapis roulant trop rapide, vous verrez Bilou se retourner pour marcher tout seul vers la gauche plutôt que de le voir s'échiner à avancer vers la droite tout en reculant malgré tout vers la gauche. Pas terrible.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc2VQAKehak_1Ja4o5axtd4-ltMbRWKsqiSQhgyXT1rLju6aFuwOqX5m81hgaPkUCgSQ0VdVY_fwRP0v8s_tsP3AS_UiD4P6IecUJ9M3GE0nFv2yAczFTyxSExRiBgaZmb6f3k6VzHtCwPekOOj2olNq6hfqd33JimBZClATuhuF1nkzQODrrsgQ/s1600/Screenshot%202023-12-17%20at%2013-43-07%20PypeBros%20(@PypeBros@mastodon.social).png ; Screenshot_02023-12-17_0at_013-43-07_0PypeBros_0(@PypeBros@mastodon.social).png
Dans Rayman, j'avais pu voir qu'on avait deux types de pentes: des normales et des glissantes. Chaque angle et chaque offset est dédoublé avec un second type pour gérer les deux types de physiques. J'avoue que je souhaite plus de souplesse pour Bilou. Pas tant que j'ambitionne de faire un jeu plus complexe que Michel Ancel, mais surtout parce que je n'ai pas l'occasion de planifier l'ensemble du jeu. Je suis incapable actuellement de garantir qu'il n'y aura jamais plus de 2 types de sol dans un niveau ni 2 types de pentes. Le projet était donc d'utiliser des emplacements séparés pour encoder la pente et les propriétés du sol. Et quand je me suis mis à coder, c'était encore plus simple que prévu: quelque soit la position de Bilou sur une pente, il est toujours à l'intérieur du tile "pentu". Et donc pour trouver le tile avec le type du sol, il suffit toujours de regarder 8 pixels plus bas. Enfin ... presque toujours.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu63ONjSDYNpu9mEEE8ikmgb7VkZTgSyDS-P75npGo1NGJw5VTbMdUEP5f0uAiLUVwpW1CHURNGaGS5v7f2bcWtpu-PrxwHDCdidyJsCgA2SshetqmVTJoFUKSIuFaQspafZaekUSl5e063aGrDmkEeYwIEdz38kXUUfB1Xx_zqWDVij9HofMy7Q/s320/Screenshot%202023-12-17%20at%2013-43-28%20PypeBros%20(@PypeBros@mastodon.social).png ; Screenshot_02023-12-17_0at_013-43-28_0PypeBros_0(@PypeBros@mastodon.social).png

Comme toujours avec les pentes, les problèmes commencent quand le sol n'est plus dans le prolongement horizontal de celui utilisé une frame plus tôt. On se retrouve dans ce cas-là soit avec Bilou qui s'arrête au milieu de la pente, soit continuant à se faire pousser, mais à l'horizontale

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh51A3DLaL3opl6Vdq3aQLGCMAzO8SpXw0nUFPmTOpMlfzk2vFlWnoXVMxHG41Gzu4kgcuNg65_FLneieSBGgYudSKOxtLZi8ke4klAELLDTiBC2YOBzR3ebkGq6uaN_LOnvOQLXxI2KWM6li_xPydGDcDp2i11PxfyVJLUGsOCpxvQ1EVeb4-hRQ/s1600/slope-tooted-5cbe46a8d5bd07b3.png ; slope-tooted-5cbe46a8d5bd07b3.png

Bref, inspector widget, ddd, j'ai pu sortir toute la panoplie. Presque (pas les unit-tests, cette fois). Mais l'éditeur de niveau m'aura bien cassé le rythme.

(wow. Le soir est tombé, j'ai encore une machine à faire tourner et je n'aurai pas fait plus de homebrew de cet aprèm' libre que de vous raconter tout ça :-P)



(2023-12-17) [dr23][newmeta][milestone][CONVEYED][slopes][pyramid]

Et un Bangbash qui marche ! ...

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGbiInTUKqY4UGdz4fHg1pG3ppjBdNb-zJ4mRq_UAxAydFAJSLK3fCO7fbNKGaqmU2FLTy6_ASFo7nyq_gOj6jC7e8wYfdocCrNKvTmrMvPaxvMsNeEcXOmC78A7MoJKyX90LkPhENJq-gdStbl-FqjuO0zkj47pRi1e4gSa2cP_m8EqC7VzqapQ/s1600/bashworks.gif ; bashworks.gif
Enfin ... "marcher", c'est beaucoup dire. Mais il bouge, il fait demi-tour en bout de plate-forme le tout dans son environnement naturel. Par contre, la quasi-totalité des animations de transition (atterrir, arriver au sommet de la courbe de saut, etc) ne fonctionnent pas (pour des raisons dont le niveau de compréhension est encore variable), mais bon sang, on l'attendait depuis tellement longtemps que je ne vais pas faire la fine bouche avec un "ouais, mais non, je vais attendre qu'il soit fini avant de poster quelque-chose", hein ;)

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWgnNUrZmRm9NnQB-2pEqe3uawjWoL7sMkN_Lw1sF4xJ33PRUZ6AmFU1TLwILIM6izBPGZ7OZ7YVtMsb7znpujWFkgifK9N8BjVMQCzm1CL_nEL6kmYcPPzUaijYcJvUg5KD0Y33AqcKLl52bQbMtmwBznOGl6GuBNPq6GNyHZwfXAYlNQeXMf7Q/w320-h240/bang4.png ; bang4.png
Bon, par contre, il faudra vraiment que je fasse une révision de Inspector Widget, pour 1) montrer les testpoints dans la zone radar, 2) faire en sorte que le *hot spot* soit toujours dans le radar (et pas le centre du personnage, parce que pour bangbash et pendat, ça ne sert strictement à rien.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHaxU4pcQrBHB90EQfAGRGcSquynVX7iZj4h_Sd6D-KGNMaPDLlEF8Hg_vMIqFlpv06TFYklqX7wCYpoZ7alLum7FY2NS0hfatnHkbPNtWINJIV3INEuWSgHfEq5nXIPVbKkEucFb1tOYxPdN4PUn_0_07PB_5EHS6aHEsA7_XHibuGa63cgIOEA/s1600/banghop.gif ; banghop.gif
Là, j'ai dû faire mon débugging en combinant ddd et gimp ... en allant gratter dans les fonctions internes de libgeds. On va dire que côté dever-friendly, il y a mieux ^^". Aucun risque de faire de l'ombre à gbstudio dans ces conditions...

edit: avec un peu plus de travail sur les animations, la position des images par rapport à la "boîte-position" du personnage, ça donne enfin (4 janvier) ce que voulais que ça donne. Bon, évidemment, ça ne satisfait pas J.L.N qui demande "il attaque déjà ? " et "on peut lui envoyer des taille-crayons ?" ... pas encore, mon p'tit loup ... pas encore ...


(2024-12-30) [bangbash][milestone][dr25][dr24]

Hang on!

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrCovQXrabzzzdgu-NGd_h9oTTDzfk5IPBhVdJaTJPVQxU0JwaaM4Af3Y2q1-fHjdyl2yYrEqo33LTjSIlVxVE2HUkgDsOE7Yv0wxrBHq2_6m6NvJolGq7SoTmSPwm-lJhjs_WhFCG2aWh56fPvT55Nnej5XrppjYjzwHcKQVI8a0HuS1wXtLx8g/s1600/Screenshot%202025-02-13%20at%2021-37-27%20Bilou%20HomeBrew's%20Blog.png ; Screenshot_02025-02-13_0at_021-37-27_0Bilou_0HomeBrew_7s_0Blog.png
It's one of the key mechanics I'd like to bring into my new game: being able to catch hanging things and hanging as well. It was a fun move in Commander Keen, it was amazingly expanded in Fury of the Furries and Mickey Magical quest ... And last week-end, I went on to try and get it prototyped.

I started with a summary of how Bilou can hang below spongebops in School Rush ... something we don't see a lot in the blog, mostly because Bilou is supposed to *ride* the sponges, not hang under them. Hanging was added as an "else" branch of another "else" branch:

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh19LN4zIdiujN0x6Ca3GSpzn4k3mHqpEJm7Nv61yuwlKRenIBXFAasVnKKebRyrHQx02rubNC6wsWuh4nmZxAKub2GmCCrt_d0aCXZk8rOsr99GOuYXxLoMFVQ-xn2KZ5tHjkm1ulT6E568YLvnxUpD6ZIabMhFrK9FCJJZujU729hMgo-Q9woPw/s320/spongegrab.png ; spongegrab.png

when you hit the "HANDS" button mid-air, Bilou does a roll move trying to grab what's nearby. that is AIRGRAB state. The original idea was to test what was *below* him and either pick-up a dumblador or ride a spongebop... but the move shows the hand grabbing in front and rear directions as well ... so it would feel natural that Bilou could grab a sponge even if he's on the same horizontal line, like in the sketch on the left. Yet, snapping Bilou on top of the sponge from this location felt glitchy.

Bon, j'ai un p'tit Bilou suspendu sur une page de mon cahier-agenda depuis le début 2024 ... j'en ai un autre sur la bannière du blog ... je crois que l'appel du pied est assez clair: il serait temps de prototyper un peu ça, d'autant que cette fois ci, ce ne sont pas les coins de niveau où s'accrocher qui manquent dans le livre-secret-du-level-design.

Et pour "commencer simple", l'idée était de faire subir à Bilou le comportement des éponges. tout en réutilisant un des états codés pour l'interaction avec les éponges: rester suspendu (la feinte). Chose qui m'a tout de même demandé de me replonger dans pas mal de gobscript, parce qu'à la base, il est prévu que Bilou s'accroche *par-dessus* les éponges, et pas qu'il pende en-dessous. Le côté "pendu" n'a été rajouté que dans les derniers 20% du projet, entre deux séances de playtesting parce "bin, oui, c'est vrai au fait: pourquoi Bilou ne pourrait-il pas rester suspendu s'il était trop bas pour escalader l'éponge au moment ou la joueuse a appuyé sur (B) ?"

So instead, Bilou will enter AIRHOP move, getting an automatic double jump and automatically tracking the sponge's position. That feels fairly naturally when playing, that gives you a sort of "fair second chance" but it might fail anyway: you may fall below sponge's position again without having reached the "riding spot", with no hope of catching up. and *that* is the time when we finally switch to HANGING. 

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyTq_d96xMpAbcus14vKpZtacTZ4JycXbJtAmwkXdnQ43reuMFLR3k_eGUNtB3BTXEsPI-e8RDtp54T4JEUQnwtet238wqAlrADW191qFzlRhzTpCcHMNd6hFYRK4kDhyU3v6y156YomdOBihLenVrXYnz_Xp1El6LXhLlfMJxNSg2iKrlxj47Fg/s1600/grabedge.png ; grabedge.png

There will be other objects to hang to in the game, especially bookmarks, vines, and the like. Some of them could be entities like spongebop (maybe moving a bit less), but sometimes it might also be nice to have tiles you can hook to. I have code to make some tiles react to collisions with the player, but that was not enough: the hitboxes used to detect spongebop explicitly search for baddies. And because I'm testing 3 areas over the course of the animation, I'm out of options to also test for friendly areas (which has been the case for all pick-ups so far ^^"). But hitting a tile can trigger an animation, and it can spawn an entity with proper hitboxes so that Bilou could hook to *that*. You couldn't really hook to a tile, anyway, because the BlockArea created during the collision test is immediately recycled, so you could not attach to it

Mon idée était ensuite d'utiliser un type de bloc spécial pour servir de point d'accroche, et d'aller "poker" quelques blocs de ce genre à des endroits bien sentis de la map "green" de la démo. ça non plus, ça n'a pas fonctionné comme j'espérais. Entre autres parce que quand Bilou cherche à s'accrocher à quelque-chose pendant sa pirouette-en-l'air, il cherche parmi la liste "EVIL" ... et les blocs interactifs, eux se présente automatiquement comme des "HERO".

Bon, ce n'est pas bien grave: puisque je voulais que Bilou s'attache au point d'ancrage, il fallait de toutes façons que j'introduise un GOB (game object) généré à partir du bloc spécial, un peu comme les scintillements qui suivent Bilou quand on ramasse un smiley bleu. Ce gob pourra être dans la liste que l'on veut. Pour éviter qu'on ne génère des quantités ridicules de gob-points-d'ancrage, on va (enfin) utiliser une animation de la map elle-même pour désactiver puis réactiver les propriétés du bloc pendant que le gob est présent. Exactement le comportement des blocs-question de SuperMario quand on les coup-de-boulise.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKcVnrarzKybzztl0MlGcrGKBDASts1VpQIObT9c_wMfmSrP05nOGd0RfLdgmyE7a0ydquevjFOg7ZRfLQZwgae_nz1PlUlAyTcQ720dP3-YDftzbD_8ZULeUCh_vPdSjgasW1KLq5wmwPBUH8HQ8Yl7g8S95b7me64QgyF1WrdgAtU0NPYot6eA/s1600/hookblock.png ; hookblock.png
So the plan was the following: a new special block that would react to GRAB action. When that happens, it trigger the animation that actually leaves graphics untouched (with "spr0 ffff") but turns the physical tile into "plain fall-through" for 5 frames, and then restore the tile as "block 07" (thus interactive) again. Quite the kind of thing that SuperMario question blocks do on a daily basis, actually.

(It turned out meanwhile that using sprite 'ffff' did not work as intended, so I ended up adding a bbox statement to that animation -- effectively making it a special 8x8 tile rather than a 16x16 special block -- and fixed the code that plays mapanim so that "props" instruction is executed immediately rather than cached until the next "spr0" instruction)

anim9 spr:2 {
   spr0 7      # visuals for the "tile replacement",
   delay 5     # here just a Bilou hand ...
   done
}

state63 :anim9 {           # behaviour for that hand :
   using freemove          # just stay there, 
   area 0 (0,0)-(8,8) 1010 # accept GRAB hits.
}

state62 :anim9 {   # should have been the persistent state when Bilou hooked...
   using freemove
}

state63->state62 on found 0 [wc $1010 ?] (t) # detecting the actual hook-up hit
state63->nil on done                         # and disappear otherwise

using shgob(state63 is e:=1:6) as 6          # a special action to spawn the hooked hand
                                             # oh ... and it's an evil hooked hand.
block 06 {
    is gndhook "ff3c7cfebe2a2a00"  # the special tile 
    area (0,0)-(7,7) 1010          # will also detect GRAB hits
    on hit [t] (x6) :anim6         # and the 'x6' will invoke shgob registered 'as 6'
    props fc0
 }

That should have done it. I could see the hand showing up, and getting away, but I couldn't ever hook to it. I couldn't get an evidence of why it failed, but I believe it is rooted to the fact that bilou's own bbox must overlap the tile in order to trigger the "on hit" transition. but since all the hitboxes with the GRAB flag tend to be off-center, the second collision (with state63 entity) doesn't occur because there's no overlap.

Alors oui, je vous balance le script directement dans le browser. Parce que ça ne fonctionne pas. Enfin, après avoir corrigé la gestion de l'animation pour ne pas dépendre des changements d'affichage (qui expliquent le bout de terre manquant dans le screenshot là-haut), ajouté une "bbox" à l'animation (pour que le code sache qu'il ne doit manipuler que 8x8 et pas 16x16), je finis par avoir un objet qui est créé tandis que le bloc devient inactif puis se réactive ... le hic, c'est que il faut pour ça que le "corps" de Bilou soit en contact avec le bloc interactif alors que ce sont ses *mains* qui vont essayer de l'attraper. Et la zone à attraper est réduite à 8x8, de toutes façons mal positionnée... bref, je n'y arrive que 1 fois sur 5-6, donc le joueur n'y arrivera pas.

Il vaut bien mieux que je me décide à dessiner un graphisme dédié (une racine ?) et que je fasse juste un GOB dédié... il y aura des import/exports mercurial à faire ... 

At some point I thought "hmm. I'll just have the little tile be a 8x8 hitbox in the middle of a 24x24 special box, that will do the trick", but it wouldn't work either: that 24x24 region around the corner of a pillar (for instance) would have "jump-through ground" on one tile, and "air" everywhere else... how could a single "props" instruction fix that ? okay, I could introduce "props(-1,0) fc4" to change one specific tile of the block but that sounds like the coding equivalent of "just stab me now" ... 

So, likely, I should forget about that "hook to tile" thing, accept that there's very little hookspots in the Dreamland levels anyway and kickstart my NDS to draw some root sprite in green.spr ... 


(2025-02-13) [tiled][HANG][gobscript][mechanics][sketch][spongebop][dr25]

stopping waters

 

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPrvyyunPysP1p9lyhCgxjWnIZRBjudnoWsVDmb_o4AMmUSBrniLB5xgso4myoMt16Pcbpnxdrv1QuQmeAc9mS5p4mPnvzFZXFRF5WRWtNIyhep4_T_j40CGGy7wuaWlcZRvY8pPBY3MAO5MQQCSwJYE4b-35aZQusaQpmwXmYJMoLGeePTe9tbA/s320/bilou-stomps-water.png ; bilou-stomps-water.png
Faudra-t-il un OBJ_WINDOW pour ne pas avoir quelque-chose de trop brutal sur l'arrêt de l'eau ou du sable ?

(full page scan: https://mastodon.social/@PypeBros/114759901752072759) 

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVDzNTL8pFM3T68Tf9m8jnkGL8P9hp00eEAuEnZhLOC0zYcxhRBMdIreK8jCQdWorJ3a8O1cWuIZKpFQYy9Wej4kidcj408-S8xSljLBd_5QDpMYZcvZH152APHqu-PYopNntS9vcQO9KL9ZZTnwbH_kfvPnOE7WAcAlETvPdKBN8UEkU1vwiGhw/s320/usingTileGun.png ; usingTileGun.png

Une possibilité serait de proposer ça par l'intermédiaire d'un TileGun.

L'autre option serait d'intégrer directement une fonction "déplacement" à l'intérieur des MapAnims 

 

 


(2025-07-05) [tiled][blockanim]

Mario in Godot

Refaire Super Mario World dans le game-maker "Godot" ... j'ai envie de dire à la fois "tout ça" et "rien que ça". Pourtant, l'idée de Wye n'est ni de proposer un Mario World Studio ni son Mario World 3. L'idée, c'est de comprendre le fonctionnement du jeu d'origine en le reconstruisant dans un nouvel outil tout en apprenant l'outil lui-même. Et ça, ça me parle. C'est le genre de bouquin que je dévorerais mais ici, ce sont des vidéos youtube.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKskGBrquARWyR-q0d_mTRpCqDlAQhTLnAG3OW9JGJBwxy96F6eSLSnwVc9UpoHxB5uz-Ejo_3nX4Orct1LEiAXCj7iuPfmnB8gp-xUjrndyN9wVJfpIZGftYW2nid_tk7M93_Z-DOupec1k3RHP3660FAaKBfzgAXo1YQq4tPTVH5QiCLmmUi1Q/s320/MarioGodotUnderwater.png ; MarioGodotUnderwater.png
"In Super Mario World, Mario was considered fully underwater if both his head and body interaction points are touching water tiles. [...]

"When Mario body is in the water but not his head, that means he is near the surface."

Du point de vue des collisions avec le niveau, Mario n'est pas une boîte. Il est ... une sorte de constellation de points qui ont chacun leur préférence sur le type de terrain 8 en tout, mais dont certains ne seront évalués que dans certaines conditions. Pour déterminer s'il faut nager ou non, ce sont par exemple ce sont les tests du milieu et de la tête qui entrent en ligne de compte. Et pour déterminer si on peut sauter hors de l'eau ? Bin il faut que le corps de Mario soit dans l'eau mais sa tête hors de l'eau. On évite en fait les complications du type "la surface est à la fois de l'air et de l'eau" dans lesquelles je me suis embarqué.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4CGLNQAGji4y8Yod-XcSkqrAZ2ObaARRCi8jMHbvm4l1Ssj0u1JKSvOVwy6Gp58V2zBCfWQCvq2xtOoZPX47W4a7NwRF6HdOTkkOL_eRzKt6yi1m91UwDyfntSCuMQcUIh9BMfgOxA6JPF8KBOn6QYzQ0aY_4iwWFDpkedsHgiEcL5GGjGIHyCw/s320/MarioGodotPoints.png ; MarioGodotPoints.png


(2025-07-12) [SWIM][JUMP][mario][tiled][special block][water]

Une pente qui tombe à l'eau

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQlkLkMGXbkdIzEnZ3r8XvLR4rMsgbTRYk0zEDPBwXfnInoHo5crIo9O8VRZQXXyIuJJ3daFEuPbGwQ4ilC6tBReLJ1h5s2XksIdUZ2rkgdawJJg6le44Tzm9PFuGzvcnP3BH6BPXuV4qCmnaM_vz_DeXFdrEFIkl0jmWbvVhQiddDaLXag2FydA/s320/UnePenteALeau.png ; UnePenteALeau.png
I had tiles that push you along a slope. They've been shown in the sands mostly, but more importantly, they've been tested in a setup where there's plain ground at the bottom of the slope.

Here, I'd like to use water falling down a slope as a way to implement a one-way region somewhere in a cavern of the green zone. But it didn't quite worked as intended. What makes Bilou slide down in such a setup is that a test-point queries the tile number under his feet and use that to look up a physics values array. But once you get down the hill, the hotspot gets in the air, and nothing finishes to push you out. 

Il y a sous l'arbre creux une sorte de pente rendue glissante par une cascade sous-terraine. Mon frère l'avait utilisée pour créer une sorte de sens interdit entre deux morceaux du niveau. Alors j'ai déjà des pentes, donc ça aurait dû être une simple formalité, mais comme vous l'aurez sûrement deviné par le titre, ça n'a pas été sans mal Premier couac: en voulant rendre ce "tapis roulant" plus rapide que les chutes de sable, je suis sorti des limites d'un tableau, ce qui a eu pour effet d'appliquer l'effet geyser à l'ensemble du niveau ^^".

Plus contrariant, une fois arrivé en bas de la pente ... rien. On ne tombe pas dans l'eau, on reste juste là, sur le rebord. Parce que c'est le pixel sous le *milieu* de Bilou (le "hotspot") qui détermine si on se trouve sur un tapis roulant mais qu'il faut qu'il n'y ait plus rien sous lui sur toute sa largeur pour qu'il commence à tomber. Je dois donc rajouter un autre type de tile qui pousse comme un tapis roulant tout en étant pas du sol.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7ZBGc6zm7goOsvTawKlzIjswIIkpd6iDH6EwDPSBi-4PhERuI0HA_AGyQillR0iGqDQpp16N9E1nA6TfZumvcGez9izb5CIEceyw8evdgfKkIXXoEYjSgX2-nJUm-lqY5ipQFl6S29im8wvmJerlnL5vXFjh7bqIyFsKvSatHNX68ezcubyYKzw/s1600/nozwip.gif ; nozwip.gifSo I added another tile that behaves like air and keeps pushing you as if you were on sliding ground and put them at the bottom of the slope, but even that wasn't enough to get it working. It would take you as far away from the slope as you want, but then, once your hotspot is in plain air, you'll stop, happily idling in the middle of nowhere.

The part I was still missing was the F_START_FALLING property to my new tile type, something introduced so that we could land in slopes properly by having slope tiles letting you keep falling into them (until the hot spot reaches the ground) but not start falling through them when you're walking.

Il restait un dernier soucis. Un couac lié à un changement plus récent et qui fait qu'après avoir bien emmené Bilou au milieu de nulle-part, il ne tombe toujours pas. tout ça parce que j'ai donné au nouveau tile possède bien la propriété F_FALLTHRU, utilisée pendant que Bilou tombe, mais pas F_START_FALLING utilisée pendant que Bilou est au sol pour voir s'il pourrait tomber ^^"

With that new bit set, we finally have it: Bilou keeps sliding until there's no solid ground, and there  it cando(START_FALLING) and ends up in the water :P

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBrPvhtjbnnL9q1FtAqd3khK-sMX4Gqh0n4GXhufWTK9z_WKOmoGAh-V2_nvF3lg1PhGr7qeOZyKKa-F-VUJFDieVySJC2xccyDUDsz4cOLqrKSHWNaJqVSdpPPmj_WYNK2xG7IXDUrUp1pPdUgRX55lGJSbioGwAu4dScv27qc0TQExwwUlKvHg/s1600/sonic-water-slide.png ; sonic-water-slide.png
There's one odd thing going on with the way the water slide is made as a conveyer, though. Conveyers just move you and don't affect your speed, and that's on purpose. But that means that as you're running full-speed against the water flow (if you manage to) and decide to jump, you suddenly move in the air at top speed while you were almost idle on the ground.

Maybe I should mimmic Sonic's water slide and make a dedicated "woah! I'm sliding down!!" state for Bilou as well.

But even then, when Bilou is walking against a conveyer, it is natural that he's walking faster than he's moving ... against water, we all know there's a force slowing us down, so it'd make sense to see his animation slowed down and pixel-fitting its motion against the water ... which would mean acting on his speed rather than shifting his position ... Meditate on this I will. 


(2025-08-23) [tiled][water][CONVEYED][gz1ac][dr25][walk]

20 ans de Nintendo DS

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV3nIfqyhfMp97_KgGCGv6jOTTuzGDgsOV2OdcK1cwQOZ67McHKaR0faj8eAAPJ8XueYc6oCD1O87NKtCxwB11OMWzS-tiFCfGzM4pMvnLb_x3CzTKnzGLW0z37393Lg1QVA1bmH4hyphenhyphens3RaayS0BYdU25HTpA7nRWk8k6im6m7QHvfj3jVDglt8g/s320/20years-timeline.png ; 20years-timeline.png
Il y a 20 ans, j'ai reçu plus qu'un nouveau gadget. Une nintendo DS .. avec aucun jeux, en fait. On nous avait annoncé un nouveau Super Mario, un nouveau Zelda et un nouveau Yoshi Island. Bien plus intéressant que les projet rub et zoo keeper qui avaient accompagné la sortie.

Comme j'avais envie de revenir un peu sur tout ça, j'ai fait un petit récapitulatif de la première année de développement et blogging sur bsky ... et d'une façon assez surprenante, ça a explosé les réactions.

Et ils n'ont pas encore vu cette ligne du temps tortueuse qui reprend les milestones, les releases et les interventions et commentaires de "guest stars


(2026-01-18) [history][milestone]