# 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