Game loops, from the metal up.
LÖVE is where I prototype: plain Lua against its update and draw callbacks, with no engine layered on top. Passages, the game I'm building, runs in Unity. The rest is study — a BSP renderer in C, and an SDL2 → Rust/Bevy track.
Active and past builds
Passages — LitRPG-inspired third-person action RPG
Combat blends FF12's Gambit system with the rule-driven party logic of .hack//GU. A dual-resource system (Vitality / Essence) governs both health and casting. The Attunement Scripts editor lets the player wire per-companion behavior trees. Abilities authored as ScriptableObjects so designers iterate without recompiling.
From-scratch BSP renderer + Unity shooter prototype
A BSP renderer written from scratch in C as a graphics deep-dive — tree construction, polygon splitting, painter's-order traversal. Separately, a 3D shooter prototype in Unity to feel the C# tooling end of the same pipeline. Both research artifacts, not productized.
Bevy + SDL2 track — SDL2 first, Bevy after
Sequential ladder, not a single project. SDL2/C++ for the fundamentals (Pong, then Breakout, then a top-down shooter), then graduate the same exercises into Rust + Bevy to feel ECS-first authoring against the same problems.
Fixed timestep, honestly.
Accumulate real time, step the world in constant slices, draw whatever is current. Deterministic under load, and the bug that only appears on fast machines goes away.
function love.load() world = love.physics.newWorld(0, 9.81*64) player = entities.spawn("player", 100, 100) end function love.update(dt) accumulator = accumulator + dt while accumulator >= STEP do world:update(STEP) input.poll() ai.tick(STEP) accumulator = accumulator - STEP end end function love.draw() camera:attach() tilemap:draw() entities:draw() camera:detach() hud:draw() end