service
The cabinet, wired up. Requiring this module IS the mount: it registers `Bus.services.ui`, registers the three screens (`el_hud` layer 20, `el_overlay` layer 40, `el_menu` layer 60), binds the `fight.*` events and starts reading the keyboard.
emberline.ui.service
The cabinet, wired up. Requiring this module IS the mount: it registers
Bus.services.ui, registers the three screens (el_hud layer 20,
el_overlay layer 40, el_menu layer 60), binds the fight.* events and
starts reading the keyboard.
require("emberline.ui.service")
Service contract: setPhase hud cutIn show hide banner subtitle
announce flash update teardown.
It reads Bus.state and Bus.registry.fighters. It writes Bus.state.phase
for the MENU phases only (attract / title / select / ending) and
Bus.state.paused on pause - the combat slice owns the fight's own phases
and this module never writes them.
Keyboard: W/S/A/D and the arrows move, Enter or Space confirms, Escape goes back and pauses a running fight. Every move and every confirm makes a sound.
Interface
What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.
conforms to
zero/source-extract/v2emberline.ui.service — the cabinet, wired up. Registers `Bus.services.ui`, owns the three screens the game draws through (HUD, overlay, menu), keeps the view state those trees are a function of, reads the keyboard so every screen is navigable without a mouse, and makes a sound on every move and every confirm. Requiring this module IS the mount: it registers the service and the screens, so anything that pulls it in gets the whole cabinet. require("emberline.ui.service") What it reads: `Bus.state` (phase, timer, wins, the two fighter runtimes) and `Bus.registry.fighters`. What it writes: `Bus.state.phase` for the MENU phases only (attract/title/select/ending and the pause flag) — the combat slice owns the fight's own phases and this module never writes them. Everything else it does is emit `ui.confirm` and call other slices through `Bus.call`, which no-ops until they land.
newSide(name: string, subtitle: string) → any
| arg | type | description |
|---|---|---|
| name | string | |
| subtitle | string |
approach(v: number, target: number, rate: number, dt: number) → number
| arg | type | description |
|---|---|---|
| v | number | |
| target | number | |
| rate | number | |
| dt | number |
fractionOf(value: any, maxValue: any, fallbackMax: number) → number
| arg | type | description |
|---|---|---|
| value | any | |
| maxValue | any | |
| fallbackMax | number |
fighterIdFor(side: number, runtime: any) → string
| arg | type | description |
|---|---|---|
| side | number | |
| runtime | any |
say(text: string, sub: string?, seconds: number?) → void
| arg | type | description |
|---|---|---|
| text | string | |
| sub | string? | |
| seconds | number? |
setPhase(phase: string) → void
| arg | type | description |
|---|---|---|
| phase | string |
desiredScreen( ) → string
hudVisible( ) → boolean
syncSide(side: number, dt: number) → void
| arg | type | description |
|---|---|---|
| side | number | |
| dt | number |
stepTimers(dt: number) → void
| arg | type | description |
|---|---|---|
| dt | number |
pressedAny(codes: { string }) → boolean
| arg | type | description |
|---|---|---|
| codes | { string } |
moveMenu(delta: number, count: number) → void
| arg | type | description |
|---|---|---|
| delta | number | |
| count | number |
confirmTitle( ) → void
confirmSelect( ) → void
confirmPause( ) → void
handleKeys( ) → void
ensureRegistered( ) → void
hudSignature( ) → string
menuSignature( ) → string
overlayLive( ) → boolean
pushScreens( ) → void
onCallback(id: any, _data: any) → void
| arg | type | description |
|---|---|---|
| id | any | |
| _data | any |
upper(s: string) → string
| arg | type | description |
|---|---|---|
| s | string |
bindEvents( ) → void
setPhase(phase: string) → void
| arg | type | description |
|---|---|---|
| phase | string |
hud(state: any) → void
Combat may push its own numbers rather than have them read off the bus. Accepts a partial table: { timer, side = { {hp, meter, wins}, ... } }.
| arg | type | description |
|---|---|---|
| state | any |
cutIn(fighterId: string, moveName: string?, side: number?) → void
The big cut-in on a super. `side` picks which edge it crosses from.
| arg | type | description |
|---|---|---|
| fighterId | string | |
| moveName | string? | |
| side | number? |
cutIn(fighterId: string, moveName: string?, side: number?) → void
| arg | type | description |
|---|---|---|
| fighterId | string | |
| moveName | string? | |
| side | number? |
show(screen: string, data: any) → void
The match driver names the CARD it wants — "win", "continue" — rather than a phase; both live under the `matchover` phase, so the name picks which face of it the cabinet shows.
| arg | type | description |
|---|---|---|
| screen | string | |
| data | any |
hide(screen: string) → void
| arg | type | description |
|---|---|---|
| screen | string |
banner(text: string, frames: number?) → void
The announcer's call, as type. `frames` is in 60ths, matching the rest of the game's timing vocabulary.
| arg | type | description |
|---|---|---|
| text | string | |
| frames | number? |
subtitle(text: string, who: string?, frames: number?) → void
A spoken line's written form. Every voiced line in this game also lands here, so a failed generation leaves the line quiet rather than lost.
| arg | type | description |
|---|---|---|
| text | string | |
| who | string? | |
| frames | number? |
announce(lineId: string) → void
The announcer's scripted lines by id, drawn as type whether or not the voice slice speaks them.
| arg | type | description |
|---|---|---|
| lineId | string |
flash(amount: number?) → void
| arg | type | description |
|---|---|---|
| amount | number? |
update(dt: number) → void
| arg | type | description |
|---|---|---|
| dt | number |
teardown( ) → void
Take every screen down. The scene entrypoint's teardown path and the final phase both want a clean glass.
preview(opts: any) → void
Put the cabinet into a state a screenshot can judge, without a fight running: named fighters, part-drained bars, meter, a round won. Sets values only — it starts no task and leaves nothing ticking.
| arg | type | description |
|---|---|---|
| opts | any |
Sub-parts
Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.
Showing up to 3 levels deep. Open a part to see what it holds further down.
Problems
Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.
agent_score is exposed.+ quality × 0.35
+ performance × 0.25
± compat factor
Usability ratings
Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".
Scoped to this part · feeds back into the world's score.