game/spine.module — SLICE: SPINE. The tower and the route.
Builds the vertebral column of the dead colossus and the salvage route the
crew left on it, and registers every hold as it places that hold's geometry
so a hand can never land on nothing.
THE ROUTE IS THE LEVEL DESIGN. It is authored in `ROUTE` below as a list of
named pitches, each with its own angle sweep, hold spacing, hold kinds, grip
quality and crumble rate. Difficulty rises with altitude for physical
reasons: the holds get smaller and further apart, the grip quality falls, the
crumbling ones get more frequent, and at "the blank" the crew's stringer runs
out entirely and you climb the raw structure.
THE STRINGER IS THE MARKER. A salvage crew bolted a twin rail up the column
and hung the hardware off it. It is brass-bright against black iron, so from
the base you can read the whole line of the climb without a waypoint, and
where it stops you know the pitch got serious.
Reading the colour is reading the route:
brass, bright a good hold
verdigris pipe a good hold you have to wrap a hand around
red, jagged, flaking a crumbling hold — it will go under load
sodium lamp a piton anchor; falling past it costs the pitch only
cold blue, at 190 m the Crown Beacon
Owner: the spine agent. Nobody else writes here.
clamp01(v: number) → number
══ the column profile ════════════════════════════════════════════════════
| arg | type | description |
|---|
| v | number | |
taperAt(y: number) → number
| arg | type | description |
|---|
| y | number | |
radiusAt(y: number) → number
| arg | type | description |
|---|
| y | number | |
vadd(a: ?, b: ?) → void
══ small helpers ═════════════════════════════════════════════════════════
rnd(k: number) → number
deterministic pseudo-random in 0..1 — the same tower every boot, on every peer
| arg | type | description |
|---|
| k | number | |
spawn(name: string, parent: any) → any
| arg | type | description |
|---|
| name | string | |
| parent | any | |
mesh(builder: any) → any
| arg | type | description |
|---|
| builder | any | |
orient(e: any, right: ?, up: ?, fwd: ?) → void
Orient an entity so its local +X runs along `right`, +Y along `up`,
+Z points out of the wall. Every piece of hardware is modelled in that frame.
| arg | type | description |
|---|
| e | any | |
| right | ? | |
| up | ? | |
| fwd | ? | |
samplePitch(seg: any, t: number) → Sample
| arg | type | description |
|---|
| seg | any | |
| t | number | |
pitchLine(seg: any, steps: number) → void
| arg | type | description |
|---|
| seg | any | |
| steps | number | |
placePiton(parent: any, s: Sample, index: number) → void
A piton anchor: the checkpoint. Spike, shackle, tag and a sodium lamp that is
the one thing on this tower you can see from a long way below.
| arg | type | description |
|---|
| parent | any | |
| s | Sample | |
| index | number | |
buildColumn(parent: any) → void
══ the column ════════════════════════════════════════════════════════════
| arg | type | description |
|---|
| parent | any | |
buildStringer(parent: any) → void
══ the stringer ══════════════════════════════════════════════════════════
The crew's twin rail. It follows the route exactly, so it IS the route: a
bright line up a black tower that tells you where the climb goes, and where
it stops ("the blank") tells you the pitch got serious.
| arg | type | description |
|---|
| parent | any | |
buildRoute(parent: any) → void
══ the holds ═════════════════════════════════════════════════════════════
| arg | type | description |
|---|
| parent | any | |
buildCrown(parent: any) → void
══ the Crown Beacon ══════════════════════════════════════════════════════
| arg | type | description |
|---|
| parent | any | |
buildDressing(parent: any) → void
══ set dressing ══════════════════════════════════════════════════════════
| arg | type | description |
|---|
| parent | any | |
buildBase(parent: any) → void
══ the base ══════════════════════════════════════════════════════════════
| arg | type | description |
|---|
| parent | any | |
buildMaterials( ) → void
══ materials ═════════════════════════════════════════════════════════════
One shader, six dressings. Vertex colour carries the tint, so the material
only has to say how weathered and how wet this class of surface is.
m(key: string, props: any) → void
| arg | type | description |
|---|
| key | string | |
| props | any | |
shear(holdId: number) → void
══ the route degrades ════════════════════════════════════════════════════
A crumbling hold that fails under a hand actually goes: the flange shears off
the wall and drops into the sea, and the registry entry goes with it, so the
route is a little worse than it was.
| arg | type | description |
|---|
| holdId | number | |
build(ctx: any) → void
══ build ═════════════════════════════════════════════════════════════════
tick(dt: number) → void
══ tick ══════════════════════════════════════════════════════════════════
| arg | type | description |
|---|
| dt | number | |
update(dt: number) → void
The tower ticks itself as well as answering the assembler.
`boot.module` only ticks a slice while its own `built` flag says so, and that
flag lives in a module-local table that a hot reload of `boot.module` — which
happens whenever any of the six slices is written — starts over empty. When
that happens the assembler stops calling this slice while the tower it built
is still standing, and the lamps freeze and the beacon stops answering the
charge. So the tower also drives itself off its own root entity, and the two
callers are made idempotent by the timestamp below: whichever reaches a frame
first does the work and the other returns.
| arg | type | description |
|---|
| dt | number | |
startDriver(rootId: string) → void
| arg | type | description |
|---|
| rootId | string | |
stats( ) → void
What the tower is, as data — for anyone checking the route without looking.