# 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