Commit graph

68 commits

Author SHA1 Message Date
Kelsi
805f7ce240 feat(editor): add --gen-texture-mold Worley-noise patches
72nd procedural texture: Worley (cellular) noise thresholded
into mold patches. Each grid cell hosts a hash-jittered
center; each pixel computes its distance to the nearest
center across 9 surrounding cells (current + 8 neighbors)
and is painted as mold if that distance is below
thresholdFrac × stride.

Distinct from --gen-texture-moss (single-spot per cell with
hash-derived presence/jitter/radius) — mold has irregular
field-shaped patches following the Voronoi cell boundaries
rather than discrete circles, mimicking real fungal growth
along surfaces.

Useful for cellars, dungeon walls, plague zones, sewer
overflow, food-warehouse spoilage, witch-hut detail trim.
Default 18-stride / 0.55-threshold gives a moderate
infestation; bump threshold near 0.9 for full coverage.
2026-05-09 13:19:30 -07:00
Kelsi
e95e983988 feat(editor): add --gen-tavern-pack composite
Eighth themed mesh pack after camp / blacksmith / village /
temple / graveyard / garden / dock. Inn/tavern scene
emitting a 7-primitive watering-hole layout:

  • house — the inn building
  • chimney — above the kitchen hearth
  • table — the common-room centerpiece
  • bench — seating
  • barrel — ale / cider stock
  • bookshelf — back-wall record / register / library
  • signpost — the inn-sign post out front

Together these form a minimum-viable tavern setup for any
roadside inn, town watering-hole, road-house mid-route stop.

Composite-pack catalogue: camp + blacksmith + village +
temple + graveyard + garden + dock + tavern = 8 themed mesh
packs. --list-packs surfaces 13 composites total
(including pre-existing zone/project starter packs).
2026-05-09 13:17:49 -07:00
Kelsi
234cfd0663 feat(editor): add --gen-mesh-bird-bath garden water-feature
77th procedural mesh primitive. Garden bird-bath:

  • stem: thin Y-axis closed cylinder (the column)
  • basin: wider shallow Y-axis closed cylinder on top

Both are full closed cylinders (side wall + ±Y cap fans) so
the model is a watertight solid. Local addYCylinder lambda
emits each tier — keeps the per-handler code self-contained
without forcing yet another module-level helper.

Distinct from --gen-mesh-fountain (basin + spout column,
larger water feature) — bird-bath is the small ornamental
garden version. Useful for monastery courtyards, druid
sanctuaries, noble-house pleasure gardens, sanctuary
clearings, ranger huts.

Watertight under weld (verified 192 manifold edges, 0
boundary, 0 non-manifold).
2026-05-09 13:16:06 -07:00
Kelsi
2a5198df42 feat(editor): add --gen-texture-ironbark hardwood-plate pattern
71st procedural texture: vertical wood-grain streaks (like
--gen-texture-bark) overlaid with horizontal "plate" bands
at regular Y intervals — the segmented look of mature
hardwood / ironwood / sycamore bark.

Per-pixel logic:
  • horizontal crack: top crackW pixels of every plateY
    cycle gets the dark crack color
  • vertical streak: per-streak hash determines an offset
    crack position within each streakSpacing block
  • elsewhere: base color modulated by per-streak-and-plate
    brightness jitter (±15) so the surface has natural
    texture variation

Distinct from --gen-texture-bark (vertical-crack only) and
--gen-texture-wood (vertical-streak only). Useful for ancient
trees, druid grove deadwood, dwarven hardwood beams,
fortress door planks, totem-pole carvings.
2026-05-09 13:14:18 -07:00
Kelsi
f167e1d2cf feat(editor): add --gen-mesh-statue-base monument pedestal
76th procedural mesh primitive. Classic 3-tier square
pedestal for statues / monuments / hero memorials:

  • plinth — bottom block, plinthExtra wider per side than
    the body (the foundation that meets the ground)
  • body — tall central pedestal sitting on the plinth
    (where the inscription would go)
  • capital — small wider cap on top of the body (where
    the statue's feet would rest)

Distinct from --gen-mesh-podium (stepped pyramid with
lectern at back) and --gen-mesh-altar (stacked round
discs) — this is the classic single-statue square
pedestal shape.

Useful for town-square monuments, hero-of-the-revolution
memorials, plaza centerpieces, mausoleum interiors,
saint-statue stands. Watertight under weld (verified 54
manifold edges, 0 boundary, 0 non-manifold).
2026-05-09 13:11:08 -07:00
Kelsi
8d75dd3867 feat(editor): add --gen-texture-swirl logarithmic-spiral
70th procedural texture: N-arm logarithmic spiral. Each
pixel computes its polar angle minus log(r)*spiralFactor
and tests whether that "spiral phase" falls inside any
arm's angular band (mod 2π/N).

Distinct from --gen-texture-starburst (straight rays from
center) — this is the curved-arm vortex variant. Small
spiralFactor gives loose pinwheel arms; large factor gives
tight whirlpool spirals.

Useful for magic sigils, summoning circles, ritual floor
markings, mystical-pool surfaces, mage-tower mosaic floors,
shaman-totem ground inlays. Center-based pattern (doesn't
tile seamlessly), so best used as standalone decals rather
than wall textures.
2026-05-09 13:08:07 -07:00
Kelsi
bdeb93bedd feat(editor): add --gen-dock-pack composite
Seventh themed mesh pack after camp / blacksmith / village /
temple / graveyard / garden. Harbor / dockyard scene
emitting a 7-primitive port-side layout:

  • dock — the pier itself
  • crate-stack — cargo waiting to be loaded
  • barrel — sailor stash
  • canopy — shade for the dockmaster's station
  • bench — passenger waiting area
  • signpost — port marker
  • hitching-post — for tying up small boats / mounts

Together these form a recognizable harbor / dockside
pickup-and-drop area when arranged in a zone.

Composite-pack catalogue: camp + blacksmith + village +
temple + graveyard + garden + dock = 7 themed mesh packs.
2026-05-09 13:06:37 -07:00
Kelsi
074f299c8b feat(editor): add --gen-mesh-pillar-row colonnade primitive
75th procedural mesh primitive. Row of N stone pillars
evenly spaced along the X axis. Each pillar is a single
tall rectangular box optionally crowned by a slightly-wider
square cap (capExtra wider per side).

End pillars inset by pillarW so they sit at exactly the
±span/2 ends. Set capH=0 for bare un-crowned columns.

Useful for ruined temples, palace colonnades, dungeon
hallways, dwarven mead-hall arcades, ceremonial entry
walks. Distinct from --gen-mesh-pillar (single column) —
this is the regular-multi-column composite, the third
"scene" primitive after --gen-mesh-crate-stack and
--gen-mesh-gravel-pile.

Watertight under weld (verified 144 manifold edges, 0
boundary, 0 non-manifold). Default 4-pillar / 4 m / 2.5 m
spacing reads as a small temple front porch.
2026-05-09 13:04:55 -07:00
Kelsi
ad21d16df0 feat(editor): add --gen-texture-dunes wave-ripple pattern
69th procedural texture: stack of parallel sinusoidal curves
spaced verticalSpacing apart. A pixel falls on a dune line
if its Y is within lineW/2 pixels of the nearest curve at
y = N*spacing + amp*sin(2π*x/period).

Distinct from --gen-texture-corrugated (uniform parallel
lines) and --gen-texture-zebra (sin-shifted strip fills) —
this is the discrete-curve variant for desert ground
textures and shallow-water sand patterns.

Useful for desert ground, shallow-water sand bottoms,
beach close-ups, mirage scene-setters, sand-storm overlays,
zone-specific weathering on stone surfaces.
2026-05-09 13:03:00 -07:00
Kelsi
b3755f8342 feat(editor): add --gen-garden-pack composite
Sixth themed mesh pack after camp / blacksmith / village /
temple / graveyard. Garden-courtyard scene emitting a
7-primitive monastery / kitchen-garden / small park layout:

  • pergola — vine-arbor frame
  • fountain — centerpiece
  • stone-bench — seating
  • shrine — decorative focal
  • beehive — productive prop
  • scarecrow — rural touch
  • well — water source

Together these form a recognizable contemplative-garden /
small park / monastery courtyard when arranged in a zone.

Composite-pack catalogue now: camp + blacksmith + village
+ temple + graveyard + garden = 6 themed mesh packs.
--list-packs surfaces 11 total composite flags.
2026-05-09 13:01:21 -07:00
Kelsi
b74c369efd feat(editor): add --gen-mesh-hitching-rail multi-post variant
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.
2026-05-09 12:59:16 -07:00
Kelsi
2225448dbf feat(editor): add --gen-texture-chevron V-stripe pattern
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.
2026-05-09 12:57:47 -07:00
Kelsi
9bd9b50bdb feat(editor): add --gen-graveyard-pack composite
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).
2026-05-09 12:55:50 -07:00
Kelsi
85e02a6132 feat(editor): add --gen-mesh-mine-cart underground transport
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.
2026-05-09 12:54:17 -07:00
Kelsi
30e58ae0b2 feat(editor): add --gen-texture-houndstooth classic-textile motif
67th procedural texture: the classic 19th-century Scottish
houndstooth broken-check pattern via a hard-coded seamless
8x8 motif:

    1 1 1 1 0 0 0 0
    1 1 1 1 0 0 0 1
    1 1 1 0 0 0 1 1
    1 1 0 0 0 1 1 1
    0 0 0 0 1 1 1 1
    0 0 0 1 1 1 1 1
    0 0 1 1 1 1 1 0
    0 1 1 1 1 1 0 0

Each motif cell scales to `cellSize` pixels (default 4 → 32
px tile), so a 256x256 texture shows 8 motifs in each axis.
Tile-seam-perfect: no row offset or fractional pixel issues
since lookup is integer mod 8.

Useful for noble-house tabard accents, formal-attire trim,
upholstery in palace dining rooms, drapes / wall hangings,
gentry-quarter banners. Distinct from --gen-texture-tartan
(weighted multi-color stripes) and --gen-texture-checker
(simple binary squares) — houndstooth has the iconic
4-pointed "tooth" silhouette.
2026-05-09 12:52:31 -07:00
Kelsi
4e64f833a7 feat(editor): add --list-packs introspection + --gen-temple-pack
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.
2026-05-09 12:51:10 -07:00
Kelsi
c18d88015a feat(editor): add --gen-mesh-stone-bench heavy seating
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.
2026-05-09 12:48:55 -07:00
Kelsi
14c77b1af5 feat(editor): add --gen-texture-diamond-grid solid-shape tile
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.
2026-05-09 12:47:28 -07:00
Kelsi
790fe64824 feat(editor): add --gen-village-pack composite
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.
2026-05-09 12:45:25 -07:00
Kelsi
ca38f77fd0 feat(editor): add --gen-mesh-gravel-pile rubble heap
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).
2026-05-09 12:43:03 -07:00
Kelsi
90063037c4 feat(editor): add --gen-texture-plaid translucent-bands pattern
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.
2026-05-09 12:39:38 -07:00
Kelsi
26af6d9df6 feat(editor): add --gen-mesh-archery-target training prop
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).
2026-05-09 12:35:15 -07:00
Kelsi
78c7aed888 feat(editor): add --gen-texture-rust-streaks vertical-drip pattern
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.
2026-05-09 12:33:25 -07:00
Kelsi
facaacd0c6 feat(editor): add --gen-blacksmith-pack + extract emitMeshPack
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.
2026-05-09 12:31:34 -07:00
Kelsi
006beffb83 feat(editor): add --gen-mesh-forge blacksmith hearth
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.
2026-05-09 12:29:09 -07:00
Kelsi
b8cfc90fba feat(editor): add --gen-texture-blueprint drafting-paper grid
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.
2026-05-09 12:27:15 -07:00
Kelsi
68db1be97a feat(editor): add --gen-mesh-outhouse small-shed primitive
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.
2026-05-09 12:24:00 -07:00
Kelsi
0b1cf65854 feat(editor): add --gen-camp-pack convenience composite
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.
2026-05-09 12:22:37 -07:00
Kelsi
ba1f458ad3 feat(editor): add --gen-texture-bamboo jungle-stalk pattern
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.
2026-05-09 12:20:11 -07:00
Kelsi
38d9575eb2 feat(editor): add --gen-mesh-hitching-post stable fixture
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.
2026-05-09 12:15:41 -07:00
Kelsi
b1fd3382a9 feat(editor): add --gen-texture-mesh-screen orthogonal grid
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.
2026-05-09 12:14:10 -07:00
Kelsi
b311916c6c feat(editor): add --gen-mesh-training-dummy sparring prop
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.
2026-05-09 12:09:36 -07:00
Kelsi
adb7e014ef feat(editor): add --gen-texture-snake-skin diamond-scale pattern
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.
2026-05-09 12:08:11 -07:00
Kelsi
4cb1c33335 feat(editor): add --gen-mesh-water-trough basin primitive
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.
2026-05-09 12:02:35 -07:00
Kelsi
5b24b54d09 feat(editor): add --gen-texture-camo woodland-disruption pattern
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.
2026-05-09 12:01:11 -07:00
Kelsi
c10b1b0fb1 feat(editor): add --gen-mesh-watchpost sentry tower primitive
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).
2026-05-09 11:57:38 -07:00
Kelsi
d7941bd4ce feat(editor): add --gen-texture-pinstripe formal-fabric pattern
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.
2026-05-09 11:56:01 -07:00
Kelsi
a10efed8f5 feat(editor): add --gen-mesh-crate-stack scene primitive
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.
2026-05-09 11:52:20 -07:00
Kelsi
68af5c10c9 feat(editor): add --gen-texture-carbon fiber-weave pattern
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.
2026-05-09 11:49:20 -07:00
Kelsi
47641bf0b4 feat(editor): add --gen-mesh-workbench crafter table
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).
2026-05-09 11:46:05 -07:00
Kelsi
7f7104623d feat(editor): add --gen-texture-woodgrain end-cut tree-rings
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.
2026-05-09 11:44:33 -07:00
Kelsi
e23b3faa1c feat(editor): add --gen-mesh-bedroll camp sleeping prop
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.
2026-05-09 11:39:33 -07:00
Kelsi
65b3352b9f feat(editor): add --gen-texture-moss organic-mottling pattern
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.
2026-05-09 11:38:03 -07:00
Kelsi
db2db04ffe feat(editor): add --bake-zone-collision aggregator
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.
2026-05-09 11:36:38 -07:00
Kelsi
836fab7f2d feat(editor): add --gen-mesh-chimney brick-stack primitive
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).
2026-05-09 11:34:24 -07:00
Kelsi
26f1947c84 feat(editor): add --audit-watertight-wob building QA tool
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.
2026-05-09 11:33:10 -07:00
Kelsi
f1528f2dd7 feat(editor): add --gen-texture-studs riveted-armor pattern
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.
2026-05-09 11:31:27 -07:00
Kelsi
6ff5df41eb feat(editor): add --gen-mesh-pergola garden-arbor primitive
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.
2026-05-09 11:26:15 -07:00
Kelsi
63048c1356 feat(editor): add --gen-texture-starburst radial-rays 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.
2026-05-09 11:20:31 -07:00
Kelsi
173ad7796e feat(editor): add --bake-wob-collision multi-group WOB→WOC
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.
2026-05-09 11:19:09 -07:00