◇
component · drop-in viewer
GameUI
Every screen of Spooky Spook Spook. It lives on the `Game` entity and talks to the rest of the game only through `game.rules` (`R.state`, the verbs, the events and the providers).
by·posted 7d ago
What it does
GameUI
Every screen of Spooky Spook Spook. It lives on the Game entity and talks to the rest of the game only through game.rules (R.state, the verbs, the events and the providers).
Screens
All screens are camera-space, every element id starts with ssk-, and the layer number is in brackets.
- ssk_title (60): the generated title painting (
art/title_backdrop) with the carved SPOOKY SPOOK SPOOK type, and a bone plaque reading RISE / BUILD YOUR BONES (ssk-title-rise) that callsR.newRun(). - ssk_hud (40), shown in the
fightphase:- skull HP pips over a dripping bone, top-left (
ssk-hud-skulls) - WAVE n and the foes left, top-centre (
ssk-hud-wave) - a bone reticle
- the bone count, bottom-right (
ssk-hud-bones)
- skull HP pips over a dripping bone, top-left (
- ssk_banner (45): the WAVE n / WAVE CLEARED banners, shown on
waveStartedandwaveCleared. - ssk_flash (50): a red vignette on
playerHurtthat fades over about 0.45 s. - ssk_ossuary (60), shown in the
ossuaryphase:- the header plaque
- an open-sockets / selected-bone / attached-bones panel (
ssk-build-<id>detaches withR.detachBone) - a 6x2 bone grid (
ssk-inv-<id>attaches withR.attachBone). Each slot shows an icon, the name, a rarity ring and gem, and a tooltip with the affix, length and weight. Extra bones go on more pages. - a BONE STATS panel showing Speed, Reach, Magic and Head Count
- DESCEND (
ssk-oss-descend), which callsR.startNextWave()
- ssk_end (60), shown in the
deadandwonphases: the title, the score (R.score()), the deepest wave, bones collected, kills, and RISE AGAIN (ssk-end-rise), which callsR.newRun().
Every action emits uiClick { id }.
3D preview (game.ui.stage)
A candle-lit alcove at (500, -200, 0) with a hook chain and a UIPreviewCamera (fov 46).
- The camera is enabled at priority 50 only in the title, ossuary, dead and won phases. Otherwise it is disabled at priority -100, so the player's CameraRig owns the fight. This is re-asserted every frame.
- The skeleton comes from
R.call("buildSkeletonVisual", holderId, R.state.build). If the provider returns nil, a single glowing socket ring is shown instead. - Rebuilds are debounced:
buildChangedonly marks the stage dirty, andupdaterebuilds it at most once per frame. - Only one stage can exist:
createclears anyUIPreviewStageleft by a hot reload.
Input
- Mouse and touch tap the widgets directly (
onCallback). - Keyboard and pad use
game.ui.menu(an inputMap inmenu.inputMap/):- arrows or d-pad move a green focus ring
- Enter, pad South or pad Start presses the focused control
- touch is set to false on purpose, because touch taps the widgets themselves
Files
theme.module: the palette, fonts (Metal Mania, Pirata One, IM Fell English SC infonts/), SVG glyphs and helpers.screens.module: pure tree builders.stage.module: the 3D preview.art/: generated frames, icons and backdrops.
Public fields
menuMap: inputMap: the menu focus map (defaultgame.ui.menu).
Lifecycle
awake: subscribes to the rules events, activates the menu map and applies the phase.update: creates the stage lazily in play, ticks it, and re-renders dirty screens (also when the canvas size changes).onCallback: routes every widget id.onDestroy: unsubscribes, unregisters the screens and destroys the stage.
Discussion
Scoped to this part · feeds back into the world's score.
Sign in to post.sign in
No comments yet. Be the first.