feat(sasch40): major overhaul with doodle jump, party bunker, and guitar hero

- Add global settings & pause modal (gear icon) with mute and reset, removing obsolete bag button
- Extend Prologue with Flo Maier (castle fire game over & Löschzug restart) and Viktor (vampire bite game over & Knoblauch restart)
- Rebuild Akt II as 3-level vertical Doodle Jump climber to rescue sisters Saskia, Maja, and Miriam with custom pixel portraits
- Update Akt III Schankraum with seamless oak floor, double-tap 'Luke zum Party Bunker', duel intro modals, and Hansi's departure in Hinterland
- Rebuild Akt IV as 3-lane medieval Guitar Hero rock concert with live crowd meter, combo multipliers, and Hansi duo
- Update AGENTS.md architectural documentation and playtest test suite
This commit is contained in:
Moritz Graf
2026-09-24 18:22:28 +02:00
parent 6374ba9e8a
commit 8a0b65c3fa
22 changed files with 2307 additions and 1250 deletions
+62 -21
View File
@@ -27,18 +27,46 @@ This document records the foundational design decisions, their rationale ("Why")
### 2. Dual Game Modes & Dynamic Chassis Layout (`GameBoyFrame.vue`)
* **The Decision**: The GameBoy physical controls (D-Pad and A/B action buttons) MUST dynamically hide and show based on the active game mode.
* **Why**: The game alternates between arcade mini-games (Jump & Run, Party Express) and point-and-click / visual-novel adventure scenes (Prologue, Tavern, Finale Certificate). Displaying a chunky D-Pad and large A/B buttons during dialogue or tavern exploration wastes mobile screen space and ruins immersion.
* **Why**: The game alternates between arcade mini-games (Doodle Jump Schwesternrettung, Mittelalter Guitar Hero) and point-and-click / visual-novel adventure scenes (Prologue, Tavern, Finale Certificate). Displaying a chunky D-Pad and large A/B buttons during dialogue or tavern exploration wastes mobile screen space and ruins immersion.
* **The Rule**:
* **Arcade Acts** (`currentAct === 'platformer'` or `'party_express'`):
* Show the GameBoy D-Pad and A/B action buttons (`arcade-layout`).
* Display the arcade HUD with Korken, Helles, and 135 BPM counter.
* **Adventure / Dialogue Acts** (`currentAct === 'intro'`, `'prologue'`, `'tavern'`, or `'finale'`):
* Hide the D-Pad and A/B buttons completely (`adventure-layout`).
* Display a sleek mini bottom bar with current Korken, Helles, and an inventory drawer button (*„🎒 Beutel“*).
* Display a sleek top-right settings button (`⚙️`) offering pause, mute/unmute, and game reset.
* On `currentAct === 'finale'`, hide even the mini bar so the certificate occupies the full screen.
---
### 2b. Global Settings & Audio Control Modal (`GameBoyFrame.vue`)
* **The Decision**: A persistent `⚙️` settings icon is available at the top-right of the GameBoy frame.
* **Why**: Mobile players need a straightforward way to mute sound in public, pause during conversations, or cleanly restart the adventure.
* **The Rule**: Clicking `⚙️` opens a modal that pauses game loops, provides toggleable audio (`🔊 Sound: AN / 🔇 Sound: AUS`), and offers a `🔄 Spielstand zurücksetzen` option with safety confirmation.
---
### 2c. Prologue Branching & Themed Game Overs (`PrologueView.vue`)
* **The Decision**: Prologue choices can trigger humorous non-fatal Game Over screens with themed reset actions:
* 🔥 **Flo Maier (*Feierdeifl*)**: Choosing to burn the castle leads to a fiery castle inferno and a `🚒 MIT DEM LÖSCHZUG NEU STARTEN` button.
* 🧛 **Viktor (*Partyvampir*)**: Choosing the vampire bite turns Sascha into dust at sunrise and provides a `🧄 MIT KNOBLAUCH-KUR NEU STARTEN` button.
* **Why**: Gives playful branching flavor without permanently penalizing the player.
---
### 2d. Akt II: Doodle Jump Schwesternrettung (`PlatformerView.vue`)
* **The Decision**: Act II is a bottom-to-top vertical bouncing climber across 3 progressive levels to rescue King Sascha's three sisters:
1. **Level 1**: Rescue **Saskia** (+3 Kronkorken, 1 Helles)
2. **Level 2**: Rescue **Maja** (+3 Kronkorken, 1 Helles)
3. **Level 3**: Rescue **Miriam** (+4 Kronkorken, 1 Helles)
* **Mechanics**:
* Continuous automatic upward bouncing upon landing on platforms.
* Spring platforms (`🌀`) for high-velocity boost with custom synthesizer audio.
* Seamless screen wrap-around (moving off the left edge wraps to the right and vice versa).
* Gentle fall protection: falling below the visible screen softly places Sascha onto a safe platform near his lower altitude rather than triggering a punitive death.
---
### 3. Protagonist System & Extensibility (`characters.ts`)
* **The Decision**: All character portraits are strictly 1:1 square pixel-art illustrations based directly on real-life friends and family photos, maintained in a centralized registry.
* **Why**: Guests at the party must immediately recognize themselves and their friends. Previous attempts at generic AI portraits caused confusion because hair, beards, and styles did not match the actual people.
@@ -67,9 +95,9 @@ This document records the foundational design decisions, their rationale ("Why")
### 4. Background Art Integrity & Cleanliness
* **The Decision**: Background scenes must remain clean of any AI-hallucinated pseudo-English text or stray UI elements.
* **Why**: AI image generators often bake random adventure-game dialogue boxes or text (e.g. `[O] I have to tell you, the glow-wurst is excellent!`) into the scene.
* **Why**: AI image generators often bake random adventure-game dialogue boxes or text into the scene.
* **The Rule**:
* `public/assets/scenes/tavern.jpg`: The bottom area is cleaned with a seamless dark oak wood beam and floor texture.
* `public/assets/scenes/schankraum_v3.jpg`: Seamless warm dark oak wood floorboards with natural planks.
* Any scene footer navigation (like `.scene-bottom-nav`) must be styled as natural wooden wainscoting with clear German labels.
---
@@ -78,8 +106,8 @@ This document records the foundational design decisions, their rationale ("Why")
* **The Decision**: Critical game HUD elements (score, act title, instructions) must either be drawn as HTML/CSS overlays or placed within a minimum safe margin of 24px on canvas.
* **Why**: Smartphones vary widely in screen aspect ratio (16:9, 19.5:9, 20:9). When a 360x480 canvas is rendered with `object-fit: cover`, the left and right (or top and bottom) edges can be cropped by 10–25px on narrow screens.
* **The Rule**:
* In `PlatformerView.vue`: The Korken counter and level title are rendered via an absolute HTML overlay (`.platformer-hud-top`) so they are 100% immune to canvas cropping.
* In `PartyExpressView.vue`: The banner title is centered (`ctx.textAlign = 'center'`), and the progress bar has symmetrical 24px padding.
* In `PlatformerView.vue`: The Korken counter, sister progress, and level title are rendered via an absolute HTML overlay (`.platformer-hud-top`) so they are 100% immune to canvas cropping.
* In `PartyExpressView.vue`: The 3-lane strings, score counter, combo meter, and crowd meter use responsive percentages.
---
@@ -89,9 +117,9 @@ This document records the foundational design decisions, their rationale ("Why")
* **Score Breakdown**:
* Kronkorken collected: `100 pts` each.
* Helles tapped: `250 pts` each.
* Guests served in Party Express: `300 pts` each.
* Guests served / Concert performance: up to `3,000 pts`.
* Gstanzl duel victory: `1,500 pts`.
* Discovered secrets (Bridgerton dialogue, Zuluman mirror): `500 pts` each.
* Discovered secrets (Bridgerton dialogue, Party Bunker, Zuluman mirror): `500 pts` each.
* **Ranks**:
* `S-Rang (Legendär)`: >= 11,000 points (*„Unsterblicher Großfürst des Basses“*).
* `A-Rang (Erhaben)`: >= 9,500 points (*„Meister-Brauer der königlichen Garde“*).
@@ -101,10 +129,10 @@ This document records the foundational design decisions, their rationale ("Why")
---
### 7. Zero-Dependency Web Audio Synthesizer (`sound.ts`)
* **The Decision**: All sound effects, fanfares, and the 135 BPM techno bassline are synthesized in pure code using the Web Audio API.
### 7. Zero-Dependency Web Audio Synthesizer (`synthAudio.ts`)
* **The Decision**: All sound effects, fanfares, lute chords, and the 135 BPM techno bassline are synthesized in pure code using the Web Audio API.
* **Why**: External audio files (.mp3/.wav) take megabytes of bandwidth, stutter on mobile cellular networks, and trigger browser autoplay blocks.
* **The Rule**: The `SoundService` initializes on the first user interaction (touch/click). Sound effects use oscillators and gain envelopes; 135 BPM kick and sub-bass use recurring periodic intervals.
* **The Rule**: The audio context initializes on the first user interaction (touch/click). Sound effects use oscillators and gain envelopes; 135 BPM kick and sub-bass use recurring periodic intervals.
---
@@ -115,25 +143,38 @@ This document records the foundational design decisions, their rationale ("Why")
---
### 9. Cellar Trapdoor & Easter Egg Invisibility Pattern (`TavernView.vue`)
* **The Decision**: Secret hotspots (the cellar trapdoor `.trapdoor-hotspot` in the Schankraum leading to the VIP Hinterzimmer) must be 100% invisible initially.
* **Why**: An Easter egg marked with a glowing button or text badge is not a secret; it invites immediate trivial clicking.
### 9. Party Bunker Trapdoor & Double-Tap Pattern (`TavernView.vue`)
* **The Decision**: Secret trapdoor (`.trapdoor-hotspot` in Schankraum leading to the VIP Party Bunker) must be 100% invisible initially and requires a deliberate double-click or double-tap to unlock.
* **Why**: A single accidental click on the floor should not whisk the player away into an Easter Egg bunker before they explore the tavern.
* **The Rule**:
* The button must render with transparent background, no border, no outline, no box shadow, no hover change, and no tooltip (`:title="undefined"`).
* Only upon the user's first click does it reveal the door icon, label itself *„Luke zum Hinterraum“*, play a celebratory fanfare, unlock the Easter egg in the game store (+500 points), and transition to the secret room.
* Rendered with transparent background, no border, no outline, no box shadow, no hover change, and no tooltip (`:title="undefined"`).
* Double-click/double-tap detection combines `@dblclick` and timestamp delta (`now - lastTrapTap < 450ms`) to work flawlessly across desktop and mobile touchscreens.
* Upon double-tap, it reveals the wood trapdoor sprite, labels itself *„Luke zum Party Bunker“*, plays a celebratory fanfare, unlocks the Easter egg in the game store (+500 points), and transitions to the Party Bunker.
---
### 10. Multi-Room World Architecture & Tavern Minigames (`TavernView.vue`)
* **The Decision**: Act III is structured as a spatial, interconnected five-room village hub rather than a cramped single screen:
1. **Gaststube (Schankraum)**: King Sascha's table, Queen Verena on the balcony, Armend at the forge, Lutz (ZTUL) at the fireplace, door to Nebenraum, door to Marktplatz, and the secret *„Luke zum Hinterraum“* in the floor.
1. **Gaststube (Schankraum)**: King Sascha's table, Queen Verena on the balcony, Armend at the forge, Lutz (ZTUL) at the fireplace, door to Nebenraum, door to Marktplatz, and the secret *„Luke zum Party Bunker“* in the floor.
2. **Königlicher Nebenraum (Kemenate & Atelier)**: Amy painting the royal *„Rave the Kingdom!“* banner at her easel in overalls, and the golden Zuluman magic mirror on the wall.
3. **Haumdaucher Marktplatz**: Mario acrobatically juggling chainsaws and hops on the cobblestones; NAT (Josef) on the wooden festival stage with wild boar banners telling stories of his girls and heroic deeds.
4. **Alpines Hinterland**: Mane (Ramona) hiking the alpine trail with walking stick; Hansi on the panoramic bench.
5. **Geheimes VIP-Hinterzimmer**: Secret rave with disco chandelier, stroboscope, Pü's crystal staff, DJ Flo Maier, and Viktor the night-guard.
4. **Alpines Hinterland**: Mane (Ramona) hiking the alpine trail with walking stick; Hansi on his departure journey towards Münchanien.
5. **Geheimes VIP-Party-Bunker**: Secret rave with disco chandelier, stroboscope, Pü's crystal staff, DJ Flo Maier, and Viktor the night-guard.
* **Minigames & Exit Safety**:
* **Bayerisches Gstanzl-Fechten**: Multi-round insult rhyming duel. Must always include a visible `[✕]` close button so players are never trapped.
* **Wildschwein-Schnick-Schnack-Schnuck**: Best-of-3 tactical duel against NAT. Rules: 🐗 Keiler bricht 🌿 Dickicht, 🌿 Dickicht fängt 🏹 Lanze, 🏹 Lanze erlegt 🐗 Keiler. First to 2 points wins (+10 Korken, 1 Helles, `wildschwein_meister` achievement). Includes `[✕]` close button.
* **Bayerisches Gstanzl-Fechten**: Multi-round insult rhyming duel. Preceded by an explanatory rules modal. Must always include a visible `[✕]` close button so players are never trapped.
* **Wildschwein-Schnick-Schnack-Schnuck**: Best-of-3 tactical duel against NAT. Preceded by an explanatory rules modal (🐗 Keiler bricht 🌿 Dickicht, 🌿 Dickicht fängt 🏹 Lanze, 🏹 Lanze erlegt 🐗 Keiler). Includes `[✕]` close button and active button blur to prevent mobile sticky hover states.
---
### 10b. Akt IV: Mittelalter Guitar Hero — Hansis Abschiedskonzert (`PartyExpressView.vue`)
* **The Decision**: Act IV is a 3-lane medieval lute rhythm game set on an epic castle festival stage in front of 12,000 cheering fans.
* **Why**: Perfectly bridges the story from Hansi's departure in the Hinterland to a grand musical send-off before the royal coronation.
* **The Rule**:
* 3 color-coded lanes (`🔴 Saite 1`, `🟡 Saite 2`, `🔵 Saite 3`).
* Notes spawn synchronized to 135 BPM audio clicks and melodic riffs.
* Three large, finger-friendly touch buttons positioned comfortably at the lower screen for thumb play.
* Combo multiplier increases up to 4x with unbroken streaks.
* Generous hit window for fun, non-punishing festival gameplay.
---