A small game engine written in Odin on top of raylib — named for Odin's spear:
- Lua scripting with a dead-simple API — a playable game in ~30 lines
- 2D and 3D in one scene — sprites, shapes, text, meshes; 2D HUD over a 3D world for free
- In-engine level designer — edit, play, stop; the authored level always comes back intact
- Procedural assets — generated sprites, textures, palettes, terrain, and synthesized sound effects, all from seeds; levels store recipes, not pixels
- Hot reload — save your script and the running game updates; script errors show a banner instead of crashing
- Odin (tested with
dev-2026-05) - macOS:
brew install lua@5.4(keg-only;build.shpasses the linker path) - Linux: no extra steps — Odin's
vendor:lua/5.4bundles a staticliblua54.a - Windows: no extra steps —
vendor:lua/5.4bundleslua54.dll(copied tobin\bybuild.bat)
./run.sh examples/hello # bouncing ball, edit the file while it runs
./run.sh examples/pong # entities, sound, score
./run.sh examples/invaders # every asset generated from a seed
./run.sh examples/terrain3d # fly over generated terrain, 2D HUD on top
./run.sh examples/pong --editor # open the level designerOn Windows use build.bat / run.bat instead:
run.bat examples\helloA game is a folder with a main.lua (plus optional level.json and assets/).
function on_init()
gen_sprite("hero", 12, 12, 7) -- generated from seed 7
player = spawn_sprite("hero", 480, 300)
set_scale(player, 4)
end
function on_update(dt)
local x, y = get_pos(player)
if key_down("left") then x = x - 200 * dt end
if key_down("right") then x = x + 200 * dt end
set_pos(player, x, y)
end
function on_gui()
draw_text("arrows to move", 10, 10, 20)
endSee docs/api.md for the full API reference.
--editor starts in edit mode (or press F1 in a running game).
- Left click select, drag move (grid snap toggle in toolbar)
- Right/middle drag pan (2D) or orbit/pan (3D view), wheel zoom
- Backspace delete, cmd+D duplicate, cmd+S save
- Play snapshots the scene and runs the script fresh; Stop restores the authored scene exactly
- The inspector edits transforms, tint, text, and — for generated assets — the recipe (drag the seed and watch the asset regenerate live)
- Levels save to
<game>/level.json: entities plus asset recipes, regenerated deterministically on load
- cmd+R full restart (fresh scene + script state)
- F1 open the editor over the running game
src/
gen/ procedural generation (noise, palettes, textures, sprites, meshes, audio)
engine/ entities, scene, assets, recipes, rendering, level io
script/ lua state, error harness, hot reload, the script-facing API
editor/ edit/play state machine, cameras, picking, panels
main.odin loop ownership and mode routing
examples/ hello, pong, invaders, terrain3d