/$$$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$$ /$$$$$$ /$$$$$$$$ /$$$$$$$$
|_____ $$ |_ $$_/ /$$__ $$ /$$__ $$| $$__ $$ /$$__ $$| $$_____/|__ $$__/
/$$/ | $$ | $$ \__/| $$ \__/| $$ \ $$| $$ \ $$| $$ | $$
/$$/ | $$ | $$ /$$$$| $$ | $$$$$$$/| $$$$$$$$| $$$$$ | $$
/$$/ | $$ | $$|_ $$| $$ | $$__ $$| $$__ $$| $$__/ | $$
/$$/ | $$ | $$ \ $$| $$ $$| $$ \ $$| $$ | $$| $$ | $$
/$$$$$$$$ /$$$$$$| $$$$$$/| $$$$$$/| $$ | $$| $$ | $$| $$ | $$
|________/|______/ \______/ \______/ |__/ |__/|__/ |__/|__/ |__/
A high-performance Minecraft-style voxel engine built with Zig, SDL3, and a modern Vulkan graphics pipeline.
ZigCraft is a technical exploration of high-performance voxel rendering techniques, developed primarily as an AI-assisted solo project. It features a custom-built graphics abstraction layer, advanced terrain generation, and a multithreaded job system to handle massive world streaming with zero hitching.
- Vulkan RHI: Modern, explicit graphics API with persistent UBO mapping for high performance.
- PBR Rendering: Physically Based Rendering with Cook-Torrance BRDF for realistic materials.
- Cascaded Shadow Maps (CSM): 3 cascades with configurable PCF sampling (4-16 samples).
- Atmospheric Scattering: Physically-based day/night cycle with dynamic fog and sky rendering.
- Advanced Graphics Menu: Real-time control over shadow quality, PBR, resolution scaling, and MSAA.
- Floating Origin & Reverse-Z: Industry-standard techniques to eliminate precision jitter and Z-fighting at scale.
- Greedy Meshing: Optimized chunk generation reducing draw call overhead and triangle counts.
- Biomes & Climate: Multi-noise system based on temperature and humidity (11+ biomes).
- Infinite Terrain: Seed-based, deterministic generation with domain warping and 3D caves.
- Level of Detail (LOD): Hierarchical LOD system enabling 100+ chunk render distances using simplified terrain meshes and specialized rendering.
- Greedy Meshing: Optimized vertex data generation for maximum throughput.
- Multithreaded Pipeline: Dedicated worker pools for generation (4 threads) and meshing (3 threads).
- Job Prioritization: Proximity-based task scheduling ensures immediate loading of local chunks.
- Comprehensive Testing: Unit tests covering math, worldgen, and core engine modules.
- Refined App Lifecycle: Modular architecture with extracted systems for rendering, input, and world management.
Optimized for high chunk render distances with greedy meshing, job-based multithreading, and a Vulkan RHI backend. Build with -Doptimize=ReleaseFast for best results.
| Key | Action |
|---|---|
| WASD | Movement |
| Space / Shift | Jump / Crouch (Fly Up / Down) |
| Left Ctrl | Sprint |
| Mouse | Look |
| Left Click / Right Click | Mine Block / Place Block |
| Tab | Toggle Mouse Capture / Menu |
| I | Open Inventory |
| 1-9 | Select Hotbar Slot |
| F / T | Toggle Wireframe / Textures |
| V | Toggle VSync |
| U / K | Toggle Shadow Debug / Cycle Cascades |
| M | Toggle World Map |
| N | Freeze / Unfreeze Time |
| F2 | Toggle FPS Counter |
| F3 | Toggle Creative Mode |
| F5 | Toggle Block Info |
| Esc | Menu / Pause |
Note: Time of day can be set via the inventory screen (buttons for DAWN, NOON, DUSK, NIGHT).
This project uses Nix for a reproducible development environment.
After cloning or creating a new worktree, run the setup script to enable git hooks:
./scripts/setup-hooks.shThis configures a pre-push hook that runs:
zig fmt --check src/- formatting checkzig build test- full test suite
To bypass in emergencies: git push --no-verify
- Run:
nix develop --command zig build run - Release build:
nix develop --command zig build run -Doptimize=ReleaseFast
- Smoke test:
nix develop --command zig build run -Dsmoke-test - Headless / no present:
nix develop --command zig build run -Dskip-present - Headless benchmark:
nix develop --command zig build benchmark -Dbenchmark-preset=low -Dbenchmark-duration=60 -Dbenchmark-output=benchmark-low.json - Auto-open a world:
nix develop --command zig build run -Dauto-world=normal - Open on monitor:
nix develop --command zig build run -Dmonitor-index=1 - Open on Hyprland monitor:
nix develop --command zig build run -Dmonitor-name=DP-2 - Force XWayland monitor placement:
nix develop --command zig build run -Dmonitor-index=1 -Dwindow-video-driver=x11 - Background window launch:
nix develop --command zig build run -Dmonitor-name=DP-2 -Dwindow-video-driver=x11 -Dwindow-no-focus - Startup diagnostic:
nix develop --command zig build run -Dauto-world=normal -Dstartup-diagnostic-seconds=5 -Dskip-present - Chunk-only debug mode:
nix develop --command zig build run -Dchunk-debug-mode -Dauto-world=normal - Shadow/cave lighting capture:
./scripts/capture_shadow_test.sh screenshots/shadow-test.png
-Dchunk-debug-mode strips the overworld down to basic chunks for isolation work:
- LOD off by default
- water generation/rendering off by default
- caves off by default
- decorations/features off by default
Re-enable individual systems with -Dchunk-debug-enable= using a comma-separated list:
lodwaterwatergenwaterrendercavesdecorations
Examples:
# LOD only
nix develop --command zig build run -Dchunk-debug-mode -Dchunk-debug-enable=lod -Dauto-world=normal
# LOD plus cave generation
nix develop --command zig build run -Dchunk-debug-mode -Dchunk-debug-enable=lod,caves -Dauto-world=normal
# Headless startup comparison after 5 seconds
nix develop --command zig build run -Dchunk-debug-mode -Dchunk-debug-enable=lod,water,caves -Dauto-world=normal -Dstartup-diagnostic-seconds=5 -Dskip-presentThe shadow/cave lighting capture launches a deterministic low-block test scene, applies a small shadow-focused graphics preset, waits 5 seconds after the target is ready, captures a PNG, and exits. It defaults to a dug-cave variant that matches a player-dug dirt/grass cave mouth. Use ZIGCRAFT_SHADOW_TEST_VARIANT=bend ./scripts/capture_shadow_test.sh screenshots/shadow-bend.png to check the older bend/deep-black regression. Override the wait with ZIGCRAFT_SCREENSHOT_DELAY_SECONDS=8 ./scripts/capture_shadow_test.sh screenshots/shadow-test.png. Screenshot paths are restricted to image extensions from image/png, image/jpeg, image/gif, and image/webp; the built-in encoder currently writes PNG.
- All Tests:
nix develop --command zig build test - Single Test:
nix develop --command zig build test -- --test-filter "Test Name" - Single Test Alternative:
nix develop --command zig build test -Dtest-filter="Test Name"
modules/engine-*: Core engine packages (RHI, graphics, math, UI, input, jobs, ECS, audio).modules/world-core: Blocks, chunks, coordinates, lighting, and shared world types.modules/world-worldgen: Procedural terrain, noise, biomes, caves, decorations, and generator registry.modules/world-meshing: Chunk storage, mesh generation, GPU block buffers, and meshing helpers.modules/world-lod: Distant terrain LOD data, scheduling, rendering, and management.modules/world-runtime: World facade, streaming, mutation, rendering, and GPU meshing runtime.modules/world-persistence: Level data, chunk serialization, region files, and save manager.src/game/: Application/gameplay state, screens, player, inventory, and session logic.assets/: GLSL shaders and textures.scripts/: Helper scripts for asset processing.libs/: Local dependencies (zig-math, zig-noise, stb).
Some textures in assets/textures/default/ are temporary development placeholders imported from external Minecraft-compatible resource packs, including Classic Faithful 64x Jappa, while the engine art pipeline is being built out. They are included only to make local development and visual iteration easier, and should be replaced with original or clearly licensed project assets before any public release or redistribution.
ZigCraft does not claim ownership of third-party placeholder textures. Keep attribution and licensing requirements with any external resource pack assets you use.
The engine supports HD texture packs with full PBR maps. To standardize high-resolution source imagery (4k JPEGs, EXRs) into engine-ready 512px PNGs, use the provided helper script:
# Standardize an entire pack
./scripts/process_textures.sh assets/textures/pbr-test 512The script automatically handles resizing and naming conventions for _diff, _nor_gl, _rough, and _disp maps.
This is primarily a solo, AI-assisted project. Contributions are welcome but the scope and direction are tightly focused. See CONTRIBUTING.md for the full development workflow.
# Clone and setup
git clone https://github.com/OpenStaticFish/ZigCraft.git
cd ZigCraft
./scripts/setup-hooks.sh
# Enter dev environment and run tests
nix develop --command zig build testmain (production)
โโ dev (staging)
โโ feature/* # New features
โโ bug/* # Non-critical fixes
โโ hotfix/* # Critical fixes
โโ ci/* # CI/workflow changes
All PRs target the dev branch. Use our PR templates (feature.md, bug.md, hotfix.md, ci.md) for best practices.
# Clean build artifacts
rm -rf zig-out/ .zig-cache/
# Update Nix channels (if using older Nix)
nix-channel --update- Linux: Ensure
vulkan-loaderand GPU drivers are installed - NVIDIA: Proprietary drivers recommended for best performance
- Verify: Run
vulkaninfoto check Vulkan support
Shaders are validated during zig build test. If glslang fails:
# Install glslang via Nix
nix develop # glslang is included in the dev shell- Try
zig build run -Doptimize=ReleaseFastfor optimized builds - Reduce render distance in-game: Press
Escโ Graphics โ Render Distance - Disable VSync if FPS is capped at 60
| Discussions | GitHub Discussions |
| Issues | GitHub Issues |
| License | MIT License |
Built by OpenStaticFish
MIT License - see LICENSE for details.