| Engine | Pico-8 (recent) |
|---|---|
| Language | Lua (Pico-8 dialect) |
| Collision | Tile flags via mget/fget |
| Time to run | ~3 minutes |
| Level | Beginner |
| Output | player table + _update/_draw hooks |
| Dependencies | None. Pure Pico-8. |
The prompt
Open a fresh chat at claude.ai/new, paste, and send.
$ Build me compact Pico-8 Lua for platformer movement with tile collision. -- shape - A player table with x, y, dx, dy, and a small w/h collision box. - Provide upd_player() to call from _update and drw_player() to call from _draw. - Keep it compact and token-aware (Pico-8 idioms: btn, mget, fget, flr, abs). -- movement - Left/Right (btn 0 / btn 1) accelerate dx with a run speed and friction. - Gravity adds to dy each frame, clamped to a max fall speed. - Jump (btn 4) sets dy negative when grounded. - Coyote time: allow a jump for ~6 frames after leaving the ground (a small counter). -- tile collision - Solid tiles are marked with flag 0 in the sprite editor. - Move on X then resolve, move on Y then resolve, checking the tiles the box overlaps with mget + fget(tile, 0). - Set a grounded flag when a downward move is blocked. - On landing, zero dy; on hitting a wall, zero dx. -- constraints - Use a helper like solid_at(x,y) that maps a world pixel to a map tile (flr(x/8), flr(y/8)) and returns fget(mget(tx,ty),0). - No object-oriented boilerplate. Plain tables and functions. -- return format - The code only, ready to paste into a cart. A one-line note on setting flag 0 on wall tiles.
What this gets you
The movement core of a Pico-8 platformer, done the Pico-8 way: tiny, token-conscious, and colliding against your actual map tiles rather than invented boundaries. Coyote time is in from the start, so the jumps feel fair even on a 128-pixel screen.
Because collision reads the solid flag, you build levels in the map editor and the code just respects them. No separate collision data to keep in sync.
Why it matters
Flag-based collision is the Pico-8 idiom
Checking mget/fget against a tile flag is how Pico-8 platformers collide. It ties collision to the map you draw, so level design happens in the editor, not in code. Hard-coding walls is a dead end the moment you add a second screen.
Resolve axes separately
Moving and resolving X, then Y, is what stops the classic corner-snag where a player catches on tile seams. Doing both at once produces jittery, sticky collision. This is the single most important structural detail.
Coyote time still matters at 128px
Small screen, same human hands. A few frames of grace after leaving a ledge is the difference between tight and frustrating, and it costs one counter variable.
What good output looks like
- A solid_at helper maps pixels to tiles. Look for
fget(mget(flr(x/8), flr(y/8)), 0)wrapped in a helper. Collision that does not go through mget/fget is not reading your map. - X and Y are resolved separately. Movement should apply and resolve one axis, then the other. A single combined check is the tell of snaggy collision.
- Grounded is set from a blocked downward move. The grounded flag should come from the Y resolution blocking a downward move, not from a fixed floor y.
- It is compact. Pico-8 has a token budget. The code should use short idioms and avoid OOP boilerplate. If it reads like verbose desktop Lua, ask for a token-tighter version.
How to wire it up
- Paste the code into your Pico-8 cart.
- In the sprite editor, draw your wall/ground tiles and set flag 0 on them.
- Draw a level in the map editor using those tiles.
- Call
upd_player()from_update()anddrw_player()from_draw()(aftermap()). - Run. Walk off a ledge and press jump a few frames late, it should still jump.
Common gotchas
The player falls through the floor
The tiles do not have flag 0 set, or solid_at is checking the wrong tile coordinates. Confirm flag 0 is on your ground sprites and that solid_at uses flr(x/8), flr(y/8).
The player snags on flat ground
X and Y are being resolved together. Split them: move and resolve X, then move and resolve Y.
Jump feels stiff near edges
Coyote time is missing or its counter resets too early. Start the counter when leaving the ground and allow a jump while it is above zero.
Where to go next
- Animation. Swap sprites based on dx and grounded, flip with the last direction.
- One-way platforms. Use a second flag and only collide downward through those tiles.
- Pickups. Read a coin flag on the tile the player overlaps and mset it away when collected.
Use it however you want
The prompt is CC0, paste it, modify it, ship a game with it. The output Claude gives you is yours. A link back to pixeldex.dev in your project's README helps the next solo dev find this stuff.