| # Hackathon Rescue Implementation Plan | |
| Date: 2026-06-15 | |
| ## Goal | |
| Turn the current Trans-Temporal Express prototype into one judge-ready endpoint: | |
| 1. A polished intro. | |
| 2. A clean first-person engine control. | |
| 3. Real generated destination and character imagery. | |
| 4. Real launch, travel, arrival, and ambient audio. | |
| 5. A final conversation scene where the world and character are the center of the UI. | |
| This plan supersedes the prior split `/blank` intro plus `/app` cockpit flow for the hackathon demo. | |
| ## Product Decisions | |
| - Use one endpoint for the whole experience. Prefer `/app/` as the canonical app and redirect `/`, `/blank`, and `/blank/` to it. | |
| - Keep Gradio for backend wiring, but hide the default controls from the user-facing experience. | |
| - The user should interact with the train cab, not with form fields. | |
| - Do not silently demo fixture SVG images. If real image generation is unavailable, show a clear developer warning. | |
| - Audio is part of the core experience, not a later nice-to-have. | |
| ## Target User Flow | |
| 1. User lands on `/app/`. | |
| 2. Full-screen ticket/train intro plays for 10-14 seconds, with skip available. | |
| 3. Intro dissolves into the train cab. | |
| 4. A highlighted physical control prompts the user to choose Past or Future. | |
| 5. The user chooses Past or Future using in-cockpit controls. | |
| 6. The throttle illuminates and prompts the user to launch. | |
| 7. User pulls/clicks the throttle. | |
| 8. The app starts the backend launch through hidden Gradio components. | |
| 9. Travel animation masks model latency: engine vibration, era signs, year counter, temporal tunnel, SFX. | |
| 10. When image generation completes, braking and steam reveal play. | |
| 11. Destination fills the windshield. | |
| 12. Character is centered or near-centered in the destination scene. | |
| 13. Chrome fades back; live voice becomes the primary action. | |
| ## Phase 0: Asset And License Gate | |
| Goal: import only safe, demo-appropriate assets from the internet. | |
| Rules: | |
| - Prefer Pixabay and Mixkit for sound effects and ambient loops because their license pages allow free use and modification without attribution, subject to prohibited-use restrictions. | |
| - Use Freesound only for CC0 or CC BY assets. Do not use CC BY-NC or Sampling+ assets. | |
| - Record every imported file in `static/audio/ASSET_LICENSES.md` or `static/assets_licenses.md`. | |
| - Store source URL, creator, license, download date, original filename, local filename, and any edits. | |
| - Avoid recognizable brands, trademarked content, celebrity/person likenesses, copyrighted train IP, or commercial movie/game sounds. | |
| Initial asset list: | |
| - `static/audio/sfx/lever_pull.mp3` | |
| - `static/audio/sfx/button_click.mp3` | |
| - `static/audio/sfx/ticket_clang.mp3` | |
| - `static/audio/sfx/charge_up.mp3` | |
| - `static/audio/sfx/gears_grinding.mp3` | |
| - `static/audio/sfx/train_whistle.mp3` | |
| - `static/audio/sfx/materialize.mp3` | |
| - `static/audio/sfx/time_warp.mp3` | |
| - `static/audio/sfx/brake_screech.mp3` | |
| - `static/audio/sfx/steam_burst.mp3` | |
| - `static/audio/sfx/chime.mp3` | |
| - `static/audio/ambient/temporal_storm.mp3` | |
| - `static/audio/ambient/rain.mp3` | |
| - `static/audio/ambient/marketplace.mp3` | |
| - `static/audio/ambient/ocean.mp3` | |
| - `static/audio/ambient/machinery.mp3` | |
| - `static/audio/ambient/wind.mp3` | |
| Implementation tasks: | |
| - Search and download candidates from approved sources. | |
| - Normalize audio to small MP3/OGG files suitable for web playback. | |
| - Trim long files into short loops where needed. | |
| - Add a manifest mapping app keys to files. | |
| - Add automated existence checks for required demo audio files. | |
| Validation: | |
| - All imported assets have a license entry. | |
| - No NC assets are used. | |
| - App still runs if an optional audio file is missing. | |
| ## Phase 1: One Endpoint | |
| Files: | |
| - `app.py` | |
| - `src/time_machine/ui/gradio_app.py` | |
| - `src/time_machine/ui/blank_app.py` | |
| - `src/time_machine/ui/assets/intro.*` | |
| - `src/time_machine/ui/assets/cockpit.*` | |
| Tasks: | |
| - Mount only the main app for the demo path. | |
| - Redirect `/`, `/blank`, and `/blank/` to `/app/`. | |
| - Move intro HTML/CSS/JS into the main app as an overlay. | |
| - Remove the separate intro Gradio app from the happy path. | |
| - Keep the intro skippable. | |
| - Add a local flag such as `?skip_intro=1` for repeated development testing. | |
| Validation: | |
| - `http://localhost:7865/` lands in the full experience. | |
| - `http://localhost:7865/app/` runs intro then cockpit. | |
| - `http://localhost:7865/blank/` does not expose a half-finished alternate product. | |
| ## Phase 2: Real Image Generation Contract | |
| Files: | |
| - `src/time_machine/application/container.py` | |
| - `src/time_machine/adapters/image_gen/together.py` | |
| - `src/time_machine/ui/view_models.py` | |
| - `config/app.yaml` | |
| - `config/models.yaml` | |
| Tasks: | |
| - Add explicit image generation readiness to startup/runtime state. | |
| - In `modal` and `dev` demo profiles, require `TIME_MACHINE_IMAGE_API_KEY` or `TOGETHER_API_KEY`. | |
| - Stop silently falling back to fixture SVG portraits for the hackathon profile. | |
| - Keep fixture fallback only for tests and local no-network development. | |
| - Add a UI developer warning if image generation is disabled. | |
| - Improve prompts so the world scene has a clear empty/usable foreground area for the character. | |
| - Improve portrait prompts so character output matches warm animated-film style and avoids crude flat avatar output. | |
| - Cache generated images by encounter id to avoid flicker and repeated API calls. | |
| Validation: | |
| - With image API key: world and portrait are PNGs, not fixture SVGs. | |
| - Without image API key in demo profile: app clearly reports missing image config. | |
| - Fixture tests still pass. | |
| ## Phase 3: Replace Form Controls With Engine Controls | |
| Files: | |
| - `src/time_machine/ui/assets/cockpit.html` | |
| - `src/time_machine/ui/assets/cockpit.css` | |
| - `src/time_machine/ui/assets/cockpit.js` | |
| - `src/time_machine/ui/gradio_app.py` | |
| Tasks: | |
| - Hide the visible Gradio dropdown, coordinate textarea, launch button, souvenir button, save button, markdown readouts, microphone controls, and audio widgets from the first-screen UI. | |
| - Keep their `elem_id`s and backend wiring intact. | |
| - Add custom in-cockpit controls: | |
| - Past button or switch. | |
| - Future button or switch. | |
| - Throttle lever as the launch action. | |
| - Optional surprise route as a small randomizer/lighted ticket slot. | |
| - On Past/Future selection, set the hidden Gradio route dropdown. | |
| - On throttle click, trigger the hidden Gradio launch button. | |
| - Add guided highlight states: | |
| - After intro: highlight Past/Future selector. | |
| - After selection: highlight throttle. | |
| - During launch: disable controls and show engine state. | |
| - After arrival: fade controls and focus voice. | |
| Validation: | |
| - User can complete launch without seeing or using Gradio form controls. | |
| - Keyboard and screen-reader users can still trigger the custom controls. | |
| - Hidden Gradio components continue to receive the expected values. | |
| ## Phase 4: Cinematic Layout Rescue | |
| Files: | |
| - `src/time_machine/ui/assets/cockpit.css` | |
| - `src/time_machine/ui/assets/cockpit.js` | |
| - `src/time_machine/ui/assets/cockpit.html` | |
| Tasks: | |
| - Make the windshield/world area the dominant visual region. | |
| - Center the generated character in the scene after arrival. | |
| - Remove or collapse UI chrome that competes with the final world: | |
| - Route card fades to a small top-left plate. | |
| - Year module shrinks after reveal. | |
| - Narration becomes a temporary subtitle, then clears. | |
| - Throttle and dashboard dim once conversation is ready. | |
| - Comm screen becomes the live voice affordance, not a competing panel. | |
| - Avoid blocking the character with narration text. | |
| - Replace current portrait crop behavior with a full-body or bust overlay treatment that feels intentionally staged. | |
| - Add final state class `.tm-state-conversation-ready` layout rules that prioritize scene/character. | |
| Validation: | |
| - In `conversation_ready`, the screenshot reads as "I am looking at a person in another world." | |
| - Character is not hidden behind controls or placed as a side widget. | |
| - Mobile view does not overlap controls, subtitles, and character. | |
| ## Phase 5: Audio System | |
| Files: | |
| - `src/time_machine/ui/assets/cockpit.js` | |
| - `src/time_machine/ui/assets/intro.js` | |
| - `src/time_machine/ui/assets/cockpit.html` | |
| - `src/time_machine/ui/assets/intro.html` | |
| - `static/audio/**` | |
| - `static/asset_manifest.json` | |
| Tasks: | |
| - Add a shared `AudioManager`. | |
| - Preload known SFX with graceful missing-file handling. | |
| - Unlock Web Audio after first user interaction. | |
| - Play intro SFX: | |
| - ticket appears | |
| - conductor punch | |
| - charge-up | |
| - materialization | |
| - train whistle | |
| - Play cockpit SFX: | |
| - button click | |
| - lever pull | |
| - charge-up | |
| - time warp | |
| - brake screech | |
| - steam burst | |
| - arrival chime | |
| - Add ambient loops: | |
| - temporal storm during travel | |
| - destination ambience based on `ambient_key` | |
| - Add ducking: | |
| - ambient lower under narration | |
| - ambient lower under character speech | |
| - restore after speech | |
| - Keep procedural tones only as fallback. | |
| Validation: | |
| - User hears distinct launch, travel, braking, arrival, and world ambience. | |
| - Missing audio does not break the page. | |
| - Browser autoplay restrictions are handled through user interaction. | |
| ## Phase 6: Intro Polish | |
| Files: | |
| - `src/time_machine/ui/assets/intro.html` | |
| - `src/time_machine/ui/assets/intro.css` | |
| - `src/time_machine/ui/assets/intro.js` | |
| Tasks: | |
| - Keep ticket/conductor/train beats, but shorten the total runtime. | |
| - Avoid dark empty time at the beginning. | |
| - Add tighter animation timing and audio hits. | |
| - End with a direct dissolve into the cockpit, not a route navigation. | |
| - Show skip affordance after 1 second. | |
| Validation: | |
| - Intro feels intentional in 10-14 seconds. | |
| - Skip works immediately after it appears. | |
| - Transition into cockpit feels continuous. | |
| ## Phase 7: Tests And Demo Verification | |
| Tasks: | |
| - Unit tests: | |
| - payload contains image readiness flags. | |
| - missing image API warning path. | |
| - hidden Gradio launch wiring is unchanged. | |
| - Browser verification: | |
| - intro first frame | |
| - cockpit ready | |
| - Past selected | |
| - travel animation | |
| - braking/steam | |
| - final world/character | |
| - Manual audio check: | |
| - SFX fire at expected moments. | |
| - ambience loops and ducks. | |
| - Demo script: | |
| - Past launch path. | |
| - Future launch path. | |
| - Live voice handoff. | |
| ## Risk Register | |
| - Real image generation latency may be longer than the intro/travel animation. | |
| - Mitigation: keep travel loop alive until scene and portrait are ready. | |
| - Browser autoplay restrictions can block audio. | |
| - Mitigation: first user click after intro unlocks audio; intro skip and controls call `audioManager.unlock()`. | |
| - Downloaded audio licenses can be ambiguous. | |
| - Mitigation: use only clear license pages and keep a ledger. | |
| - Gradio DOM changes can break hidden-control automation. | |
| - Mitigation: target stable `elem_id`s and add smoke tests. | |
| - Network/image API failure could ruin demo. | |
| - Mitigation: pre-generate and cache demo encounter images before judging where possible. | |
| ## Suggested Implementation Order | |
| 1. One endpoint and intro overlay. | |
| 2. Hide Gradio controls and build engine controls. | |
| 3. Final-state layout rescue. | |
| 4. Real image generation hard gate and prompt improvements. | |
| 5. Audio asset import and `AudioManager`. | |
| 6. Intro timing/audio polish. | |
| 7. Browser screenshots and demo rehearsal. | |
| ## External License References | |
| - Pixabay Content License Summary: https://pixabay.com/service/license-summary/ | |
| - Mixkit License: https://mixkit.co/license/ | |
| - Freesound FAQ Licenses: https://freesound.org/help/faq/#licenses-0 | |