Run WebAssembly (WASM-4) games on small devices.
Gamgee is a WASM-4 games emulator written in Rust and designed to be executed on devices with very little memory and space available. Currently, it supports only Adafruit PyBadge but we plan to add more in the future.
Features:
- πΎ Small size. The binary is just about 270 Kb, and it includes wasm interpreter, allocator, graphics library, a custom font, etc.
- π Small memory requirements. The runtime itself needs just a few kilobytes of RAM and the rest is fully available to the running game.
- πΉ WASM-4 compatible. It can run any WASM-4 game (and there are quite a few) as long as it fits into memory.
- Install Rust.
- Install task.
- Connect PyBadge and turn it on.
- Press the "reset" button twice on PyBadge to put it into the bootloader mode.
- Flash a game onto the device:
task flash -- $PWD/watris.wasm
. The path must be absolute (hence$PWD
). - Press the "reset" button on PyBadge once to refresh the screen.
- PyBadge screen size is 160x138. WASM-4 games expect 160x160. To fit the image, we skip every 5th line.
- WASM-4 games expect 60 FPS but the PyBadge screen is limited to 20 FPS and then there is often just not enough CPU to keep up. The solution is to try calling the
update
callback as many times as possible but draw only every 5th frame. However, the games can still be slower than they should. - PyBadge screen uses 16 bits per pixel for colors. WASM-4 color palette is defined as 24 bits for each color. We translate the color palette to pybadge colors as close as possible but the colors might look a bit different from (not as vibrant as) what you see on your PC screen.
- PyBadge has 192KB of RAM, and a few Kb are needed for the runtime itself. WebAssembly memory is allocated in pages of 64 Kb. So, we can allocate only 2 pages (128 Kb) of memory for the game to use before crashing with OOM. It's enough for most of the games but not all of them.
- Unsupported:
tone
(playing sounds). PyBadge doesn't have a speaker by default. You can attach your own but I don't have one yet. PyBadge has a built-in buzzer but that's not enough for WASM-4 games. - Unsupported:
diskw
anddiskr
(persistent storage). The unused flash space can be used to store additional data, and we might use it for these two functions. However, I haven't seen a game yet that would use them. WASM-4 provides game save by dumping the whole game state, so games don't neet to implement their own save system.
I want to thank:
- Ron Evans for inspiting me to do the project and helping me to figure out some PyBadge quirks
- Robin Freyler for maintaining wasmi and answering my questions about how to make Rust borrow checker happy.
- Creators of all other dependencies that the project uses, including pybadge-high, embedded-graphics, atsamd, and embedded-alloc.
And thank you for using the project