storebound/media/teaser/README.md

7.3 KiB

storebound teaser (v9, 41 s, 16:9)

The v8 story cut tight: the game is done, the stores pile up work, one line gets it rejected, so your AI does it, and you press Submit. Editing rules: frame 0 already moves and shows the product (no black, no calm intro); nothing holds still longer than 0.8 s; every shot does one thing in 2-4 s and cuts when that thing completes (a line lands, a number lands, a check turns green); captions are at most six words and on screen for at least 2 s; the camera pushes toward the thing that changes; the last 4 s are the end card with npx storebound init typed out big and storebound.dev. Real product footage only. Every frame is a pure function of time, rendered from an HTML/CSS/JS timeline in headless Chrome and encoded with ffmpeg; the music and sound design are synthesized in the same browser (Web Audio OfflineAudioContext): no samples, nothing to license.

120 BPM: every cut is a hard cut on a beat (whole half seconds), with a sound accent on each. Before any final render, make the animatic (--animatic: a 960x540 draft with sound, a one-frame-per-second contact sheet and the shot list) and get the owner's OK.

s shows text music
0-3 the demo game's own screens rush past, a push in Your game is done. drives from frame 0: kick, bass, arpeggio
3-7 real store work lands one card per beat: App Privacy answers and steps, the Data safety CSV (768 rows), screenshot sizes, price sheets Then come the stores. tension: B minor pulse, kicks, a thud per card
7-9.5 the real scan finding (BLOCKER 5.1.1(v), Planner/LoginView.swift:11) slams in, a push onto it, the picture darkens One line. Rejected. a low boom, the clock keeps ticking
9.5-12 one request typed to the AI agent, sent on the beat So my AI did it. a short drop: an impact, half-time beat, key clicks, a swell
12-15 apple build --dry, play build --dry: build 52, versionCode 52 Builds. the drop
15-18 the demo game's renders: 7 store sizes x 4 languages fill in Screenshots, every size. + hats
18-21 play products --dry, catalog diff (175 / 174 region prices, 0 mismatches) Products, 175 countries. + claps
21-24 the scan's declarations proposal, the Data safety rows ticking, 768 answers Forms. + sixteenths
24-27 console plan apple-app-privacy, then the desktop app's plan panel, the owner's Publish ringed Consoles. + lead
27-31 storebound scan: five findings turn green one per beat, the clean re-scan Nothing left to reject. a chime per fix
31-33 the desktop app's Send for review, the camera pushes onto Submit, the pointer arrives You press Submit. the music stops
33-36 the click, then the app's own "Waiting for review" (same line) the resolve
36-41 the logo, npx storebound init typed out, storebound.dev; holds 4 s (none) a confident kick and bass on D, the chord; fades over the last 1 s

The demo game has 4 languages (en, tr, ja, ar), so the screenshot beat says "every size", not a language count. The video shows no drawn system dialog and no mail: between the click and "Waiting for review" the real app shows its own dry-run plan and then the system's confirm dialog, which the story skips.

file what
script.js the timeline: scenes in seconds, camera moves, captions, every line shown, the sound cues
desktop.ts the desktop frames: apps/desktop's Vite dev server in fixture mode (VITE_FIXTURES=1, example.com-style data), captured headlessly in dark at 1280x800 @2x with the dev markers hidden, plus boxes.json (ring and pointer targets) -> out/desktop/. The console plan panel gets the real storebound console plan apple-app-privacy --json of a fresh storebound init folder; the send-for-review frames press "Read state" and pick build 52 as the owner would (submit-ready), and the "Waiting for review" frame serves the fixture's apple status with the new submission waiting. It also captures the frames the site uses (site-shots.ts)
index.html + teaser.js the picture; window.teaser.seek(t) sets every element for time t
music.js music and sound design, one section per part of the arc (see the table)
render.ts frames at 60 fps blended to 30 fps -> ffmpeg (H.264 high, yuv420p); sound: one gain to about -16 LUFS with the true peak at or below -1.5 dBTP (no dynamic normalization, so the quiet parts stay quiet), mux, poster, the 1280x720 web version
icons/ the mouse cursor and the UI icons: Phosphor files copied unchanged by bun tools/site-icons.ts (no hand-written SVG; CI checks it)

Every CLI line in the video is real output, and tests/teaser.test.ts runs each command and checks every line (the clock prefix and the "(0s)" timer left out), in a fresh storebound init folder with two products:

  • storebound console plan apple-app-privacy (offline): the answer sheet and step lines of the pile, the plan lines of the consoles beat, the never-press list and the owner's final button.
  • storebound play data-safety --dry (the CSV lines), storebound check (768 rows), storebound prices ppp --offline --dry (the price rows).
  • storebound apple build --dry and storebound play build --dry in a minimal Capacitor project.
  • storebound play products --dry and catalog diff, with the stores answered by tests/helpers/teaser-store-mock.ts (preloaded through a bunfig.toml in the folder; nothing reaches the network).
  • storebound scan of tests/fixtures/scan/teaser (the 5.1.1(v) finding, all five findings, the declarations proposal) and of teaser-fixed after the fixes.

The test also checks the timing (every cut on a half-second beat, scenes 3-6 s, the montage at 19-37 s speeding up with cuts rather than dissolves, captions of at most 8 words fully on screen at least 2.5 s inside their scene, 56-62 s in total, 16:9 only), that the game screens and screenshot tiles are the demo game's own, and that every desktop frame a scene names is one desktop.ts captures (where they were captured: each file there, 2560x1600 JPEG).

Render

Needs Bun, ffmpeg, Playwright (repo devDependency; Playwright's Chromium or an installed Google Chrome) and the demo game's store captures and renders:

cd examples/demo-game && bun serve.ts & bun ../../cli/index.ts shots capture && bun ../../cli/index.ts shots fonts && bun ../../cli/index.ts shots render
# from the repo root
bun media/teaser/render.ts > media/teaser/out/render.log 2>&1 &   # master, sound, poster, web version: about 20 min
bun media/teaser/render.ts --desktop                                # capture the desktop app frames again (after a UI change)
bun media/teaser/render.ts --animatic ../storebound-dist/teaser-v9-animatic  # draft.mp4 (960x540), contact-sheet.png, shots.md: for the owner's OK
bun media/teaser/render.ts --stills 2.5,13.5,38                     # PNG stills in out/stills for a quick layout check
bun media/teaser/render.ts --sound                                  # the music only (out/music.wav)
bun media/teaser/render.ts --serve --port 8750                      # live preview: /index.html?play=1 (or ?t=12.5)

Outputs (gitignored) in media/teaser/out/: teaser-1920x1080.mp4 (master), teaser-web.mp4 (1280x720, about 6.7 MB) with poster-web.jpg, teaser-1920x1080-silent.mp4, poster-1920x1080.jpg, music.wav.