Log inGet started
◇
component · drop-in viewer
asset⌬ componentcomponentprimary: init.luau·originates fromworld bdf6a40a-f…

Screens

One instance, on the scene's `MountUI`. Owns the title card, the HUD, the quest line, the cinematic boss bar, the banners, the pause menu, the controls card and the ending cards.

by◐satish·posted 25d ago
What it does

Screens — everything the game puts on the glass

One instance, on the scene's MountUI. Owns the title card, the HUD, the quest line, the cinematic boss bar, the banners, the pause menu, the controls card and the ending cards.

Public fields

None. It reads game.Game.state and never writes it.

Methods

  • :screens() — the names of the screens it registers.

Lifecycle

  • start() — reaches MountUI, builds all six screens, and shows the one the current act calls for.
  • update(dt) — rewrites the HUD every 0.12 s, re-applies the act, and reads ESC (pause) and R (retry after a loss).
  • onDestroy() — unsubscribes and hides every screen it registered.

Screens

ScreenLayerUp when
g_title900the act is TITLE
g_hud40any act except TITLE, ENDED, DEAD
g_pause950ESC
g_controls960CONTROLS, from the title or the pause menu
g_credits960CREDITS
g_end970the act is ENDED

Notes

  • Every colour comes out of G.PALETTE, so the interface and the world cannot drift apart: gold is divine power, marigold is the festival, the rift colours are the portal, stone and bone are stone and bone.
  • The HUD is one screen. Its text-bearing widgets carry ids and are rewritten in place by gui.update; the boss bar and the player bars are drawn as block glyphs at a fixed width, so a value change never re-lays out the frame.
  • The screens do not own the game. A press is answered by calling the Director's public verbs — beginRun, retryArena, toTitle — so the rules stay in one place.

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

conforms to

zero/source-extract/v2

game.ui.Screens — everything GANESHA: GUARDIAN OF THE PORTAL puts on the glass. Boots onto `MountUI`. Owns the title card, the HUD, the quest line, the cinematic boss bar, the banners, the pause menu, the controls card and the ending cards. It reads `G.state` and never writes it: the only things it does are register screens, update their text, and answer a press by calling the Director. Screens are real: type, a chosen palette, art rather than words alone. Every colour comes out of `G.PALETTE`, so the interface and the world cannot drift apart.

text(s: string, size: number, colour: string, opts: any?) → any

argtypedescription
sstring
sizenumber
colourstring
optsany?

display(s: string, size: number, colour: string, opts: any?) → any

argtypedescription
sstring
sizenumber
colourstring
optsany?

mono(s: string, size: number, colour: string, opts: any?) → any

argtypedescription
sstring
sizenumber
colourstring
optsany?

space(px: number) → any

argtypedescription
pxnumber

uiH( ) → number

The UI's own logical height, so a card can be placed as a fraction of the window instead of by a number that only fits one screen.

padTop(frac: number) → any

argtypedescription
fracnumber

row(children: { any }, gap: number?) → any

argtypedescription
children{ any }
gapnumber?

col(children: { any }, gap: number?) → any

argtypedescription
children{ any }
gapnumber?

btn(label: string, cb: string, width: number?) → any

argtypedescription
labelstring
cbstring
widthnumber?

buildTitle( ) → void

buildCredits( ) → void

buildControls( ) → void

buildPause( ) → void

buildEnd( ) → void

buildHud( ) → void

setText(id: string, s: string) → void

argtypedescription
idstring
sstring

updateHud( ) → void

show(name: string, on: boolean) → void

argtypedescription
namestring
onboolean

applyAct( ) → void

directorCall(name: string) → void

argtypedescription
namestring

onCallback(callbackId: string, _data: any) → void

argtypedescription
callbackIdstring
_dataany

awake( ) → void

start( ) → void

update(dt: ?) → void

argtypedescription
dt?

onDestroy( ) → void

screens( ) → void

Which screens this slice has registered.

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

11items
▣
module · born here
❒asset
# Game The spine of **GANESHA: GUARDIAN OF THE PORTAL**. One shared module every slice requires: the tuning numbers, the eight Rakshasas and their arenas, the eleven quests, the story machine's acts, the mount points, and the event bus. It draws nothing, moves nothing and sounds nothing — it is the contract that lets a slice be written without knowing who else is in the world. `require` returns one shared instance per world, so `G.state` read in the hero slice is the same table the interface slice reads, and `G.on` / `G.emit` is how one slice learns what another did. ## Exports - `G.TITLE`, `G.SUBTITLE` — the title card's own words. - `G.ART_STYLE` — the one art-direction sentence every visual decision answers to. - `G.PALETTE` (hex, for the interface) and `G.RGB` (0-1 triples, for lights/materials). - `G.ACT` / `G.ACT_ORDER` — the story machine's phases. - `G.QUESTS` — the eleven quests, in order: `{ title, objective }`. - `G.PLAYER` — the guardian's 2000 HP, speeds, stamina, jump. - `G.ATTACKS` / `G.ATTACK_ORDER` / `G.ABILITY_BAR` — the four attacks with damage, timing, reach, arc and cooldown. - `G.FOES` — the eight Rakshasas: health, speed, damage, reach, behaviour, tells. - `G.ARENAS` — the eight battlefields: ground colour, sky, sun, fog, props. - `G.BEATS` — timings for the beats between fights. - `G.state` — the shared run state (act, quest, arena, health, foe, banner…). - `G.EV` — event names; `G.on(name, fn)` and `G.emit(name, payload)`. - `G.setAct` / `G.setQuest` / `G.setArena` — the only writers of those fields. - `G.banner` / `G.toast` / `G.kick` / `G.freeze` — the presentation verbs. - `G.MOUNTS` / `G.SLICES` — where each slice is booted. - `G.clamp` / `G.lerp` / `G.damp` / `G.angleDelta` / `G.horizDist` / `G.yawTo`. - `G.arena()` / `G.foeAt(i)` / `G.questForArena(i)` / `G.restart()`. ## Usage ```luau local G = require("game.Game") G.on(G.EV.FOE_DIED, function(foe) G.setQuest(G.questForArena(G.state.arena)) end) if G.state.act == G.ACT.FIGHT then local arena = G.arena() local tuning = G.foeAt(G.state.arena) end ``` ## Notes - **State has one writer per field.** The hero slice owns `health`, `stamina` and `cooldowns`; the foes slice owns `foe` and `bossBar`; the world slice owns `act` transitions from its own beats. Announce changes with `G.emit` so the interface and the sound slice hear them. - **The bus is per world, not per frame.** Subscribe in `start()` and keep the unsubscribe function the subscribe returns; drop it in `onDestroy()` or a reload will leave two listeners running. - **Arenas are 1-indexed and match `G.FOES` by `arena.foe`.**
▲ 0↑ born
◇
component · born here
❒asset
# Director The referee of **GANESHA: GUARDIAN OF THE PORTAL**. One instance, on the scene's `Director` entity. It boots every slice onto its mount, owns the story machine's act transitions, keeps the shared timers (banner, toast, camera shake, hit-stop) and hands the interface slice the verbs it needs. It draws nothing, moves nothing and sounds nothing — the slices do all of that, and this decides when. ## Public fields None. The Director's state is the run state itself, held in `game.Game.state`. ## Methods - `:beginRun()` — leave the title screen, open at the festival (quest 1, arena 1). - `:retryArena()` — restore the guardian and re-enter the arena they fell in. - `:startFight()` — begin the current arena's fight with no intro beat. - `:toTitle()` — return to the title screen. - `:liveSlices()` — the slice ids whose component type is registered and running. ## Lifecycle - `start()` — boots the slices named in `G.SLICES`, subscribes to the bus, and parks the run on `G.ACT.TITLE`. - `update(dt)` — counts down the banner, toast and shake timers in real time (dividing out `engine.timeScale`), and drives hit-stop by holding `engine.timeScale` low for the freeze's duration. - `onDestroy()` — drops every bus subscription and restores `engine.timeScale`. ## Notes - **A slice that is not written yet is skipped, not an error.** Each entry in `G.SLICES` is checked with `asset.exists(name, "component")`; an unregistered one is passed over and lands the moment its component file exists. That is what lets the slices be built one at a time against a scene none of them writes. - **The mount names are the interface.** `G.MOUNTS` names the five entities the scene lays out; a slice reaches its mount with `entity.find(G.MOUNTS.Hero)` rather than guessing a path. - **Acts advance from events, never from polling.** The Director reacts to `FOE_DIED` and `PLAYER_DIED`; the world slice reports a portal reached by emitting its own event and letting this decide.
▲ 0↑ born
backing path · game/ui/Screens.component

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

0problems
No problems reported. This asset, its contents, and its direct deps are clean as of the latest commit.
⌬ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability—
did it work as advertised
quality—
authoring polish + cohesion
performance—
frame & memory budget held
agent review score
—
/ 100
awaiting first pass
usability × 0.40
+ 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".

—%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.