Zigon
Zigon: A procedural 3D terrain generator and visualizer written in Zig using Raylib
Install / Use
/learn @JosefAlbers/ZigonREADME
Zigon - Procedural 3D World Builder
Zigon is a 3D procedural generation engine built in Zig with Raylib, designed for instant web deployment and python scripting.
Live Web Demo • YouTube Demos • PyPI Package
Running Zig Executables
| Command | Description |
|---------|-------------|
| zig build run | 3D render demo |
| zig build run-terrain | Terrain generation demo |
| zig build run-dungeon | Dungeon generation demo |
| zig build run-bench | Benchmarking |
| zig build | Python scripting library |
Configure terrain, dungeons, and rendering with compile-time flags:
| Option | Description | Default |
|--------|-------------|---------|
| -Dmap-size=<size> | Terrain grid size (64, 128, 256, 512, 1024) | 128 |
| -Ddungeon-type=<type> | Dungeon archetype: -1=none, 0=rooms, 1=rogue, 2=cavern, 3=maze, 4=labyrinth, 5=arena | -1 |
| -Ddungeon-magnify=<factor> | Dungeon upscaling factor | 4 |
| -Dseed=<number> | Initial random seed (0=timestamp) | 0 |
| -Dwindow-width=<pixels> | Window width | 800 |
| -Dwindow-height=<pixels> | Window height | 600 |
| -Draylib-include=<path> | Custom raylib include directory | system default |
| -Draylib-lib=<path> | Custom raylib library directory | system default |
Dungeon Generation
Zigon implements Wave Function Collapse (wfc) with backtracking for procedural dungeon generation. Six archetypes are supported:
zig build run -Ddungeon-type=4 -Dseed=86
The WFC solver maintains adjacency rules from example layouts, ensuring generated dungeons are traversable and aesthetically consistent.

Terrain Generation
Zigon uses Fractional Brownian Motion (fbm) to synthesize organic landscapes by layering multiple iterations of noise at varying frequencies:
Zig build run-terrain
- Octaves: Defines the number of detail layers; more octaves create more complex terrain.
- Persistence: Determines how much the amplitude (height) decreases each layer, controlling surface roughness.
- Lacunarity: Sets the frequency (density) increase per layer, dictating the scale of fine details.

Python Scripting
Zigon exposes a full Python API via ctypes. Write game logic in Python while terrain generation, rendering, and physics run at native speed.
python main.py

Basic Example
from zigon import Zigon
# Initialize engine
game = Zigon(size=128)
# Load procedural or real-world terrain data
game.load_map(get_base_map(128, 'gradient'))
# Spawn entities
game.spawn("House", 100, 100)
game.spawn_shape("Cube", -10, -10, size=2.0, height=20.0, color=(100, 100, 100))
# Register event callbacks
@game.set_callback
def on_frame(event_key, event_val):
if event_key == 0: # Frame update
# Update game state
pass
elif event_key == 2: # Mouse click
pos = game.get_click_pos()
print(f"Clicked at {pos}")
# Start main loop
game.start()
Advanced: Entity Management
from rpg import Objects
# Spawn NPC with patrol path
npc = Objects(game, "Human", 0, 0)
npc.set_path([(-20, 0), (-20, 20), (-10, 20)], speed=3.0, loop=True)
# React to clicks
@npc.on_click
def handle_interaction(obj):
print(f"NPC clicked at {obj.get_pos()}")
# Spawn visual effect
x, z, _ = obj.get_pos()
Objects(game, "Beam", x, z, duration=2.0)
Performance
All benchmarks measured on Apple M1 Max at 1920×1000 resolution. See actual_benchmark_results.out for raw data.
# Build Zig terrain benchmark
zig build bench
./zig-out/bin/bench_terrain
# Run full comparison suite (Python + Zig)
python bench_zigon.py
# Rendering stress test (opens window)
python bench_render.py
# Generate markdown report
python bench_zigon.py --report BENCHMARKS.md
<details><summary>Click to expand output</summary><pre>
~/D/tzg> python bench_render.py (tzg) ╔══════════════════════════════════════════════════════════════╗ ║ ZIGON RENDERING STRESS TEST ║ ╚══════════════════════════════════════════════════════════════╝
── Test 1: Terrain-Only FPS (no entities) ──
INFO: Initializing raylib 5.5 INFO: Platform backend: DESKTOP (GLFW) INFO: Supported raylib modules: INFO: > rcore:..... loaded (mandatory) INFO: > rlgl:...... loaded (mandatory) INFO: > rshapes:... loaded (optional) INFO: > rtextures:. loaded (optional) INFO: > rtext:..... loaded (optional) INFO: > rmodels:... loaded (optional) INFO: > raudio:.... loaded (optional) INFO: DISPLAY: Device initialized successfully INFO: > Display size: 1920 x 1080 INFO: > Screen size: 1920 x 1000 INFO: > Render size: 1920 x 1000 INFO: > Viewport offsets: 0, 0 INFO: GLAD: OpenGL extensions loaded successfully INFO: GL: Supported extensions count: 43 INFO: GL: OpenGL device information: INFO: > Vendor: Apple INFO: > Renderer: Apple M1 Max INFO: > Version: 4.1 Metal - 89.4 INFO: > GLSL: 4.10 INFO: GL: VAO extension detected, VAO functions loaded successfully INFO: GL: NPOT textures extension detected, full NPOT textures supported INFO: GL: DXT compressed textures supported INFO: PLATFORM: DESKTOP (GLFW - Cocoa): Initialized successfully INFO: TEXTURE: [ID 1] Texture loaded successfully (1x1 | R8G8B8A8 | 1 mipmaps) INFO: TEXTURE: [ID 1] Default texture loaded successfully INFO: SHADER: [ID 1] Vertex shader compiled successfully INFO: SHADER: [ID 2] Fragment shader compiled successfully INFO: SHADER: [ID 3] Program shader loaded successfully INFO: SHADER: [ID 3] Default shader loaded successfully INFO: RLGL: Render batch vertex buffers loaded successfully in RAM (CPU) INFO: RLGL: Render batch vertex buffers loaded successfully in VRAM (GPU) INFO: RLGL: Default OpenGL state initialized successfully INFO: TEXTURE: [ID 2] Texture loaded successfully (128x128 | GRAY_ALPHA | 1 mipmaps) INFO: FONT: Default font loaded successfully (224 glyphs) INFO: SYSTEM: Working Directory: /Users/jjms/Downloads/tzg INFO: TIMER: Target time per frame: 16.667 milliseconds INFO: VAO: [ID 2] Mesh uploaded successfully to VRAM (GPU) INFO: TEXTURE: [ID 3] Texture loaded successfully (63x63 | R8G8B8A8 | 1 mipmaps) Terrain 64x64 FPS: 59.1 avg: 16.93ms p99: 17.82ms INFO: VAO: [ID 2] Unloaded vertex array data from VRAM (GPU) INFO: MODEL: Unloaded model (and meshes) from RAM and VRAM INFO: TEXTURE: [ID 3] Unloaded texture data from VRAM (GPU) INFO: TEXTURE: [ID 2] Unloaded texture data from VRAM (GPU) INFO: SHADER: [ID 3] Default shader unloaded successfully INFO: TEXTURE: [ID 1] Default texture unloaded successfully INFO: Window closed successfully INFO: Initializing raylib 5.5 INFO: Platform backend: DESKTOP (GLFW) INFO: Supported raylib modules: INFO: > rcore:..... loaded (mandatory) INFO: > rlgl:...... loaded (mandatory) INFO: > rshapes:... loaded (optional) INFO: > rtextures:. loaded (optional) INFO: > rtext:..... loaded (optional) INFO: > rmodels:... loaded (optional) INFO: > raudio:.... loaded (optional) INFO: DISPLAY: Device initialized successfully INFO: > Display size: 1920 x 1080 INFO: > Screen size: 1920 x 1000 INFO: > Render size: 1920 x 1000 INFO: > Viewport offsets: 0, 0 INFO: GLAD: OpenGL extensions loaded successfully INFO: GL: Supported extensions count: 43 INFO: GL: OpenGL device information: INFO: > Vendor: Apple INFO: > Renderer: Apple M1 Max INFO: > Version: 4.1 Metal - 89.4 INFO: > GLSL: 4.10 INFO: GL: VAO extension detected, VAO functions loaded successfully INFO: GL: NPOT textures extension detected, full NPOT textures supported INFO: GL: DXT compressed textures supported INFO: PLATFORM: DESKTOP (GLFW - Cocoa): Initialized successfully INFO: TEXTURE: [ID 1] Texture loaded successfully (1x1 | R8G8B8A8 | 1 mipmaps) INFO: TEXTURE: [ID 1] Default texture loaded successfully INFO: SHADER: [ID 1] Vertex shader compiled successfully INFO: SHADER: [ID 2] Fragment shader compiled successfully INFO: SHADER: [ID 3] Program shader loaded successfully INFO: SHADER: [ID 3] Default shader loaded successfully INFO: RLGL: Render batch vertex buffers loaded successfully in RAM (CPU) INFO: RLGL: Render batch vertex buffers loaded successfully in VRAM (GPU) INFO: RLGL: Default OpenGL state initialized successfully INFO: TEXTURE: [ID 2] Texture loaded successfully (128x128 | GRAY_ALPHA | 1 mipmaps) INFO: FONT: Default font loaded successfully (224 glyphs) INFO: SYSTEM: Working Directory: /Users/jjms/Downloads/tzg INFO: TIMER: Target time per frame: 16.667 milliseconds INFO: VAO: [ID 2] Mesh uploaded successfully to VRAM (GPU) INFO: TEXTURE: [ID 3] Texture loaded successfully (127x127 | R8G8B8A8 | 1 mipmaps) Terrain 128x128 FPS: 59.2 avg: 16.90ms p99: 17.60ms INFO: VAO: [ID 2] Unloaded vertex array data from VRAM (GPU) INFO: MODEL: Unloaded model (and meshes) from RAM and VRAM INFO: TEXTURE: [ID 3] Unloaded texture data from VRAM (GPU) INFO: TEXTURE: [ID 2] Unloaded texture data from VRAM (GPU) INFO: SHADER: [ID 3] Default shader unloaded successfully INFO: TEXTURE: [ID 1] Default texture


