hazards
The shared ground of HULLBREAKER's **hazard** slice — the wreck fighting back.
game.hazards
The shared ground of HULLBREAKER's hazard slice — the wreck fighting back.
require("game.hazards")
What is in here
CFG | the hazard slice's own numbers: vent rhythm and reach, collapse interval, debris speeds, contact radii. The numbers that cross a slice boundary (ventShove, impactDamage, the instability gates) stay in game.rules. |
VENTS / BRACES / DEBRIS_COUNT | the manifests. Where the danger is bolted to the Kestrel Wake — seven pressure vents down the shaft, six cross-braces of truss, fourteen chunks adrift. |
armed(kind) | "vent" / "collapse" / "debris" — reads state.instability against the gates in RULES.CFG. The single place the escalation is decided. |
quiet() | the run is won or lost; nothing swings any more. |
playerBody() | the local player's body, re-resolved every call. |
impulse(x, y, z) | the only way this slice moves the player. |
reportImpact(amount, source) | RULES.emit("impact", …) plus the counter. |
buildRig() | spawns the whole rig under one HazardRig root. |
stats | live counters every hazard writes; HazardDirector mirrors them onto public fields so a run is readable from outside the component VMs. |
The two contracts this module keeps
Hazard never writes the player's position or velocity. Every shove goes
through impulse, which resolves the impulse entry point on flight's
Scrapper component from the component's own declared surface
(asset.inspect) and calls it. In this world that resolves to
Scrapper:applyImpulse(x, y, z) and the resolution is logged at startup. If
Scrapper is not on the body, or declares no matching entry point, the shove
is dropped and counted (stats.impulsesDropped) rather than faked by
writing the transform.
Hazard never writes state.integrity. Contact reports
RULES.emit("impact", amount, source) and shell decides what it costs.
source is "vent", "collapse" or "debris".
Determinism
This world is always multiplayer, and every peer runs the scene entrypoint,
so every peer builds its own copy of this rig. Nothing here calls
math.random: a chunk's whole trajectory comes from debrisRow(i), a hash of
its index, and HazardDirector picks the next member to let go by sorted
name. Two scrappers in the same shaft are dodging the same beam.
The rig
buildRig() despawns any existing HazardRig before spawning a new one, so
ownership is re-derived from the world rather than from a module-local list —
a hot-reload or a mode flip cannot leave two copies of the wreck's danger
standing. It runs from game/wiring/hazard's onSceneReady in both edit
and play, so a vent can be looked at while authoring.
Scoped to this part · feeds back into the world's score.