A declarative language for generating Minecraft worlds programmatically.
- Block Placement: Place blocks with coordinates and properties
- Variables: Define and use variables in expressions
- Loops: Generate patterns with
forloops - Arithmetic: Full expression support with +, -, *, /, %
- Macros: Reusable generators for complex patterns (NEW!)
#sphere- Generate filled 3D spheres- Easy to add custom macros
- Occurrences: Pattern-based placement using noise and repetition
@every- Place blocks at regular intervals@section- Place blocks once per section at a specific offset@noise2d- 2D noise-based placement (terrain, trees, surface features)@noise3d- 3D noise-based placement (caves, volumetric features)
Generate filled 3D spheres:
#sphere .x=8 .y=5 .z=8 .radius=5 .block=stone
Parameters:
.x- X coordinate of sphere center (required).y- Y coordinate of sphere center (optional, defaults to 0).z- Z coordinate of sphere center (optional, defaults to 0).radius- Sphere radius (required).block- Block type (required)
All parameters support variables and expressions!
// Sphere at ground level
#sphere .x=8 .y=0 .radius=5 .block=stone
// Sphere floating in the air
#sphere .x=8 .y=20 .z=8 .radius=5 .block=stone
// Using variables
radius = 7
center_y = 10
#sphere .x=8 .y=center_y .radius=radius .block=dirt
// Multiple spheres
#sphere .x=8 .y=5 .z=8 .radius=5 .block=stone
#sphere .x=20 .y=5 .z=8 .radius=3 .block=oak_planks
See MACRO_IMPLEMENTATION.md for details on adding custom macros.
Occurrences allow you to place blocks based on patterns, noise, or regular intervals. Coordinates inside occurrence bodies are relative to the occurrence anchor point.
Place blocks at regular intervals:
@every(step_x, step_y, step_z) {
// Blocks to place at each occurrence point
}
Example:
// Place a marker every 4 blocks vertically
@every(0, 4, 0) {
[0, 0, 0] oak_planks
}
Place blocks once per section (16x16x16) at a specific offset within the section:
@section [.x=<offset>] [.y=<offset>] [.z=<offset>] {
// Blocks to place
}
Parameters:
.x- X offset within section (0-15, default: 0).y- Y offset within section (0-15, default: 0).z- Z offset within section (0-15, default: 0)
Examples:
// Place a tree at the center of each section (8, *, 8)
@section .x=8 .z=8 {
[0, 0, 0] oak_log
[0, 1, 0] oak_log
[0, 2, 0] oak_log
[-1, 3, 0] oak_leaves
[0, 3, 0] oak_leaves
[1, 3, 0] oak_leaves
}
// Place a beacon at specific section coordinates
@section .x=5 .y=10 .z=7 {
[0, 0, 0] beacon
}
// Place at section origin (0, 0, 0)
@section {
[0, 0, 0] bedrock
}
Use Cases:
- Section markers/landmarks
- Regular structure placement
- Chunk-aligned features
- Debug visualization
2D noise sampling over the XZ plane, ideal for heightfields, surface decals, trees, and ores. Uses FastNoiseLite OpenSimplex2 under the hood.
@noise2d .frequency=0.02 .seed=12345 [.threshold=<0-1>] [.spread=<blocks>] [.y=<base_y>] {
// Blocks to place
}
Parameters:
.frequency- Controls pattern density/smoothness (0.01-0.2)- Lower values (0.01-0.03): Smooth, large-scale terrain features
- Higher values (0.1-0.2): Noisy, small-scale patterns
.seed- Random seed for reproducible patterns.threshold- Optional (0-1). Executes body only when noise >= threshold (use for sparsity).spread- Optional. Multiplies the noise value (-1..1) and adds it to the base Y.y- Optional. Base Y level when using spread (defaults to the occurrence origin)
Usage Patterns:
Use .spread + .y, omit threshold for full coverage:
// Rolling hills varying ±16 blocks around y=64
@noise2d .frequency=0.02 .seed=12345 .spread=16 .y=64 {
[0, 0, 0] grass_block
[0, -1, 0] dirt
[0, -2, 0] stone
}
Use threshold for sparsity, spread for canopy alignment:
// Trees on ~30% of terrain, following height variations
@noise2d .frequency=0.02 .seed=12345 .threshold=0.7 .spread=16 .y=65 {
[0, 0, 0] oak_log
[0, 1, 0] oak_log
[0, 2, 0] oak_log
[0, 3, 0] oak_leaves
}
Threshold only for flat placement:
// Flowers on 10% of area at y=64
@noise2d .frequency=0.1 .seed=12345 .threshold=0.9 {
[0, 64, 0] dandelion
}
Layer multiple @noise2d ranges with the same seed:
// Base terrain (full coverage)
@noise2d .frequency=0.025 .seed=77777 .spread=20 .y=64 {
[0, 0, 0] grass_block
[0, -1, 0] dirt
}
// Trees (25% coverage, on terrain)
@noise2d .frequency=0.025 .seed=77777 .threshold=0.75 .spread=20 .y=65 {
[0, 0, 0] oak_log
[0, 1, 0] oak_log
[0, 2, 0] oak_log
[-1, 2, 0] oak_leaves
[1, 2, 0] oak_leaves
[0, 3, 0] oak_leaves
}
// Flowers (5% coverage, on terrain)
@noise2d .frequency=0.025 .seed=77777 .threshold=0.95 .spread=20 .y=65 {
[0, 0, 0] dandelion
}
Pro Tip: Reusing the same .seed, .spread, and .y keeps secondary features aligned with the underlying terrain.
3D noise sampling across entire sections, perfect for caves, volumetric decor, and scattered clusters.
@noise3d .frequency=0.08 .seed=424242 [.threshold=<0-1>] [.min_y=<min>] [.max_y=<max>] {
// Blocks to place
}
Parameters:
.frequency- Controls volumetric feature size.seed- Random seed for reproducible caves/features.threshold- Optional (0-1). Executes body only when noise >= threshold; omit for full coverage.min_y/.max_y- Optional inclusive world-height bounds to constrain sampling
Example:
// Glowstone clusters suspended underground
@noise3d .frequency=0.08 .seed=424242 .threshold=0.95 {
#sphere .radius=2 .block=glowstone
}
// Iron ore between y=16 and y=48
@noise3d .frequency=0.12 .seed=11235 .threshold=0.78 .min_y=16 .max_y=48 {
[0, 0, 0] iron_ore
[1, 0, 0] iron_ore
[0, 1, 0] iron_ore
[0, 0, -1] iron_ore
}
- See
worlds/tour.paintfor comprehensive language examples - See
worlds/test_sphere.paintfor sphere macro examples - See
worlds/noise_terrain_demo.paintfor noise terrain and tree examples - See
worlds/advanced_terrain.paintfor complex biome generation - See
MACRO_IMPLEMENTATION.mdfor implementation details