Showing posts with label traduis-moi. Show all posts
Showing posts with label traduis-moi. Show all posts

Wednesday, July 15, 2026

It's blogpress time again

French journalists have a word for that seasonal topic that comes up again in newspapers when every high-end interviewers are on holiday and things are up to interns: "Le marronnier de l'été" ... and it may feel that doing some blog-to-printable/epub conversions pops up every summer here, but hopefully not for the same reason.

The motion started with the late-night idea that "tiled" engine discussions could be a chapter 1 if the blog ever had to be converted into a book, but also that editions could use their own tag, like "ch1" for that chapter 1. On the next day, I was dusting off repositories and working directories for the next "blogpress" round, motivated by the fact that I'll have up to early August before the next automated snapshot/takeout.

I wrote a small introduction to that chapter (french only, atm) and then grew surprised by how little preparation there was on that "tiled" tag. Reader would just be thrown stuff at their eyes, and they'd better understand things. Sure, I introduced it rather late, not as I was writing those posts... I discovered a bit sadly that most of the tutorial I had used by the time are now offline (and even their archive.org copy are firewalled T_T by "my" most powerful computer).

I edited some of the early posts in "tiled" following the idea that "Many posts contain parts that would be useful for a chapter (say, one about tiled game engines) but also parts that don't quite fit. So how about having <span> or <div> tags assigning those items a "no-ch1" (or no-ch5 when I'll be at chapter 5) and let the simple.css make them display: none ?"

Finally, 4 days ago, I managed to get all the issues fixed in my scripts and re-generate a good-looking page that I can use in calibre to export an epub file. And because each issue involved a good deal of html snippets and that I'd rather have a clipboard to compare them when that happens, I decided to use codeberg's issue tracking system for that. 



script output, as uploaded on codeberg

what it looks like on the blog

what it looks like copy-pasted in office

what I had from older (2025) script output
We're not fully done, but it's getting in good shape. I couldn't get it printable, though, as the browser seems to ignore the CSS instructions that make it neat and stylish on screen. 
Next points would be
  • recognized purple-colored-text as English
  • if a picture is large enough to cover most of the column width, don't try to make it floating.

A sad discovery while working at all this was that the 72x72 thumbs are no longer automatically provided by the takeout. They might have annoyed me when doing the last conversion back in 2025, but no more than I month later I had figured out that they could be a "magical portal" to posts and uploaded them to neocities.

And now I have another project for those thumbs. I had included the "milestone" tag together with "tiled" to get a bit of reminder of what had already happened and what not between two "tiled" posts, but many of the milestones are too large and distracting compared to what I want. The first paragraph (?), the date, title and the thumbnail would likely be sufficient. Hopefully, I can recontruct some thumbs URIs from regular picture URIs, but I'll need to resort on my drive-archived blogthumbs.zip for the missing ones...  

There's one line of all that that I'd like to bring here. It's the incarnation of "make the possible easy" part of Perl:

$post=~s/src=\"([^"]+)"/src="$larger{$pix{$1}}$escaped{$1}" alt="$1 ; $pix{$1}"/sg; 

In that single line, we iterate through (thanks, g modifier) all the image URLs of a single post and patch them using the hash tables that we constructed by parsing "temporary" files that other scripts produced. No need for split-patch-join sort of loop. 

edit: Some commands used to generate the latest version:

THUMBS=../thumbs/thumbz.html perl ../git/list-atoms.pl ../bilou/feed.atom <(cat ../pictures3.lst ../morepix.lst ../pictures2.lst) tiled '(milestone)' > tm3t.html
where "thumbz.html" is the page featuring a link & thumbnail for every post, which list-atom will look for contents. It needs so many .lst files because I worked on list-
grep '<!-- all images' -A9999 tm3t.html | grep ^i | fe - "cp % /d/local/pages/geds/attach_files/ -v"
I added a flat list of filenames with the pictures at the tail of the HTML file so you can "more easily" cherry-pick the files you need (save-as-html in web browser is doing too weird things)
BLOG=https://sylvainhb.blogspot.com perl ../git/thumbify.pl <(perl ../git/summarize-atoms.pl ../bilou/feed.atom) > thumbz.html
Above: how the thumbs page is generated, below, how I got some -0- thumbs from files that had more normal identifiers. (applied in the folder where I unziped blogthumbs.zip I got from that-time-where-thumbs-appeared-in-exported-data.
ls i* | sed -e 's/\(i[0-9][0-9]*\)-\([^0]\)-\(.*\)/mv \1-\2-\3 \1-0-\3/' | grep -v '^i' > renamethumbs.sh

edit+: fine-tuning keeps going on mastodon

Wednesday, June 03, 2026

autocrlf

I have a git folder that is accessed both by a windows host and a linux guest from a VM (as a shared folder). Everything was fine until some git package upgrade started warning about "in the working copy of 'project.txt', LF will be replaced by CRLF the next time Git touches it" (or the equivalent from the Linux guest).

I'd like to avoid cloning the repository twice and I already have something that makes these file LF-only on the master repository. I set autocrlf = false in .git/config, but that does not seem to help.

The manpages of git are heavy, freaky and intimidating to say the least. But I guess if I had rtfm'd them, I'd have eventually encountered the git config --show-origin --get-all core.autocrlf command, which conveniently reports all the files where the given configuration item. I'd have figured out that while I had my local configuration file requiring "do not do auto-CRLF conversions", the system-global configuration actually had the precedence. ... ridiculus, but that's the way it is now.

git check-attr -a project.txt and git ls-file --eol project.txt could be useful to check the current state as well.

With autocrlf=false in Git/etc/gitconfig, I don't have the warnings anymore, but I still have the file that is switching between CRLF and LF depending on whether Windows host or Linux guest is checking it out. It looks like the only way to get the desired behaviour is to edit * text=auto eof=lf in .gitattributes, at the root of the repository. I want that to remain a local decision, and hopefully, my colleagues haven't committed that file yet, so that'll work.

Saturday, April 25, 2026

Foreground for the underground ?

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

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

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

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

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

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

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

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

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

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

Saturday, April 04, 2026

NDS for DSi

I had announced on some discord channels that I had a new NDS demo of my ongoing work. One of these channels is the one where I'm in touch with Fei, who already tried a copy of the 3-rooms demo back in 2021 and 2023.

Back then, we finally managed to have something running at his place, but it doesn't seem it has been preserved. After locating a register that could tell me whether we're running on DSi (and then skipping the InitGBA function that would blue screen the demo -- as there are no GBA memory around), the best I could get is a "EFS search failed" message, but also a mention that 1) DLDI is around but 2) the demo is installed on Fei's SD card rather than in the filesystem.

Bad news is that I don't see anything in libfat or in libnds that would enable DSi' SD card access, which goes through completely separate hardware and isn't covered by DLDI at all (to my best knowledge). I'm not the only one to have such problems, but there was no answers to be found.

So I guess my best move to make progress there is finally to get homebrew software running on my own DSi thanks to StyleHax...  for that, the next step was to enable a DNS server on the cube. That sounded like a task the rubber duck could take care of and it suggested the following: 

Use a small local DNS resolver (dnsmasq or unbound) bound to the interface and configure only the few hosts to use it via per-interface/etc resolver settings or systemd-resolved split DNS. Since you want minimal config/deps on Ubuntu 18.04, dnsmasq is simplest.

  • Edit /etc/dnsmasq.conf (or add /etc/dnsmasq.d/custom.conf) and add: 
  • interface=eth1 # replace with your interface name 
  • bind-interfaces # ensure dnsmasq binds only to listed interface 
  • listen-address=192.0.2.10 # IP of that interface (optional, stronger) 
  • no-resolv # avoid reading /etc/resolv.conf 
  • add local hostnames: address=/host1.example/192.0.2.101 address=/host2.example/192.0.2.102 

ok, fine. That allowed me to fake some website with some other DNS name, and eventually get stylehax page shown on the DSi, even once making a green screen (exploit worked, but boot.nds was missing) and once loaded the dumptool.nds, but it complained the SD card was too small (it's a 128MiB one) and refused to do anything. Each attempt takes 1-2 minutes, and I'd say the success rate is at best 1:10.

One of my ideas was to use e.g. runME as boot.nds and work directly from there, but from this experience, it doesn't seem to be a viable plan ...  

Maybe I should pay a closer look to the updated nds_loader ? 

Maybe I should check the way GetDeviceOpTab is implemented and try to write something that reports all available devices ? (alt. repo from Patater)

Or maybe I should simply use another hack ? like the Memory Pit for the camera application ? 

edit (25/5): Got lucky with stylehax this morning: every boot.nds made it through in 1 or 2 attempts. So I managed to get DLDI scanning of Dreams-inspector.twl.nds and figured out I had to fix my Makefile to apply efstool processing over that new .twl.nds as well ^^. And eventually, I got Dreamlands 3-room demo running on my own DSi !_!  

Tuesday, March 24, 2026

A few fixes

It should have been a calendar, and somehow I'm using it that way on the "recto" side. But it's a week-by-week calendar, which means it's also a near-A3 rigid laptop with good quality paper that I can use nearly anywhere to write notes about nearly anything. 

But I wouldn't be studying Turing processors this week-end, nor how the 1st Pokemon game stored its maps. Instead I was trying to tackle two old bugs in my editors that affect loading new files in AnimEditorDS and leaving "monsters edition mode" in LEDS. It's not very impressive, but it's releaseversary day, so here it is anyway.

And, well, it seems like it's been nearly one year since I made a release of the Dreamland demo itself. Now that the "WIP" level in the greenzone -- the one I intend to keep and that has been historically the first Bilou level ever -- has an exit door, I can make some release for that as well. Enjoy

  • water slides
  • revised appleman mechanics, including the funny rolling throw
  • connected doors
  • smashing big punches

I'm sure there are plenty of bugs and glitches here and there. This is not a polished demo, more a presumably playable snapshot of the ongoing work.

 

 

 


 

Saturday, March 14, 2026

Dashosaurus and the gamedev afterwork

It's a small game, where you drive a triceratops-like dinosaur, collecting eggs and completing levels while avoiding falling lava bombs. But that was the game Antoine from Sleeping Panda presented last wednesday at the local gamedev afterwork event.

He made the game with Gameboy Studio, one of these recent desktop applications that bring together all the things you need to create software on 8-bit machines -- although here you're largely able to draw stuff in Gimp and lay out maps with Tiled. And you're also able to export your work as HTML5 game in addition to GB and GBC roms, which is clearly a plus to distribute your creations.

Antoine did talk a bit about GB Studio itself, and how that tool let him do things he wouldn't have done otherwise as well as how it would frequently make impossible some things that I'd have thought trivial, like the ability to destroy some of the ground with the lava bombs.

While he was talking, I couldn't help noting that graphics would have easily allowed to make parallax scrolling, but I doubt the events scripting system would have supported such low-level techniques, although -- according to Antoine -- the tool allow to "eject the engine", rewriting some parts to compensate e.g. the lack of Dash support in the platformer character while his game was all centered about dashing.

But the most interesting part of the talk for me was about the reception of the game by gamers. How it caught speedrunners interest while the author of the game did not know of speedrun beforehand. How people started to send him their best time. How people started to make him cover art, contact him to see whether he'd approve patches for retro achievement. And honestly, when I see how many people hype about gameboy and gb studio in general over the networks, I'm not so surprised about it. It was more complicated to explain how NDS is different. Because the nostalgy around the device is still very young. Because technically and legally, producing DS cartridges for homebrew is much more complicated. There are 8-bit catridge manufacturing online now, likely some 16-bit as well. But for DS cartridges I don't expect any such things before again some years.

But nonetheless ... Maybe I should take the extra step that I've never made so far: writing an itch.io page for School Rush because this is where gamers will look for games, not on github or sourceforge. 

Sunday, February 08, 2026

Ripple Dot Zero

Whoa! Seems http://Ruffle.rs has been making a ton of progress since I checked it last. I can now start Ripple and play the first level in my browser Not quite ready for prime time yet (performance is very swingy), but what a great leap! -- Tommislav
That was a tweet of the author of Ripple Dot Zero, about a port of his own game, to wich I added That game is impressive. I definitely owe it a blog post. And he added

Thanks. Send me a ping if you want some "behind the scenes" anecdotes if you do

So, to someone who wasn't playing flash games in 2013, I could describe "Ripple.0" as a fast-paced shooting platformer. If you could extract the core DNA of Jazz Jackrabbit and inject it into a penguin with sleek shoes, you wouldn't be far away from Ripple.0. Now, chances are that the modified penguin would escape its pod and start putting a mess in your facility while attempting to rescue as many of its peers as possible.

Of course, because it's a flash game, I can't point you to a playable location, but there are youtube videos to get an idea of how it looked an played. I played the game back then and was baffled by how smoothly it worked and how large the levels were. Until then, flash game had mostly been 'small online arcade' titles, not something with 4-directional scrolling into Sonic-sized maps.

And the post came dormant again since September '25, where I "met" Tommislav again on bsky, with a collection of links to dig. I'll have to accept to post it as is, because real-life is quite demanding these days, and even dropping a few more lines to an ongoing post while things compile haven't occurred in ages ^^". So here they are, in their imperfect, wabi-sabi beauty:

Sunday, January 04, 2026

I must make some isocahedron gem!

This is a screenshot from @makeshifted, back in December 2022, that showed up in the last snapshot the Internet Archive could take of my twitter timeline. A repost with the annotation "3D was *that* awesome back in the Assembly 9x #demoscene days."

It showed up again a few times ago and I told to myself "you know, those stonekeys in Commander Keen ? Well, if I can make NDS 3D look that sleek, I won't need to pixelstudy them!

And it appeared again, posted by @benji__t this week-end while I'm doing my farewell tour on twitter.  

One possible system of Cartesian coordinate for the vertices of a regular icosahedron, giving the edge length 2, is: where denotes the golden ratio. -- https://en.wikipedia.org/wiki/Regular_icosahedron --

https://upload.wikimedia.org/wikipedia/commons/thumb/f/f4/Coxeter%27s_snub_octahedron_from_octahedron.gif/100px-Coxeter%27s_snub_octahedron_from_octahedron.gif
Oh! look at that ...  

Take a tetrahedron of psi, split summit so that it turns into a 2-edge, and voilà! isocahedron !

- - - 

those words above were written around the 19th of February, last year. I haven't written a single line of DSGL to make it appear in the infinite pyramid, and while I initially thought of using it as keygems, I realise that what they really be are the "magic stones" that you collect after defeating bosses.

Monday, December 29, 2025

Slides testing

I've been re-drawing the water slides directly on the "three rooms" test screen, because it feels easier to prototype there than within the reconstructed green zone level. Then I've been prototyping different things about it that I had in my notes ... only mostly ruling out some options so far. For instance, the idea of re-using the sprite of waterjets to avoid issues with waterfall-to-slide transition should be forgotten ... it helped me coding something to select the layer where Gobs should appear ... one of the things I'll need for the smashing fist.

Another such test was placing some special tiles along the slide, in an attempt to make them trigger some "fall and slide on slippery ground". 

That failed. Almost completely. I had to create an empty animation just to avoid the normal "special blocks handling" from deleting chunks of the slope as soon as Bilou touched them.

I also had to drop the idea of placing "jet" tiles in an attempt to push Bilou harder out of the slope at its bottom : they allowed (but only sometimes) Bilou to hover the whole slide upwards ! 

Saturday, October 19, 2024

Newer collision flags

It wasn't as easy as I wanted to make the "soft land" mechanism work, and knowing that Bilou will have to attach to an invisible block for it to work with the "bumping branch" rather than to the branch itself will make it even a bit harder. The issue is to allocate new "kinds of collisions" in an already crowded 16-bit space.

That issue is not new: it already appeared when I wanted to add pick-and-throw mechanism together with get-your-feet-back while I was just done with direction tiles for inkjet. Each of these would require about 4 different type of "messages" exchanged between game object and I had barely more than 8 flags left... And the solution had been to use some combination of bits for the different things. So you'd still have 0010 saying "up" and 0020 saying "down", but that would only be valid in connection with 0100 that says "direction tile" and not with 0400 that says "interplay" or with 0800 that has been used to collect feet and animate ink level in pipes.

I've got notes already about addressing that, but they mostly question the fact that there are only two "casts" (read game object lists) in the engine: heroes and foes. And that actually address a different issue (collision performance) although they somehow partition "messages" as well: almost only Bilou can receive a "HURT" collision (well, blador receives it too from spiky pencils tiles so it can align with them and this is likely BadDesign ^^")

And well, introducing bridges and things like that could easily use more casts to keep good performances: both heroes and baddies will collide with bridges, but that doesn't requires baddies to test each others to work. And likely only part of the bridge internal.

I had collected a set of questions on my new notes, and one of the first one got its answer: despite we have only 16 bits communicated to the script about what truly happened in a collision, a full 32-bit number is stored internally. Some of the high bits are already use for special purpose such as "keep checking collision even after a first item was found" or "only consider objects attached to me", but plenty others could be used to restrict the scope, e.g. creating a private "namespace" between blador and blador feet so that the feet cannot accidentally attach to an inkjet (although maybe that's redundant with "must be attached to me"). It makes little sense to keep the upper 16-bits as "flags" and process them the same way the lower 16-bits are processed (a single matching bit and bingo, we have a collision) because we would be unable to identify which flag had a match. Did we caught fire ? or get smashed ? or got an electric shock ? no way to find out.

So the plan would be the following:

  • 8 "casts" (lists) seems a good number. Each test area indicates exactly which cast it tests. If we have casts Evil and Bridge and need to test both for STOMP, then 2 test areas are needed.
  • two three "control" bits: ALL, ATTACH and Reverse-ATTACH (fact-checked against Aug'25 commit)
  • 16 "flags" bit: a collision occur as soon as two masks have at least one in common
  • 8 10 "namespace" bit: a collision occur only if the two area exactly use the same namespace 
  • any other are reserved for future extensions.

Saturday, August 24, 2024

game design with Super Sunny World

There is a NES game in the making. Yes, a new one. A homebrew, of course. There are quite a few ongoing, actually, but this one features artwork from Kenneth Fejer ! and aims at cloning the gameplay of Super Mario Bros in a different setting. And I must admit I'm loving the simple charm it has, and I've been using Matt's posts on Super Sunny World as a sandbox to toy with game design ideas since March '23 the same way I did with Cyber Shadow a few years ago.

Matt proposes "grow up" power that sits still and "fire" power-up that slides away (like a SMB mushroom). Personally, I feel like both sliding and sitting idle do not fit the power-up personalities. I'd like the "grow-up" flower to have a little motion. To make it easier to grab than Mario's mushroom, it could be floating down towards the player. (post-thought: that might be luring a bit too much into Leilani's Island gameplay ^^")

Also, it feels odd that the pearl slides since it is in a shell but if it was a bare pearl, it would perfectly work to see it rolling away. I'm afraid it moves a bit too fast now and I'm unsure you could catch it unless you realized that you can run, which most young player won't. And even if it is only barely faster than yourself, 

Another follower, XPascalou, points out that In Super Mario Bros, players have to work to get their power-ups. It is not "free". Players have to master "run & jump" to catch the mushroom or the star. The star is even harder to catch because it gives much more power. That's true, but level designers put some surrounding elements so that early mushrooms are redirected towards you. (that would be interesting to study SMB1 maps to see how often that happens and when the games start making you take risks for a mushroom, then compare that with SMB3 and Giana Sisters)

Sometimes, it's just a tiny interaction, like when Matt announce he has adjusted the "hit range" for going down tree trunks, and now allows the player to trigger the transition when "duck sliding" across the top. But by all the hours spent on Super Princess Peach ... Thank you, Matt.

Sometimes, there's more meat, like when Matt wants to introduce a cousin to the snail (his default koopa-like creature). But as much as I love its look, with spikes-like on the shell, it looks more like it's deadly to jump on its head and seeing it shielded against shots was a surprise. (I guess I must unlearn to think of them as fireballs ^^"). It would be nice that the shots would slightly bounce them backwards (unless they entered the "stick to the ground" state after they bounced once, possibly).

Of course, for a programmer, it's always nice to get crusty details about what did not really went right, like how initially, shots would be "swallowed" by blocks 1 tile about the ground. Especially because that feels like something the Giana Sisters would have featured, and thus gives a new light on why there were such weird behaviours in that game.

It's nice to see other platformer authors come up with creative alternatives like waterfalls we can swim in ... rather than artificial ladders or elevator that would have felt out of place in the Sunny's world setting. +1 for using white clouds at the bottom of waterfall only when it is swimmable (it wasn't the case initially, and it will definitely help distinguish interactive and decorative waterfalls). I think mixing swimmable and non-swimmable waterfalls will be very demanding for non-expert players and should only be done if there's plain ground to catch us if we're confused. The way that waterfall is placed in the level perfectly introduce the mechanics in a no-tuto way, too ^_^

And then there are the cases where Matt's post make me think "uh. No. I wouldn't do that in my own game", like with the fishes:

fun twist on the "flying cheep cheeps" 🐡 for my NES game, Super Sunny World 🌞! Instead of just jumping and falling, they land and slide across solid surfaces. Maybe I should replace the fish sprite with a penguin sprite

Maybe they could either slow down and become immobile hazard on the ground or fall back through the ground once they are done bouncing ? I like them being fishes. Sliding penguins only work with slippery ground (and well, so could fishes, if ground is slippery) oh. Or they could slide to a stop, then miserably try to avoid you with ridiculously small jumps. Possibly jumping faster if you approach them.

I could try it, but my plan it to have 3 of those active at the same time, at all times, so my instinct is the keep the movement very linear and consistent, to allow the player to more easily track 3 moving enemies flying around the screen.

Okay, a last one, because that was on my blog-me list for such a long time:

Did you ever notice: In Mario 3, if you hit a block that bounces up, it pushes mario downward faster than if he hits a solid block?

I noticed that while playing "Croc World" demo which was lacking it. It felt cheap. I think Mario's Y speed is reverted while bouncing on an active block. On a solid block, the speed is simply set to 0 so it takes a little time to start falling down. Note on Matt's video how the same question block is active when flashing and just solid once empty. That surely contributes to how the game communicates what is interactive and what isn't.


Monday, February 15, 2021

Your First Koopa ...

As I was enjoying my free week of Super Mario on Switch, I found it interesting to compare how we are introduced to Koopa Troopa mechanics in Super Mario episodes. Because, yeah, I'm fond of Koopas mechanics. 


Koopas are dangerous, but you can turn them back at their allies (same for dumbladors, you'd say). And you can dispatch many of them at once that way (unlike dumbladors) if you follow it closely enough. But then it can trick you if it bounces on a wall.

In SMB1, you're welcome to kick in and dispatch 2 goombas, then another 4 if you're running after the shell, but then it will bounce back at you. To some extent, your first experience with Koopa Troopa is the full experience. Dangerous/helpful/treacherous. You're warned: this is what the game has for you.

You'll have to clear about one half of that level before you can see your first koopa, though. And you can easily miss the only one of the level if you take the secret pipe.

SMB3 comes with something new for you. Koopas shells can now be used to unlock contents of question blocks that lay on the ground. This can be discovered from the very second screen of the first level!
 
Note how you can decide not to face it by sneaking under the green block or escalading the pink and white blocks to easily jump past it. Note, too, how the shell bounce on the question block may be harmless as it will be cleared out through that 'under green block' route, optionally dispatching a goomba. (That might possibly be a bit too much complexity packed into one first screen, but it surely offers you plenty of alternatives and replay value).
 

Weird enough, the first koopa in SMW is not in its shell. It falls towards you at the very start of the level, giving you only a few seconds to find the JUMP button. Its shell awaits you nearly half a level away, ready to let you discover you can kick things upwards. 

But we all know the real first level in SMW is Yoshi Island 2, where plenty of koopas await you, harmless unless you decide to face them, and a free shell ready to line them up for a free 1UP

When you do so, there is high chance that the shell will eventually slip past the edge of the screen and be discarded by the game engine. You're safe. pfewh. You'd have to race the shell for more than half a level before it eventually bounces on a solid stairs-like structure.

This, my friends, is the price to pay to have a 'first' level where you have no risk of falling into a pit before 3/4th of the level. 

Thursday, October 11, 2018

Amy Zing

It only took Ant a few days to include my little "Amy Zing" sprites into his neat labyrinth crawler homebrew, actually. For some reason, I completely missed it by then (March '18) and only realised that the game was released thanks to some anonymous internet folk who followed a link from simian zombie web site to mine, leaving a mark into the logging system which I tracked backwards to hit the page with the release.

So I grabbed the game, enjoyed it, enjoyed again, tried the various resolutions (normal is my favourite one) and smiled: that was my first ever homebrew collab as a spriter ^_^. And then started to wonder... Could such simple labyrinths work for Bilou, under gravity ?

I traced some of them in a notebook and started to check where I would put collectibles or hazards and why. In a platformer, you shouldn't (imho) try to make your labyrinth with individual blocks, because the player will need some room to manoeuver. If I pick 4x3 Bilou-sized blocks as a "maze cell" (3 blocks being a standard jump height), the maze now scrolls over 4x3 screens. You can no longer plan your move easily with that limited visibility, so you'll end up more often in dead ends and will have to back-track. Hence the rewards and hazards.

And well, Imho, with properly tuned jump distances and some wall-kick mechanics, you might not even need fancy ladders or similar tricks to support those labyrinths.

That's not quite "infinite pyramid", but it could be a nice step towards it.

edit: good news: my 5-year-old J.L.N wasn't afraid of the half-dead monkey and accepted the maze game as something to do when he's bored.

Friday, March 30, 2018

Aladdin Sources Analysis

They made a wonderful job at gamehistory.org, based on an in-depth analysis of the sources of the Mega-drive game "Aladdin". The game was made by David Perry's team who also brought us Cool Spot. At the core of their work is a technique and a toolset to allow more flexibility in animating graphics on 16-bits system that had read/write video memory on-board (as opposed to NES with read-only video memory alone, on the cartridge) and fixed-size sprites (e.g. 16x16, 16x32, 32x32).

https://gamehistory.org/aladdin-source-code/#sect_36Everything else will seem silly to you if you do not accept that, by then, getting more KB of memory for your game was very - very - hard. The size of your game was decided by non-technical people based on how much the console vendor would charge for a 2Mbit chip, when the game should came out and how much kids would be allowed to spend given which license you'd be using. So they have early planning deciding how much to dedicate to sprites, levels, code, maps, etc. Based on that, they'll decide how much levels there will be in the game, etc.

Of course, game characters animation all started by having characters whose size fit the hardware requirements (mario nicely stands within a 16x16 box and a 16x16 mushroom makes him 16x32), flipping from one sprite to another within an all-in-VRAM bank. Then some special characters (the hero) would get a special status and only get one or two VRAM slots dynamically updated. To crunch more animation frames, one could use run-length-encoding compression that does wonders on row of pixels of identical color. Others have used 2/3-bit-to-4-bit decompression once realizing that Link sprite (and all others) only need 8 colors per palette, not 16. But all this requires CPU, and the CPU resources too, were limited (Not even 8MHz. Less than my good old 80386).


If we could instead keep the same binary format between the ROM and the RAM, having the right picture in video memory at the right time is all a matter of "blasting" them through the Direct Memory Access chip. See that big line on my notes ? that's the DMA doing its job, while the CPU can focus on crunching numbers to make the game physics stunning and fun...

To make that possible with fun stretch-and-squash, cartoon-like animation, they ultimately relied on their chopper tool that cuts pictures into hardware-sized sprites. Just like the one I imagined for Titus's Prehistorik II sprites.

Ok, granted, it doesn't look completely automated. But the idea is clearly there. And ultimately, it would run on a system that has 1/4 of the power of my Nintendo DS.

So, am I allowed to dream of porting some libgeds game on 16-bit engines ? Well, with the engine refactoring that splits script parsing, it is pretty tempting to see what we could do about it.


Let's start with the animations, thus. What is weird with the animations is that their code has to interrupt every here and there when there is some delay. In high-level language, we'd likely use a switch construct branching you to frame T or frame T+1 code depending on some argument we'd pass to the function. But if we're generating machine code instead, we can do much better. We can then have the actual next animation instruction remembered, rather than an index into an array of virtual instructions. No more conditionals and branch delays on that non-speculating old CPU. Just one jump.

Implementing "keep that state for N screen refreshes" is then looking a lot like software multi-threading: you have a call to some yield_animation micro-routine (and saving your current position into the generated animation code on the stack), which will pop that resume position into some CPU register (an internal scratch variable, in case you didn't know yet), and then return to the code that called animate_aladdin, letting it save the next animation position where it sees fit. Looping animation ? super-easy ! Have you seen how much boilerplate the current virtual-RISC-processor-for-animations of libgeds and AnimEDS must deal with instead ?


What else ? State machine of course. State machines are built with simple expressions used either to guard transition (only let them used when some condition is met) or to define what to do when the transition occur (besides changing states, that is, like playing a sound, changing speed, etc).

The collision system currently will follow a list of GobExpressions calling eval(guard_predicate) until one returns true, then proceeding with eval(action) and changing state. Instead, with generated machine code, that would all be packed into a sequence of predicate code that branch to the appropriate action code or keep testing until we hit the "okay, then nothing happens" terminator that returns to the collision system itself.

One day ... maybe. That would be much more interesting on 16-bit than it would be on DS or native x86_64 code, anyway.

edit: for more background information about how things actually came into existence, seeing tools and teams in action, don't miss the excellent "Splash Wave" episode on the game.
 

Saturday, November 18, 2017

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.

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


Bug 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!


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