Skip to content

Coming from another engine

If you’ve shipped games before, this page gets you productive fast: how picogame’s model maps to tools you know, what it can do, and where its limits are. For the underlying ideas in plain terms, see How picogame works; for exact signatures, the API reference.

The one thing that’s different: retained mode + dirty-rect

Section titled “The one thing that’s different: retained mode + dirty-rect”

Many 2D engines are immediate mode: every frame you clear the screen and redraw everything. picogame is retained mode: you build a Scene of objects once, then each frame you mutate them and call scene.refresh(). The engine figures out which rectangles changed and redraws only those, sending just those pixels to the display. You don’t clear, you don’t blit-everything, and you don’t manage a framebuffer. This is what makes it fast on a tiny chip — and it’s the main mental shift coming from Pygame/SDL.

One consequence to remember: if you mutate a bitmap’s pixels in place, the dirty-rect tracker won’t notice — call sprite.touch() to tell it. Swapping sprite.bitmap/sprite.frame or moving the sprite is tracked automatically.

You want…Pygamedisplayio (CircuitPython)PICO-8picogame
An imageSurfaceBitmap + Palettesprite sheetpg.Bitmap(data, w, h, …) (PAL8 or RGB565, multi-frame atlas)
A movable objectsprite.SpriteTileGridspr()pg.Sprite(bitmap, x, y) (anchor, flip, frame, scale, angle)
The scene/worldGroup/manualGroupthe screenpg.Scene(...) — retained, dirty-rect
Draw itscreen.blit()add to Groupspr()/map()scene.add(obj) once; then scene.refresh() per frame
A tiled levelyour ownTileGrid+Bitmapmap()pg.Tilemap(tiles, cols, rows)tile(x, y, value)
A scrolling cameramanual offsetGroup.x/ycamera()scene.set_view(ox, oy) (world bigger than screen)
The main loopwhile, flip()while, refresh()_update()/_draw()while: buttons.poll(); …; scene.refresh(); clock.tick()
Inputpygame.eventkeypad/pinsbtn()picogame_input.Buttonsis_pressed() / just_pressed() (poll() for the bitmask)
Soundmixeraudiocore/audiopwmiosfx()/music()picogame_audio (tone(), .wav)
CollisionRect.colliderectmanualmanualpg.collide(...) / picogame_collide (zero-alloc, off sprites)
Textfont.renderlabelprint()picogame_ui HUD / picogame_font → Bitmap
Many bullets/enemiessprite groupsmanualmanualpicogame_pool.Pool (fixed pool, no per-frame alloc)
Transformstransform.rotatelimitedspr flipssprite.scale (float) + sprite.angle (deg), nearest-neighbour
  • Arbitrary-size sprites with anchors, flips, multi-frame animation atlases.
  • Runtime scale and rotation per sprite (nearest-neighbour affine, no FPU needed), about an anchor.
  • Tilemaps you read and write at runtime (use them as game boards, not just backgrounds).
  • A moving camera (set_view) over a world larger than the screen, with fixed (HUD) layers.
  • Particles, a drawing Canvas (retained shapes), and StripDraw (zero-RAM full-frame effects like a pseudo-3D road).
  • Audio (PWM tones + .wav), NVM save for high scores/settings, a bundled font + HUD helpers.
  • A desktop simulator: the same game code runs on your PC (headless screenshots or a live window), so you build and debug without hardware.

Where the limits are (design around these)

Section titled “Where the limits are (design around these)”
  • Tiny RAM. RP2040 has ~138 KB of usable heap (RP2350 ~520 KB). Assets dominate. A full-screen Canvas(320, 240) is ~150 KB — don’t. Band it, tile it, or use StripDraw. Big sprite sheets stream from flash one frame at a time (StreamSheet). See Fit it in RAM.
  • One display, no GPU. No shaders, no alpha blending. Transparency is a single transparent index/colour; for a darken effect there’s a shadow mode. Transforms are nearest-neighbour (crisp at integer scales, shimmery at fractional).
  • Paletted art. PAL8 is 1 byte/pixel (cheap); RGB565 is 2 bytes/pixel. Build colours with rgb565(r, g, b) — never raw 0xRRGGBB.
  • Few buttons. D-pad + A/B (and sometimes X/Y). Design controls accordingly.
  • Ship .mpy, not big .py. Compiling a large source file on-device can MemoryError; pre-compile to .mpy. See Run on hardware.
  1. Skim How picogame works (5 min) for the loop + dirty-rect model.
  2. Copy the first game and run it in the simulator to feel the API.
  3. Keep the API cheat sheet and feature guide open while you build.
  4. Steal patterns from the examples — 30+ genre ports, each a working game.