# Peggle Sprite Sheet Spec Drop-in art for the pegs and ball. Physics and geometry are unchanged — these frames are pure display skins drawn at each peg's/ball's existing position and size. ## What to create **One PNG:** `assets/images/peggle-sprites.png` - **Frame size:** 64 × 64 px per cell - **Grid:** 8 columns × 2 rows → the PNG is exactly **512 × 128 px** - **Background:** fully transparent (32-bit PNG with alpha) ## Frame map Frames are numbered left→right, top→bottom (row 0 = frames 0–7, row 1 = frames 8–15). | Frame | Content | Notes | |-------|--------------------|-------| | 0 | Blue peg | The common filler peg | | 1 | Blue peg — LIT | Hit state: brighter / glowing version of frame 0 | | 2 | Orange peg | The objective peg | | 3 | Orange peg — LIT | | | 4 | Green peg | The power peg | | 5 | Green peg — LIT | | | 6 | Purple peg | The bonus (500-pt) peg | | 7 | Purple peg — LIT | | | 8 | Ball | The silver launch ball | | 9–15 | *(reserved)* | Leave empty/transparent — future use (e.g. fireball ball, brick pegs) | ## Drawing guidance - **Pegs (frames 0–7):** draw a circle that **fills the full 64 px cell** (i.e. 64 px diameter, touching the cell edges). In game a peg is 32 px across, so the art renders at 2× resolution and is scaled down — keep detail readable at 50%. - **LIT variants (odd frames):** same silhouette as the unlit frame, but clearly "switched on" — brighter core, inner glow, or highlight ring. The game swaps unlit↔lit frames instantly on hit, and lit pegs fade out 1.5 s later, so the two states should read at a glance. - **Ball (frame 8):** draw a circle filling the full 64 px cell. In game the ball is 26 px across. It's seen against a dark blue board — a light, specular look (chrome/silver) reads best. - Do **not** bake in drop shadows that extend outside the circle — pegs sit close together and overhang would overlap neighbours. - Keep each sprite centered in its cell; the game positions frames by cell center. ## How it activates 1. Save the PNG as `assets/images/peggle-sprites.png`. That's it — no code or config changes. The sheet is registered in `src/data/assetManifest.js` and lazy-loads the first time Peggle is entered. 2. Until the file exists (or if it fails to load) the game silently falls back to the current procedural circles — you'll just see a `[assets] failed to load peggle-sprites` console warning, which is harmless. 3. To revert to procedural art, delete the PNG. ## Board backgrounds (per master) One optional PNG per friend/master, shown behind the peg field on their levels. - **Path & naming:** `assets/images/peggle/.png`, where `` is the opponent's key from `levels.json` — e.g. `ethel.png`, `kona.png`, `zanthor.png`, `fireball.png`, `victor.png`. - **Dimensions:** exactly **1200 × 900 px** (4:3). The board window is 1200×900 logical pixels rendered 1:1 on the 1920×1080 canvas, so this is native resolution. If you want extra sharpness on large/4K displays, paint at **2400 × 1800** (same 4:3 ratio) — any other aspect ratio will be stretched to fit. - **Style:** the game lays a dark scrim (38% opacity, near-black blue) over the image so pegs, the ball, and the aim guide stay readable — so paint at full vibrancy and expect it to read darker in game. Avoid fine high-contrast detail in the central play area; big soft shapes work best behind ~50 pegs. - **Loading:** lazy-loaded when Peggle is first entered (listed from `levels.json` masterIds automatically — a new master's background needs no code change). Missing files fall back to the procedural starfield with a harmless console warning. ## Intro videos (per friend) One optional MP4 per friend, played on the intro screen that precedes their first level (levels 1, 6, 11, 16, 21 — detected automatically as the first level of each friend's block in `levels.json`). - **Path & naming:** `assets/videos/peggle/.mp4` — e.g. `ethel.mp4` (already saved), `kona.mp4`, `zanthor.mp4`, `fireball.mp4`, `victor.mp4`. - **Dimensions:** **720 × 720 px**, MP4 (H.264 video + AAC audio for the widest browser support). Displayed at 560×560 in the intro window. - **Behavior:** autoplays when the intro opens (the level click counts as the user gesture browsers require); when it finishes, a ▶ Replay overlay appears and clicking the video plays it again. The Continue button starts the level (and never auto-fires the cannon). - **Fallback:** a friend with no video yet shows their static 300×300 roster portrait in the same window — the intro screen works either way. - The intro shows on every fresh entry to that level (level select or "Next Level") but is skipped on Replay / Try Again. ## Brick curves Wavy lines of peg-like brick sections (the classic Peggle curved walls). Authored in the editor with the **Brick Curve** tool; stored in the level file as a `curves` array (`anchors` + per-segment `bends` + `orangeEligible`) and tessellated into 36×22 brick sections at load. Each brick behaves exactly like a peg — same color pool (blue/orange/green/purple), scoring, fade, and fever sweep. Bricks are **procedurally drawn** (not in the sprite sheet): color fill with a dark outer stroke and a light inner inset stroke, using the same palette as the pegs. The palette (`PEG_TINT`/`PEG_LIT` in `src/games/peggle/PeggleGame.js`) is sampled from the dominant fill of each peg frame in `peggle-sprites.png` — **if you repaint the peg colors, re-sample those two constants** so bricks stay in scheme. The reserved sheet frames 9–15 could skin them later if wanted. ## Not covered by the sheet - **Level editor** (`?peggle-editor=1`) intentionally keeps procedural circles — its colors encode editing state (gold = orange-eligible, blue = normal, red = invalid), not gameplay colors. - Bucket, launcher, background, and particles remain procedural for now. If you want art for those later, the reserved frames 9–15 (or a second sheet) can take them.