kartoffels v0.7: Cellular Automata, Statistics, 32-bit RISC-V
kartoffels is a game where you're given a potato and your job is to implement a firmware for it:

ssh kartoffels.pwy.io
|
source code
Today I've released v0.7, which spans 122 commits and brings:
Cellular Automata Worldgen
Rooms are nice. I like rooms. Who doesn't like a room or two? They remind me of my favourite movie, they are great. Anyway, at least that's what I thought when I started implementing kartoffels:

Everything changed when the Fire Nation atta I learned that you
can use
white noise paired with cellular automata
to generate some real nice-looking caves. Real. Nice.

Here's the algorithm in live action. Seeing CA generate plausibly looking caves out of pure noise is purely amazing:
My algorithm mostly follows recommendations given by roguebasin.com, with the only major difference being in handling isolated caves.
You see, this entire algorithm is prone to creating disconnected parts of the map:

This is problematic, because kartoffels can't drill (and implementing drilling mechanic would come with its own bag of problems...), so a robot with a bad luck would just get spawned into one of those tiny caves and avoid all of the Fun.
There are a couple of solutions to this problem - some smarter, some... not so much. You could, for instance, join all the sub-caves together into a larger cave system, possibly using Langton's Ant to make the corridors looks more natural.
I have tried that, I have failed - brute force now is my name.
(to be specific - I couldn't get the corridors to look nice, you could always see something's off there)
My current approach simply discovers all caves on the map using flood fill and then fills all caves except the largest one with stone. If after this operation map ends up containing less than 50% of stone, it is rejected and the worldgen is repeated on another seed.
To avoid being a frustrating experience for the players ("did the entire map just reset ???"), all of this actually happens before the animation - by the time the map is presented, we already know that its seed is golden.
Statistics
Following the example of Google, Amazon, and a couple of other companies, the engine now intimately tracks the history of each bot - recording every birth, death, movement, and stab:



There are no world-wide leaderboards yet, but the data is being recorded - I'm hoping to implement things like "what was the best bot in the previous 24h" in the next version.
32-bit RISC-V
Each kartoffel is equipped with an arm, compass, motor, radar, serial port, and - of course - a CPU!
Up until this version, the game emulated the 64-bit RISC-V architecture (aka RV64) and this version changes it to the 32-bit one (aka RV32). There's a couple of reasons behind this:
-
Each bot has only 128 kB of RAM, so there's no point in providing a 64-bit address space.
-
RV64 has more instructions, making it the more difficult variant to emulate.
In particular there's a lot of instructions such as "do this, but in 32-bits" (e.g.
addiw
) that you simply don't have to implement otherwise. -
Binaries compiled for RV64 are larger.
This of course depends on what your program (firmware) actually does, but the heaviest bot I have weighs 59 kB compiled for RV64 and just 50 kB compiled for RV32. It might not seem like a lot, but since the firmware's size counts towards RAM usage, and you're given 128 kB for everything, every kilobyte counts.
Unfortunately, especially paired with the worldgen change, this has forced me to reset the server, wiping all the bots uploaded so far. Let me honor the memory of some of the souls that perished:





Interface changes
Next to all the new goodies, a couple of already existing windows and
widgets got redesigned - in particular the bots
dialog
can now be fully operated using just the keyboard:

Other things
-
Bots can now move backward.
-
Couple of cooldowns got changed, especially around motors.
-
API documentation got reworked to be more thorough.
-
Engine got reworked to use
bevy_ecs
, viva la schedulation. -
If you don't want to or can't play the online version, you can now build and run kartoffels locally. This has always been supported, it's just that now the instructions (n.b. rather straightforward, since it's just a Rust project) are written down in README.
Anyway, come and play! (or
ssh kartoffels.pwy.io
)