Sumo Showdown

Worlds·sumo·

Tie.

Remix in Claude

The prompt

Build **"Sumo Showdown"**: a real-time, interactive 3D sumo match between a **Claude mascot** and a **ChatGPT mascot**, two glossy jelly wrestlers on a raised ring who charge, slap, grip and shove until one is driven out and **tumbles off the edge**. **Physics decides the winner.** It is staged like a big TV fight night: entrance animations, best-of-3 rounds, slow-motion falls, instant replays and a winner screen, with **cinematic image quality** and **synthesised sound**, rendered with native **WebGPU** and **WGSL**. People can **poke**, **shove** and **fling** the wrestlers, start rematches, and run 100 bouts to see who really wins.

This should look and feel like a trailer people stop scrolling for and watch to the end. Spend effort on the look, the camera and the timing of every fall.

## Priorities

This is a big brief. Build it in this order, and finish each tier properly before starting the next. A polished tier 1 beats a broken everything.

1. **Must be excellent:** fair, deterministic physics; the charge, the clash with hit-stop and the slow-motion fall off the ring; glossy jelly wrestlers with expressive faces; the HUD with balance bars and rounds; the demo mode.
2. **Must work:** the full show (splash, entrance, banners, winner screen), move names, the instant replay, Sim 100 and Best bout, sound, the control card.
3. **Polish:** haze, crowd, footprints, droplets, streamers, film grain, motion blur.

Never ship a feature half-working: if something from tier 3 can't be done well, leave it out cleanly.

## Deliverable

- One self-contained `.html` file with all JavaScript, WGSL and CSS inline.
- **No external requests of any kind**: no libraries, CDNs, web fonts, images, textures or audio files. Generate everything procedurally in code (sound included, see Sound). Use system font stacks.
- It must run inside a sandboxed iframe (`sandbox="allow-scripts allow-pointer-lock"`). Do not use `localStorage`, cookies, `alert`, pop-ups or top-level navigation, and wrap any storage access in `try/catch`.
- This must be a live simulation, not a video, a pre-baked animation, a scripted outcome or a 2D fake.

## The wrestlers

Two chunky, toy-like jelly creatures with stubby legs, big round bellies, short arms and a thick cloth sumo belt (mawashi). Cute and funny, never violent: nobody gets hurt, they bounce.

- **Claude:** a warm terracotta-orange jelly body with a soft cream belly, and a small radiating sparkle / starburst mark on its chest. Calm, friendly face.
- **ChatGPT:** a near-black smoky jelly body with a soft white belly, and a small interlocking knot / flower mark on its chest. Calm, friendly face.
- The marks are **simple original shapes inspired by** each brand's feel, not copies of any logo. No wordmarks on the bodies.
- **Expressive faces** (procedural, drawn in the shader): neutral before the bout, determined squint on the charge, gritted strain while pushing, wide surprised eyes when losing balance, swirly dizzy eyes after a fall, a big grin for the winner.
- Each wrestler shows its name on a small floating tag above its head (hidden in demo mode and during replays).

## Fairness (the most important rule)

This is a fair fight. The outcome must come from the simulation, never from a script or a bias.

- **Both wrestlers use identical physics and identical behaviour.** Same mass, size, shape, stiffness, friction, strength, speed, reach, stamina and reaction time. Only colour, chest mark, face and name differ.
- **One shared controller** (a single function or class) drives both wrestlers. It receives only its own state, the opponent's state and the ring; it must not know or use which mascot it is.
- Every round uses a **seeded random number generator** (show the seed). Starting jitter, timing and tactics may vary by seed, and the same seed always replays the same round.
- **Sides swap every round** (east / west), so any left/right asymmetry cancels out.
- Cinematic effects (slow motion, camera cuts, replays) only change how a round is shown, never its result: the result is the same with them on or off, and the same as in Sim 100.
- A collapsible **"Fair fight"** panel lists every physics and behaviour parameter for both wrestlers side by side, so anyone can check they match.

## Physics

### Bodies (robust first, jiggly second)
- Each wrestler is an **articulated rigid body**: a small skeleton of capsules (pelvis, torso, head, two upper and lower arms, two thighs and shins, two feet) joined with angle-limited joints, kept upright by a **balance controller** (joint motors that hold a pose and keep the centre of mass over the feet). Solve it with a stable fixed-step method (for example XPBD or sequential impulses).
- **Jelly on top:** the skin is a smooth mesh skinned to the skeleton plus **secondary jiggle** (spring-damped offsets for belly, cheeks, chest and arms, volume preserving), so every impact sends a wobble through the body and bellies visibly squash against each other on contact.
- When balance is lost, the motors weaken and the wrestler becomes a **heavy, floppy ragdoll** that tumbles naturally, then motors fade back in and it gets up with a bounce.
- Feet plant with **friction**; they slide when pushed hard and dig in when the wrestler leans forward.

### Balance and stamina
- **Balance** (0 to 100%) is measured from the physics: how far the centre of mass is from the support of the feet, plus recent hits. It drops when a wrestler is slapped, pushed, off-balance or near the edge, and slowly refills while the feet are planted. **It never decides a round by itself**: at low balance the wrestler simply becomes easier to push over.
- **Stamina** (0 to 100%) drains while charging, pushing and gripping, and recovers while circling. Low stamina weakens pushes. Same rules for both.

### Ring and rounds
- A **raised clay ring** (dohyo) about a body height above the arena floor, with a straw-bale edge and sloped sides. A wrestler **loses the round** when any part of its body touches outside the ring, or when anything other than its feet touches the clay.
- Losing usually means a **dramatic fall**: getting driven over the straw edge and tumbling down the slope onto the arena floor, a belly-flop, being thrown and rolling, or tipping over backwards with a big jelly bounce.
- Round flow: both wrestlers stomp (shiko), crouch at their starting lines, then **charge** (tachi-ai) on the same frame. They clash, slap (tsuppari), grab the belt, lean, shove, pivot, side-step and try to push or throw the other out. The shared controller picks between these from balance, stamina, distance and the ring edge, with seeded randomness.
- Rounds typically last 4 to 15 seconds; if a round passes 25 seconds it is a draw (a draw is replayed).
- **A match is best of 3 rounds.** Each round result names the winning move, using real sumo terms detected from how the round ended:
  - **Oshidashi** (push out), **Yorikiri** (forced out while gripping the belt), **Tsukiotoshi** (thrust down), **Uwatenage** (overarm throw), **Hatakikomi** (slap down after a side-step), **Isamiashi** (stepped out by mistake).
  - Decide the name with simple, explicit rules from the last about 1 s before the round ended: was the winner gripping the belt, did the loser leave the ring or fall inside it, was the winner's last action a push, a slap, a throw or a side-step, and was the loser moving backwards or forwards. Fall back to Oshidashi (out) or Tsukiotoshi (down) when unsure, never to a wrong-looking name.

### Stability
- **Fixed simulation timestep** with bounded substeps, decoupled from frame rate. On a slow frame, drop simulation time rather than exploding.
- No explosions, no stretched or inverted limbs, no limbs passing through bodies or the ring, no jitter at rest, no wrestler stuck inside the straw edge.

## The show (presentation and timing)

Stage every match like a fight-night broadcast. All of this is presentation; the simulation underneath is unchanged.

1. **Title splash:** a bold "CLAUDE vs CHATGPT" card slams in with each wrestler's mark, then wipes away (about 1.5 s).
2. **Entrance:** each wrestler walks out from its side under a spotlight, throws a handful of **salt** (white particles that arc and scatter on the clay), and stomps once with a dust burst and a camera shake. Then a **"ROUND 1"** banner.
3. **The round:** the camera follows the action. At the charge it pushes in low and fast; on the clash, a short **hit-stop** (about 80 ms freeze) plus a shockwave ring of dust and a punchy camera shake.
4. **The fall:** when a round is decided, time drops to about **0.2× for about 1 s** while the camera swings to a dramatic low angle on the falling wrestler, then eases back to normal speed as it lands in a burst of dust.
5. **Instant replay:** the last about 2.5 s of the round replays in slow motion from a different camera angle (side, low or overhead), with a "REPLAY" badge, a subtle film grain and letterbox bars. Record wrestler poses in a ring buffer for this; do not re-simulate. Skippable with a click or Enter.
6. **Round result:** the winning move in big brush-style lettering (for example "YORIKIRI!") with its English meaning below, a round-win dot fills under the winner's name, then the next round banner.
7. **Winner screen:** after the deciding round, confetti-like paper streamers (purple banner tassels and the winner's colour) fall, the winner does a happy jelly bounce under a spotlight, the loser sits up dizzy and claps, and a big "**CLAUDE WINS**" / "**CHATGPT WINS**" card shows the round score and the moves. A **Rematch** button sits under it.

## Actions

A tool picker for **Poke**, **Shove** and **Fling**. Dragging the empty background orbits within limits. The default tool is Poke.

- **Poke:** a tap dents a wrestler's jelly, which wobbles out from the contact point. It doesn't change the round much.
- **Shove:** dragging on a wrestler pushes it in the drag direction with a strong but limited force.
- **Fling:** grab a wrestler and throw it; it ragdolls, tumbles and bounces with squash and stretch, then gets up.
- Any Shove or Fling during a round marks it **"Assisted"** in the history, and assisted rounds never count in the scoreboard.
- Use pointer events with **pointer capture** so drags never drop, and support mouse, pen and touch (including a second finger on mobile without breaking the first drag).

### Rematch and Sim 100
- **Rematch** starts a new match (skipping the title splash) with the next seed.
- **Sim 100** runs 100 full matches in a row **headless and fast** (no rendering, no show, same physics and timestep, a progress bar), starting from the seed shown, then shows the tally: Claude match wins, ChatGPT match wins, rounds won by each, draws, and the most common winning move. The UI stays responsive while it runs (do the work in chunks) and it can be cancelled.
- Sim 100 also remembers the **best bout**: the closest, most dramatic match (it went to 3 rounds, with the most lead changes in balance and the longest final round). A **Watch best bout** button then plays that seed with the full show, so the most exciting match is always one click away.
- Show the tally as a clean result card worth screenshotting: both marks, both match-win counts in huge numbers with a split bar in the two colours, rounds and draws below, the starting seed, and "100 matches · same body · same brain".

## Sound

Every action has a **synthesised sound effect**, generated live with the **Web Audio API** (oscillators, filtered noise, envelopes, a short procedural reverb for the arena). **No audio files, no samples, no speech synthesis, no external requests.**

- **Title splash:** a heavy taiko hit and a whoosh.
- **Entrance:** a building taiko rhythm, the salt as a soft sandy hiss, the stomp as a deep jelly thud with a clay crunch.
- **Charge and clash:** a single big drum hit on the charge, then a huge wet "BLOOMP" when the bellies meet, with a low sub thump on the hit-stop.
- **Slap:** a short wet smack, pitched by speed. **Feet sliding:** a gritty scrape that follows slide speed.
- **Fall:** the slow motion pitches all audio down and muffles it (a low-pass sweep), then the landing comes back at full speed as a heavy jelly flop with a dust burst.
- **Crowd:** a soft synthesised crowd bed (filtered noise with slow swells) that rises with the action, gasps on near-falls and roars on a win.
- **Round result / winner:** wooden clappers (hyoshigi) and a big drum roll into a final hit; the winner's bounce boings.
- **Poke / Shove / Fling:** a jelly blup, a squash and a cartoon whoosh.
- Small random variations so repeated sounds never feel identical.

Rules:
- Create the `AudioContext` only after the first user gesture. Resume a `suspended` context on interaction, and wrap every audio call in `try/catch` so a failure can never break the toy.
- A **mute button** with a speaker icon, **sound on by default**, and the `M` key toggles it. Master gain plus a limiter / compressor, no clipping.
- Limit simultaneous voices (about 16). Sim 100 is silent.

## Camera and keys

- **Camera:** a broadcast director. The default is a low three-quarter view from about 20° above with the ring large in frame. During a round it follows the action smoothly (never jerky), framing both wrestlers; it cuts or swings only at the beats listed in The show. The user can still drag the empty background to orbit, wheel or pinch to zoom, and double-click to reset; the director takes over again a few seconds after the user lets go.
- **Keyboard:** `1` Poke, `2` Shove, `3` Fling, `Enter` rematch or skip replay, `S` Sim 100, `B` watch best bout, `C` cinema mode, `M` mute, Space pauses or resumes, R resets.

## Rendering (WebGPU and WGSL)

Aim for the polish of a premium animated short: glossy jelly toys in a small, moody fight-night arena. Avoid both "plastic figurines" and "flat cartoon".

- **Jelly bodies:** physically based, with **subsurface scattering** (light glows through thin parts like cheeks, arms and belly edges), a glossy clearcoat with sharp highlights, Fresnel rim light, and a darker inner core faintly visible through the jelly. The ChatGPT wrestler's dark jelly still reads as jelly: deep smoky translucency, a coloured rim light and bright highlights. Bodies brighten slightly where they squash.
- **Faces and chest marks:** procedural SDF shapes in the shader, so they stretch and wobble with the skin.
- **Belts:** thick cloth with a procedural weave and a few hanging tassels that swing with motion.
- **Ring:** sandy clay with fine procedural grain and footprints / scuffs that accumulate where wrestlers slid during the match, a straw-bale edge, white starting lines, raised on sloped clay sides.
- **Arena:** a dark arena with a hanging roof canopy with purple tassels above the ring, warm spotlights cutting through soft **haze** (cheap: soft light cones and a low-resolution fog pass, never expensive ray marching), and a crowd suggested by dark tiered silhouettes, a few twinkling phone lights and soft bokeh in the background.
- **Lighting and shadows:** a strong warm key spotlight from above, a cool rim light, soft shadow maps (filtered, no shimmering) and ambient occlusion where bodies touch each other and the clay.
- **Post-processing:** HDR rendering with filmic tone mapping, **bloom** on highlights and lights, **depth of field** that focuses on the wrestlers (stronger in slow motion and replays), a light vignette, subtle film grain, and a little **motion blur** on fast moves and falls. Keep it tasteful: the image must stay crisp and readable.
- **Effects** (all preallocated particle pools): dust bursts and shockwave rings on clashes and landings, salt arcs, sweat-like jelly droplets flicking off on hard slaps, sliding dust trails, paper streamers on the winner screen.
- Build pipelines once at start-up and preallocate buffers for every cap. Never create shaders, pipelines or geometry during interaction. Handle resize and device-pixel ratio (cap at 2).
- Include an automatic **quality scaler**: if the frame rate drops, reduce effect resolution (bloom, DOF, haze) and particle counts before ever touching physics or the base image.
- If WebGPU is not available, show a clear, well-designed message explaining that the piece needs a WebGPU browser (for example recent Chrome, Edge or Safari) and why. Do not fall back to WebGL or fake it.

## Interface

Two layers: a bold **fight-game HUD** over the ring, and a calm **control card** at the side. The ring is the hero, and UI must never cover the fight on desktop or mobile (on narrow screens, controls collapse into a compact bottom sheet).

**HUD (top, full width):** fighting-game style but clean.
- On each side: the wrestler's mark, its name in bold condensed capitals, a long chunky **balance bar** (in the wrestler's colour, angled ends, a flash and shake when it drops sharply, a trailing "damage" segment that catches up a moment later) and a thinner **stamina bar** under it.
- Round-win dots under each name (best of 3).
- In the centre: the round number, the round timer, and the current seed in small type.
- Big banners ("ROUND 1", "YORIKIRI!", "CLAUDE WINS") appear centred with a squash-and-stretch pop, a short shine sweep and a drum hit, then clear.

**Top left (small):** `POKEABLE · SPECIMEN 005`. **Top right (small):** a live status dot with `WEBGPU · LIVE`, a **speaker icon button** (with `ON` / `MUTED`), and `PAUSED` when paused or `WEBGPU UNAVAILABLE` on fallback.

**Right panel: control card "Ring"**

Style it as a **floating control card**: a rounded card (about 20px corners) in a solid dark charcoal slightly lighter than the arena (no transparency), with a soft drop shadow and no hairline borders, about 240px wide, in the plain system sans-serif font. A bold sentence-case card title, bold sentence-case section labels, tools as rounded pills or tiles (the active tool tinted and ringed), chunky sliders (a 6px rounded track and a round thumb), live values in small rounded monospace chips, secondary buttons as rounded chips without borders, toggles as on/off switches (label on the left, switch on the right), and **Pause / Resume** as a solid full-width pill. The card can be collapsed to a small button so the fight fills the screen. On narrow screens it becomes the bottom sheet with rounded top corners.

- The tool picker: **Poke**, **Shove**, **Fling**, each with a small drawn icon and its key number.
- **Seed** field with its value and a dice button for a random seed.
- **Wobble** slider (jelly softness, applied equally to both) with its live value.
- **Ring size** slider (applied to both) with its live value.
- **Sound** slider (master volume) with its live value.
- Buttons: **Rematch**, **Sim 100**, **Reset score**, **Mute**.
- Switches: **Show** (title, entrance, slow-motion falls and replays; on by default; off goes straight to the fights), **Auto rematch** (on by default: a new match starts 3 s after the winner screen), **Slow motion** (¼ speed) **X-ray** (skeleton, joints, centre of mass, support area and contact points as lines and dots) and **Cinema** (`C`: hides the card, hint, scoreboard, small labels and cursor, keeping only the HUD and banners, for clean screen recordings; a tap or `C` brings everything back).
- A **Pause / Resume** button.

**Bottom left:** a one-line hint that changes with the tool:
- Poke: "Tap a wrestler to poke it. It won't change the round."
- Shove: "Drag a wrestler to push it. Assisted rounds don't count."
- Fling: "Grab a wrestler and throw it."

Under it, the overall **scoreboard** (Claude match wins, draws, ChatGPT match wins) and a **history** of the last 10 rounds as small coloured dots (assisted rounds hollow).

**Bottom right:** two collapsible sections: **"Fair fight"** (the side-by-side parameter table, see Fairness) and **"How it fights"** (4 to 6 plain-English lines on the skeleton and jelly, the balance controller, the shared controller, the seed and how a winner is decided).

Respect `prefers-reduced-motion`: no camera shake, gentler banners and transitions, and shorter slow motion. The physics still responds fully to the user.

## Demo mode (required)

If the URL has `?demo=1`, auto-play a 4-second loop with no user input: the object drops in, wobbles, gets poked or sliced once, then settles.

Exactly:
- **Hide all UI** (HUD, banners, panel, name tags, hint, scoreboard, cursor, replay badge and letterbox bars). Only the wrestlers, the ring and the arena are visible.
- Use one **fixed demo quality preset** (no automatic quality scaler, so every frame looks the same): full lighting, shadows, bloom, depth of field and dust; haze and crowd simplified; no motion blur or film grain.
- **Sound is completely off in demo mode:** never create an `AudioContext`, play nothing.
- A fixed camera (no follow, no orbit, no cuts; a small shake on the clash is fine), a low three-quarter view with the ring filling about 70 to 80% of a square frame and both wrestlers large and clearly visible.
- A deterministic loop that restarts every 4.0 s of real time from the identical state, always with seed `1`:
  - **0.0 to 0.4 s:** both wrestlers drop onto their starting lines already crouched, land with a squash, a dust puff and a wobble.
  - **0.4 to 0.8 s:** the charge.
  - **0.8 to 1.2 s:** the clash: a short hit-stop, bellies squash into each other, a shockwave ring of dust.
  - **1.2 to 2.0 s:** one hard shove and slap exchange; the real simulation with seed `1` decides who drives the other to the edge. Start the wrestlers close to the middle of a slightly smaller ring so this happens in time.
  - **2.0 to 3.5 s:** the loser goes over the edge in **slow motion** (the longest beat: it must read clearly) and tumbles down the ring's side in a burst of dust; the winner wobbles happily.
  - **3.5 to 4.0 s:** everything settles; the scene then cleanly restarts (a short soft fade is allowed in the last 0.2 s to hide the cut).
- The timeline may speed the bout up so it finishes in time, but **the winner is never scripted**: it must be whoever the shared controller and physics make win with seed `1`, applied equally to both wrestlers.
- Drive the simulation from real elapsed time with the fixed timestep, so the loop lasts 4 s even at low frame rates.
- The demo is recorded in a slow software renderer: **the clash and the fall must still read clearly at 15 fps**. If needed, lower effect resolution and particle counts, but never skip the clash or the fall.
- Start moving within 1 second of the page loading.

## Before you finish

Self-check against this list and fix anything that fails:
- Run Sim 100 several times with different seeds, then Watch best bout and check it really is an exciting three-rounder: the same seed always gives the same tally, the tally is the same with Show on or off, the controller never reads which mascot it is, and every parameter in "Fair fight" matches for both wrestlers.
- Watch many full matches with Show on: the title, entrance, rounds, hit-stops, slow-motion falls, replays, move names and winner screen all play at the right moments, are never stuck or doubled, and the replay matches what actually happened.
- Wins are decided correctly (out of the ring or anything but feet on the clay), the move names fit what happened, draws resolve within 25 s, and fallen wrestlers always get back up.
- Poke, shove and fling both wrestlers in every phase, including mid-fall, during replays and on the arena floor; assisted rounds are marked and not counted.
- Try every slider and toggle at both extremes, plus Rematch many times, Reset, Reset score, pause and resume, X-ray, keys 1 to 3, Enter, S, M, and resizing to phone width (the HUD stays readable).
- No explosions, no stretched limbs, no jitter at rest, nothing passes through a body or the ring.
- Sound: every action has its effect, nothing plays before the first gesture, mute and volume work, rapid actions never clip or pile up, Sim 100 is silent.
- Image: no shimmering shadows, no blown-out highlights, no muddy blur; the quality scaler keeps it smooth on a laptop.
- `?demo=1` matches the timeline above, loops cleanly, shows no UI and plays no sound.
- No console or WebGPU validation errors.

Put the spectacle of the clash and the fall first: two glossy jelly bellies slamming together, the hit-stop, and the slow-motion tumble off the ring. It should be something people watch to the end and then press Rematch.