74th procedural mesh primitive. Long horizontal hitching
bar held up by N evenly-spaced vertical posts. Distinct
from --gen-mesh-hitching-post (just 2 posts + bar) — this
is the longer multi-post variant for taverns, stockyards,
racecourse parking, market days, festival hitching lines.
Posts auto-spaced from -L/2 to +L/2, inset by postW so the
end posts align with the rail tips. Bar spans the full
length on top of the post tier.
Watertight under weld (verified 90 manifold edges, 0
boundary, 0 non-manifold). Default 4-post / 4 m rail at
1.2 m mount height fits typical mount silhouettes.
Milestone: kArgRequired now reaches 400 documented flags.
68th procedural texture: stack of V-shape stripes with
sharp seams. Within each vertical period the upper half
slopes one way and the lower half slopes the other; the
distance from the apex is added as an x-shift to the
stripe-column test, so stripes follow the V profile and
form clean chevrons.
Distinct from --gen-texture-herringbone (which alternates
slab orientation between cells) and --gen-texture-zebra
(sinusoidal stripes with no seam) — chevron has the
characteristic sharp V transition.
Useful for military insignia, sportswear, heraldic banners,
roadwork signage, paladin tabards, ranger cloaks. Default
24-period / 24-stride / 6-wide gives a chunky chevron at
256x256; tighter values read as fine ribbon trim.
Fifth themed mesh pack after camp / blacksmith / village /
temple. Cemetery scene emitting a 7-primitive burial yard:
• grave — filled plot mound
• tombstone — marker stone
• coffin — above-ground or open
• statue — mourning angel / patron deity
• stone-bench — for visitors and mourners
• gravel-pile — loose earth from a fresh dig
• cage — fence section / mausoleum gate
Together these form the standard town-edge burial yard
when arranged in a zone. Composite-pack catalogue now:
camp + blacksmith + village + temple + graveyard.
All 7 outputs validate clean. --list-packs surfaces 10
composite flags total (5 mesh packs + the pre-existing
zone/project starter packs).
73rd procedural mesh primitive. Open-top mining cart on
4 wheel boxes:
• bin: 5-piece basin construction (bottom slab + 4
perimeter walls), same arrangement as
--gen-mesh-water-trough
• wheels: 4 cube boxes at the corners, inset by
wheelInset and sitting on the ground (y from 0 to
2*wheelR)
• bin sits on top of the wheels at y = 2*wheelR
All axis-aligned — exercises every shared helper. Useful
for mines, dwarven forges, gnomish junk-yards, abandoned-
tunnel set dressing, salvage scenes.
Default 0.9 × 0.5 m bin with 0.08-radius wheels gives the
classic narrow-gauge ore-cart silhouette. The 4-wall basin
construction (verified via --info-mesh-stats: 6 non-manifold
edges at the wall corners — same as --gen-mesh-water-trough's
expected branchy edges) means the cart can hold collision-
visible ore inside if a content author drops in another
primitive.
Two related changes:
• --list-packs walks kArgRequired and surfaces every flag
matching --gen-*-pack (excluding --gen-mesh-* and
--gen-texture-* which are individual primitives). Sister
command to --list-primitives. Auto-tracks new packs as
they're added — no parallel registry.
• --gen-temple-pack composite — temple/shrine ritual hall
(altar + shrine + brazier + pillar + statue + portal +
podium). Fourth themed mesh pack after camp / blacksmith /
village.
list-packs now surfaces 9 composites including the pre-
existing zone-* / project-starter packs that match the
naming convention. All 7 temple-pack outputs validate clean.
72nd procedural mesh primitive. Long stone bench from 3
axis-aligned boxes:
• horizontal seat slab spanning the full length on top
• 2 vertical block supports near the ends, inset by
supportInset from each end so the seat slab overhangs
them slightly (the standard "seat rests on legs" look)
Distinct from --gen-mesh-bench (wooden 4-leg construction
with thinner pieces) — this is the heavier stone variant
for parks, temple courtyards, ruined cities, dwarven mead
halls, library-courtyard reading nooks.
Watertight under weld (verified 54 manifold edges, 0
boundary, 0 non-manifold). Default 2.0 m × 0.4 m bench at
0.45 m sit height reads at adult-human proportions.
Uses every shared helper added in recent batches —
new gen-mesh handlers now consistently land at ~50 lines
including parse + validate + geometry + finalization.
66th procedural texture: axis-aligned grid of solid diamond
shapes (no row offset) separated by visible bg gaps. Each
cell hosts one diamond computed via L1 (taxicab) metric:
|dx|/halfW + |dy|/halfH < fillFrac.
Distinct from --gen-texture-snake-skin (brick-offset diamonds
that touch tangentially with a derived dark outline) — this
variant uses uniform spacing and a configurable fill fraction
so diamonds float in clean grid rows.
fillFrac = 0.80 default gives a 20% bg-gap moat between
diamonds; bump near 1.0 for nearly-touching chevron-floor
look, drop to 0.5 for sparse polka-diamond.
Useful for clean tile floors, mosaic inlay panels, banner
seamless backgrounds, formal heraldry trim, jeweled-cloak
tabards.
Third composite pack (after --gen-camp-pack and
--gen-blacksmith-pack), emitting a 7-primitive village-square
scene into <outDir>:
• house — main dwelling
• outhouse — privy beside it
• chimney — for the house roof piece
• hitching-post — at the hitching rail
• well — village square centerpiece
• signpost — pointing the way out of town
• haystack — from the nearby farm
Together these form a recognizable rural-village hub when
arranged in a zone. Uses the existing emitMeshPack helper —
the new pack is just an 8-line declarative table.
All 7 outputs validate clean (--validate-wom PASSED across
the board). Composite-pack catalogue now: camp + blacksmith
+ village.
71st procedural mesh primitive. Hash-distributed pile of
stone cubes in a roughly conical heap. Each stone gets:
• polar position (radial, theta) with sqrt(rand) on radial
so stones aren't bunched at center
• height limited by yMax = pileH * (1 - radial/baseR), so
larger / more numerous stones land near the base and
smaller ones perch on top — natural gravel-pile profile
• size in the 40-100% range of maxStoneSize
The second multi-box "scene" composite primitive (after
--gen-mesh-crate-stack), but using irregular hashed
placement instead of a regular N×M×K grid. Deterministic
from seed: re-running with same args reproduces the
identical pile.
Useful for mine entrances, construction sites, quarries,
ruined walls, abandoned-fort rubble, pirate-cove stash
mounds. Default 24 stones at 0.6 m base radius gives a
reasonable medium-pile.
Uses every shared helper introduced this batch (printWomWrote,
printWomMeshStats, setCenteredBoundsXZ, addFlatBox,
saveWomOrError, parseOpt*, stripExt).
65th procedural texture: 2 sets of parallel "translucent"
bands — one horizontal, one vertical — overlaid on a base.
Each band contributes 0.5 alpha, so where bands cross both
half-alphas combine for the darkest color (the unmistakable
plaid grid intersection).
Distinct from --gen-texture-tartan (3-4 colors with
asymmetric stripe pitches) — this is the simple symmetric
2-color variant. Distinct from --gen-texture-checker (hard
binary squares) — plaid uses 3-tone alpha-blend gradient.
Useful for pub-table cloths, country-tavern napery, dwarven
formal-attire trim, picnic blankets, peasant-clothier
swatches. Default 24-stride / 8-band reads as classic
country-checked at 256x256.
First procedural texture to also use the new printPngWrote
helper from this batch.
70th procedural mesh primitive. Round-faced archery target on
a 2-post stand:
• face: closed cylinder along the Z axis (flat ±Z caps face
the archer line, side wall is the rim) of radius faceR
centered at height postH
• stand: 2 vertical posts at the bottom, sized to reach
from ground to the bottom of the face, with a horizontal
cross-beam joining them just below the face for rigidity
Concentric scoring rings live in texture space, not geometry —
the cap discs are the natural canvas for a separate target-
ring texture (or use --gen-texture-rings / --gen-texture-
starburst on top).
Pairs naturally with --gen-mesh-training-dummy /
--gen-mesh-fence for sparring grounds, training yards,
militia drill squares, mid-summer fair scenes.
Watertight under weld (verified 198 manifold edges, 0
boundary, 0 non-manifold).
64th procedural texture: vertical rust drips on a metal base.
Each streak is a hash-derived (x position, width 1..4 px,
top y, length H/3..H) band that fades from full rust at the
top to bg at the bottom — the "streak" effect of years of
rain washing rust down from rivets and seams.
Distinct from --gen-texture-rust (generic surface noise) —
this is the directional-drip variant for:
• weathered metal walls (especially under high windows)
• sewer-grate backings under standing puddles
• ship-hull stains below scupper ports
• abandoned-machinery panels under leaking pipes
Deterministic from seed: re-running with same args produces
the byte-identical image. Default 40 streaks at 256x256
gives a reasonable "lightly aged" intensity; bump
streakCount for heavier corrosion.
Two changes in one commit because they're co-designed:
• Extract emitMeshPack(outDir, packName, items) as a shared
helper that takes a vector of PackItem {flag, fn, leaf}
and runs each handler with a synthetic argv. Keeps the
"build a 2-element argv per sub-handler" wiring in one
place instead of copy-pasted per pack.
• Add --gen-blacksmith-pack on top: a smithy-themed
composite emitting forge + anvil + workbench +
water-trough + crate-stack + hitching-post into outDir.
The classic forge-floor layout in 6 .wom files.
Refactors --gen-camp-pack to use emitMeshPack (verified
unchanged: 6 .wom files still land in the camp dir).
Pattern is now established for future packs (--gen-village-
pack, --gen-temple-pack, --gen-dock-pack…) — each is just a
list of primitives in 8 lines of code.
69th procedural mesh primitive. Built from up to 3 axis-
aligned boxes:
• stone hearth: rectangular base spanning width × depth ×
baseH, where the smith's fire would sit
• hood: smaller smoke-collector box on top of the hearth,
inset by hoodInset on each side so it reads as the
chimney's flared base
• optional thin chimney rising from the hood — set
chimneyH=0 for an open-vented forge
Pairs naturally with --gen-mesh-anvil and
--gen-mesh-workbench for blacksmith/armorer/farrier scenes,
and with --gen-mesh-bench / --gen-mesh-crate-stack for
the storage corner of a smithy.
Watertight under weld (verified 54 manifold edges, 0
boundary, 0 non-manifold). Default 1.4×1.0×0.9 m hearth +
0.5 m hood + 1.2 m chimney reads as a normal village smithy.
63rd procedural texture: minor + major grid lines on a base.
Minor lines at every `minorStride` pixels (default 16);
every `majorEvery` minor lines a thicker major line is drawn
(default every 4). Both axes get the same treatment so the
result is a sectioned drafting / engineer's paper look.
Distinct from --gen-texture-mesh-screen (uniform line
weight) — this is the periodic-emphasis variant. Good for:
• drafting-table surfaces
• technical-schematic backdrops
• architect-shop / cartographer-shop walls
• engineer / scholar ritual tables
• star-chart room floors
Default 16-stride / every-4-major gives the classic blue
graph-paper aesthetic at 256x256. First procedural texture
that takes 4 numeric layout params plus W/H — exercises the
new parseOpt* helpers across more args than usual.
68th procedural mesh primitive. Built from 3 axis-aligned
boxes:
• solid body slab spanning width × depth × (height-roofT)
• thin door slab on the +Z face (pushed slightly outward
so it visually sits on the wall — gives doorframe-like
relief without a real cutout)
• roof slab slightly larger than the body footprint and
sitting on top, controlled by roofOverhang
Distinct from --gen-mesh-house (multi-walled, peaked-roof
dwelling). An outhouse is the single-room privy / tool shed
variant — useful for villages, frontier outposts, small
farms, refuse-shed corners.
Watertight under weld (verified 54 manifold edges, 0
boundary, 0 non-manifold). First handler to use the new
setCenteredBoundsXZ helper from this batch.
Convenience composite command: emits a complete outdoor-camp
scene (tent + firepit + bedroll + canopy + woodpile +
haystack) into <outDir>/ as 6 .wom files in one invocation.
Internally builds a synthetic argv array per primitive and
calls each existing handler — so the camp pack always
matches the per-primitive defaults exactly. Users wanting
custom dimensions should call the individual --gen-mesh-*
commands.
Smoke tested:
• Creates outDir if needed
• All 6 .wom files validate clean (--validate-wom PASSED)
• Vertex / triangle counts match per-primitive defaults
(firepit 240/120, woodpile 324/288, etc.)
The first composite command in the editor — establishes the
pattern for future packs (--gen-village-pack, --gen-dock-pack,
etc.) by showing how synthetic argv arrays let one handler
delegate to many others without spawning subprocesses.
62nd procedural texture: vertical bamboo stalks with
cylindrical sin² brightness shading + horizontal darker
node bands at regular Y intervals. Each stalk gets a small
hash-derived hue jitter (±15) so adjacent stalks don't
read as a perfect repeat.
Per-pixel logic:
• 10% horizontal gap between stalks (gapFrac=0.10) →
visible bg seam between bamboo stalks
• Inside the stalk, brightness = sin²(insetFraction * π)
rising from 0 at the stalk edge to 1 at the centerline
• Every nodeY pixels, a `nodeBand`-tall horizontal strip
has its brightness knocked down to 2/3 — the segmented
bamboo joint look
Useful for jungle huts, pandaren / asian-themed architecture,
swamp boardwalks, tropical-tribe weapon trim, brewmaster
zone trim. Default 24-pitch / 64-spacing / 4-band reads as
adult-bamboo at typical 256x256 wall-tile scale.
67th procedural mesh primitive. Standard town/stable
hitching post:
• two vertical posts separated by `span`
• horizontal cross-bar at upper-post height (length =
span - postW so it tucks INSIDE the post inner faces,
matching real fence joinery)
• optional decorative caps on each post — set capH=0
for a bare working-yard post
All axis-aligned boxes, exercises every shared helper
(stripExt, initWomDefaults, addFlatBox,
finalizeAsSingleBatch, saveWomOrError). Watertight under
weld (verified 90 manifold edges, 0 boundary, 0
non-manifold).
Useful for stables, taverns with mount parking, town
squares, frontier outposts, ranger camps, post-and-rail
fence segments.
61st procedural texture: thin horizontal + vertical wires
forming an axis-aligned grid. Distinct from
--gen-texture-lattice (which uses ±45° diagonals to make
diamond openings) — this gives the right-angle window-
screen / chain-link / sci-fi-grille look.
Tested per-axis: a row is "on a wire" if (y % stride) <
wireW; a pixel falls on a wire if either its row OR its
column tests positive. Result is the unmistakable
orthogonal-mesh appearance.
Useful for window screens, anti-pest grates, fish nets,
sewer grilles, sci-fi vent panels, prison-cell windows,
goblin-workshop catwalks. Default 12-stride / 2-wide
gives a coarse mesh; finer versions read as bug screen.
66th procedural mesh primitive. Combat training dummy from
axis-aligned boxes:
• vertical post from ground to baseH (the stand)
• cubic torso block stacked on top of the post
• horizontal cross-bar arms at upper-third torso height
spanning armSpan along the X axis
• optional head cube above the torso (set headSize=0
for a headless training-block style)
Pairs with --gen-mesh-anvil / --gen-mesh-workbench /
--gen-mesh-fence for sparring grounds, militia drill
squares, training yards, weapon-master compounds. Useful
for any "things-to-hit" set dressing where animated NPCs
would target a static prop.
Watertight under weld (verified 72 manifold edges, 0
boundary, 0 non-manifold). Default 1.0 m post + 0.4 m
torso + 0.18 m head reads at adult-human height.
60th procedural texture: brick-offset grid of diamond-shaped
scales using L1 (taxicab) metric so |dx|/halfW + |dy|/halfH
< 1 inside each diamond. Even rows are aligned with the cell
grid; odd rows shift by halfW so adjacent scales touch
tangentially along their points — the classic snake/dragon
hide pattern.
A thin dark outline at d ∈ [outlineFrac, 1] gives definition;
outline color is automatically derived as scaleHex × 0.4
(2/5 brightness). Set outlineW=0 to skip the outline for a
smoother painted-scale look.
Distinct from --gen-texture-scales (overlapping circles for
fish/dragon scales) and --gen-texture-chainmail (rings for
metal mail). Useful for snake-cult robe trim, naga skin,
dragon-scale armor inserts, lizardman set dressing,
basilisk-themed dungeon decor.
65th procedural mesh primitive. Open-top rectangular basin
built from 5 axis-aligned boxes (uses every shared helper
from cli_box_emitter):
• bottom slab spanning full footprint at wallT thickness
• +X / -X side walls spanning full length
• +Z / -Z front/back walls spanning the inner length so
they tuck inside the side walls without overlap
Inner cavity (length-2*wallT × height-wallT × width-2*wallT)
is the open water/feed volume. Useful for stables, farmsteads,
taverns, stockyards, alchemist mixing basins.
Default 1.4 × 0.5 × 0.5 m is a reasonable horse-trough size;
configurable for smaller hand-basins or larger livestock
troughs.
59th procedural texture: 2-octave bilinear value noise
thresholded into hard bg/fg blobs. Sharp edges read as
real military camouflage rather than the smooth gradient
--gen-texture-noise-color produces.
Two octaves combined at 0.7/0.3 weights:
• low frequency at cellSize lattice → large dominant blobs
• high frequency at cellSize/4 lattice → finer mottling
overlay so blob edges aren't perfectly smooth
Threshold parameter shifts the bg/fg balance — lower values
expose more accent color (good for leaf-pattern), higher
values keep the dominant color dominant (good for rock/sand).
Useful for guard cloaks, military uniforms, ghillie suits,
druid robes, hunter blinds, scout cloaks. First procedural
texture to use the new savePngOrError helper from
cli_png_emit.hpp.
64th procedural mesh primitive. A simple scout/sentry
watchpost from axis-aligned boxes:
• tall central pole rising from ground to postH
• square platform slab on top of the pole, wider than
the pole so it overhangs as the lookout deck
• 4 corner railing posts on the platform — set
railingH=0 for a bare deck
Distinct from --gen-mesh-tower (round castle tower with
crenellated battlements). A watchpost is the rough scout/
forward-outpost variant — just wood and rope, no masonry.
Pairs naturally with --gen-mesh-tent / --gen-mesh-firepit
for camp + lookout scenes, and --gen-mesh-fence for
perimeter setups. Watertight under weld (verified
108 manifold edges, 0 boundary, 0 non-manifold).
58th procedural texture: thin vertical lines at every
`stride` x position, with optional thicker "feature" line
every Nth stripe. The periodic doubled-thickness emphasis
is what distinguishes this from --gen-texture-stripes
(which renders wide alternating bands of each color).
Each stripe is centered within its column and has
configurable lineW; feature stripes are 2× the regular
width. Set featureEvery=0 to disable feature emphasis for
a uniform pinstripe pattern.
Useful for noble-house tabards, formal-attire fabric,
banker's counter cloth, sci-fi panel detailing, royal-
guard uniform trim, library / archive carpet runners.
Default 12-pixel stride, 1-pixel line, feature every 6th
stripe gives the classic suit-pinstripe look at 256x256.
63rd procedural mesh primitive. The first to explicitly
compose a *scene* of multiple objects rather than a single
structure: an N×M×K arrangement of cube crates with a small
gap between each so they read as discrete shipping boxes
rather than one merged solid.
Default 2×2×2 = 8 crates with 0.40 m sides on a 0.02 m gap
gives a tight pyramidal pile. Larger configurations (e.g.
4×3×2 = 24 crates) read as warehouse pallets.
Uses every shared helper added this batch — addFlatBox for
each crate, finalizeAsSingleBatch for the trailing batch,
stripExt for the .wom suffix, parseOptInt/Float for the
optional dimension args. Each crate emits the standard
24-vert / 12-tri box, so an N×M×K stack is a clean
N*M*K-multiple in vertices and triangles.
Useful for warehouses, cargo holds, dock loading bays,
market stalls, dwarven mining caches, pirate stash piles.
Watertight under weld — the gap keeps adjacent crates
from sharing corner positions.
57th procedural texture: 2x2 cell pattern where alternating
cells hold horizontal vs vertical fiber segments. Each
segment gets a sin² brightness profile across its
perpendicular axis — 0 at the segment edge, peak at center —
giving the rounded highlight of a real woven fiber bundle.
Cell-pair parity (cx + cy) % 2 determines orientation, so
adjacent cells always alternate weave direction in both X
and Y. Reads as the unmistakable carbon-fiber checkerboard
even at small scales.
Useful for sci-fi armor, sleek tech panels, vehicle bodies,
ritual obsidian inlays, dwarven runeplate accents — any
"machined composite" surface where flat dark grey would
read as plain plastic.
Default 12-pixel cell at 256x256 reads cleanly with about
21 visible weave segments per side.
62nd procedural mesh primitive. A blacksmith / crafter
workbench built from axis-aligned boxes (uses the new
cli_box_emitter helper plus the new cli_arg_parse helpers
for all 7 optional dimension args):
• flat top slab spanning length × depth at topT thickness
• 4 corner legs sized so their outer faces line up with
the top edges (post-style, no overhang)
• optional vise box at the +X end of the top — set
viseSize=0 for a bare bench
• optional raised tool tray along the +Z back edge —
set trayH=0 to omit
Pairs naturally with --gen-mesh-anvil (existing) for
blacksmith forge scenes, and --gen-mesh-cauldron for
alchemist labs. Default 1.6×0.7×0.85 m bench reads at
realistic adult-human working height.
Watertight under weld (verified via --info-mesh-stats:
126 manifold edges, 0 boundary, 0 non-manifold).
56th procedural texture: concentric annual growth rings
centered slightly off-image (at -W*0.2, H/2) so the texture
shows sweeping arcs across most of its area rather than the
bullseye --gen-texture-rings produces.
Per-ring jitter shifts the dark-band center within each
ring's annular cell, so adjacent rings don't read as a
perfect modulus pattern — mimics real annual-growth
variation. Brightness lerps from lightHex (early-wood)
to darkHex (late-wood / heartwood) with a smooth
triangular falloff at the dark-band peak.
First procedural texture to use the new cli_arg_parse
helpers for the optional spacing/seed/W/H args.
Useful for tabletops, log-end caps (chopped firewood
stumps), barrel lids, beam cross-sections, plank ends —
distinct from --gen-texture-wood which renders vertical
grain streaks for plank surfaces.
61st procedural mesh primitive. Builds a bedroll prop:
• horizontal closed cylinder along the Z axis sitting at
y = R so it rests on the ground (radius defaults to
0.16 m, length 1.4 m — adult-human-shaped)
• optional pillow box at the +Z end (squashed cube,
pillowSize controls extent)
• per-segment N-sided cylinder uses the new addVertex
helper; pillow uses addFlatBox
Set pillowSize=0 for a bare rolled mat. Watertight under
weld (verified via --info-mesh-stats: 90 manifold edges,
0 boundary, 0 non-manifold).
Pairs naturally with --gen-mesh-tent / --gen-mesh-firepit /
--gen-mesh-canopy for outdoor camp scenes — completes the
tent-side camping kit.
55th procedural texture: irregular spots scattered on a hash-
jittered grid. Each cell tests its 8 neighbors so spots near
cell boundaries don't get clipped at the cell wall.
Per-cell hashing controls:
• presence — density 0-100 chance the cell hosts a spot
• position — uniform jitter inside the cell
• radius — 25-75 % of stride, so adjacent spots vary in size
Result reads as random patches of organic growth rather than
a visible lattice. Useful for forest floors, weathered stone
walls, dungeon flagstones, swamp ground, ruined-temple
overlay, fungal-cavern detail.
Default 16-stride / 70-density on a stone-grey base reads
cleanly at 256x256 with about half the surface mossed over.
Walks every .wom and .wob under <zoneDir>, optionally welds
each one independently (per-mesh / per-WOB-group), and
appends its triangles to a single WoweeCollision. Useful for
shipping a zone — one .woc artifact holds all object collision
so the server side has just one file to load.
Per-file weld preserves between-object boundaries: two
distinct WOMs sitting at the same world position keep
their topology separate even if their corner positions
happen to overlap.
Same flag surface as the single-file bakers: optional
[out.woc] (defaults to <zoneDir>/zone.woc), --weld <eps>,
--steep <deg> for the walkable/steep slope cutoff.
Smoke tested over /tmp/migtest: scanned 79 WOM + 1 WOB,
produced 9259-triangle WOC (1563 walkable, 1943 steep)
with correct world bounds.
60th procedural mesh primitive. Builds a chimney as two
axis-aligned boxes (uses the shared addFlatBox helper):
• main shaft: rectangular brick stack of width × depth ×
(height - capH)
• protective cap: a slightly wider box on top (capExtra
wider than shaft on every side) — the rain-throw crown
that sits on real masonry chimneys
Set capH=0 for a bare unfinished stack. Default 0.45×0.45×
1.8 m shaft with a 0.10-tall cap reads at human scale for
rooftop placement.
Useful for cottage rooflines, blacksmith forges, alchemist
labs, dwarven longhouses — any structure with a fireplace
that needs visible vent. Watertight under weld (verified
via --info-mesh-stats: 36 manifold edges, 0 boundary, 0
non-manifold).
Sibling of --audit-watertight that walks every .wob under
<root> and runs the welded watertight check on every group.
A WOB passes only if every group is closed — interior rooms
in a real building should each be a closed solid even
though the building as a whole has intentional portal
openings between them.
Per-failure detail lists which groups failed and why
(boundary edge count + non-manifold edge count). Exit code
is the number of failed buildings (capped at 255) — same
CI-friendly contract as the WOM audit.
Smoke tested against /tmp/migtest cube.wob: PASS, 12 tris,
exit code 0.
54th procedural texture: grid of round rivet caps with an
inner highlight. Each stud has:
• outer ring (40%-100% of studR) at the studHex base color
• inner core (0-40% of studR) at studHex × 1.4 brightness
• bg color outside studR
The 40% bright core sells the 3D rivet appearance — a flat
solid circle (which --gen-texture-dots already produces)
reads as a polka dot, while the bright/dim concentric pair
reads as a metal stud catching light.
Useful for studded leather armor, riveted plate, banded
mail trim, dwarven hauberks, prison-cell door reinforcement,
ship hull plating. Default 24-stride grid with R=7 reads
cleanly at typical body-armor scale.
59th procedural mesh primitive. Builds an open-top pergola
from axis-aligned boxes (uses the new addFlatBox helper):
• 4 corner posts sized so their outer faces line up with
the footprint perimeter
• 2 long perimeter beams resting on top of the posts
along the long edges
• N cross beams running between the perimeter beams
(slightly thinner so the lattice has visible crossings)
Distinct from --gen-mesh-canopy because there's no closed
overhead panel — the open lattice top reads as a sun-trellis
or vine-arbor instead of a market-stall awning. Useful for
palace courtyards, druid groves, garden mazes, viewing
arbors, harvest-festival entrance pieces.
Set crossbeams=0 for a bare 4-post + 2-beam frame; default
5 crossbeams gives a pleasing alternating pattern.
53rd procedural texture: N rays radiating from the texture
center. Each pixel computes its angle via atan2 and finds
the angular distance to the nearest ray axis (handling the
±π wrap so rays around the seam are continuous). Pixels
inside any ray's angular band get the ray color.
Brightness tapers linearly with distance from center: 1.0
at the hub, 0.4 at the texture diagonal — gives sun-rays
that fade as they extend outward instead of reading as
infinite lines.
Useful for sun motifs, holy/divine symbols, paladin
insignias, mage-robe trim, mosaic medallion centers,
shrine floor inlays, and any "radiant glory" surface.
Sibling of --bake-wom-collision for buildings. Walks every
group in a WOB, optionally welds vertices PER GROUP (groups
are intentionally separate — rooms with portals between them,
so welding across groups would fuse walls that should remain
distinct collision surfaces), and appends each to a single
WoweeCollision via WoweeCollisionBuilder::addMesh.
Same flag surface as the WOM variant: optional [out.woc]
output path, --weld <eps> for per-group vertex merge,
--steep <deg> for the walkable/steep slope cutoff.
Smoke tested on a 1-group cube WOB: 8 verts → 12-triangle
WOC with proper bounds (-1,-1,-1)..(1,1,1) and walkable/
steep classification matching the cube face orientations.
58th procedural mesh primitive. Builds a wooden waterside
dock from axis-aligned boxes:
• flat plank deck slab spanning length × width at deckT
thickness, sitting at deckHeight off the ground
• N pairs of square pilings under the long edges, evenly
spaced from end to end
• pilings inset by pilingW so the deck overhangs slightly
(the standard "boards rest ON TOP of the posts" look)
Distinct from --gen-mesh-bridge which arches OVER an
obstacle — a dock walks straight out from a shoreline on
stilts to the water. Useful for fishing villages, port
warehouses, lake settlements, ferry stations, smuggler
hideouts.
Watertight under weld (--audit-watertight passes): pilings
sit below the deck overhang and don't share corners with it.
52nd procedural texture: water-surface caustics via four
superimposed sine waves running along x, y, x+y, and x-y.
Each wave is taken in absolute value before multiplication
so peaks shine on either side of the wave centerline,
giving the bright-line interference network you see on a
pool floor or sunlit shallow streambed.
Two-color lerp from bgHex (depth) to hiHex (highlight).
Default 24-pixel period reads at the right scale for water-
plane underlay; pass a smaller period for tighter ripple.
Useful as the floor texture under transparent water
volumes, magic-fountain pools, fish-tank ground plates,
ritual scrying basins, and any "submerged surface seen
through clear water" effect.
Walk every .wom under <zoneDir|projectDir>, run the welded
watertight check from cli_weld + the same edge-analysis as
--info-mesh-stats, and report PASS/FAIL with the per-mesh
failure detail (boundary / non-manifold edge counts).
Exit code is the number of failures (capped at 255), so
CI pipelines can gate on `--audit-watertight $project` and
fail the build if any mesh isn't a closed solid.
Smoke-tested over 61 procedurally-generated WOMs:
• 49 PASS — most stand-alone primitives are watertight
• tent_fixed FAIL with 5 boundary edges = the intentional
door cutout (correct surface count)
• woodpile / bed / well variants FAIL with non-manifold
edges = adjacent stacked cylinders/legs sharing corners
(correct geometry callout)
Defaults to weld eps 1e-4 — a good balance for procedural
output where positions are exact rationals at typical scales.
57th procedural mesh primitive. Builds a layered haystack:
N stacked frustums, each smaller than the one below, with
the topmost layer tapering to an apex point. The visible
shelves where each layer overhangs the smaller one above
read as bound straw shocks rather than the smooth
silhouette --gen-mesh-pyramid produces.
Per layer: vertical side wall ring (no taper within a
single layer) plus a top "shelf" annulus where it meets
the next layer up. Final layer is a cone fan to a single
apex vertex. Closed bottom disc keeps the model a solid
for collision baking — verified watertight under weld.
Useful for farms, granaries, stables, harvest-festival
clearings, druid groves with bound bundles. Default 3
layers at 12 sides reads cleanly at typical NPC scale.
51st procedural texture: two interleaved sinusoidal strands
running along the Y axis. Each strand's X position oscillates
as W/4·sin(2π·y/period); the second strand is phase-shifted
by π so the two snake around each other forming the classic
helical twist of a tightened rope.
Within each strand, brightness rises from 0.55 at the edge
to 1.0 at the centerline (cos² falloff) — gives the rounded
3D appearance of cylindrical fibers without a separate
shadow pass.
Useful for hanging ropes, ship rigging, tied-bundle textures,
suspension bridges, market-stall awning ties, and any
"twisted cord" surface where a flat color would read as
ribbon rather than rope.
Default 24-pixel period with 8-pixel strands renders cleanly
at 256x256 with about 10 visible twists.
Convert any WOM mesh into a WOC collision file via
WoweeCollisionBuilder::addMesh, with optional --weld <eps>
that merges shared positions into a single canonical index
before baking. The weld pass is what makes per-face-shaded
procedural primitives produce a properly indexed collision
mesh — adjacent faces that previously authored 4 unique
verts per face now share 1 corner across all incident
faces, so raycasts can traverse edges naturally.
Also accepts --steep <deg> to control the walkable/steep
classification threshold (default 50° from horizontal,
matching the terrain pipeline).
Smoke-tested end-to-end:
• firepit: 240 verts → WOC with 120 tris (20 walkable
floor, 20 steep stone walls, rest neutral)
• tent_solid: 18 verts welds to 6, produces 8-tri WOC
• canopy: 216 → 56 weld, 108 tris, 30° steep cut
Pairs naturally with --info-mesh-stats --weld for
collision-quality QA before baking.
56th procedural mesh primitive. Builds a rectangular awning
on 4 corner posts with a flat overhead panel and optional
drape lips hanging down from each edge:
• 4 corner posts inset by postR so their outer faces line
up flush with the panel edges above
• flat panel slab spanning the full footprint, sitting on
top of the posts
• optional drape lips on all four panel edges (set drape=0
for a clean flat-top canopy with no hanging fabric)
All axis-aligned boxes; the no-drape variant is fully
watertight (verified via --info-mesh-stats --weld). Useful
for market-square stalls, vendor stations, alchemist booths,
caravan rest stops, and tournament viewing platforms.
Add --info-wob-stats reporting per-group + aggregate
triangle counts, surface area, edge analysis, and watertight
check for WOB buildings. Same flag surface as --info-mesh-stats
including --weld <eps> for true topological closure check
on per-face-vertex meshes.
Also fixes a correctness bug in the weld implementation
of --info-mesh-stats: the previous code used a 64-bit hash
of the quantized position as the equality key, which gave
false-positive collisions that incorrectly merged distinct
vertices. A unit cube's 8 corners collapsed to 2 positions
under the buggy hash. Replace with std::map keyed on the
actual quantized (qx, qy, qz) tuple so equality is exact.
Re-verified: cube 8→8 watertight YES; firepit 240→80
watertight YES (was wrongly reporting 56 unique with 48
non-manifold edges); tent_solid 18→6 watertight YES;
tent_fixed 21→9 with 5 boundary edges at the door perimeter
(correct — door is intentionally open).
50th procedural texture: smooth cosine ridges that lerp
between bgHex (trough) and hiHex (crest) over a configurable
period. Direction defaults to vertical ridges (wave varies
along X) — the standard corrugated-sheet-metal-roof look —
with optional horizontal mode for siding panels and pipe
texturing.
Useful for sheet-metal roofing, corrugated-iron walls,
sci-fi paneling, and any "ridged plate" surface where the
existing flat --gen-texture-metal would read as too uniform.
Default 16px period at 256x256 reads cleanly with about 16
ridges across the tile.