# One Pigeon — the prompt Create a single self-contained HTML file called "One Pigeon". Vanilla JavaScript, Canvas 2D, optional Web Audio. No libraries, fonts, images or network requests. Everything is drawn in code. ## THE JOKE A window ledge. One pigeon lands. Every tap drops a crumb. Crumbs bring more pigeons. It never stops. An absurd premise executed with total seriousness: the birds must move like real pigeons. ## RENDERING - One canvas. devicePixelRatio capped at 2. A 1600×1000 design space, letterboxed to 16:10 on desktop and landscape. On a phone held upright it fills the whole screen: the sky continues above, the concrete continues below, and the camera frames a narrower column that pans gently to follow the action. - Premium flat illustration, like a printed editorial cover. Wes Anderson framing: a symmetric street of a pastel pink hotel with a clock, mint houses with shutters, pale rooftops with water towers and antennas from a seeded PRNG, a cream window frame, crisp flat shadows. A limited palette (about 20 colours) and a subtle procedural print grain baked once into an offscreen canvas. No neon, no emoji, no clip-art look. - Background layers painted once to offscreen canvases (again on resize). They shift with the pointer for parallax. - The ledge is the foreground: a deep concrete ledge seen slightly from above, with 4 depth rows (17, 13, 11 and 9 spots). Birds grow toward the viewer. A front-row pigeon is about 160 design units long. Birds in different rows may overlap (it reads as a crowd). Birds in the same row never do. - A camera tied to the crowd: with 1 bird it is zoomed 2.2× and framed on the first pigeon. As birds arrive it pulls back with a critically damped spring to 1.0× at 25 birds, revealing the power line, the sign and the hotel. Far layers zoom less than near ones. Birds, crumbs and the ledge are vectors drawn after the camera transform, so they stay crisp. - A power line sags across the sky. It is a second perch. - Pigeon anatomy: small round head, plump teardrop body, grey-blue plumage, rows of scalloped covert feathers, two dark wing bars, darker primary tips, soft back-to-belly shading, an iridescent green-and-purple neck that shifts with the head angle, an orange ringed eye with a catch-light, blinks, head tilts, white cere on a dark beak, coral-pink feet with toes, dark tail band. Heads can turn to face the camera (both eyes showing). From the front a pigeon is pear-shaped: a round, puffed chest with a soft highlight, folded wings hugging both sides with the tips of the bars showing, iridescent patches on the sides of the neck (never a band across the throat), eyes on the sides of a small head, three splayed toes. Staring birds tilt and bob their heads now and then. Morphs: blue-bar, checker, white, and a rare dark one. Fine details are skipped when a bird is small on screen. - Build each morph's parts once (Path2D in local space, cached fills) and draw each bird with transforms. Depth-sort by y. - The only text: a monospace counter top-left, `PIGEONS 01`; a small "tap to feed" hint that fades after the first tap; a small "prompt ↗" link bottom-right to `./prompt.md`. ## SCENE AND ESCALATION - t = 0: an empty ledge. 0.8 s of quiet. - The first pigeon glides in from the right, flares big in frame, lands with two hops, walks to its spot, bobs, and turns one eye to the camera. - Every crumb that lands raises "attractiveness", every crumb eaten raises it again, and crumbs left lying keep raising it. Each arrival spends it. Arrivals come faster as the crowd grows. Target pacing for one tap per second: bird #2 within about 4 s, 30 birds in about 40 s, 60 in about 90 s, 120 in about 3 minutes. Bread gets there faster. Maximum 120 (60 on phones), decided once at load. Perches: the ledge rows, the power line, the sign, cornices and rooftops across the street, then circling in the sky. - Milestones. Each one must read with the sound off: - 10: pigeons start landing on the power line. The line sags and bounces under each landing. - 30: a "NO FEEDING" sign slides in on the right. Pigeons land on it. - 45: one pigeon hops onto the outer sill, the closest spot to the camera, faces the viewer and taps the glass with its beak. Ripples cross the glass, a breath smudge stays, the view shakes 2 units and the camera pushes in. It is the funniest frame of the piece. - 60: a pigeon lands on the counter and hides the number. After 3 s it shuffles onto the top of the digits. Tap it and it flies off, then comes back on top of the digits. - 120: every pigeon turns its head to the camera at the same moment. Hold 2 s. Then one coos. - Swipe to scatter: every bird within 300 units bursts into flight, loops off-screen and comes back, plus one extra. ## SIMULATION - Fixed timestep of 1/120 s with an accumulator, at most 8 steps per frame, render interpolated. - Structure-of-arrays typed pools preallocated at the maximum size (x, y, vx, vy, facing, state, timer, slot, morph, phase…). Crumbs in a 200-slot ring buffer. Zero allocation in update and draw: no object or array literals, closures, push or string building. Cache the counter strings. - States: ARRIVE (Bézier flight path, wings flapping at 9 Hz and slowing into a landing flare, feet down last), IDLE (head turns every 2–6 s, preening, a feather ruffle), WALK, PECK (crumb within reach: 3 pecks at 140 ms, the crumb shrinks bite by bite), SCARED (burst of flight, loop off-screen, return), ROOST (after 40 s idle: puffs up 12%, eyes closed). - The head bob is the signature. While walking, the head stays locked in world space during the "hold" phase (65% of the cycle) while the body moves under it, then thrusts forward to catch up during the "thrust" phase. Feet stay planted during stance: no foot sliding. - A bird reserves a free spot before walking to it. Neighbours never stand tail to tail. - Crumbs are projectiles: gravity, bounce (restitution 0.3), rolling friction, then they settle on the ledge. ## INTERACTION - Pointer events only, `touch-action: none`, no page scroll. - Tap: drop a crumb from the pointer. Long-press 400 ms: a slice of bread that sheds a crumb every 100 ms. - Fast swipe (over 1.2 units/ms, after at least 10 CSS px of travel): scatter. - The power line is a slingshot. Near it the cursor becomes a drawn open hand; press to grab (the hand closes), drag to pull the line down while the perched pigeons slide toward the low point, flapping for balance; release and the line snaps back and flings them into the air. They tumble, catch the air, then land again. A grab never drops a crumb. On touch the hand appears on touch-down, with a wider grab zone. - R restarts the current mode. M turns the sound on (first press), then toggles it. - Sound, only after a gesture (pointerup or touchend on phones, so iOS unlocks it), all synthesised: coos (filtered noise plus two sine partials with a slow wobble), wing claps on take-off, a small glass tap. - URL options for recording: `?pigeons=N` starts with N settled birds, the camera already at its target. `?tour` plays a scripted 35 s sequence with a visible hand cursor: the landing close-up, the first crumb at 3 s, the crowd growing while the camera pulls back, the glass tap at about 13 s, the hand pulling the power line at 16 s and flinging the pigeons at 17.6 s, a scatter at 19.6 s, the return, then 61 pigeons all staring at 28 s and one coo. "PIGEONS 61" is readable at the end. `?t=S` fast-forwards S seconds and `?still` then freezes the simulation, for deterministic captures. - Open Graph and Twitter card tags in the head, pointing to a 16:10 poster. ## QUALITY BAR - 60 fps with 120 birds on an M1 MacBook, at least 55 fps with 60 birds on an iPhone 13. No memory growth over 10 minutes. Resize-safe. No console errors. - Pigeons never slide with their feet planted and their heads never clip through their bodies. Every landing shows a flare frame. - The muted test: a stranger watching 30 s with no sound understands "feeding = more pigeons" and smiles by second 5. If not, redo the landing.