2 cases built from this template
Same prompt, different [VARIABLES]. Click one to preview it above.About this template
Neon Snake 3D Game is a single-page browser game. The first screen is a dark 16 by 16 grid, with a four-part sea-glass snake already posed and one copper bead ahead of it. A frosted card sits left of that view on a desk, and along the bottom on a phone, leaving the grid visible. Every segment glides from cell to cell together. The camera stays south of the head, so arrow keys stay tied to the screen.
The default game is Lumen Coil, a cabinet from Northglass Hall at 18 Marrow Lane in invented Port Elling. Players collect ion beads on the Relay Floor. Each bead adds a segment and scores 10 times the current speed step, and the step climbs from 1 to 5 as the line grows. The HUD shows score, length, step, and the floor rule. Wrap brings the snake back on the far side of an open edge. Walls draws a low rail, and touching it ends the run, as does crossing the line. Each rule keeps a best score and five sets of initials in the browser.
The bead swells on a loop at 96 beats per minute, synthesized in Web Audio. Arrow keys and WASD steer at a desk. A phone uses a swipe and a four-button pad. Pause and game over are their own cards. Reduced motion holds the bead steady, stops the title camera's small drift, and slows the follow.
Developers and indie hackers can ship it as static files and rename it from one content file. Six variables cover the game, the hall, the pickup, the floor, the cabinet line, and the opening sentence. Grid size, colors, speeds, and controls stay fixed. Fern Current, a night conservatory from Glasshouse After Hours, is the second set of names.
The template prompt
The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].
# Neon Snake 3D Game
Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.
## Brief
Build [BRAND], a complete single-page 3D snake game on a dark 16 by 16 grid called [ARENA]. A four-segment glowing capsule line and one pulsing bead are already in view behind a frosted start card. The line glides from cell to cell, the camera follows from the south, and the bead pulses with a short loop synthesized in Web Audio. Two floor rules, Wrap and Walls, speed steps 1 to 5, and local bests are part of the game. [STUDIO] presents it. Opening sentence: [TAGLINE].
- Audience: Indie hackers and front-end developers who want a finished static Three.js game with keyboard, swipe, and on-screen controls, readable on a desk and a phone.
- Goal: Ship one replayable run: a start card over a living grid, immediate play, growing speed, wrap or rail rules, pause, game over with initials, and bests stored in the browser. A second set of names must keep the same grid, snake, colors, and rules.
- Tone: Calm, precise, and a little playful. Short US English. Talk about the line, the floor, and the bead. No military ranks, no hype, and no cyber slang.
## Stack
- Framework: Vite 6 + TypeScript 5
- Styling: Vanilla CSS
- Libraries: three (MIT), lucide (ISC), @fontsource/syne (OFL), @fontsource-variable/outfit (OFL), @fontsource/ibm-plex-mono (OFL)
- Build: `npm run build` → static files in `dist/`. No backend, no server code, no external APIs.
- Setup:
- Scaffold Vite's vanilla TypeScript template. Scripts: dev=vite, build=tsc && vite build, preview=vite preview. Package name is the slug of BRAND, not a fixed template id. Set vite base to './', build.outDir to dist, build.emptyOutDir to true, and build.sourcemap to false. tsconfig: strict true, noEmit true.
- Install only three, lucide, @fontsource/syne, @fontsource-variable/outfit, and @fontsource/ibm-plex-mono as runtime dependencies, plus Vite and TypeScript as dev dependencies. Do not add React, a physics engine, a game framework, postprocessing, a tween library, or an audio decoder.
- Import Syne 700 and 800 from @fontsource/syne, Outfit variable weights from @fontsource-variable/outfit/wght.css, and IBM Plex Mono 500 from @fontsource/ibm-plex-mono. Copy only the Lucide Pause, Volume2, and VolumeX icon nodes into src/icons.ts and render them with lucide createElement at 18px, currentColor, aria-hidden. Wait up to 800ms for document.fonts.ready, then show the card even if fonts are still swapping.
- Use modules src/content.ts, main.ts, game.ts, scene.ts, audio.ts, ui.ts, and styles.css. Keep every proper name, button label, hint, and sentence in content.ts. Grid size, speeds, coordinates, and colors are named constants in game.ts and scene.ts.
- World axes: +x east (screen right), +y up, +z south (toward the camera, screen down). North is decreasing iz and points up the screen during play. Cell (ix, iz) center is ((ix - 7.5) * 1.2, 0, (iz - 7.5) * 1.2) with ix and iz from 0 to 15. Playable lip is x and z of ±9.6. Wrap period is 19.2.
- Use BRAND, STUDIO, PICKUP, ARENA, PLACE, and TAGLINE for all player-facing names. Sentence patterns: Collect ${PICKUP} on the ${ARENA}. The ${ARENA} is holding. Document title is BRAND, an em dash, and ARENA. When values differ from the defaults, rewrite TAGLINE so it does not name the old floor or the old pickup. Never show raw bracket placeholders. The capsule line stays a snake even if TAGLINE uses a metaphor.
- Persist scores under the key slug(BRAND) + '-runs' and mute under slug(BRAND) + '-muted'. slug lowercases and turns every non-alphanumeric run into one hyphen, then trims hyphens. Lumen Coil becomes lumen-coil-runs. Wrap localStorage in try/catch and keep playing if it throws. No calendar dates.
- One index.html, lang=en, viewport with viewport-fit=cover, a full-view canvas, and HTML overlays. Body margin 0, overflow hidden, background #07080A, height 100dvh. Touch-action none on the canvas. No router and no second page.
- Read prefers-reduced-motion on load and on change. Reduced motion holds the bead at scale 1 and halo opacity 0.32, freezes the title drift and the grid breathe, sets follow smoothing to the slower taus, and skips the score pop and the death color flash. Audio may still play.
- Cap device pixel ratio at 1.75, and at 1.25 below 800px. Antialiasing on, shadows off, alpha false. If the rolling frame time stays above 28ms for three seconds after the first two seconds of play, lower the cap by 0.25 once and not below 1. Do not change speeds when you do that.
## Variables
- [BRAND] — Game name (default: "Lumen Coil"). Invented name on the start heading, the top bar, the document title, and the save-key slug.
- [STUDIO] — Hall name (default: "Northglass Hall"). Invented hall or house. Shown as the eyebrow above the game name.
- [PICKUP] — Pickup (default: "ion beads"). Lowercase plural noun for what the line collects.
- [ARENA] — Floor name (default: "Relay Floor"). Invented name of the grid. Used in the collect sentence, the pause line, and the document title.
- [PLACE] — Cabinet line (default: "Cabinet 4, 18 Marrow Lane, Port Elling, 6pm–1am"). One short line: which cabinet or house, an invented street address, and hours.
- [TAGLINE] — Opening sentence (default: "Steer the sea-glass line across the Relay Floor."). One sentence under the game name. Rewrite it when the floor or the pickup changes. The 3D line stays capsules.
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/neon-snake-3d-game in the footer (default: yes; delete this line to remove it)
The copy under Pages & Sections is written for the default values. If your values differ, rewrite every headline, paragraph, label and image for them — same length, tone and structure. Layout, colors, type and motion stay as described.
Keep all copy, image paths and links in one content file (for example `src/content.ts`), keyed by section, so the content can be swapped later without touching components.
## Design
### Colors
- Void `#07080A` — Page background, renderer clear color, fog, and the overlay scrim base
- Floor `#07100F` — Grid shader background
- Grid `#1E4A42` — Idle grid lines
- Hot line `#8CFFE0` — Grid lines near the head
- Sea glass `#2EE6A6` — Snake body emissive, primary button, focus ring, Wrap chip border, filled speed pips
- Head `#E9FFF8` — Head emissive, game name, and start heading
- Copper `#FF8A3D` — Bead emissive, bead halo, and the food pool on the floor
- Cream `#FFE6D0` — Bead core diffuse color
- Ink `#071410` — Text on the primary button
- Mist `#D5E8E2` — Body copy, HUD values, and ghost-button text
- Mute `#8AA39A` — Eyebrow, hints, place line, and the credit link
- Rail pink `#FF5D73` — Walls rail emissive, Walls chip border, and the brief death tint on the head
- Card `#0C1414` — Frosted cards at 82% opacity
- Stroke `#234840` — Card borders, idle chips, and unselected radios
- Pip `#1A3330` — Empty speed pips
- Hover `#76F6C4` — Primary button hover
### Typography
- Game name and start heading: Syne (OFL), weights 700/800
- UI, buttons, hints, and body: Outfit Variable (OFL), weights 400/500/600
- Scores, length, and step: IBM Plex Mono (OFL), weights 500
### Layout & motion
- Spacing: Use a 4px base. Desktop card padding 28px, inset 36px from the left. Mobile card inset 12px plus safe-area insets. HUD chip gap 8px, top-bar padding 12px 16px. Buttons are at least 44px tall. The pad keys are 64px. The center of the play view stays clear of the pad.
- Radius: Cards 20px, buttons 12px, radios 12px, HUD chips fully round, pad keys 14px. The snake and the bead are round capsules and spheres. The rail is a sharp low box.
- Motion: Simulation uses the frame delta capped at 0.05 seconds, with at most 3 cell crossings processed per frame. Render after the step.
- Motion: All capsules share one offset from 0 to 1 and glide together between cell centers. The play camera never yaws. Its position eases toward a southern offset with tau 0.28 seconds, or 0.62 when reduced motion is on.
- Motion: The bead swells on each quarter note at 96 beats per minute: scale 1 to 1.2 in 0.09 seconds, back to 1 by 0.32 seconds. Reduced motion holds scale 1 and halo opacity 0.32.
- Motion: Title camera drifts by a sine of 0.08 radians over about 28 seconds and stops when the run starts. Buttons darken or lighten on hover. A pressed control scales to 0.98 in 80ms unless reduced motion is on.
- Motion: Pause freezes the offset, the beat phase, and the title drift. The hidden tab pauses the same way and does not resume until Resume.
- Imagery: Draw the floor, the line, the bead, and the rail from Three.js primitives and one grid shader. No photographs, generated bitmaps, textures, HDRIs, or downloaded models. The first screen is that 3D floor beside or above a frosted card, never type on a flat field. The head has no face. No people and no portraits.
## Pages & Sections
### Lumen Coil — Relay Floor (`index.html`)
1. **Start card over the glowing floor** — Document title: Lumen Coil — Relay Floor, from BRAND and ARENA. Eyebrow, uppercase with 0.12em tracking: Northglass Hall. Heading: Lumen Coil. Deck, from TAGLINE: Steer the sea-glass line across the Relay Floor. Collect sentence: Collect ion beads on the Relay Floor. Always-visible rule line, with the noun taken from PICKUP: Each of the ion beads scores 10 times the current step. Primary button: Start run. Disclosure button: How to steer. Inside it, three lines: Arrows or W A S D point up, left, down, and right on the screen. You cannot turn back on yourself. On a phone, swipe the floor or use the pad. P or Esc pauses. And the rates: Steps run at 3.4, 4.4, 5.5, 6.6, and 7.8 cells a second. Floor rule radios, default Wrap: Wrap, with hint Leave an edge and return on the far side. Walls, with hint A low rail. Touch it and the run ends. Show the hint for the selected radio only. Best wrap and Best walls show the stored number or an em dash. Under the heading Recent, list the top 3 initials for the selected rule, or the sentence No runs saved on this browser yet. Place line, from PLACE: Cabinet 4, 18 Marrow Lane, Port Elling, 6pm–1am. If [CREDIT] is present, one 12px Outfit link in Mute under that line. Focus Start run on load. Switching radios updates the rail and the recent list and does not start the run.
Layout: The canvas is already rendering the posed line and the bead before the click. Hide the HUD and the pad. Desktop at 900px and wider: a 400px card, 20px radius, 28px padding, background rgba(12,20,20,0.82), border 1px solid #234840, backdrop-filter blur(14px), placed 36px from the left and vertically centered, max-height calc(100dvh - 48px), overflow auto. It covers well under half of 1440px. Title camera position (6.2, 8.2, 10.8), lookAt (0.2, 0.25, 0.5), fov 44. At 1440×900 the whole four-capsule line and the bead must sit fully in the open area to the right of the card. If they do not, shift lookAt.x west until they do and keep the camera south of the floor. Mobile under 900px: a bottom sheet, left and right 12px, bottom 12px plus safe area, max-height 58dvh, same fill, radius 20px. Title camera (4.2, 12.4, 10.5), lookAt (4.2, 0.0, 3.6), fov 56, so the line and the bead fall in the top 42% of a 390×844 frame, above the sheet. Heading Syne 800, 44px desktop and 34px mobile, color #E9FFF8. Deck Outfit 400 16px, color #D5E8E2, line-height 1.45. Start run is full width, 48px, background #2EE6A6, text #071410, Outfit 600. Ghost controls use a #234840 border and Mist text.
Motion: While the card is up the line does not move. The bead pulses. The title camera yaws by sin(time * 0.22) * 0.08 radians around the lookAt point. Reduced motion uses the base camera with no yaw. How to steer toggles its panel and does not start the game. Start run hides the card, shows the HUD, resumes the audio context, and begins movement on that click. The camera eases from the title rig to the follow rig. Enter activates the focused button.
2. **Grid, rail, snake, and bead** — The line is four capsules, not a picture of an animal. Head cell (11, 8), then (10, 8), (9, 8), (8, 8), facing east, offset 0, so the whole line sits in the eastern half of the floor and stays clear of the left card. First bead, and the bead after every restart, is cell (14, 8). Later beads pick a random cell that is not in the body. The head has no eyes, mouth, tongue, or markings. The bead is one sphere plus a soft halo, with no rings and no orbiting pieces.
Layout: Floor: a 36 by 36 shader plane at y=0. Lines exist only inside x and z of ±9.6, on multiples of the cell edge. World distance to the nearest line feeds a 1.6px screen-width mask via fwidth. Line color mixes #1E4A42 to #8CFFE0 by smoothstep across 5.2 to 0.6 units from the head. A copper pool, smoothstep from 2.0 to 0.2 units around the bead, adds #FF8A3D at 35% strength. Outside the lip the lines fade to the floor color #07100F. A slow breathe multiplies line strength by 0.94 + 0.06 * sin(time * 1.3), frozen when reduced motion is on or the run is paused. FogExp2 color #07080A density 0.045. Ambient light #10211C intensity 0.25. A point light parented above the head, color #D7FFF3, intensity 4, distance 8, decay 2. Clear color, fog, and the page are #07080A. ACES filmic tone mapping, exposure 1.05, output color space sRGB. Head capsule: radius 0.38, cylinder length 0.28, center y 0.40, MeshStandardMaterial color #D9FFF4, emissive #E9FFF8, emissiveIntensity 2.0, roughness 0.4, metalness 0.08. Body capsules: radius 0.32, cylinder length 0.36, same y, shared material, emissive #2EE6A6, emissiveIntensity 1.5. Align each capsule's long axis with its short cell delta. Create the two geometries once. Show one mesh per segment, adding a mesh only when the line grows, up to 256. Bead core: sphere radius 0.32 at y 0.48, color #FFE6D0, emissive #FF8A3D, emissiveIntensity 1.6, roughness 0.25. Halo: sphere radius 0.58, MeshBasicMaterial #FF8A3D, opacity 0.30, depthWrite false, additive blending. Rail, visible only while Walls is selected: four boxes, height 0.16, thickness 0.12, inner face on the ±9.6 lip, centers at ±9.66. North and south boxes are 19.2 long along x. East and west boxes are 19.44 long along z so the corners meet. Material color #3A2428, emissive #FF5D73, emissiveIntensity 0.55, roughness 0.6. No posts and no towers. Hide the rail in Wrap. Favicon at public/favicon.svg: a 32 viewBox rounded square filled #07080A with one sea-glass arc, no text and no face.
Motion: On the title card the meshes sit on cell centers. The bead scale and halo follow the beat clock. The rail appears or disappears immediately when the radio changes, with no camera cut. Reduced motion skips the breathe and the swell.
3. **Stepping, growth, and the two rules** — Speed from length, including the head: step 1 at length 4 to 7 is 3.4 cells a second and 10 points; step 2 at 8 to 11 is 4.4 and 20 points; step 3 at 12 to 16 is 5.5 and 30 points; step 4 at 17 to 22 is 6.6 and 40 points; step 5 at 23 or more is 7.8 and 50 points. Points are awarded at the step in effect when the bead is taken, then length grows by one and the step is recomputed. Filling all 256 cells ends the run as a clear floor after that last score.
Layout: One shared offset advances by cellsPerSecond times dt. Every segment i glides from its origin cell toward its target: the head targets head plus direction, and each later segment targets the cell in front of it. Short delta: subtract or add 16 so each axis delta is -1, 0, or 1. World position is the origin center plus short delta times 1.2 times offset. In Wrap, if x or z leaves the ±9.6 lip, add or subtract 19.2 so the capsule reappears on the far lip instead of streaking across the middle. In Walls, do not wrap that coordinate. When offset reaches 1, resolve one crossing before subtracting. On a successful commit, subtract 1 and continue, at most 3 commits per frame. On rail, cross, or clear, leave offset at 1 and stop. Apply the queued turn first. The upcoming cell is the head plus that direction. In Walls, a cell outside 0 to 15 ends the run with reason rail and does not commit, so the head rests on the rail. In Wrap, wrap the cell with modulo 16. If the upcoming cell is occupied by any body cell, except the tail when the grow queue is 0, end with reason cross and do not commit. Otherwise commit. If the cell is the bead, add 10 times the current step, add 1 to the grow queue, and play the eat blip before moving the cells. Unshift the new head. If the grow queue is positive, decrement it and keep the tail; otherwise pop the tail. If this crossing ate a bead, pick the next bead uniformly at random among cells not in the updated body. If none remain, end with reason clear and hide the bead. A new tail capsule scales from 0.2 to 1 in 0.18 seconds, or appears full size when reduced motion is on. Ignore a queued turn that is the reverse of the current direction. One queued turn, replaced by the latest legal key. Apply it at the crossing, then clear it. Direction map, world and screen: north (0, -1) is up, south (0, +1) is down, west (-1, 0) is left, east (1, 0) is right.
Motion: Segments move together for the whole step, including the tail. Only a capsule that is crossing an open edge jumps to the far lip. Pause, the hidden tab, and game over stop the offset. A hitch must not skip the collision check: the while-loop of at most 3 crossings is what prevents that.
4. **Follow camera and the beat** — During play the camera sits south of the head and does not swing behind it. Up on the keyboard stays up on the screen after a turn. The bead is the only thing locked to the music. There is no visualizer, no waveform, and no extra glow pass.
Layout: Perspective camera, near 0.1, far 80. Desktop fov 44. Below 800px, fov 56. Desired position is the head world position plus (0, 7.4, 8.2) on desktop and plus (0, 10.2, 10.4) below 800px. Look point is the head plus (0, 0.4, -1.6) on desktop and (0, 0.3, -2.2) below 800px, so more of the floor north of the head stays in view above the pad. Each frame, move position and the look point toward those targets by 1 - exp(-dt / tau), then lookAt. Position tau 0.28 and look tau 0.16. Reduced motion: 0.62 and 0.45. camera.up stays (0, 1, 0). No roll, no shake, no fov punch. On game over, add 1.2 to the desired camera height. Reduced motion skips that extra height. Audio: create the AudioContext inside the Start run handler and call resume. Master gain 0.2. Loop at 96 beats per minute, quarter note 0.625 seconds, 8 beats. Schedule 0.15 seconds ahead from the animation frame, not from setInterval. Each beat: a triangle tick at 740Hz, gain 0.05, decay 0.05 seconds. Bass square through a lowpass at 220Hz, gain 0.12, duration 0.2 seconds, frequencies 55, 55, 41.2, 49, 43.65, 43.65, 32.7, 41.2 across the eight beats. Beats 0 and 4 also play a sine falling from 120Hz to 52Hz in 0.09 seconds, gain 0.2. Eat blip: sine 520Hz to 880Hz in 0.07 seconds, gain 0.15. Rail or cross ending: sine 200Hz to 45Hz in 0.32 seconds, gain 0.16, then stop the loop. A player-ended run only ramps the master to 0 in 0.08 seconds. A clear floor plays sines at 523, 659, and 784Hz, 0.12 seconds each, gain 0.12, then stops the loop. Mute sets the master gain to 0 in 0.03 seconds and stores the flag. The title card pulses from performance.now modulo 0.625. When the run starts, reset the phase to 0 and use the audio clock. Pause suspends the context and freezes the phase.
Motion: Bead envelope after each beat, elapsed e: for e under 0.09, scale 1 + 0.2 * (e / 0.09) and halo opacity 0.28 + 0.28 * (e / 0.09); until 0.32, ease back to scale 1 and opacity 0.28; then hold. Reduced motion: scale 1, opacity 0.32, for the whole run including the title. A new bead scales from 0.6 to 1 in 0.09 seconds unless reduced motion is on.
5. **HUD, pause, and game over** — Top bar wordmark: Lumen Coil, Syne 700 18px, color #E9FFF8, with Northglass Hall in Outfit 500 12px color #8AA39A. Truncate the wordmark with ellipsis below 400px, max-width 58vw. Sound button aria-label Sound on or Sound off, aria-pressed, Lucide Volume2 or VolumeX. Pause button, Lucide Pause, aria-label Pause, visible only while the run is moving. HUD chips, IBM Plex Mono 13px: Score and the integer, Len and the length, Step and the digit plus five 6px pips, and the rule name Wrap or Walls. Group thousands with en-US separators. The Walls chip border is #FF5D73. The Wrap chip border is #2EE6A6. Other chip borders are #234840. Chip fill rgba(7,8,10,0.72), text #D5E8E2. Pause heading: Paused. Line: The Relay Floor is holding. Buttons: Resume and End run. End run opens game over with reason ended, keeps the score, and does not play the falling tone. Game over heading: Run over, or Floor clear when the board is full. Cause lines: The line crossed itself. The rail stopped the run. You ended the run. Every open cell is taken. Repeat Score, Len, Step, and the rule. If the score is above that rule's stored best and above 0, show New best for Wrap. or New best for Walls. and write the best immediately. Initials field, maxlength 3, letters only, uppercase, autocomplete off, aria-label Initials, three letters. Empty save stores YOU. Button Save, then Saved. Run again restarts the same rule, the same opening cells, the bead at (14, 8), score 0, and the audio loop, without reloading. Change rule returns to the start card with the radios available and the line posed again.
Layout: Top bar is fixed, padding 12px 16px plus safe area, pointer-events none except its buttons, z-index 3. At 800px and wider the HUD is centered in that bar. Below 800px the HUD is a second row of four equal chips under the bar. HUD is hidden on the start card and on game over, and visible while playing or paused. Pause and game over are dialogs, aria-modal true, focus trapped, labelled by their headings. Desktop cards are 400px, centered, same frost as the start card. A scrim rgba(7,8,10,0.45) covers the view. Mobile: bottom sheets, max-height 70dvh, scroll inside. Game over does not trap the page behind a dead end: Run again and Change rule are both present. A visually hidden polite live region announces Run started, Paused, Run over with the score, and New best. The canvas accessible name is Glowing grid snake game.
Motion: On an eat, the score digits scale 1 to 1.08 to 1 in 120ms. Reduced motion skips that pop. On a rail or cross ending, the head emissive eases to #FF5D73 over 0.32 seconds and then back, unless reduced motion is on. Dialogs fade in 160ms, or snap when reduced motion is on. Opening pause suspends audio and freezes the step. Resume continues the same offset and beat phase. Returning to a hidden tab stays paused.
6. **Keyboard, swipe, and the pad** — Keyboard during play: ArrowUp or W queues north, ArrowLeft or A west, ArrowDown or S south, ArrowRight or D east. Ignore e.repeat. A reverse of the current direction is ignored and does not clear a queued turn. The latest other direction replaces the queue. P or Escape pauses, and the same keys resume from pause. Escape does nothing on game over. Prevent default on those keys so the page does not scroll, except while the initials field is focused. Do not bind Space as a global shortcut. Buttons use native Enter and Space.
Layout: Show the pad only while the run is moving, and only when the pointer is coarse or the width is under 800. Hide it on the start card, during pause, and on game over. Four 64px keys in a plus, gap 8px, center bottom 16px plus safe area. Empty center, no fifth button. Labels are CSS chevrons, 10px, color #D5E8E2, not extra icon files. Accessible names: Turn up, Turn left, Turn down, Turn right. They set the same four directions as the arrows. Swipe on the canvas during play: pointer down and up, ignore the gesture if it starts on a control. A swipe counts when the longer axis exceeds 28px and is at least 1.15 times the shorter axis. Swipe up, left, down, and right match the arrow keys. Release stuck keys and pointers on blur, pause, and when the tab hides.
Motion: A pressed pad key uses fill rgba(46,230,166,0.16) and scale 0.98, or no scale when reduced motion is on. Focus ring is 2px solid #2EE6A6 with 3px offset on every control.
7. **Scores, phone fit, and fallback** — Stored JSON is an object with wrap and walls. Each holds best, a number, and board, up to five objects with name, score, and length. Sort the board by score descending, then length descending. Corrupt JSON resets to best 0 and an empty board. The numeric best updates at game over before Save. Save only edits the named board. Both rules are shown on the start card. Game over shows the named five for the rule just played. Mute persists across reloads. Nothing is sent off the device.
Layout: Target 1440×900 and 390×844 with no horizontal overflow, no page scroll, and no console errors. Safe-area padding on the bar, the sheet, and the pad. The start sheet scrolls inside itself if a long hall name wraps. The wordmark ellipsizes before it collides with the sound button. If WebGL is missing or the renderer throws, hide the canvas and show the frost card with the heading, the deck, and the sentence This browser could not start the 3D floor. A current browser with WebGL still can. Keep How to steer available. Do not log that failure as an uncaught error. Dispose geometries, materials, listeners, and the audio context on teardown. Keep dist under 20 MB. Favicon linked from index.html. Internal links, if any, point at index.html.
Motion: The pixel-ratio cut does not reset the run. Reduced motion and the quality cut are independent. The posed line is visible on the first presented frame, before the start button is pressed.
## Assets
- image: No photographs, generated bitmaps, or downloaded textures. Draw the floor, the line, the bead, the rail, and the halo in code. Favicon is the original SVG at public/favicon.svg, a dark rounded square and one sea-glass arc. In ASSETS.md state that the scene is code-drawn and that no external image file is used.
- icon: Copy only Pause, Volume2, and VolumeX from the lucide package (ISC) into src/icons.ts and draw them with lucide createElement. In ASSETS.md list those three icons, https://www.npmjs.com/package/lucide, Lucide contributors, and the ISC license. Pad chevrons are CSS, not icons.
- font: Self-host Syne, Outfit Variable, and IBM Plex Mono through @fontsource/syne, @fontsource-variable/outfit, and @fontsource/ibm-plex-mono (OFL). In ASSETS.md list the local woff2 files, the npm package pages, the copyright lines from the bundled OFL notices, and OFL. Do not request fonts.googleapis.com or any other font host.
- video: No video and no audio files. The loop, the eat blip, the ending tones, and the clear-floor tones are oscillators in Web Audio, started from the Start run gesture.
## Don'ts
- Do not add a backend, accounts, a database, analytics, remote APIs, multiplayer, payments, a form that submits anywhere, or a public leaderboard. Bests, initials, and mute stay in localStorage.
- Do not load scripts, fonts, icons, models, textures, images, or audio from a CDN. Use relative paths, emit minified files to dist/, and do not emit source maps or copy src/ into dist/. Keep dist under 20 MB.
- Do not build a marketing landing page, a pricing page, or a scroll story. The deliverable is one playable index.html, and the grid, the line, and the bead are visible on the first screen.
- Do not use Agent OS, GoldieBench, AI Profit Boardroom, AIPB, Grok, xAI, Julian Goldie, Built in the Agent OS, or Join AIPB. Do not use the slogans The chart is the vendor's. The game is yours. or Played, not posed.
- Do not use the titles NEONSNAKE, NEONSNAKE 3D, CYBER GRID 3D, or SELF-PILOTING NEON ARENA, or the interface words AUTO-PILOT, AUTOPILOT ON, LINK SEVERED, sector 7, GRID SYNC, INITIALIZE, data-nodes, or Slither through the synthwave grid.
- Do not give the snake eyes, a face, a tongue, orbital rings, corner pylons, or towers. Do not add autopilot, pathfinding, a self-playing demo, or a task overlay. Do not name or depict Nokia, a handset, or any shipped snake-game product.
- Do not yaw the play camera behind the head. Arrow keys, WASD, swipes, and the pad stay aligned to north, west, south, and east on the screen.
- Do not snap the body from cell to cell while only the head moves. Every capsule glides on the shared offset. A wrap moves one capsule to the far lip and does not draw a streak across the floor.
- Do not hard-code Lumen Coil, Northglass Hall, ion beads, Relay Floor, or Marrow Lane outside content.ts. When the variables change, keep the grid, speeds, colors, and controls. Never show raw bracket placeholders.
- Do not mention VibeFather except the single optional [CREDIT] link on the start card. Do not show a calendar date.
- Do not autoplay sound before Start run, shake the camera, or flash the whole screen. Honor prefers-reduced-motion for the bead swell, the title drift, the grid breathe, the score pop, and the death tint.
- Do not leave keys or pointers stuck after blur, pause, or a hidden tab. Do not advance the offset or the beat while paused.
- Do not drop the phone layout. At 390×844 the pad keys are 64px, type does not overflow, and the head and the bead sit above the start sheet.
- Do not show a blank page if WebGL fails. Show the frost fallback once, and do not throw in the frame loop.
- Do not add bloom postprocessing, particle trails, downloaded models, or a second scene. Internal links, if any, point at index.html rather than a bare directory.
---
Inspired by Grok Build neon snake demo — https://agentos.guide/grok-4-7-agent-os
— Prompt by VibeFather · https://vibefather.ai/t/neon-snake-3d-game · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown
Free for personal projects under CC BY-NC 4.0. Commercial use comes with Pro.
DESIGN.md
The design system on its own — colors, type, spacing and motion. Apply this look to a project you already have.
---
name: "Neon Snake 3D Game"
colors:
void: "#07080A"
floor: "#07100F"
grid: "#1E4A42"
hot_line: "#8CFFE0"
sea_glass: "#2EE6A6"
head: "#E9FFF8"
copper: "#FF8A3D"
cream: "#FFE6D0"
ink: "#071410"
mist: "#D5E8E2"
mute: "#8AA39A"
rail_pink: "#FF5D73"
card: "#0C1414"
stroke: "#234840"
pip: "#1A3330"
hover: "#76F6C4"
typography:
game_name_and_start_heading: { family: "Syne", weights: [700, 800] }
ui_buttons_hints_and_body: { family: "Outfit Variable", weights: [400, 500, 600] }
scores_length_and_step: { family: "IBM Plex Mono", weights: [500] }
spacing: "Use a 4px base. Desktop card padding 28px, inset 36px from the left. Mobile card inset 12px plus safe-area insets. HUD chip gap 8px, top-bar padding 12px 16px. Buttons are at least 44px tall. The pad keys are 64px. The center of the play view stays clear of the pad."
radius: "Cards 20px, buttons 12px, radios 12px, HUD chips fully round, pad keys 14px. The snake and the bead are round capsules and spheres. The rail is a sharp low box."
---
# Neon Snake 3D Game — Design System
Apply this design system to an existing project. It describes the look and feel only; for the full site, use prompt.md.
## Colors
- **Void** `#07080A` — Page background, renderer clear color, fog, and the overlay scrim base
- **Floor** `#07100F` — Grid shader background
- **Grid** `#1E4A42` — Idle grid lines
- **Hot line** `#8CFFE0` — Grid lines near the head
- **Sea glass** `#2EE6A6` — Snake body emissive, primary button, focus ring, Wrap chip border, filled speed pips
- **Head** `#E9FFF8` — Head emissive, game name, and start heading
- **Copper** `#FF8A3D` — Bead emissive, bead halo, and the food pool on the floor
- **Cream** `#FFE6D0` — Bead core diffuse color
- **Ink** `#071410` — Text on the primary button
- **Mist** `#D5E8E2` — Body copy, HUD values, and ghost-button text
- **Mute** `#8AA39A` — Eyebrow, hints, place line, and the credit link
- **Rail pink** `#FF5D73` — Walls rail emissive, Walls chip border, and the brief death tint on the head
- **Card** `#0C1414` — Frosted cards at 82% opacity
- **Stroke** `#234840` — Card borders, idle chips, and unselected radios
- **Pip** `#1A3330` — Empty speed pips
- **Hover** `#76F6C4` — Primary button hover
## Typography
- **Game name and start heading** — Syne (OFL), weights 700/800. Self-host the font files.
- **UI, buttons, hints, and body** — Outfit Variable (OFL), weights 400/500/600. Self-host the font files.
- **Scores, length, and step** — IBM Plex Mono (OFL), weights 500. Self-host the font files.
## Spacing & shape
- Spacing: Use a 4px base. Desktop card padding 28px, inset 36px from the left. Mobile card inset 12px plus safe-area insets. HUD chip gap 8px, top-bar padding 12px 16px. Buttons are at least 44px tall. The pad keys are 64px. The center of the play view stays clear of the pad.
- Radius: Cards 20px, buttons 12px, radios 12px, HUD chips fully round, pad keys 14px. The snake and the bead are round capsules and spheres. The rail is a sharp low box.
## Motion
- Simulation uses the frame delta capped at 0.05 seconds, with at most 3 cell crossings processed per frame. Render after the step.
- All capsules share one offset from 0 to 1 and glide together between cell centers. The play camera never yaws. Its position eases toward a southern offset with tau 0.28 seconds, or 0.62 when reduced motion is on.
- The bead swells on each quarter note at 96 beats per minute: scale 1 to 1.2 in 0.09 seconds, back to 1 by 0.32 seconds. Reduced motion holds scale 1 and halo opacity 0.32.
- Title camera drifts by a sine of 0.08 radians over about 28 seconds and stops when the run starts. Buttons darken or lighten on hover. A pressed control scales to 0.98 in 80ms unless reduced motion is on.
- Pause freezes the offset, the beat phase, and the title drift. The hidden tab pauses the same way and does not resume until Resume.
## Imagery
Draw the floor, the line, the bead, and the rail from Three.js primitives and one grid shader. No photographs, generated bitmaps, textures, HDRIs, or downloaded models. The first screen is that 3D floor beside or above a frosted card, never type on a flat field. The head has no face. No people and no portraits.
## Tone
Calm, precise, and a little playful. Short US English. Talk about the line, the floor, and the bead. No military ranks, no hype, and no cyber slang.
---
Inspired by Grok Build neon snake demo — https://agentos.guide/grok-4-7-agent-os
— Prompt by VibeFather · https://vibefather.ai/t/neon-snake-3d-game · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown
Make it yours
- An arcade cabinet at a retro bar: set BRAND to the cabinet name, STUDIO to the venue, and PLACE to the address and hours so the start card reads like a real machine.
- A classroom coding demo: keep the Lumen Coil names, set ARENA to a lesson floor name, and use the Wrap rule to show how a grid game handles edges.
- A studio portfolio piece: set STUDIO to your studio name, PICKUP to a themed collectible, and rewrite TAGLINE to describe the line and floor in your own words.
- A party game for a friend group: set BRAND and PLACE to an invented hall and address, then let players enter initials on the game over card for a shared best score.
Neon Snake 3D Game: questions and answers
How do I rename the game and change the pickup to match my own project?
The Neon Snake 3D Game template keeps every player-facing name in one content file with six variables: BRAND for the game name, STUDIO for the hall, PICKUP for the collectible, ARENA for the floor, PLACE for the cabinet line, and TAGLINE for the opening sentence. Change those values and rewrite the collect sentence and pause line so they name your floor and pickup. The grid, colors, speeds and controls stay fixed.
What are the two floor rules in the Neon Snake 3D Game and how do best scores work?
The Neon Snake 3D Game template ships two floor rules. Wrap brings the snake back on the far side of an open edge, while Walls draws a low rail and touching it ends the run, as does crossing the line. Each rule keeps its own best score and five sets of initials stored in the browser under a key built from your game name, so renaming the game gives you a fresh score table.
Can I host the Neon Snake 3D Game as static files without a backend?
Yes. The Neon Snake 3D Game template builds to static files with no backend, no server code and no external APIs, so you can host the output on any static host. Scores and mute state are kept in the browser rather than a database, and the whole game is one page. Developers and indie hackers can ship it as-is after renaming the variables.
How does the Neon Snake 3D Game handle controls on a phone versus a desktop?
Arrow keys and WASD steer the Neon Snake 3D Game at a desk, while a phone uses a swipe and a four-button pad. The frosted card sits left of the grid on a desk and along the bottom on a phone, leaving the grid visible. The camera stays south of the head so arrow keys stay tied to the screen, and the center of the play view stays clear of the pad.
What should I change first when adapting the Neon Snake 3D Game for a different audience?
Start with the six variables in the content file: set BRAND, STUDIO, PICKUP, ARENA, PLACE and TAGLINE to your own names, then rewrite the start card copy, pause line and game over text to match. If your floor or pickup changes, rewrite TAGLINE so it does not name the old ones. Grid size, colors, speeds and controls are fixed, so the game still plays the same way.
How do I build a neon snake 3D game with AI?
Copy the prompt from this page or run npx vibefather add neon-snake-3d-game, replace [ARENA], [BRAND], [PLACE] and [PICKUP] with your own content, and paste it into Claude Code, Codex, Cursor or another AI coding agent. The live demos were built from exactly that text.
Which AI model built the Neon Snake 3D Game demo?
The Night hall snake case was built by Grok 4.7 in Grok Build; the Night conservatory snake case was built by Grok 4.7 in Grok Build. Each build used the published prompt with nothing added.
What tech stack and pages does the Neon Snake 3D Game template use?
Neon Snake 3D Game is a single-page site built with Three.js, with 3d / webgl and micro-interactions. The prompt fixes the stack so every AI tool builds the same kind of project, and the result runs as a static site you can host anywhere.
Can I use the Neon Snake 3D Game template for a client or a business?
The Neon Snake 3D Game prompt and DESIGN.md are free for personal, non-commercial projects under CC BY-NC 4.0. Client work and commercial use need VibeFather Pro, which also includes the source code of the live demo.
Does the Neon Snake 3D Game template work on mobile?
Yes. Every Neon Snake 3D Game build was tested on a phone-sized screen as well as desktop before it went live, checking layout, text size and touch targets. Open the live demo on your phone, or switch the preview on this page to mobile view, to check it yourself.