Home
Pages

src/sculpt

declarative-hex-worlds

declarative-hex-worlds


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?

readonly optional contactFloor?: 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?

readonly optional contactHeight?: 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?

readonly optional finishes?: 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?

readonly optional grounded?: 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

readonly gain: 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

readonly shadowed: 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

readonly finish: 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

readonly geometry: BufferGeometry

Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:58

The part's geometry, already placed in the piece's frame.

shade

readonly shade: 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

readonly tone: 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?

readonly optional at?: SculptVec3

Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:70

Position in the piece's frame, metres. Default [0, 0, 0].

finish?

readonly optional finish?: string

Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:78

The finish key. Default DEFAULT_FINISH ('matte').

rot?

readonly optional rot?: SculptVec3

Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:72

Euler XYZ rotation, radians. Default [0, 0, 0].

scale?

readonly optional scale?: SculptVec3

Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:74

Per-axis scale, applied before the rotation. Default [1, 1, 1].

shade?

readonly optional shade?: number

Defined in: packages/declarative-hex-worlds/src/sculpt/parts.ts:80

Multiplies the tone. Finite, at least 0. Default 1.

tone

readonly tone: 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?

readonly optional finish?: string

Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:89

The finish key. Default 'matte'.

radius?

readonly optional radius?: number

Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:93

The rope's radius, metres: above 0. Default 0.014.

segments?

readonly optional segments?: 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?

readonly optional shade?: number

Defined in: packages/declarative-hex-worlds/src/sculpt/sheet.ts:91

Multiplies the tone. Default 1.

tone

readonly tone: 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

readonly glow: 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

readonly matte: MeshStandardMaterial

Defined in: packages/declarative-hex-worlds/src/sculpt/materials.ts:11

Rough, non-metallic: stone, wood, clay, cloth.

metal

readonly metal: MeshStandardMaterial

Defined in: packages/declarative-hex-worlds/src/sculpt/materials.ts:13

Glossy, metallic: gold, bronze.

veil

readonly veil: 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

const DEFAULT_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

const DEFAULT_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

SculptMaterials


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

SculptVec3

b

SculptVec3

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