# game.rules
Banana 2077's one shared module: palette, the Peel Kabuki street layout every slice builds to, tuning for the player, baton and enemies, the controls list, the live game state (`R.state`, kept across hot reloads), the event bus (`R.on` / `R.emit`) and the rule functions that change state (`damagePlayer`, `healPlayer`, `addEddies`, `setSunglasses`, `registerTarget`, `hit`, `reportKill`, `setPhase`, `startRun`). Required by every slice; owned by the lead. See `/zero/source/design/spec.md`.
# ui
The quests slice's screens, all drawn on events and never rebuilt per frame:
- **Toasts** (`b77q_toasts`, layer 151): stacked notification cards at the top
right, one per `game.rules` `notify`. Each card takes its colour and icon from
its kind (info, xp, item, quest, romance, eddies, warn, hack, objective). A card
lasts about 3 s, and at most 4 show at once.
- **Banner** (`b77q_banner`, layer 152): one banner at a time from a queue.
It shows NEW QUEST / GIG ACCEPTED when a quest starts, QUEST COMPLETE with the
rewards when one ends, and the big LEVEL UP ("+1 ATTRIBUTE POINT — PRESS I").
- **Phone** (`b77q_phone`, layer 153): the incoming-call card for a fixer's call.
- **Journal** (`b77q_journal`, layer 154): quests grouped MAIN JOBS / GIGS /
ROMANCE / DONE. The selected quest shows its title, giver, summary, objectives
(done stages struck through, the current one highlighted) and rewards, plus a
TRACK button. Opening it takes the `journal` focus, frees the mouse pointer and
activates `game.quests.journalnav` (up / down / track / close). Closing gives
them all back.
`U.new(io)` returns the runtime. `io.put(name, tree)` and `io.hide(name)` come
from the `Quests` component, which registers the screens itself so the journal's
clicks (`jq:<id>`, `jtrack`, `jclose`) reach its `onCallback`.
`U.rewardsText(rewards)` formats a reward table as one line.
# flow
The quests runtime. The `Quests` component calls `F.start(env)` once in `start()`
and gets back a session. Call `session.tick()` at about 4 Hz and
`session.stop()` in `onDestroy`.
What a session does, all on `game.rules` events:
- Registers the cast's quest dialogue (`content.TALK`) as talk providers at
priority 50.
- Starts **The Rotten Apple** on the first run of a profile. It also keeps the
job in step with the street: `bossCue` moves it to *take down Don*,
`bossDefeated` to *see Dex*, and a death reset puts it back to *clear the
street*. A save with `don_defeated` set never needs the street again.
- Keeps the live objective counters current ("Clear the Rotten Crew 3/8",
"Find the clues 2/3").
- Requests each gig's fight from the combat slice while its stage is active, and
cancels it when the stage ends. `encounterCleared` advances the stage.
- Spawns the props a stage needs and registers them as interactables:
terminals, crane console and server open a Breach Protocol; clues and the
guitar are picked up. `breachDone` advances the stage or asks V to retry.
- Places Dex's phone calls once the main job reaches the docks and again once
it is done. Each call opens two gigs. `env.phone(call)` draws the card.
- Moves the one neon waypoint beacon to the tracked quest's waypoint. It is
coloured by quest kind and hidden when V stands next to it.
`session.stop()` unsubscribes everything and removes the providers, props,
interactables and beacon.
# journal
The quest journal toggle: **J** on keyboard, **D-pad Right** on a gamepad, and a
small **JOURNAL** touch button at the upper right. The `Quests` component
activates this map while a run is playing and toggles the journal on press.
Its group is `quests_hud`, so the journal's own navigation map does not stand it
down, and the same button also closes the journal.
# journal.inputBinding
One control of the quest journal; see the map README for what it does on each device.