Installation Guide
Getting Started
From zero to a generated 3D world in under five minutes on any Linux or macOS machine with GCC 13+.
Step 1
Prerequisites
Core (required for CLI tools + library)
# GCC 13+ or Clang 17+ sudo apt install gcc-13 g++-13 # CMake 3.20+ sudo apt install cmake # SQLite development library sudo apt install libsqlite3-dev # Lua 5.4 and sol2 are downloaded automatically # by CMake FetchContent — no manual install needed
Viewer (optional — for MeshWorldApp)
# SDL3 (for the interactive viewer) sudo apt install libsdl3-dev # OpenGL sudo apt install libgl1-mesa-dev libglu1-mesa-dev # Sibling repositories (cloned next to mesh-world): # openeggbert/cna # openeggbert/sharp-runtime # openeggbert/easy-gl # openeggbert/mesh-craft
Step 2
Clone the Repositories
MeshWorld depends on mesh-craft at sibling directory level. Both repos must be cloned into the same parent directory.
# Create a workspace directory mkdir ~/openeggbert && cd ~/openeggbert # Clone mesh-craft (MeshWorld depends on this) git clone https://github.com/openeggbert/mesh-craft # Clone mesh-world git clone https://github.com/openeggbert/mesh-world # Directory structure must be: # ~/openeggbert/ # mesh-craft/ ← sibling # mesh-world/ ← this repo
Step 3
Build
cd ~/openeggbert/mesh-world # Configure (downloads Lua 5.4.7 + sol2 3.3.0 automatically) cmake -B build -DCMAKE_BUILD_TYPE=Release # Build all targets (adjust -j to your core count) cmake --build build -j$(nproc) # Verify with tests cd build && ctest --output-on-failure # Expected output: 100% tests passed, 0 tests failed out of 119
The build produces these binaries in build/:
| Binary | Description |
|---|---|
MeshWorld | World info + sample chunks |
MeshWorldMap | ASCII zone layout map |
MeshWorldExport | Export all chunks to MC3 XML / MCB |
MeshWorldMaterials | List all registered materials |
MeshWorldPack | Pack content into SQLite |
MeshWorldTests | GTest test runner |
Step 4
Generate Your First World
cd ~/openeggbert/mesh-world # Print world info + sample 4 chunks ./build/MeshWorld examples/world.json # Show ASCII zone map ./build/MeshWorldMap examples/world.json # Export all 400 chunks to MC3 XML mkdir -p output ./build/MeshWorldExport examples/world.json output/ # Files are cached — second run is instant ./build/MeshWorldExport examples/world.json output/ # Export to MCB binary format (for MeshCraft) ./build/MeshWorldExport --mcb examples/world.json output/
demo_city (20×20, 64m chunks) seed=42 style=central_europe_small_city 0 1 1 0123456789012345678 9 0 HHHHHHHHHHHHHHHHHHHR 1 HHRRRRRRRRRRRRRRHHR 2 HHRHHHHHHHHHHHRHHHR 3 HHRHHPPPPPPPPHHRHHR 4 HHRHHPPPPPPPPHHRHHR 5 HHRHHHHHHHHHHHRHHHR 6 HHRHHAAAAAARRAAAAHRH 7 HHRRRRRRRRRRRRRRHHR ... H=SmallHouseBlock A=Apartment P=Park Q=Square R=Road
Generated MC3 files are at output/x_y.mc3.xml. The cache is at cache/chunks/ and is reused on subsequent runs.
CLI Reference
All CLI Tool Usage
# World info and 4 sample chunks ./build/MeshWorld examples/world.json # ASCII zone map ./build/MeshWorldMap examples/world.json # Export to MC3 XML ./build/MeshWorldExport examples/world.json output/ # Export to MC3 XML AND compile to MCB binary ./build/MeshWorldExport --mcb examples/world.json output/ # List all ~100 registered materials ./build/MeshWorldMaterials # Pack all content into a SQLite file ./build/MeshWorldPack meshworld_content.sqlite # View a specific chunk in MeshCraft meshcraft output/2_9.mc3.xml # park chunk meshcraft output/9_9.mc3.xml # town square chunk
Optional: Interactive Viewer
Build and Run MeshWorldApp
cna, sharp-runtime, easy-gl, and mesh-craft sibling repositories, plus SDL3 and OpenGL development libraries.
# Clone viewer dependencies (siblings of mesh-world) cd ~/openeggbert git clone https://github.com/openeggbert/cna git clone https://github.com/openeggbert/sharp-runtime git clone https://github.com/openeggbert/easy-gl # Build MeshWorldApp (separate CMake project) cd mesh-world cmake -S apps/mesh-world-app -B apps/mesh-world-app/build cmake --build apps/mesh-world-app/build --parallel # Run ./apps/mesh-world-app/build/MeshWorldApp
WASD keys
Move forward / back / strafe left / strafe right
Q / E keys
Move down / up (vertical movement)
Mouse
Look around — captured when window is focused
ESC
Exit to main menu
Streaming
Chunks load automatically as you move. Cache is used for instant re-load.
On-demand gen
If a chunk has never been generated, it's generated on the fly as you approach.
Step 5
Write Your First Lua Generator
-
Create the file
Lua generators are auto-discovered. Create a new file in the right subdirectory:
touch generators/lua/zone/farmland.lua
-
Write the generator module
lua — generators/lua/zone/farmland.lualocal M = {} M.id = "lua.zone.farmland" M.version = "0.1.0" M.category = "zone" function M.generate(ctx, scene) local S = ctx.chunk_size_m -- Ploughed field ground scene:addGround("soil") -- A farmhouse in one corner scene:addInstance("farmhouse", { generator = "lua.building.simple_house.standard", position = {5, 0, 5}, ry = 0, parameters = { width = 12, depth = 9, wall_material = "plaster_white", roof_material = "roof_tile_red" } }) -- Crop rows (dark soil strips) for i = 0, 7 do scene:addPlane("crop_"..i, { position = {20 + i*5, 0.01, 10}, size = {3, S-20}, material = "soil" }) end scene:setMetadata({ generator = {id=M.id, version=M.version, language="lua"}, generation = {variationInput=ctx.variation} }) end return M
-
Wire it to a zone region in world.json
json — add to zones[].regions{ "x_min": 0, "x_max": 5, "y_min": 15, "y_max": 19, "type": "farmland" } -
Generate and view
bash# Clear the cache for the affected chunks, then regenerate rm cache/chunks/0_15.mc3.xml # etc. ./build/MeshWorldExport examples/world.json output/ # View a farmland chunk meshcraft output/0_15.mc3.xml