Touch Grass

grassmeadow

OpusSol
Opus$10.10 · 1h06m00s
Claude Opus 5.5$10.10 · 1h06m00s
Claude Opus 5.5 $10.10 · 1h06m00s
Winner
Sol$0.96 · 24m00s
ChatGPT-6.1 Sol$0.96 · 24m00s
ChatGPT-6.1 Sol $0.96 · 24m00s
CheapestFastest

Opus wins. Opus paints the meadow the prompt asked for: a low golden-hour sun, backlit blades of every height and a hand wake you can see at a glance; Sol built a working field for a tenth of the price in a third of the time, but its hazy, flat light and far-off view make it read like a lawn.

Remix in Claude

Scorecard

Opus3Sol0

CriterionOpusSol
Golden-hour lightWarm low sun, blades glow where it shines through them, tree silhouettes on the horizon.Grey-green haze and a pale sun: correct, but flat.
The fieldTall seed heads, short tufts and sun-bleached tips mixed in patches.Dense and even, closer to a mown lawn than a meadow.
Demo: hand wake and gustThe S-curve wake and the gust read clearly, even small.The wake is hard to spot at card size.
Cost$10.10$0.96
Time1h06m00s24m00s
OverallWinner–

The prompt

Build **"Touch Grass"**: a real-time, interactive 3D meadow of **tens of thousands of grass blades** that people **brush through with their hand**, **mow**, **plant flowers in**, **blow** and **set on fire**, alive with wind, light, critters and **synthesised sound**, rendered with native **WebGPU** and **WGSL**.

It should feel like the calmest, most satisfying thing on the internet: you move your hand and the grass answers. No score, no levels, no tutorial screens. The only goal is a hidden one (see Easter egg).

## Priorities

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:** the dense field, the hand brushing the blades (bend away, spring back with a little wobble), the wind waves and the golden-hour light; the demo mode.
2. **Must work:** the five tools (Hand, Mower, Seeds, Blower, Fire) with regrowth, the critters, day / night, sound, the control card, the Easter egg.
3. **Polish:** dandelion seeds, the hidden cat, fireflies following the hand, depth of field, pollen motes.

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 static render or a 2D fake.

## The meadow

- A gently rolling meadow on a small hill under a wide sky, seen from a low three-quarter view, as if you are kneeling at the edge of it. The field fills most of a square frame, with a soft horizon, a few distant trees as silhouettes and light haze.
- **Grass:** about **60,000 to 150,000 blades** on desktop (scale down automatically on phones and slow GPUs, never below about 20,000). Each blade is a tapered, slightly curved strip with its own height, width, lean, stiffness and colour, from fresh green to sun-bleached yellow, with darker roots and brighter tips. Mix in some taller seed-head grasses and clover so it doesn't look like a lawn carpet.
- Density and height vary in natural patches; the field never shows a visible grid or tiling.
- A few wildflowers and **dandelions** already grow in the field.

## Physics

- Every blade is simulated, not just shader-swayed: a **spring per blade** (bend direction, bend amount and velocity, stored in GPU buffers and updated in a compute shader) pulled back towards upright by its stiffness, with damping, so blades **overshoot and wobble** a little when released.
- **The hand:** the pointer projects onto the ground as a soft round hand of influence. Blades inside it bend **away from the hand and along its direction of motion**, harder when the hand moves faster, then spring back after it passes, leaving a fading trail you can see for a second. A slow pass parts the grass like running fingers through it; a fast swipe makes a wave.
- **Wind:** constant gentle sway plus **gusts that roll across the field as visible waves** (bright sheen bands where blades bend and catch the light), from a slowly changing direction. Wind and hand forces add together.
- Blades never pass through the ground, never stretch, and never jitter at rest.
- **Fixed simulation timestep** with bounded substeps, decoupled from frame rate. On a slow frame, drop simulation time rather than exploding.

## Tools

A tool picker with **Hand**, **Mower**, **Seeds**, **Blower** and **Fire**. Dragging the empty sky orbits within limits. The default tool is Hand.

### Hand
- As described in Physics. A tap pats the grass down in a small circle that springs back up.

### Mower
- Dragging pushes a small mower across the field that **cuts the grass short** in a clean stripe, throwing up a little spray of clippings. Cut stripes have the classic light / dark lawn sheen depending on direction.
- **You can write in the grass**: cutting is precise enough to draw letters and shapes.
- Cut grass **slowly grows back** over about 20 to 30 seconds (faster with the Regrowth slider), so the canvas always resets itself.

### Seeds
- Tapping plants a flower: it **sprouts, grows and blooms** in about a second (a few procedural varieties: daisies, poppies, cornflowers, buttercups), and sways with the grass. Holding scatters several. Cap at about 300 flowers, removing the oldest gracefully.
- A butterfly sometimes lands on a new flower.

### Blower
- Holding blows a strong stream of air from the hand: a **shockwave** pushes the blades flat in a cone that ripples outward, lifts loose clippings and dandelion seeds, and sends nearby butterflies tumbling away. Releasing lets everything spring back with a big, satisfying wave.

### Fire
- Tapping lights a small fire: it **spreads outward in a ragged ring** through the grass, with flickering flames, glowing embers, rising smoke and a black ash scar behind it. Mowed stripes and flowers act as natural firebreaks or fuel (cut grass burns slowly, tall grass fast).
- The fire **burns out by itself** within a few seconds and never takes the whole field. Then fresh green shoots sprout through the ash and the meadow regrows in about 20 to 30 seconds.
- Cap the number of fires burning at once (about 5).

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).

## Life

- **Grasshoppers** hidden in the grass leap away in arcs when the hand or mower comes near, then land and disappear again.
- **Butterflies** (a handful) flutter over the field, rest on flowers, and scatter from the Blower.
- **Dandelions:** poking one makes its seed head burst into parachute seeds that drift away on the current wind, then the stem slowly grows a new puff.
- **A sleepy cat** is hidden somewhere in the tall grass (only its ears and a tail tip show). Brushing near it makes it lift its head, blink slowly and stretch; brushing it again makes it roll over. It never runs away.
- **Pollen motes** float in the sunlight, swirling around the hand.

## Day and night

- A **Time of day** slider runs from dawn through golden hour (the default) to night.
- At night the sky deepens with **stars**, the grass turns silvery blue in moonlight, and **fireflies** rise from the grass, blink, and drift lazily **towards the hand**, gathering around it when it stays still.

## Easter egg

- If the hand stays **resting in the grass** (pointer down on the field, or hovering over it, barely moving) for **10 seconds**, birdsong swells, the light warms, and a small badge gently appears: **"✓ Grass touched. You may return to the internet."** with a short soft chime. It stays a few seconds, then fades. Never hint at it in the UI.

## Sound

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

- **Brushing:** a soft, airy rustle (band-passed noise) that follows the hand's speed and how much grass it is moving; silent when the hand is still.
- **Wind gusts:** a low whoosh that swells as each gust wave passes.
- **Mower:** a gentle buzzing hum (not harsh) with a soft chopping texture while cutting.
- **Seeds:** a small pop and a soft rising "bloom" tone as each flower opens, pitched slightly differently each time.
- **Blower:** a breathy rush that swells while held.
- **Fire:** crackles and a low roar that grows and fades with the flames.
- **Life:** quick clicks for grasshoppers, a soft purr from the cat, a faint shimmer for fireflies.
- **Ambience:** distant birdsong by day, crickets at night, both very quiet.
- **Easter egg:** a short, warm, gentle chime.

Rules:
- Create the `AudioContext` only after the first user gesture (browsers block it before that). Handle a `suspended` context by resuming it 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. A master gain, a limiter / compressor and no clipping.
- Limit simultaneous voices (about 12) so rapid actions never turn into noise or glitch.

## Camera and keys

- **Camera:** dragging the empty sky orbits within limits; the wheel or a pinch zooms within limits (from the default kneeling view down to a close-up at blade level); double-clicking the sky resets the view.
- **Keyboard:** `1` Hand, `2` Mower, `3` Seeds, `4` Blower, `5` Fire, `N` toggles night / day, `C` Cinema, `M` mute, Space pauses or resumes, R resets the meadow.

## Rendering (WebGPU and WGSL)

Aim for the look of a sunny nature film at golden hour, not a video-game lawn.

- **Instanced blades** drawn from GPU buffers, bent by the simulation in the vertex shader, with smooth curved normals so blades shade like real leaves.
- **Translucency:** blades glow warm yellow-green when the sun is behind them (strong backlit subsurface), with a soft specular sheen along their length and darker self-shadowed bases (ambient occlusion towards the ground).
- **Sky and light:** a procedural sky gradient with a low warm sun, soft atmospheric haze towards the horizon, long soft shadows from the trees and flowers, and a gentle sun glow.
- **Fire:** emissive flames and embers that light the nearby grass, smoke that drifts with the wind, and an ash texture that regrows to green.
- **Post-processing:** HDR with filmic tone mapping, light bloom on the sun, flowers, fireflies and fire, a subtle **depth of field** when zoomed in close, and a light vignette. Keep the image crisp.
- Level of detail: fewer, wider blades in the distance so the far field stays dense without the cost.
- Build pipelines once at start-up and preallocate buffers for every cap (blades, flowers, particles, critters). 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 blade count, shadow and post-effect resolution before ever touching the physics feel.
- 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

A calm, light interface that stays out of the way. The meadow is the hero, and UI must never cover it on desktop or mobile (on narrow screens, controls collapse into a compact bottom sheet).

**Top left**
- Small caps: `POKEABLE · SPECIMEN 006`
- A large italic serif heading on two lines: *Touch* / *Grass.*
- Caption lines: "Go on." / "Nobody's watching." / "It grows back."

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

**Right panel: control card "Meadow"**

Style it as a **floating control card**: a rounded card (about 20px corners) in a soft off-white, 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 in a fresh green accent), chunky sliders (a 6px rounded track filled with the accent up to the value and a round white thumb), live values in small rounded monospace chips, secondary buttons as rounded light-grey chips without borders, toggles as on/off switches (label on the left, switch on the right), and **Pause / Resume** as a solid dark full-width pill. The card can be collapsed to a small button. On narrow screens it becomes the bottom sheet with rounded top corners.

- The tool picker: **Hand**, **Mower**, **Seeds**, **Blower**, **Fire**, each with a small drawn icon and its key number.
- **Wind** slider (calm to stormy) with its live value.
- **Time of day** slider (dawn, golden hour, night) with its live value.
- **Grass height** slider with its live value.
- **Regrowth** slider (how fast cut and burnt grass grows back) with its live value.
- **Sound** slider (master volume) with its live value.
- Buttons: **Reset meadow**, **Mute**.
- Switches: **Critters** (on by default), **Slow motion** (¼ speed) and **Cinema** (`C`: hides every piece of UI and the cursor 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:
- Hand: "Run your hand through the grass."
- Mower: "Drag to mow. Try writing your name."
- Seeds: "Tap to plant a flower. Hold to scatter."
- Blower: "Hold to blow. Let go for the wave."
- Fire: "Tap to light it. It always grows back."

Under it, live readouts computed from the simulation: **blades**, **flowers**, **grass cut** (% of the field) and **wind** (km/h, illustrative). Values update smoothly, not every frame.

**Bottom right:** a collapsible **"How it grows"** section, 4 to 6 plain-English lines explaining the per-blade springs, how the hand and wind push them, how mowing and regrowth work, how the fire spreads, and how the sounds are synthesised.

Respect `prefers-reduced-motion`: soften UI transitions and calm the default wind. The grass 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.

For this toy that means:
- **Hide all UI** (text, panel, status, hint, readouts, cursor). Only the meadow, sky and critters are visible. Show an invisible hand: only its effect on the grass is visible.
- Use one **fixed demo quality preset** (no automatic quality scaler, so every frame looks the same), golden hour, no fire.
- **Sound is completely off in demo mode:** never create an `AudioContext`, play nothing.
- A fixed camera at the default kneeling view, the field filling the square frame.
- A deterministic loop that restarts every 4.0 s of real time from the identical state:
  - **0.0 to 0.6 s:** the meadow at rest, swaying gently; a little pollen in the light.
  - **0.6 to 2.0 s:** the hand sweeps in a smooth S-curve through the middle of the field, parting the grass in a clear visible wake.
  - **1.4 s:** a grasshopper leaps out of the hand's path in a high arc and lands.
  - **2.0 to 3.0 s:** a wind gust rolls across the field as a bright wave from left to right; a butterfly lifts off a flower.
  - **3.0 to 4.0 s:** everything springs back and settles to the same gentle sway as at 0.0 s, so the loop restarts cleanly.
- Use no randomness in demo mode (fixed seed for the field). 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 wake and the gust must still read clearly at 15 fps**. If needed, use fewer blades in demo mode (but keep the field looking dense).
- Start moving within 1 second of the page loading.

More toys

All toys →