Walks every WOM in a zone, collects texture references from
each model's texturePaths, and checks whether each path
resolves to a real file. Tries 4 candidate paths per ref
(as-is, relative to zone, in textures/, alongside the WOM)
before flagging as missing.
Catches "WOM was added but its texture wasn't copied into
textures/" mistakes before runtime. Exits 1 if any reference
is unresolved — suitable for CI.
Cellular Worley noise at small grain scale: each "pebble" cell
darkens at its boundary with neighbors (the irregular bump
shading characteristic of fine-grain leather), with per-cell
tint variation so the surface doesn't read as uniform.
Defaults: grainSize=4px, seed=1. Useful for armor, saddles,
chairs, book bindings, scabbards. Brings the procedural
texture pattern set to 19.
Procedural altar: stack of N stepped cylindrical discs, each
one wider and shorter than the next so the silhouette descends
like a wedding cake. The top disc is the altar surface; base
discs widen out to anchor the structure visually.
Skips the bottom cap on every disc except the lowest (saves
~24 tris per disc since each is hidden by the next one below).
Defaults: topR=0.7, topH=0.3, 3 steps, stride=0.3. Pairs
naturally with --gen-texture-marble for a temple aesthetic.
Brings the procedural mesh primitive set to 23.
Per-pixel white noise heavily blurred along one axis (long
brush strokes) and lightly along the other (thin variation
across strokes), then contrast-stretched and applied as a
multiplicative tint on the base color. Result: long thin
streaks of varying brightness — the visual signature of
brushed steel/aluminum/iron.
Defaults: horizontal orientation, seed=1. Useful for armor,
weapons, machinery, sci-fi panels. Brings the procedural
texture pattern set to 18.
Project-level companion to --gen-zone-readme. Writes PROJECT.md
with a per-zone status table (BOOTSTRAPPED/PARTIAL/EMPTY plus
biome and per-category counts) and a project-level rollup
(total zones, assets, bytes). Pairs naturally with the per-zone
README — running both gives self-documenting content at every
level.
Procedural statue silhouette: square pedestal block + tall
narrow body cylinder + UV-sphere head. Reads as a statue
without needing limb geometry. The head sphere is 16×12 lat/lon
so silhouette stays smooth at distance.
Defaults: pedestal=1.0, bodyH=2.5, headR=0.4. Useful for
monuments, hero statues, plaza centerpieces, religious
shrines. Brings the procedural mesh primitive set to 22.
Writes README.md to a zone (or to --out path) with a Markdown
asset table covering textures (PNG bytes), meshes (verts/tris/
bones/batches/bytes), and audio (sample rate + duration). Reads
zone.json for the friendly map name and biome.
Saves the manual README maintenance every time content changes.
Marble pattern via warped sinusoidal veining (the canonical
"marble shader"): take a sine wave, warp its input by smooth
multi-octave noise, raise |sin| to a high power so the bright
vein bands stay narrow. Result: irregular bright veins on a
base color with low-freq variation across the texture.
Defaults: sharpness=8, seed=1. Useful for floors, statues,
cathedral walls, ornate furniture. Brings the procedural
texture pattern set to 17.
Project-wide companion to --info-zone-summary. Walks every
zone in <projectDir>, classifies each as BOOTSTRAPPED (textures
+ meshes + audio all non-empty), PARTIAL (some categories), or
EMPTY (none), and shows per-category counts in a status table
with a project total at the bottom.
Quick "what shape is the whole project in" view that pairs
naturally with --validate-project-packs (which actually loads
and verifies every asset).
Procedural fountain: low cylindrical basin with a narrower
spout column rising from its center. Solid (not hollow) for
simplicity but still reads as a fountain because of the spout
silhouette. Cylinder helper builds side ring + top/bottom
caps so basin and spout share the same construction.
Defaults: basin r=1.5 h=0.5, spout r=0.2 h=1.5. Useful for
town squares, plazas, garden centerpieces. Brings the
procedural mesh primitive set to 21.
Compact per-zone status command. Reads zone.json for the
friendly map name, scans textures/, meshes/, audio/ for asset
counts and total bytes per category, and assigns a status:
BOOTSTRAPPED (all 3), PARTIAL (some), or EMPTY (none).
Lighter-weight than --validate-zone-pack (which loads + sanity-
checks every WOM/PNG/WAV) — useful for quick "what shape is
this zone in" checks during interactive editing.
Worley-style cellular pattern: each pixel finds its nearest
"stone center" in a perturbed grid (3x3 neighborhood search).
Pixels with a small gap between closest and second-closest
center become mortar boundaries; everything else is the stone
face with per-stone tint variation and radial darkening for a
3D rounded-stone look.
Defaults: stone=24px, seed=1. Useful for streets, plazas, town
squares. Brings the procedural texture pattern set to 16.
Batch 34's --list-project-meshes (per-zone aggregate) introduced
a flag collision with a pre-existing per-mesh sorted listing
that's been in the codebase. The dispatch chain ran the new
handler first, leaving the older detail view as dead code.
Resolves the duplicate by renaming the older handler to
--list-project-meshes-detail. Both views are now reachable:
the per-zone aggregate stays under the simpler name (covers
the common "how heavy is each zone" case), and the per-mesh
sorted-by-tris detail listing is back as -detail (used for
project-wide outlier detection and mesh-sharing audits).
Procedural house: 4 outward-facing wall quads + a floor slab,
topped by a 4-triangle pyramid roof meeting at a central apex.
Eaves line up with the wall edges so the roof sits flush. Pass
roofHeight=0 for a flat-roof shed.
Defaults: 4×4×3 with 2m roof. Useful for villages, settlements,
quest hubs. Brings the procedural mesh primitive set to 20.
Project-wide bootstrap orchestrator. For every zone in
<projectDir>, runs --gen-zone-starter-pack (textures + meshes)
and --gen-zone-audio-pack (audio). Each zone gets a unique
sub-seed offset from the base seed so per-zone content reads
as distinct (rocks differ, wood grain differs).
Pairs with --validate-project-packs as the inverse: bootstrap
the entire project in one call, audit, ship.
Sine wave whose frequency glides from startHz to endHz across
the duration. Two shape modes:
linear: f(t) = f0 + (f1-f0)*t/T (integrated phase = quadratic)
exp: f(t) = f0 * (f1/f0)^(t/T) (logarithmic glide)
Same RIFF/PCM-16 mono envelope as gen-audio-tone with 5ms
attack/release. Useful for sci-fi door whoosh, alert ramps,
sliding pitch cues, and as a standard signal-engineering test
signal — all hand-synthesized open-format WAV.
Project-wide companion to --list-zone-audio. Walks every
zone in <projectDir> and reports per-zone WAV count + bytes
+ total duration, plus a project grand total. Reuses the
RIFF/WAVE header parse from list-zone-audio.
Completes the project-scope inventory trio alongside
--list-project-meshes and --list-project-textures.
Procedural round castle tower: solid cylindrical shaft with
crenellated battlements ringing the top — alternating raised
merlons and gaps. Each merlon is an extruded arc segment
sitting on the rim. Pass battlementH=0 for a smooth-topped
tower.
Defaults: radius=1.5, height=8, battlements=8, battlementH=0.5.
Useful for keeps, watchtowers, perimeter walls. Brings the
procedural mesh primitive set to 19.
Fans out --validate-zone-pack across every zone in a project
and reports a single PASS/FAIL per zone plus a summary line.
Exits non-zero if any zone fails — designed as a CI gate
before shipping a project's content pack.
Pairs with the existing zone-pack orchestrator family for
end-to-end "bootstrap → audit at project scale" coverage.
Procedural fabric: alternating warp (vertical) and weft
(horizontal) threads on a checkerboard cell grid, with each
thread shaded brighter at center and darker at edges so the
weave reads as 3D yarn rather than flat checker squares.
Defaults: thread=4px, W=H=256. Useful for banners, tapestries,
clothing, sails. Brings the procedural texture pattern set to 15.
Project-wide companion to --list-zone-meshes. Walks every
zone in <projectDir> and reports per-zone WOM count + bytes/
verts/tris row, plus a project grand total. Both human-
readable table and --json supported.
Useful for "how heavy is the entire project mesh-wise"
budgeting before shipping a content pack.
Audits a zone's open-format asset pack: counts and total bytes
for textures (PNG signature check), meshes (WOM load + sanity
check), and audio (RIFF/WAVE header check). Reports any
malformed files by relative path and exits 1 if anything is
invalid or the pack is empty.
Ties together the zone-pack orchestrator family — a CI step
can now gate that gen-zone-starter-pack output is healthy
before downstream packaging.
Procedural plank bridge: deck of N axis-aligned planks running
along the length with small gaps between, optional side rails
(top rail + 3 posts each side). Length runs along +X, width
along Z. Pass railHeight=0 to skip rails for a simpler footbridge.
Defaults: length=6, width=2, planks=6, railHeight=1. Useful for
river crossings, dungeon catwalks, scenic overlooks. Brings the
procedural mesh primitive set to 18.
Three audio-engineering noise colors:
white — equal energy per Hz (uniform random samples)
pink — equal energy per octave via Voss-McCartney 7-band
cascade (1/f spectrum, sounds like rain or wind)
brown — 1/f² spectrum via random walk (sounds like distant
surf or rumbling weather)
All written as PCM-16 mono with same RIFF header + 5ms
attack/release envelope as gen-audio-tone. Replaces typical
proprietary nature-sound MP3 placeholders for ambient zone
audio with hand-synthesized seeded WAVs.
Inventories every WAV under <zoneDir>/audio/ with stats parsed
straight from the RIFF/WAVE header: sample rate, channel count,
bit depth, duration. Both human-readable table and --json
output supported.
Completes the per-zone asset accounting trio alongside
--list-zone-meshes and --list-zone-textures.
Drops a 6-WAV starter pack into <zoneDir>/audio/: ambient-low
+ ambient-mid (drone pair, fifth interval), music-stinger,
chime, alert, click. All hand-synthesized PCM-16 mono WAVs
via --gen-audio-tone — no MP3 patent or licensing baggage.
Closes the audio side of the open-format zone bootstrap. A
fresh zone now has full coverage across textures (PNG), meshes
(WOM), and audio (WAV) from procedural generators alone.
Procedural classical column. Cylindrical shaft with N concave
flutes (radius modulated by cos² of angle×flute-count) capped
by wider disc bases above and below — basic capital + base
geometry. Defaults: radius=0.4, height=4, flutes=12, capScale=1.25.
Useful for ruins, temples, dungeons, plaza decoration. Brings
the procedural mesh primitive set to 17.
Hand-rolled RIFF/WAVE PCM-16 mono encoder — no library deps,
44-byte header written field-by-field. Supports four waveforms
(sine/square/triangle/saw), 5ms attack/release envelope to
prevent click on tone start/stop, freq 0..24kHz, duration
0..600s, sampleRate 8k..192k.
Opens a brand-new file family in the open-format ecosystem
alongside WOM/WOB/PNG/JSON. Proprietary MP3 placeholders for
zone audio can now be replaced by hand-synthesized WAVs with
no patent or licensing baggage.
Companion to --list-zone-textures. Walks every WOM under a
zone dir and reports per-mesh size, vertex/triangle counts,
bone/anim/batch counts, and texture-ref counts. Both human-
readable table and --json output supported.
Useful for "how heavy is this zone" budgeting and verifying
that bootstrapping orchestrators (gen-zone-mesh-pack, gen-zone-
starter-pack) produced what they claim.
Convenience entry point that runs --gen-zone-texture-pack and
--gen-zone-mesh-pack in sequence so a fresh zone gets a full
open-format asset bootstrap from one command. Seed propagates
to both children for reproducibility.
A new zone now goes from "just a zone.json" to "11 placeholder
assets across textures/ and meshes/" with one invocation —
zero proprietary M2/BLP imports required.
Companion to --gen-zone-texture-pack. Drops a 5-mesh starter
pack (3 rock variants + tree + fence) into <zoneDir>/meshes/ by
fanning out to the procedural --gen-mesh-* family. Each rock
variant uses a distinct seed so they read as different boulders.
Together with the texture-pack orchestrator a fresh zone can now
be bootstrapped to first-render-ready state with zero proprietary
M2/BLP imports — entirely from open WOM/PNG output.
Procedural grass texture: jittered base color + scattered short
vertical blade strokes blending toward a brighter highlight hue.
Strokes wrap on Y so the texture tiles vertically. Reproducible
from a seed.
Defaults: density=0.15, seed=1, W=H=256. Brings procedural
texture pattern set to 14 commands.
Subdivided octahedron + smooth sin-product noise displacement.
Each seed produces a unique silhouette so scattering looks
varied. Defaults: radius=1, roughness=0.25, subdiv=2 (128
triangles), seed=1.
Pairs naturally with random-populate-zone for outdoor decoration
and brings the procedural mesh primitive set to 16.
New zone-scope command that drops a 6-texture starter pack
(grass, dirt, stone, brick, wood, water) into <zoneDir>/textures/
by fanning out to the procedural --gen-texture-* family. Saves
users from sourcing proprietary art when bringing up a new zone —
the entire pack is open PNG output from procedural generators.
Adds to the gen-random-zone family of project orchestrators.
Procedural wood grain texture: vertical streaks of varying width
between two hues, plus pseudo-random knots. Reproducible from a
seed via tiny LCG (no <random> dep). Suitable for doors, planks,
fences, crates.
Defaults: spacing=12px, seed=1, W=H=256. Brings procedural
texture pattern set to 13 commands.
Procedural brick wall texture with offset rows + mortar lines. Each
row alternates by half a brick width, mortar gap appears between
rows and within each row. Useful for walls, chimneys, paths, and
medieval-zone props.
Defaults: brickW=64 brickH=24 mortarPx=4 W=H=256. Brings procedural
texture pattern set to 12 commands.
Procedural tree: cylindrical trunk (12 segments) + UV-sphere
foliage (12 segs × 8 stacks). Foliage centered above the trunk
with a slight overlap so the trunk pokes into the bottom of the
canopy.
Useful for ambient zone decoration, distant tree placeholders,
magic-grove props. The 15th procedural primitive — composite of
cylinder + sphere with everything in a single batch so it ships
as one mesh.
Args: <wom-base> [trunkRadius] [trunkHeight] [foliageRadius]
Defaults: 0.1 / 2.0 / 0.7 (3.2y total height — small/medium tree).
Pairs naturally with --add-texture-to-mesh for the bark+leaf
textures, or just one composite texture since this is a single-
batch mesh. Verified: defaults produce 143 verts / 216 tris.
Times each --audit-project sub-step end-to-end so users can see
where the slow checks are. Useful for tuning a CI pipeline: drop
the slowest check from a fast-feedback pre-commit hook, run the
full audit on push.
Reports wall-clock per step, share of total, and pass/fail status
for each. Status column means the check ran cleanly even on a zone
with content issues — bench timings are about runtime, not
correctness.
On a small test zone, items-schema and spawn-placement dominate
the share (~25% each) since they involve loading content +
sampling terrain. Format/open-only/refs/content are sub-10ms each.
Same value-noise function as --gen-texture-noise but interpolated
between two RGB endpoints rather than emitted as grayscale.
Useful for terrain detail (grass+dirt mottle), magic fog, marble
veining, or any "natural variation" pass that shouldn't be
desaturated.
Args: <out.png> <colorAHex> <colorBHex> [seed] [W H]
Defaults: seed 1, 256x256.
11th procedural texture pattern (joining solid, BW checker, color
checker, grid, vertical/horizontal/radial gradients, grayscale
noise, stripes, dots, rings).
Compares two zones' creatures + objects with two-pointer match-by-
(kind, name): paired entries with mismatched positions report as
"moved" with the (dx, dy, dz) delta; entries that exist in only one
zone are added/removed.
Useful for "what did this branch change vs main" before merging,
for confirming a copy-zone-items produced the expected result, and
for cross-zone consistency reviews.
Move threshold is 0.5y; smaller deltas count as "same" since
typical drift from snap-zone-to-ground is sub-yard. Exit 1 if
anything differs so CI can gate on cross-zone consistency.
Verified: 2 different random-populated zones → reports 6 added /
5 removed / 1 moved / 0 same with the moved entry showing its
position delta.
Extended the composite project audit from 4 sub-checks to 6,
adding the two new gates:
- validate-project-items (items.json schema across zones)
- audit-project-spawns (spawn Z within 5y of terrain)
Sub-checks now ordered cheapest → most expensive so a fast failure
surfaces before the slow ones run: format validation runs in
milliseconds, but spawn-placement audit requires loading every WHM
tile and casting rays.
Single-command release-readiness gate: a green --audit-project
now means format-clean + open-only + items-clean + refs-resolve +
content-sane + spawns-grounded.
The existing --gen-texture's "checker" pattern is fixed black/white
at 32px. This is the configurable variant: pass two colors and an
optional cell size to generate boards in any palette. Useful for
chess/checker game boards, kitchen-floor textures, hazard markers
in colors other than monochrome, retro UI backgrounds.
Args: <out.png> <colorAHex> <colorBHex> [cellPx] [W H]
Defaults: cellPx 32, 256x256.
10th procedural texture pattern (joining solid, the BW checker,
grid, vertical/horizontal/radial gradients, noise, stripes, dots,
rings).
Builds a doorway arch from two rectangular columns (one on each
side of the opening) plus a semicircular curved band across the
top. Total height = openingHeight + archRadius (where archRadius
= openingWidth/2). Aligned so the inside of the opening is
centered on the Y axis.
Args: <wom-base> [openingW] [openingH] [thickness] [depth] [segments]
Defaults: 1.0 / 1.5 / 0.2 / 0.3 / 12. Curve segments hard-capped
at 256.
Useful for cave entrances, gates, portal frames, dungeon
thresholds. The 12th procedural primitive (joining cube/plane/
sphere/cylinder/torus/cone/ramp/grid/disc/tube/capsule).
Verified: 1.0×1.5 opening with 12 segments produces 96 verts /
48 tris, bounds Z spans 0..2.0 (= 1.5 + 0.5 arch radius).
Recursively copies an entire project tree (every zone subdir +
manifests + content files). Refuses to overwrite an existing
destination so a typo doesn't silently merge into the wrong
project — user must delete the destination first if intentional.
Reports zone count, total file count, and total byte count of
what was copied. Useful for forking a project for experimentation,
or for creating snapshot backups before risky bulk operations
like --strip-data-tree or --remove-project-orphans.
Verified: 2-zone gen-random-project source → copy-project →
"zones: 2, files: 12, total bytes: 395989" reported correctly,
existing destination correctly rejected.
Project-wide companion to --info-zone-overview. Single-page table
with one row per zone showing biome / tile count / creature / object
/ quest / item counts and audio yes-or-no, plus aggregate totals
across the project.
Useful for "what's in this project" at-a-glance reviews and CI
artifacts that need a compact status snapshot. Cheap content
counts via direct JSON parse (same approach as --info-zone-overview)
so even a 100-zone project takes milliseconds.
Verified on 3-zone gen-random-project run: per-zone rows show
identical counts (5c/2o/3i each), totals row aggregates correctly
to 15c/6o/9i.
Where --info-zone dumps every manifest field, --info-zone-overview
is a tweet-length status: zone name, biome, content counts, audio
flag. Easy to grep through --for-each-zone output to spot
outliers.
Format: name [biome] Nt/Cc/Oo/Qq/Ii [+audio]
N = tiles, C = creatures, O = objects, Q = quests, I = items
+audio shown when music or any ambience is set
Cheap content counts via direct JSON parse — no need to spin up
the full NpcSpawner/ObjectPlacer/etc classes for an overview.
Both human and --json output modes.
Capsule along the Y axis: cylindrical body of length cylHeight
bookended by two hemispheres of `radius`. Total height is
cylHeight + 2*radius.
Useful for character collision shells, pill-shaped buttons,
hot-dog props, physics-friendly placeholders, sausages.
Layout: top hemisphere (stacks rings, north pole at the top) →
cylindrical body (1 quad band) → bottom hemisphere (mirror).
Per-vertex normals follow the smooth surface so shading works
correctly through the body-cap transition.
Args: <wom-base> [radius] [cylHeight] [segments] [stacks]
Defaults: 0.5 / 1.0 / 16 / 8.
Verified: defaults produce 340 verts / 544 tris with bounds
spanning the expected total height of 2.0 (= 1.0 cylinder +
2*0.5 hemispheres). Brings the procedural primitive set to 11.
Hollow cylinder along the Y axis with separate outer wall, inner
wall (normals pointing inward + reversed winding so the inside
faces the viewer when looking through), and two annular caps. UV
coords on the caps map the inner ring proportionally so a radial
texture stays continuous across both rings.
Useful for railings, fence posts, pipes, hollow logs, ring towers
— anywhere a solid cylinder would feel wrong because you should
be able to see through the middle.
Args: <wom-base> [outerR] [innerR] [height] [segments]
Defaults: 1.0 / 0.7 / 2.0 / 24. Validates innerR < outerR so the
walls don't intersect.
Verified: defaults produce 200 verts / 192 tris (4 surfaces × 48
quads × 2 tris = 384, halved by per-segment-pair indexing → 192).
Brings the procedural primitive set to 10 (cube/plane/sphere/
cylinder/torus/cone/ramp/grid/disc/tube + stairs + heightmap).