Prerequisites

Core (required for CLI tools + library)

bash — Debian / Ubuntu
# 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)

bash
# 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
The viewer is optional. The core library and all CLI tools build with only the core requirements above.

Clone the Repositories

MeshWorld depends on mesh-craft at sibling directory level. Both repos must be cloned into the same parent directory.

bash
# 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

Build

bash
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/:

BinaryDescription
MeshWorldWorld info + sample chunks
MeshWorldMapASCII zone layout map
MeshWorldExportExport all chunks to MC3 XML / MCB
MeshWorldMaterialsList all registered materials
MeshWorldPackPack content into SQLite
MeshWorldTestsGTest test runner

Generate Your First World

bash
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/
output — MeshWorldMap
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.

All CLI Tool Usage

bash
# 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

Build and Run MeshWorldApp

MeshWorldApp requires the cna, sharp-runtime, easy-gl, and mesh-craft sibling repositories, plus SDL3 and OpenGL development libraries.
bash
# 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.

Write Your First Lua Generator

  1. Create the file

    Lua generators are auto-discovered. Create a new file in the right subdirectory:

    touch generators/lua/zone/farmland.lua
  2. Write the generator module

    lua — generators/lua/zone/farmland.lua
    local 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
  3. 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"
    }
  4. 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
Next steps: See the full Lua API reference for all scene methods and ctx fields, or browse the generators page to see what's already available.