src/sculpt
declarative-hex-worlds / src/sculpt
src/sculpt
src/sculpt/ — a procedural prop modelling kit for three.js (declarative-hex-worlds/sculpt).
Build period props, terrain pieces and clutter from code instead of downloading models: place primitives (box, cyl, cone, ball, ring, plane, disc, lathe), roughen a rock, stretch cloth with sheet, pull a rope, then buildPiece merges every part into one vertex-coloured geometry per finish: one draw call per finish however many parts, and an instanced mesh draws every copy.
The kit is palette-free. Parts name a tone; the consumer hands buildPiece the palette that gives each tone its colour, so the same recipes can be repainted for any game. It generalises the "toy chest" of a fleet game that models every prop this way.
Units and frame. Metres; a piece stands on y = 0, its front toward +z, its length along
x. Determinism. Nothing here is random: rocks are roughened by a hash of their vertex
positions and a seed, so a piece is byte-identical in every process.
three is an optional peer dependency, needed only by this subpath, like ./three. The root
entrypoint does not re-export it.
Interfaces
BuildPieceOptions
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:51
Options for buildPiece.
Properties
contactFloor?
readonlyoptionalcontactFloor?:number
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:62
The colour factor at y = 0, from 0 to 1. Default 0.62.
contactHeight?
readonlyoptionalcontactHeight?:number
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:60
Height in metres at which the contact shadow ends. Above 0. Default 0.5.
finishes?
readonlyoptionalfinishes?:Readonly<Record<string,FinishSpec>>
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:64
Finishes to add, or built-in finishes to retune, keyed by finish name.
grounded?
readonlyoptionalgrounded?:boolean
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:58
Bake a contact shadow: shade each vertex from contactFloor at the ground (y = 0) up to
full colour at contactHeight, so a crate or a jar sits on the floor rather than floating
over it. Pieces that do not stand on the ground (a hanging lamp) leave it off. Default
false.
FinishSpec
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:25
How a finish bakes into vertex colours.
Properties
gain
readonlygain:number
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:30
Multiplies the baked colour. Above 1 over-drives it past display white, so an unlit, un-tone-mapped material blooms (lamp glass, embers). Finite, at least 0.
shadowed
readonlyshadowed:boolean
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:32
Whether a grounded piece's contact shadow darkens this finish.
Part
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:56
One modelled part: a geometry in the piece's frame, the tone it is painted, the finish it is drawn with, and a shade multiplier.
Make parts with part or the primitives; buildPiece expects the geometry
invariants they establish (non-indexed, position + normal).
Type Parameters
Tone
Tone extends string = string
Properties
finish
readonlyfinish:string
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:62
A key into the finish table (matte, metal, glow, veil, or a consumer's own).
geometry
readonlygeometry:BufferGeometry
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:58
The part's geometry, already placed in the piece's frame.
shade
readonlyshade:number
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:64
Multiplies the tone: below 1 is darker (a crack, a shadowed underside).
tone
readonlytone:Tone
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:60
A key into the palette handed to buildPiece.
PartOptions
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:68
How a part is placed, turned, scaled and painted.
Type Parameters
Tone
Tone extends string = string
Properties
at?
readonlyoptionalat?:SculptVec3
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:70
Position in the piece's frame, metres. Default [0, 0, 0].
finish?
readonlyoptionalfinish?:string
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:78
The finish key. Default DEFAULT_FINISH ('matte').
rot?
readonlyoptionalrot?:SculptVec3
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:72
Euler XYZ rotation, radians. Default [0, 0, 0].
scale?
readonlyoptionalscale?:SculptVec3
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:74
Per-axis scale, applied before the rotation. Default [1, 1, 1].
shade?
readonlyoptionalshade?:number
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:80
Multiplies the tone. Finite, at least 0. Default 1.
tone
readonlytone:Tone
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:76
The palette key this part is painted.
RopeOptions
Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:85
How a rope is painted and built.
Type Parameters
Tone
Tone extends string = string
Properties
finish?
readonlyoptionalfinish?:string
Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:89
The finish key. Default 'matte'.
radius?
readonlyoptionalradius?:number
Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:93
The rope's radius, metres: above 0. Default 0.014.
segments?
readonlyoptionalsegments?:number
Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:95
Sides round the rope: an integer of at least 3. Default 4.
shade?
readonlyoptionalshade?:number
Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:91
Multiplies the tone. Default 1.
tone
readonlytone:Tone
Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:87
The palette key the rope is painted.
SculptMaterials
Defined in: packages/declarative-hex-worlds/src/sculpt/materials.ts:9
One material per DefaultFinish, each reading the vertex colours buildPiece bakes.
Properties
glow
readonlyglow:MeshBasicMaterial
Defined in: packages/declarative-hex-worlds/src/sculpt/materials.ts:15
Unlit and outside tone mapping, so the baked gain over 1 blooms: lamp glass, embers.
matte
readonlymatte:MeshStandardMaterial
Defined in: packages/declarative-hex-worlds/src/sculpt/materials.ts:11
Rough, non-metallic: stone, wood, clay, cloth.
metal
readonlymetal:MeshStandardMaterial
Defined in: packages/declarative-hex-worlds/src/sculpt/materials.ts:13
Glossy, metallic: gold, bronze.
veil
readonlyveil:MeshStandardMaterial
Defined in: packages/declarative-hex-worlds/src/sculpt/materials.ts:17
A faint two-sided film that writes no depth: cobweb, dust.
Type Aliases
DefaultFinish
DefaultFinish = keyof typeof
DEFAULT_FINISHES
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:48
The names of the built-in finishes.
SculptPalette
SculptPalette<
Tone> =Readonly<Record<Tone,ColorRepresentation>>
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:20
A palette: the colour of each tone key a piece's parts use. Supplied by the consumer — the kit
has no colours of its own. Any value three.js's Color accepts: a CSS string, a hex number, or
a Color.
Type Parameters
Tone
Tone extends string = string
SculptPoint
SculptPoint =
SculptVec3| {x:number;y:number;z:number; }
Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:19
A point in a sheet: a [x, y, z] tuple, or anything with x, y and z (a Vector3).
SculptVec3
SculptVec3 = readonly [
number,number,number]
Defined in: packages/declarative-hex-worlds/src/sculpt/validate.ts:14
A metres-or-radians triple: a position, an Euler rotation or a scale.
Variables
DEFAULT_FINISH
constDEFAULT_FINISH:"matte"='matte'
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:47
The finish a part gets when its options name none.
DEFAULT_FINISHES
constDEFAULT_FINISHES:Readonly<{glow:Readonly<{gain:3.2;shadowed:false; }>;matte:Readonly<{gain:1;shadowed:true; }>;metal:Readonly<{gain:1;shadowed:true; }>;veil:Readonly<{gain:1;shadowed:true; }>; }>
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:40
The finishes the kit knows: matte stone, wood, clay and cloth; metal gold and bronze;
glow lamp glass and embers (gain 3.2, never shadowed); veil cobweb and dust. Pass
BuildPieceOptions.finishes to retune these or add your own.
Functions
ball()
ball<
Tone>(r,o,seg?):Part<Tone>
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:211
A sphere of radius r with seg segments round (default 10) and a proportional number of
latitude rings, never fewer than four.
Type Parameters
Tone
Tone extends string
Parameters
r
number
o
PartOptions<Tone>
seg?
number = 10
Returns
Part<Tone>
box()
box<
Tone>(w,h,d,o):Part<Tone>
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:164
A box w wide (x), h tall (y) and d deep (z), centred on its own origin.
Type Parameters
Tone
Tone extends string
Parameters
w
number
h
number
d
number
o
PartOptions<Tone>
Returns
Part<Tone>
buildPiece()
buildPiece<
P>(parts,palette,options?):Map<string,BufferGeometry<NormalBufferAttributes,BufferGeometryEventMap>>
Defined in: packages/declarative-hex-worlds/src/sculpt/build.ts:101
Merges a piece's parts into one geometry per finish, vertex-coloured: each vertex is
palette[tone] * shade * finish.gain, and, when grounded, times the contact factor for its
height. The result maps each finish name that has parts to its merged geometry (insertion order
follows the first part of each finish); load each into one mesh with that finish's material.
The parts are consumed: their geometries are disposed after the merge, so build a piece from fresh parts each time.
Deterministic and allocation-light: no randomness, no scratch state shared between calls.
Throws GameboardValidationError for a tone missing from palette, a finish missing
from the finish table, a part geometry that is not non-indexed with position and normal, or an
out-of-range option. Everything is validated before any part is consumed.
Type Parameters
P
P extends Readonly<Record<string, ColorRepresentation>>
Parameters
parts
readonly Part<Extract<keyof P, string>>[]
palette
P
options?
BuildPieceOptions = {}
Returns
Map<string, BufferGeometry<NormalBufferAttributes, BufferGeometryEventMap>>
cone()
cone<
Tone>(r,h,o,seg?):Part<Tone>
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:195
A cone of base radius r and height h along y, centred, with seg sides (default 8).
Type Parameters
Tone
Tone extends string
Parameters
r
number
h
number
o
PartOptions<Tone>
seg?
number = 8
Returns
Part<Tone>
createSculptMaterials()
createSculptMaterials():
SculptMaterials
Defined in: packages/declarative-hex-worlds/src/sculpt/materials.ts:35
Creates the materials the built-in finishes are meant to be drawn with. Pair each merged geometry from buildPiece with the material of the same name:
const materials = createSculptMaterials();
for (const [finish, geometry] of buildPiece(parts, palette)) {
group.add(new Mesh(geometry, materials[finish as keyof SculptMaterials]));
}Every call makes fresh materials, so each owner disposes its own. A consumer with custom
finishes builds the materials for those itself; the vertex colours are the same either way, so
any material with vertexColors: true draws them.
Returns
cyl()
cyl<
Tone>(rTop,rBottom,h,o,seg?):Part<Tone>
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:180
A cylinder h tall along y, centred, rTop across at the top and rBottom at the bottom
(a radius of 0 makes a cone), with seg sides (default 10).
Type Parameters
Tone
Tone extends string
Parameters
rTop
number
rBottom
number
h
number
o
PartOptions<Tone>
seg?
number = 10
Returns
Part<Tone>
disc()
disc<
Tone>(r,o,seg?):Part<Tone>
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:249
A flat disc of radius r in the xy plane, facing +z, with seg sides (default 16).
Type Parameters
Tone
Tone extends string
Parameters
r
number
o
PartOptions<Tone>
seg?
number = 16
Returns
Part<Tone>
lathe()
lathe<
Tone>(profile,o,seg?):Part<Tone>
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:264
A turned vessel: profile is a list of [radius, height] points, bottom to top, revolved
about the y axis in seg steps (default 12). A profile that starts and ends at radius 0 is
closed. Needs at least two points, each with a finite radius of at least 0 and a finite height.
Type Parameters
Tone
Tone extends string
Parameters
profile
readonly readonly [number, number][]
o
PartOptions<Tone>
seg?
number = 12
Returns
Part<Tone>
part()
part<
Tone>(geometry,o):Part<Tone>
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:103
Any geometry as a part: placed, turned and scaled by o, painted its tone and finish. Use it
for custom shapes (a sheet of cloth, a heap).
The geometry is taken over: made non-indexed, stripped to position and normal (flat
normals are computed if it has none), and transformed in place. An indexed source is disposed
and replaced. Throws GameboardValidationError for a geometry without positions, a
non-finite transform, a negative or non-finite shade, or an empty finish name; the geometry is
left untouched in that case.
Type Parameters
Tone
Tone extends string
Parameters
geometry
BufferGeometry
o
PartOptions<Tone>
Returns
Part<Tone>
plane()
plane<
Tone>(w,h,o):Part<Tone>
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:238
A flat rectangle w wide and h tall in the xy plane, facing +z.
Type Parameters
Tone
Tone extends string
Parameters
w
number
h
number
o
PartOptions<Tone>
Returns
Part<Tone>
ring()
ring<
Tone>(r,tube,o,seg?):Part<Tone>
Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:225
A torus lying in the xy plane: ring radius r to the middle of the tube, tube radius tube,
seg segments round (default 16).
Type Parameters
Tone
Tone extends string
Parameters
r
number
tube
number
o
PartOptions<Tone>
seg?
number = 16
Returns
Part<Tone>
rock()
rock<
Tone>(r,seed,o,rough?):Part<Tone>
Defined in: packages/declarative-hex-worlds/src/sculpt/rock.ts:45
A rough, faceted stone: an icosahedron with each vertex pushed in or out by a stable hash of
its position and seed, then squashed to 80 % height so it sits low.
Deterministic: the same r, seed and rough give the same vertices in every process, and a
different seed gives a different stone. Each vertex lands between r * (1 - rough) and
r * (1 + rough) from the origin (before the y squash and before o places it). rough is
from 0 (a smooth flattened ellipsoid) to 1; default 0.28. Normals are flat, recomputed after the
roughening.
Throws GameboardValidationError for a radius that is not positive and finite, a
non-integer seed, or a roughness outside 0 to 1.
Type Parameters
Tone
Tone extends string
Parameters
r
number
seed
number
o
PartOptions<Tone>
rough?
number = 0.28
Returns
Part<Tone>
rope()
rope<
Tone>(a,b,o):Part<Tone>
Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:106
A thin cylinder running from a to b: its base cap centre sits exactly at a and its top cap
centre exactly at b, however the two are oriented (straight down included). Throws
GameboardValidationError for a non-finite endpoint, coincident endpoints, a radius that
is not above 0, or fewer than three segments.
Type Parameters
Tone
Tone extends string
Parameters
a
b
o
RopeOptions<Tone>
Returns
Part<Tone>
sheet()
sheet(
rows,flip?):BufferGeometry
Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:46
A surface from a grid of points: rows is a list of rows, each a list of the same number of
points. Every cell of four neighbouring points becomes two triangles.
Winding. The front face (the side a backface-culled material shows) looks along
(row step) x (column step): with a a point, d the point one row on and b the point one
column on, the front normal is (d - a) x (b - a). A ground sheet whose rows step +z and
columns step +x therefore faces up (z x x = +y); a wall whose rows step +x and columns
step +y faces +z. Pass flip to reverse it.
Returns an indexed geometry holding only position. Hand it to part to place and paint
it. Throws GameboardValidationError for fewer than two rows or two columns, rows of
unequal length, or a point with a non-finite coordinate.
Parameters
rows
readonly readonly SculptPoint[][]
flip?
boolean = false
Returns
BufferGeometry
