promo-video

Record a high-FPS autonomous promo video of a Phaser game using Playwright. Triggers on: promo video, gameplay recording, marketing video, game capture.

By playableintelligence · 728 installs

npx skills add playableintelligence/game-creator --skill promo-video

Source repository · Upstream listing

Promo Video Recording Record smooth, autonomous promo footage of a Phaser game for marketing / social media. The output is a 50 FPS MP4 in mobile portrait (9:16) — ready for TikTok, Reels, Moltbook, or X. Technique Playwright's recordVideo caps at 25 FPS with no config option. We work around it: 1. Slow the game to 0.5× by patching all 5 Phaser time subsystems 2. Record for 2× the desired duration at Playwright's native 25 FPS 3. FFmpeg speed up 2× → effective 50 FPS output Parameter Default Effect SLOW MO FACTOR 0.5 Game runs at half speed → 50 FPS output WALL CLOCK DURATION DESIRED GAME DURATION / SLOW MO FACTOR Record for 2× to get correct game time VIEWPORT { width: 1080, height: 1920 } 9:16 mobile portrait (always default unless user specifies otherwise) DESIRED GAME DURATION 13000 (ms) ~13s of game time → ~6.5s promo clip Prerequisites Playwright — must be installed ( npm install D @playwright/test && npx playwright install chromium ) FFmpeg — must be available on PATH ( brew install ffmpeg on macOS) Dev server running — game must be served on localhost Check both before starting: If FFmpeg is not found, warn the user and skip the promo video step (it's non blocking — the game still works without it). Capture Script — Game Specific Adaptation Every game gets a custom scripts/capture promo.mjs . The subagent must read the game's source files to determine: 1. Death/Failure Patching (CRITICAL) The video must show continuous gameplay — never game over. Read GameScene.js (or equivalent) to find the death/failure method and monkey patch it out. How to find it : Search for the method called on collision/death. Common patterns: this.triggerGameOver() — dodge games this.takeDamage() → this.lives <= 0 — multi life games this.gameOver() — direct call eventBus.emit(Events.PLAYER HIT) / eventBus.emit(Events.GAME OVER) — event driven Patch template (adapt per game): 2. Input Sequence Generation The video must show dynamic, natural looking gameplay. Read the game's input handling to determine: Which keys — ArrowLeft/ArrowRight? Space? WASD? Mouse clicks? Input style — continuous hold (movement), tap (jump/shoot), or both? Movement pattern — should the player sweep across the screen, dodge reactively, jump rhythmically? Input patterns by game type: Game Type Input Keys Pattern Side dodger ArrowLeft, ArrowRight Alternating holds (150 600ms) with variable pauses, occasional double taps Platformer / Flappy Space Rhythmic taps (80 150ms hold) with variable gaps (200 800ms) Top down WASD / Arrows Mixed directional holds, figure eight patterns Shooter ArrowLeft/Right + Space Movement interleaved with rapid fire Clicker/Tapper Mouse click / Space Rapid bursts separated by brief pauses Randomize timing to avoid robotic looking movement: Add a pause at the start (1 2s) to let the entrance animation play — this is the hook. 3. Game Boot Detection All Phaser games built with the /viral game or /make game pipelines expose these globals: window. GAME — Phaser.Game instance window. GAME STATE — GameState singleton window. EVENT BUS — EventBus singleton Wait for both boot and active gameplay: 4. Time Scaling Injection Slow all 5 Phaser time subsystems for the recording: The 5 subsystems: 1. Update delta — scene.update(time, delta factor) slows frame delta dependent logic 2. Tweens — scene.tweens.timeScale slows all tween animations 3. Scene timers — scene.time.timeScale slows scene.time.addEvent() timers 4. Physics — scene.physics.world.timeScale slows Arcade/Matter physics (uses inverse: 1/factor ) 5. Animations — scene.anims.globalTimeScale slows sprite animation playback 5. Video Finalization Full Capture Script Template FFmpeg Conversion After recording, convert the raw slow mo WebM to a high FPS MP4. The convert highfps.sh script is bundled with this skill at skills/promo video/scripts/convert highfps.sh . The script: Applies setpts to speed up the video by 1/factor Sets output framerate to 25 / factor (= 50 FPS for 0.5× slow mo) Encodes H.264 with crf 23 , yuv420p , faststart Verifies output duration, frame rate, and file size Viewport Defaults Always record in mobile portrait (9:16) unless the user explicitly requests otherwise. Rationale: Games are played on phones — promo footage should show the real mobile experience 9:16 is native for TikTok, Instagram Reels, YouTube Shorts 1080×1920 is the standard resolution Aspect Ratio Viewport Use Case 9:16 (default) 1080 × 1920 Mobile portrait — TikTok, Reels, Shorts, Moltbook 1:1 1080 × 1080 Square — Instagram feed, X posts 16:9 1920 × 1080 Landscape — YouTube, trailers, desktop games Duration Guidelines Game Type Recommended Duration Why Arcade / dodger 10 15s Fast action, multiple dodge cycles Platformer 15 20s Show jump timing, level progression Shooter 12 18s Show targeting, enemy waves Puzzle 8 12s Show one solve sequence Checklist Before running the capture: [ ] Dev server is running and responding [ ] FFmpeg is installed on the system [ ] Playwright is installed with Chromium [ ] Game boots directly into gameplay (no menu blocking) [ ] Death/failure method identified and patched [ ] Input keys match the game's actual controls [ ] Entrance animation pause is included (1 2s) [ ] Output directory exists After capture: [ ] Raw WebM exists in output/ [ ] FFmpeg conversion produces valid MP4 [ ] Duration is ~half the raw recording (speed up worked) [ ] Frame rate is 50 FPS [ ] Video shows gameplay (not a black screen)