# Add the BallEngine player to this website You are adding BallEngine (https://ballengine.app), a physics ball simulation player, to the user's website. It is ONE iframe that BallEngine hosts. Do not install any package, do not copy any BallEngine code, do not add a build step. Keep the user's existing design: the player runs in its own frame and the page's CSS cannot affect it. ## Facts - Public key: be_pk_YOUR_KEY Safe to put in page source. It only works on: the websites registered for your key - Modes: RHYTHMIC, ESCAPE, DRAWER, SPAWNER, GHOST_ESCAPE, SPIRAL_BREAKER, GLASS_TOWER, FLAG_BATTLE, WEAPON_BALL_BATTLE, MERGE_EVOLUTION, GLASS_RUSH, WAVE_GRID, MARBLE_RUN_3D, BALL_CRUSH, SOFT_BODY, CUT_COUNT, MAGNETIC, GRID_MERGE - Randomize makes a new simulation; Download video records an MP4 on the visitor's own device (no server, no credits). Each finished download counts against the site's monthly videos. - The player is vertical 9:16. Never give it a fixed height that breaks that ratio. ## First, ask the user ONE question, then build only what they choose "How much do you want to build? 1. Quick test: the player with its built-in Randomize and Download buttons (about 2 minutes) 2. My own controls: your own Randomize, Download video and mode picker buttons in your design 3. Full: level 2 plus progress bar, monthly videos left, keeping the video on your server, and a per-user limit" If the user already said what they want, skip the question. If unsure, build level 1: it already makes great-looking videos, because Randomize does the design work. ## Level 1: the player (everyone starts here) Place this where the player should appear, with the mode the user wants: It already has a Randomize button and a Download video button at the bottom. Done for level 1. URL options: mode (key like FLAG_BATTLE or page name like flag-battle), duration (5 to 60 seconds, default 15), visitor (optional id of the signed-in user, for a per-user limit). Look settings, the SAME names the cloud render API takes, so the site and its rendered videos match: theme (cyberpunk_neon, dark_minimal, retro_synthwave, matrix_code, gold_luxury, fire_and_ice, pastel_dream, deep_space), palette (comma-separated hex colours), title_text, watermark_text, speed (0.5 to 3), ball_count, gravity (0 to 5), sound_effect, config_overrides (URL-encoded JSON). They stay on through every Randomize. Only add them if the user wants a fixed look. React: same tag, style as an object. SSR frameworks: render it client-side if needed. ## Level 2: the site's own buttons (build in this order) The page talks to the player with postMessage. Always check the origin. const BE = 'https://ballengine.app'; const player = document.getElementById('ballengine-player'); const send = (msg) => player.contentWindow.postMessage({ target: 'ballengine', ...msg }, BE); a) Randomize button: send({ type: 'randomize' }) b) Download video button: send({ type: 'export' }) // records locally, then downloads c) Mode picker: wait for the 'ready' message, it lists every mode as e.data.modes = [{ id, name }]. Build a