Skip to content
Comfy Engine

Comfy Engine

A reading room for people who build games close to the code. How small engines are put together, Rust patterns that survive a real game loop, wgpu and shaders explained from the first triangle, pixel art that reads at a glance, and the checklists between a jam prototype and a release.

Start with the BookBrowse examples

The heart of every small game

Fixed updates, variable rendering, and a little interpolation to hide the seams. The full walkthrough explains each line.

use std::time::{Duration, Instant};

const STEP: Duration = Duration::from_millis(16);

fn main() {
    let mut world = World::new();
    let mut last = Instant::now();
    let mut lag = Duration::ZERO;
    loop {
        lag += last.elapsed();
        last = Instant::now();
        while lag >= STEP {
            world.update(STEP.as_secs_f32()); // the same tick on every machine
            lag -= STEP;
        }
        world.draw(lag.as_secs_f32() / STEP.as_secs_f32());
    }
}

Latest on the blog

Every post →

Pick a system