EngineLÖVE 11.x
LanguageLua 5.1 (LuaJIT)
Time to run~4 minutes
LevelIntermediate — comfortable with Lua tables and OOP-via-metatables
OutputOne module (~120 lines), ready to require
DependenciesNone. Pure Lua.

The prompt

Open claude.ai/new, paste, send.

$ Build me a tile-grid collision module for LÖVE 11.x in pure Lua.

// shape
- A module returned via "return Collision" exposing:
  - Collision.new(tile_grid, tile_size) → returns a world instance
  - world:move(entity, dx, dy) → returns actual_dx, actual_dy, hit_horizontal, hit_vertical
- entity is a table with x, y, w, h fields.
- tile_grid is a 2D table where grid[y][x] = tile_id.
- A tile is solid if tile_id > 0 and not in the world.passable set.

// behavior
- Move axis-separated: resolve X first, then Y. This avoids corner snags.
- For each axis, compute the candidate AABB at the new position, query overlapping grid cells, find the first solid one in the direction of travel, snap entity flush to its edge.
- If no collision, accept the full motion.

// extras
- world:set_passable(tile_id) and world:set_one_way(tile_id, "up" | "down" | "left" | "right").
- One-way tiles: only block when entity is moving in the blocked direction AND was not already overlapping the tile.

// constraints
- No global state. Each world is independent.
- No external libs. Bump.lua-style API but reimplemented.

// return format
- One file collision.lua in a code block.
- Include a 10-line example showing how to use it from love.update.
- No prose before or after.
Open in Claude ▸ Run · 4 min

What this gets you

The collision system that's "good enough for jam, good enough for shipped indie." Nothing fancy, no broadphase optimization, no rotated AABBs. But the axis-separated resolution avoids the most-common collision bug (catching on tile corners), and the one-way platform support is the thing that makes this go from "tutorial code" to "actually usable".

Quick checklist

Full breakdown coming soon

The deeper writeup with slopes, swept-circle alternative, and a worked platformer example is on the roadmap. Bookmark this page or check back on the blog.