The ability to write Python on microcontrollers with the likes of MicroPython and later CiruitPython has made them much more accessible. [MakerClassCZ] brings that to game development with PicoGame.
Like any good project, it starts with a problem that needs solving. Put simply, the existing CircuitPython libraries aren’t too impressive for gaming. The DisplayIO library tends to do full display refreshes, which are slow on such tiny displays, and the Stage library just wasn’t flexible enough for [MakerClassCZ]’s liking. So he built his own.
PicoGame, like the others, implements the performance-sensitive things in C, but does partial updates for the screen, on its own massively increasing the framerate. On the other end, it uses fixed-point math–much cheaper than soft-float–and makes an active effort to keep the RAM usage low so Python can have it. What’s even more clever is using the downtime between sending one tiny portion of frame to calculate the next just in time.
Of course, the display is still the limit. If you need to update a lot of it, you might end up with 10 FPS if you’re lucky. But if you can settle for less motion, you could see 100.

This sounds like it could be wonderful just for making user interfaces. I’ve used PyGame to make embedded UI before, and it is much easier than doing the same with purpose made tools.
User interfaces aren’t picogame’s strong suit… However, my experience developing picogame has led me to create a simple GUI library that’s independent of Picogame (although it could serve as one of its backends). But it’s not finished yet… https://github.com/MakerClassCZ/picogui + demo https://picogame.makerclass.cz/playground/?game=uikit_settings
thanks for letting me know! I’ll check it out.
“ CiruitPython” —> “CircuitPython”
#DeleteThisMessage
if you like gaming on a microcontroller I made pico8 run on the stm32 so you can write games in Lua.
Any link to your work?
+1 I’d like to try it out. pico8 on bare metal is damn nice. If you documented how you did your port that would be awesome guidance for people porting on other platforms.
Lua? No tinyLua or something?
I think one if of the slowest python happy micro controllers i use regularly is a samd21 clocked at a weird ass 84MHz, and you’re telling me I can make intellevision grade games that run at 10fps on something that should … on paper kick a 80386 right in the dick?
God I love python
Well a 80386 had a lot of additional components, foremost a GPU. You can’t really compare MHz when you have different architectures, not just inside the CPU but also outside on the system. Sure 84MHz is a lot more than a typical 386SX at 25 MHz, but supporting systems make quite a difference.
For instance;
The Commodore PET and the C64 both have a 6502 CPU, but the additional system components make quite a difference.
The main handicap with these microcontroller based devices is the SPI bus, which seems to be limited under 10 megabits per second in the typical case, while a 386 machine with an ISA bus video card can reach 8 mega bytes per second which is 64 Mbps.
Note: SPI can operate faster, the individual devices can’t.
I always get confused with micropython vs circuitpython. So this is circuitpython only? Is it because circuitpython is more suitable to micropython? I thought that circuitpython wasn’t able to make use of second cores? To me using both cores seems valuable to games…
The firmware is CircuitPython, but the engine is a portable C module – the same code already runs on MicroPython in the browser playground, and proper MicroPython support is in the works. So it’s not CircuitPython locked.
I went with CircuitPython first for the ecosystem, not speed: displayio, ready-made board definitions, settings.toml, and the code.py on the “flash drive”. It is easier for beginners and classrooms.
On the second core – you’re right that CP doesn’t expose it. But honestly it’s not the main lever here, because it adds synchronization complexity. The actual bottleneck is the SPI display push.
@HA: CiruitPython
See? Why do we still do FPS in computing, with most of it being static GUIs?
Because the CRT display in 1970 relied on it?
Because often you do need to update the entire screen, and then it’s going to look bad if you can’t do it fast enough.
I hate this mindset of “the average is enough”. It’s what ruined digital television – the averaged metrics show that the image quality is almost perfect, but the actual image looks like shit any time the camera moves.
Imagine watching a nature documentary on digital broadcast TV, the camera pans over a majestic savanna with distant mountains in the horizon…. and the mountains stop moving while the rest of the scene pans on, and the whole thing jerks and snaps in place every 2-3 seconds because there’s not enough data for motion prediction between the key frames.
Plastic foreheads and faces on people, grass disappearing and appearing on a football match, stuttering films and documentaries. Why is this “better”? It’s garbage – the only difference is that now we have 12 times more of it, because they crammed so many channels in the bandwidth of one.
lvgl + micropython also works well and it’s fast. Not specifically for games, but has lot of things ready made for a game GUI.