emberline.staging.fx — how a hit lands.
Every effect in this file is a POOLED PIXEL CANVAS whose frames are drawn
once, at boot, and then only stepped. Nothing is drawn at fight time: a
canvas write is expensive and forbidden in play mode, while `setActiveFrame`
costs 0.2 ms. So the whole impact language is authored up front as sheets,
and the fight just points at frames.
The three strengths are deliberately different EVENTS, not the same event at
three sizes:
light a thin white star, 40 sheet pixels, gone in four frames. No shake.
medium a hot core with an ember ring and flung grit. A nudge of shake.
heavy a white-out disc first, then an ember shockwave with eight long
spokes, debris and smoke — plus a directional camera kick, a tilt
and a two-frame screen flash.
With the sound off that is three distinguishable things happening.
ring(K: any, cx: number, cy: number, r: number, thick: number, color: string, from: number?, to: number?, gap: number?) → void
| arg | type | description |
|---|
| K | any | |
| cx | number | |
| cy | number | |
| r | number | |
| thick | number | |
| color | string | |
| from | number? | |
| to | number? | |
| gap | number? | |
spokes(K: any, cx: number, cy: number, r0: number, r1: number, n: number, w0: number, w1: number, color: string, phase: number?) → void
| arg | type | description |
|---|
| K | any | |
| cx | number | |
| cy | number | |
| r0 | number | |
| r1 | number | |
| n | number | |
| w0 | number | |
| w1 | number | |
| color | string | |
| phase | number? | |
star(K: any, cx: number, cy: number, r: number, w: number, color: string) → void
| arg | type | description |
|---|
| K | any | |
| cx | number | |
| cy | number | |
| r | number | |
| w | number | |
| color | string | |
debris(K: any, cx: number, cy: number, r: number, n: number, size: number, color: string, seed: number) → void
Debris thrown outward on a fixed set of angles, so it looks scattered but
redraws identically.
| arg | type | description |
|---|
| K | any | |
| cx | number | |
| cy | number | |
| r | number | |
| n | number | |
| size | number | |
| color | string | |
| seed | number | |
drawHitLight(K: any, f: number, w: number, ht: number) → void
Each draw function renders frame `f` of `n` into a kit sized (w, ht).
| arg | type | description |
|---|
| K | any | |
| f | number | |
| w | number | |
| ht | number | |
drawHitMedium(K: any, f: number, w: number, ht: number) → void
| arg | type | description |
|---|
| K | any | |
| f | number | |
| w | number | |
| ht | number | |
drawHitHeavy(K: any, f: number, w: number, ht: number) → void
| arg | type | description |
|---|
| K | any | |
| f | number | |
| w | number | |
| ht | number | |
drawBlock(K: any, f: number, w: number, ht: number) → void
The guard flash faces LEFT in sheet space; the entity is flipped on Y when
the defender is looking the other way.
| arg | type | description |
|---|
| K | any | |
| f | number | |
| w | number | |
| ht | number | |
drawDust(K: any, f: number, w: number, ht: number) → void
A landing puff: low, wide, and it spreads sideways rather than upward.
| arg | type | description |
|---|
| K | any | |
| f | number | |
| w | number | |
| ht | number | |
drawDash(K: any, f: number, w: number, ht: number) → void
A dash puff: the cloud is left BEHIND, so it streaks away to the left.
| arg | type | description |
|---|
| K | any | |
| f | number | |
| w | number | |
| ht | number | |
drawSuper(K: any, f: number, w: number, ht: number) → void
The super hit. The biggest single thing in the impact language.
| arg | type | description |
|---|
| K | any | |
| f | number | |
| w | number | |
| ht | number | |
drawFlashFrame(K: any, color: string, stride: number) → void
| arg | type | description |
|---|
| K | any | |
| color | string | |
| stride | number | |
drawSpeedFrame(K: any, f: number) → void
| arg | type | description |
|---|
| K | any | |
| f | number | |
drawBarsFrame(K: any, rows: number) → void
| arg | type | description |
|---|
| K | any | |
| rows | number | |
despawnByName(name: string) → void
| arg | type | description |
|---|
| name | string | |
makeParent(name: string, parentName: string?) → any
| arg | type | description |
|---|
| name | string | |
| parentName | string? | |
buildSheet(name: string, spec: any, parentId: string) → any
| arg | type | description |
|---|
| name | string | |
| spec | any | |
| parentId | string | |
dirSign(v: any) → number
A facing arrives from the fight as a number OR as a word, depending on which
event raised it. Everything here multiplies by it, so it is normalised once
at the door instead of comparing a string to a number at nine call sites.
take(kind: string) → any
| arg | type | description |
|---|
| kind | string | |
launch(kind: string, x: number, y: number, opts: any?) → void
| arg | type | description |
|---|
| kind | string | |
| x | number | |
| y | number | |
| opts | any? | |
spark(x: number, y: number, kind: string?, opts: any?) → void
A hit spark. `kind` is "light" | "medium" | "heavy" | "block" | "super",
and anything unknown falls back to medium so a caller is never silent.
| arg | type | description |
|---|
| x | number | |
| y | number | |
| kind | string? | |
| opts | any? | |
dust(x: number, y: number, kind: string?, opts: any?) → void
Ground dust. `kind` is "land" | "dash" | "jump".
| arg | type | description |
|---|
| x | number | |
| y | number | |
| kind | string? | |
| opts | any? | |
shake(mag: number?, frames: number?) → void
| arg | type | description |
|---|
| mag | number? | |
| frames | number? | |
hitstop(frames: number?) → void
Freeze the fight. Combat reads Bus.state.hitstop and stops advancing; the
sparks keep running on real time, which is what makes the freeze read as
impact rather than as a stall.
| arg | type | description |
|---|
| frames | number? | |
flash(color: string?, frames: number?, startStep: number?) → void
A full-frame flash. `color` is "white" | "ember" | "black"; `frames` is how
long it lasts and `startStep` how solid it starts (1 = solid).
| arg | type | description |
|---|
| color | string? | |
| frames | number? | |
| startStep | number? | |
curtain(color: string?, step: number?) → void
Hold a solid curtain (used by the attract sequence's fades). `step` 1 is
solid; call `Fx.flash` afterwards to dither it away.
| arg | type | description |
|---|
| color | string? | |
| step | number? | |
clearOverlays( ) → void
Take every full-frame overlay off the glass and reset the state that drives
them. A curtain or a bar row left standing covers the whole game, so this is
what every hand-off out of a staged beat ends with.
speedlines(frames: number?) → void
| arg | type | description |
|---|
| frames | number? | |
letterbox(rows: number?) → void
Cinematic bars. `rows` 0 clears them, 5 is the full bar.
| arg | type | description |
|---|
| rows | number? | |
update(dt: number) → void
| arg | type | description |
|---|
| dt | number | |