Current Features
What MeshWorld Can Do Today
A complete procedural world generation library and interactive viewer. 119 tests pass on every push.
Core System
Chunk-Based Generation
The world is divided into square chunks of configurable size (default 64 m × 64 m). Each chunk is generated independently — a self-contained MC3 XML scene file.
Chunks are keyed by (x, y) coordinate. Once generated and validated, they are cached to disk and never regenerated unless the cache is cleared. This makes large exports (400+ chunks) fast on subsequent runs.
- Configurable grid size (
grid_w×grid_h) - Configurable chunk size in metres (
chunk_size_m) - Zone and region types per chunk coordinate
- Variation seed per chunk (deterministic noise)
- Disk cache with file-level invalidation
{
"name": "demo_city",
"seed": 42,
"style": "central_europe_small_city",
"grid_w": 20,
"grid_h": 20,
"chunk_size_m": 64,
"zones": [
{
"type": "city",
"x_min": 0, "x_max": 18,
"y_min": 0, "y_max": 18,
"region_default": "small_house_block",
"regions": [
{
"x_min": 9, "x_max": 10,
"y_min": 9, "y_max": 10,
"type": "square"
}
]
}
]
}
Generation Engine
Dual-Language Pipeline
Every chunk goes through a Lua-first pipeline. If a Lua generator with the matching ID exists, it runs. If not, MeshWorld falls back to the equivalent C++ generator. This makes it trivial to override any built-in generator with a custom Lua version.
The LuaGeneratorRegistry scans generators/lua/ at startup and maps each generator's M.id string. The LuaSandbox blocks all dangerous modules (io, os, debug, require) for safe execution.
20 production-ready C++ generators cover every zone type. If no Lua override is found, get_generator(zone, region) returns the appropriate C++ generator.
lua.zone.park exists in the registry, it runs instead of cpp.chunk.park. Override only what you want to change — the rest stays untouched.
.lua file in the right subdirectory, run the app, and the generator is live.
Quality Assurance
MC3 Validation Pipeline
Every generated chunk is validated before it is cached to disk. The MC3Validator checks four categories of correctness:
| Check | Description |
|---|---|
| Well-formed XML | The output parses as valid XML with the mc3 root element. |
| Metadata | Generator ID, version, and language fields are present and non-empty. |
| Bounds | All geometry is within the declared chunk boundary (0 to chunk_size_m). |
| Material names | Every material reference exists in the MaterialRegistry. |
Validation failures are reported with the chunk coordinate and a descriptive error message. Invalid chunks are not cached.
ValidationResult struct containing a boolean valid flag and a vector of human-readable error strings.
The validation pipeline ensures that every MC3 file in the cache is guaranteed to load correctly in the MeshCraft viewer. Broken generators cannot corrupt the cache.
Materials
~100 Built-in Materials
The MaterialRegistry ships with approximately 100 procedural materials covering all major surface categories. Each material entry stores:
- RGB colour (linear float triplet)
- Roughness value (0.0 – 1.0)
- Category tag (stone, wood, metal, glass, foliage…)
- License metadata (MIT, CC0, etc.)
Material names are validated during MC3 validation. Any unknown material name is a validation error, ensuring generators never produce invalid material references.
# List all registered materials ./build/MeshWorldMaterials # Example output: grass rgb(0.28,0.52,0.22) rough=0.95 MIT stone_wall rgb(0.55,0.52,0.48) rough=0.88 MIT wood_bench rgb(0.55,0.38,0.22) rough=0.75 MIT metal_lamp rgb(0.72,0.72,0.72) rough=0.20 MIT glass_clear rgb(0.80,0.90,0.95) rough=0.05 MIT foliage_oak rgb(0.20,0.45,0.15) rough=0.90 MIT
Material Categories
Stone & Masonry
stone_wall, stone_pavement, stone_path, brick_red, brick_dark, concrete, asphalt…
Wood
wood_bench, wood_door_panel, wood_birch, wood_bark_dark, wood_bark_light…
Metal & Glass
metal_lamp, glass_clear, metal_railing, metal_frame…
Foliage
foliage_oak, foliage_linden, foliage_birch, foliage_chestnut, grass, grass_park…
Soil & Ground
soil, sand, gravel, dirt, mud…
Flowers & Accents
flowers_red, flowers_yellow, flowers_white, flowers_purple, plaster_white…
Content Organisation
Taxonomy & Containment Rules
The TaxonomyRegistry loads a JSON node hierarchy that describes how world objects relate to each other — what can contain what, at which level of detail.
The ContainmentRuleRegistry extends this with LOD-aware rules: at low detail, a city zone contains only block shapes; at high detail, blocks contain individual buildings; buildings contain rooms; rooms contain furniture.
This hierarchy drives generator selection and will underpin future multi-LOD streaming.
{
"rules": [
{
"parent": "city",
"child": "block",
"lod_min": 0, "lod_max": 2
},
{
"parent": "block",
"child": "building",
"lod_min": 2, "lod_max": 4
},
{
"parent": "building",
"child": "room",
"lod_min": 4, "lod_max": 6
}
]
}
Distribution
SQLite Content Packs
The MeshWorldPack tool bundles all generators, taxonomy, and materials into a single portable .sqlite file. Content packs can be distributed, versioned, and swapped independently of the main executable.
The ContentPackLoader reads these bundles at runtime. Multiple packs can be loaded, with later packs overriding earlier ones — enabling a clean mod/override system.
# Pack everything into one file ./build/MeshWorldPack meshworld_content.sqlite # The resulting .sqlite file contains: # generators — Lua source + C++ metadata # taxonomy — node hierarchy JSON # materials — RGB + roughness + license # styles — style name → parameter set
Real-time Viewer
World Streaming & Rendering
WorldStreamer tracks the player's current chunk coordinate and maintains a configurable load radius. As the player moves, chunks outside the radius are unloaded and new ones are loaded (or generated on demand).
WorldRenderer wraps the streamer and drives Mc3Renderer, which uses MeshCraft's SceneRenderer to draw geometry on screen. Mc3MeshBuilder tessellates MC3 primitives (boxes, cylinders, planes) into triangle meshes at load time.
- Configurable load radius (default 2 chunks)
- LOADED / UNLOADED event callbacks
- FPCamera: position, yaw, pitch, fov_y, near/far, aspect
- SDL3 + OpenGL rendering via CNA framework
- WASD / Q / E movement, mouse look
apps/mesh-world-app/ with its own CMake project. It requires the cna, sharp-runtime, easy-gl, and mesh-craft sibling repositories.
WASD — move horizontallyQ / E — move down / upMouse — look aroundESC — exit to main menu
CLI Toolset
Five Command-Line Tools
MeshWorld
Loads a world config, prints world info, and samples 4 chunks with their zone/region assignments and generation stats.
./build/MeshWorld examples/world.json
MeshWorldMap
Prints an ASCII zone layout map of the world grid — zone type and region type per chunk. Useful for visualising world structure at a glance.
./build/MeshWorldMap examples/world.json
MeshWorldExport
Exports all chunks to MC3 XML files. Pass --mcb to also compile to the MCB binary format. Output goes to a specified directory.
./build/MeshWorldExport \ --mcb world.json output/
MeshWorldMaterials
Lists all registered materials with their RGB values, roughness, category, and license. Useful for finding the right material name for a Lua generator.
./build/MeshWorldMaterials
MeshWorldPack
Packs all generators, taxonomy, materials, and styles into a portable SQLite content pack file for distribution or archival.
./build/MeshWorldPack \ meshworld_content.sqlite
MeshWorldTests
GTest-based test suite. 119 tests covering all major subsystems — ChunkPipeline, LuaSandbox, MaterialRegistry, MC3Validator, WorldStreamer, and more.
cd build ctest --output-on-failure