https://github.com/deblasis/ziogameloop
Fixed-timestep game loop for Zig. Accumulator-based, frame rate control. 40 tests.
https://github.com/deblasis/ziogameloop
game-engine gamedev gamedev-library zig zig-lang
Last synced: about 14 hours ago
JSON representation
Fixed-timestep game loop for Zig. Accumulator-based, frame rate control. 40 tests.
- Host: GitHub
- URL: https://github.com/deblasis/ziogameloop
- Owner: deblasis
- Created: 2026-05-01T06:14:03.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-01T12:27:56.000Z (about 2 months ago)
- Last Synced: 2026-05-01T13:24:53.690Z (about 2 months ago)
- Topics: game-engine, gamedev, gamedev-library, zig, zig-lang
- Language: Zig
- Size: 17.6 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- Agents: AGENTS.md
Awesome Lists containing this project
README
# ziogameloop
> Fixed-timestep game loop for Zig. Accumulator-based update, frame rate control.
Part of the [zio-zig](https://github.com/deblasis/zio-zig) ecosystem.
## Quick start
```zig
const gameloop = @import("ziogameloop");
var loop = gameloop.GameLoop.init(.{
.tick_rate = 60, // 60 updates per second
.max_catchup = 5, // max updates per frame to prevent spiral
});
var dt = gameloop.DeltaTracker.init();
// Game loop
var ns: u64 = 0;
while (true) {
const now = std.time.nanoTimestamp();
dt.update(@intCast(now));
ns += @intCast(dt.dt_ns);
const result = loop.tick(ns);
// Fixed-rate update (may run multiple times)
for (0..result.updates) |_| {
updatePhysics();
}
// Variable-rate render with interpolation
render(result.alpha); // alpha ∈ [0, 1] for smooth rendering
}
```
```bash
zig build test # Run 40 tests
zig build run-example # Run example
```
## Example output
```
$ zig build run-example
Frame 0: updates=0, alpha=0.00
Frame 1: updates=1, alpha=0.00
Frame 2: updates=1, alpha=0.00
Frame 3: updates=1, alpha=0.00
Frame 4: updates=1, alpha=0.00
```
## API
### Config
| Field | Default | Description |
|-------|---------|-------------|
| `tick_rate` | 60 | Updates per second |
| `max_catchup` | 5 | Max updates per frame |
| `target_fps` | 0 | 0 = unlimited |
### GameLoop
| Method | Description |
|--------|-------------|
| `init(config)` | Create game loop |
| `tick(current_ns)` | Process frame, returns `TickResult` |
| `totalFrames()` | Total frames processed |
| `totalUpdates()` | Total fixed updates run |
### TickResult
| Field | Description |
|-------|-------------|
| `updates` | Number of fixed updates to run this frame |
| `alpha` | Interpolation factor [0, 1] for smooth rendering |
### DeltaTracker
Tracks frame-to-frame delta time.
| Method | Description |
|--------|-------------|
| `init()` | Create tracker |
| `update(current_ns)` | Update delta |
| `dt_ns` | Delta time in nanoseconds |
| `dt_sec` | Delta time in seconds (f32) |
## License
MIT. Copyright (c) 2026 Alessandro De Blasis.