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

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 ver…

by◐satish·posted 25d ago
What it does

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.

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.Director — the referee of GANESHA: GUARDIAN OF THE PORTAL. One instance, on the scene's `Director` entity. It boots each 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. The scene names this component and nothing else about the game — every slice is reached through `G.SLICES`, so a slice that is not written yet is simply skipped and lands later without an edit to the scene.

attachIfPresent(entityName: string, componentName: string) → boolean

Attach one component to one entity, saying nothing when the type is not registered yet. The lead slice in each is the one that must exist.

argtypedescription
entityNamestring
componentNamestring

bootSlices( ) → void

armBeat(seconds: number, fn: () → void

argtypedescription
secondsnumber
fn(

restoreHealth(share: number) → void

argtypedescription
sharenumber

beginArena(index: number) → void

argtypedescription
indexnumber

onFoeDied(foe: any) → void

argtypedescription
foeany

onPlayerDied( ) → void

subscribe( ) → void

awake( ) → void

start( ) → void

update(dt: ?) → void

argtypedescription
dt?

onDestroy( ) → void

beginRun( ) → void

Leave the title screen and open the run at the festival.

retryArena( ) → void

Retry the arena the guardian fell in.

startFight( ) → void

Begin the fight for the current arena without the intro beat.

toTitle( ) → void

Go back to the title screen.

liveSlices( ) → void

Which slice ids are currently running. For the interface's debug line.

Sub-parts

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

7items
▣
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
backing path · game/Director.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.