2 cases built from this template
Same prompt, different [VARIABLES]. Click one to preview it above.About this template
Sci-Fi Arena Wave Survival Game is a one-page browser game played in first person inside a closed industrial yard. Crates, low walls, and a gantry are built from boxes under four sodium lamps. The opening screen is a glass title card over that live view, with one hovering drone in sight and a short control legend. The start click begins the round and asks for pointer lock. If the browser or a sandboxed frame refuses the lock, the refusal is caught and looking switches to dragging the view and the arrow keys.
The player stays on foot with a single magazine-fed carbine. The magazine is short, an empty click means it is dry, and a reload takes under a second. Every shot uses the same cyan tracer. Enemy bolts empty a shield bar before they touch health, and neither bar refills by itself. A warm floor cell restores health, a cool floor cell restores shield, and a taken cell comes back on a timer.
Drones are boxy and hovering. They arrive in numbered waves, strafe, and fire slow bolts. Each wave adds a few drones and a little speed, then leaves a short breather. There is no last wave. A destroyed drone breaks into sparks, with no blood, people, or creatures. A dark glass HUD shows ammo, both bars, the wave number, and how many drones have dropped. At zero health a retry card shows the wave reached and the drones dropped.
Phones use a left move stick, a right look stick, and fire and reload buttons. Narrow screens keep fewer drones aloft, and reduced motion removes head bob and shake. Five names let a developer or student reuse the lamps, bars, and wave loop as a static demo with no server.
The template prompt
The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].
# Sci-Fi Arena Wave Survival Game Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else. ## Brief A single-page first-person wave game inside a closed industrial yard built from boxes. A glass title card sits over the live yard, with one hovering drone already in view. The visitor then walks, aims, and fires one magazine-fed carbine, collects health and shield cells from the floor, and faces numbered waves of boxy drones until health reaches zero. A retry card shows the wave reached and the drones dropped. Geometry and sound are generated in code. - Audience: Developers and students who want a finished browser game they can reskin with their own names and ship as static files. - Goal: A round that plays with a mouse and keyboard, and still plays when pointer lock is refused, including inside a sandboxed iframe: look, shoot, reload, collect cells, lose, and retry, with the score kept in memory and no console error. - Tone: Dry and physical, like a notice posted at a test range. Short labels, no jokes, no exclamation marks, and no gore. ## Stack - Framework: Vite 5 + TypeScript + three.js - Styling: Tailwind CSS 3.4 - Libraries: three (MIT), tailwindcss (MIT), vite (MIT), typescript (Apache-2.0), @fontsource/chakra-petch (OFL-1.1), @fontsource/source-sans-3 (OFL-1.1), @fontsource/jetbrains-mono (OFL-1.1) - Build: `npm run build` → static files in `dist/`. No backend, no server code, no external APIs. - Setup: - Create a Vite 5 + TypeScript app with no React, Vue, or Svelte. The entry is index.html plus src/main.ts. Set the document language to en. The title element reads [BRAND] — [ARENA]. The body contains one canvas and one div#ui for every overlay. - In vite.config.ts set base to './', build.sourcemap to false, and build.outDir to dist. Do not copy src into dist. - Install tailwindcss 3.4 with postcss and autoprefixer. Point Tailwind content at ./index.html and ./src/**/*.ts. Do not install Tailwind 4 and do not load Tailwind from a CDN. Map the font families and the hex colors below into the Tailwind theme. - Install three and import it from the three package. Do not load it from a CDN. Do not use GLTFLoader, TextureLoader, AudioLoader, EffectComposer, or any other postprocessing pass. - Install the Fontsource packages and import @fontsource/chakra-petch/600.css, @fontsource/chakra-petch/700.css, @fontsource/source-sans-3/400.css, @fontsource/source-sans-3/600.css, and @fontsource/jetbrains-mono/500.css from src/main.ts. - Put every user-facing string in src/content.ts. Build the strings that name the range from [BRAND], [OPERATOR], [ARENA], [WEAPON], and [DRONE]. Pluralize [DRONE] by appending the letter s when the value does not already end in s. When those values differ from the defaults, rewrite the strings and keep every number, layout, and mechanic. - Split play code into src/scene.ts, src/player.ts, src/weapon.ts, src/drones.ts, src/pickups.ts, src/waves.ts, src/input.ts, src/hud.ts, and src/audio.ts. Drive them from one requestAnimationFrame loop in src/main.ts. Clamp each frame delta to 0.05 seconds. While document.hidden is true, freeze the simulation. - Write public/favicon.svg as a rounded square filled #100F0C with a centered 18 by 4 rounded bar of #3EE0D2 and no letters. Link it with a relative href. - Write ASSETS.md at the project root listing each Fontsource package, the OFL-1.1 license, and the author. There are no third-party images. - Cap the renderer pixel ratio at 1.5, and at 1.25 when the viewport width is under 768. Resize the drawing buffer to the canvas client size. Make the canvas position fixed and inset 0, with touch-action none. Set the page margin to 0, the background to #100F0C, overflow hidden, and the height to 100dvh. ## Variables - [BRAND] — Game title (default: "Lampwright"). The large name on the title card and in the document title. Invented. It is not a weapon name and not a real studio. - [OPERATOR] — Range operator (default: "Hale Relay Works"). Short invented company on the title-card eyebrow and inside the premise sentence. - [ARENA] — Yard name (default: "Sodium Court"). The closed yard. Shown under the title and in the pause card. Also the second half of the document title. - [WEAPON] — Carbine name (default: "Ash Spool"). Label above the ammo count only. The weapon stays a 12-round magazine carbine whatever this says. Never a real firearm model name. - [DRONE] — Drone name (default: "Wick"). Singular name of the only enemy. The pause card and the game-over card use the plural, which is the value plus s unless it already ends in s. - [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/sci-fi-arena-wave-survival-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 - Yard Black `#100F0C` — Page background, renderer clear color, and fog - Floor `#1A1915` — Main floor slab - Panel `#14130F` — Thin inset floor plates, visual only - Crate `#3A342C` — Perimeter walls and odd-numbered crates - Crate Dark `#2E2B26` — Low walls, even-numbered crates, and the carbine shroud - Steel `#4A463E` — Gantry and carbine receiver - Sodium `#E8A15A` — Lamp light, eyebrow, primary buttons, and drone lamps - Sodium Hot `#FFC27A` — Lamp emissive and primary-button hover - Paper `#F4EFE6` — Title, HUD numbers, and the crosshair - Dust `#A39C90` — Secondary labels, legends, and the credit line - Ink `#1A120C` — Text on the sodium buttons - Tracer `#3EE0D2` — The only cyan: tracers, weapon rib, reload fill, and hit-confirm crosshair - Shield `#7EB6FF` — Shield bar and shield cells - Health `#F08A4B` — Health bar and health cells - Bolt `#E7B15A` — Enemy projectiles and the empty-magazine numeral - Track `#241F1A` — Empty tracks behind the bars and the reload fill - Glass `rgba(12,11,9,0.78)` — Title, pause, game-over, and HUD panels - Hurt `#C46B4A` — Damage vignette only. Never a splatter decal ### Typography - Display: Chakra Petch (OFL), weights 600/700 - Body: Source Sans 3 (OFL), weights 400/600 - Ammo: JetBrains Mono (OFL), weights 500 ### Layout & motion - Spacing: The canvas fills the viewport. Overlay panels sit 20px from the edges on viewports at least 768px wide, and 14px from the edges below that, plus env(safe-area-inset-*). The title card padding is 28px 32px. Stacked HUD rows use a 6px gap. Touch sticks are 112px across with 16px outer margins, and the Fire and Reload buttons have a 10px gap. - Radius: Title, pause, and game-over cards are 10px. Text buttons are 8px. Health bars, shield bars, sticks, and the round Fire and Reload buttons are pills at 999px. - Motion: Before the round, the title drone yaws at 0.25 rad/s and bobs 0.12 m at 0.8 Hz. The bob amplitude is 0 when prefers-reduced-motion is set. - Motion: While the player is moving faster than 0.4 m/s, the camera bobs 0.016 m vertically and 0.008 m laterally, with 0.004 rad of roll. A shot kicks pitch by 0.008 rad for 70 ms. A hit offsets the camera 0.012 m for 100 ms. Skip all three when prefers-reduced-motion is set. - Motion: Floor cells spin at 0.7 rad/s on Y. Combat drones bob 0.1 m at 1.4 Hz. Both hold still when prefers-reduced-motion is set. - Motion: A destroyed drone emits 18 sparks that travel 2.2 m and fade in 0.4 s. A viewport under 768px, or a coarse pointer, uses 8 sparks. Reduced motion uses 6 sparks that fade in place over 0.25 s and do not travel. - Motion: The reload track fills linearly across 950 ms. A hit on a drone turns the crosshair Tracer for 80 ms. At 30 health or below, the health bar pulses from opacity 1 to 0.45 and back over 0.8 s, unless reduced motion is set, in which case the bar stays solid. - Motion: Buttons only change background color on hover. They do not scale, bounce, or rise. Cards show and hide with no page transition. - Imagery: No photographs, textures, or downloaded models. The first screen is the live yard: dark slabs, four warm lamp pools, crate stacks, a gantry, and one hovering drone, with the glass title card centered over that scene rather than a flat color field. The carbine, drones, bolts, cells, tracers, and sparks are three.js meshes and points. The only flat graphic is the favicon SVG. ## Pages & Sections ### Arena (`index.html`) 1. **Shell and states** — Four states: title, playing, paused, and gameover. The page loads in title. There is no marketing page, shop, account, or second route. The round numbers live in module memory only and reset only when Retry runs. WebGLRenderer uses antialias, ACES filmic tone mapping at exposure 1, and a clear color of Yard Black. Fog is Fog in Yard Black with near 16 and far 40. If constructing the renderer throws, catch it, leave no uncaught error, and show the title card on a flat Yard Black field with the sentence This browser could not start the yard view. Hide the start button in that failure state. Layout: The canvas is the bottom layer. A full-viewport vignette sits above it. #ui is position fixed and inset 0, pointer-events none, and holds the HUD, the hint line, the touch controls, and the modal card. Cards and touch controls set pointer-events auto. Z order from back to front: canvas, vignette, HUD, touch controls, card. The vignette is a radial gradient, transparent at the center and Hurt at the edges. 2. **Round rules** — These numbers stay fixed when the variables change. Health 100 and shield 100 start full and never regenerate. A bolt deals 18 damage to shield first, then overflow to health. From full bars, a shield of 10 and one bolt ends at shield 0 and health 92. After damage, ignore bolts for 0.35 s; bolts that arrive during that window vanish. Health is clamped at 0 and ends the round. Move speed is 4.6 m/s, with no jump and no sprint. The carbine holds 12 rounds, reloads to 12 in 950 ms, and has unlimited reserve. Holding fire shoots once every 125 ms. Reload is ignored at 12 rounds or while already reloading, and fire is ignored during reload. An empty magazine dry-clicks no faster than once per 180 ms and draws no tracer. Each hit on a drone deals 34. A drone has 100 health and dies at 0, so it dies on the third hit. Wave 1 contains 3 drones. Wave n contains 3 + (n - 1) * 2. Drone move speed is min(4.2, 2.2 + (n - 1) * 0.18) m/s. A drone fires every max(0.95, 1.7 - (n - 1) * 0.06) seconds. Bolt speed is always 9 m/s. The live cap is 8 when the viewport is at least 768px wide and the primary pointer is fine; otherwise the cap is 4. The breather after a wave is fully destroyed is 4.5 s. A cell restores 40 of its own bar, clamped to 100, and returns after 14 s. There is no victory and no wave cap. The run ends only at 0 health. Layout: Do not print this rule list on the page. The visitor learns the loop from the title-card lines, the HUD, and play. Drive health, shield, ammo, wave size, speeds, and timers from one rules object imported by the other modules. 3. **Title card** — Default copy, in this order: eyebrow HALE RELAY WORKS from [OPERATOR] in uppercase; title Lampwright from [BRAND]; subline Sodium Court from [ARENA]; premise Hale Relay Works shut the bay doors on Sodium Court. The Wicks are already inside. Build that premise as [OPERATOR] shut the bay doors on [ARENA]. The [DRONE plural] are already inside. Button: Enter the yard. Desktop legend, two lines: WASD move · Mouse look · Click fire · R reload · Esc pause, then If the lock is blocked: drag the view, arrow keys look, F or the Fire button shoots. Touch legend, used instead of those two lines when touch controls will show: Left stick move · Right stick look · Fire · Reload. Cell line: Warm floor cells restore health. Cool floor cells restore shield. Neither bar refills on its own. Sound button: Sound on, toggling to Sound off. Last line: the [CREDIT] link. No exclamation marks. Layout: The card is centered, width min(420px, calc(100% - 32px)), max-height calc(100dvh - 32px), overflow auto, padding 28px 32px, background Glass, 1px border at rgba(244,239,230,0.16), radius 10px, and a 12px backdrop blur. The yard stays visible around it. Eyebrow is Chakra Petch 12px weight 600, tracking 0.18em, Sodium. Title is Chakra Petch 64px weight 700, 40px below 768px, line-height 0.95, tracking -0.02em, Paper. Arena is Source Sans 3 16px Dust with 8px space above. Premise is Source Sans 3 15px Paper, line-height 1.45, 14px space above. The start button is 12px 22px padding, 8px radius, Chakra Petch 15px weight 600, Sodium background, Ink text, hover Sodium Hot, 20px above it. Legends and the cell line are Source Sans 3 13px Dust with 14px space above the first legend. The sound control is a transparent button, 13px Dust, 10px above. The credit link is 12px Dust, 16px above. Only the start button begins the round. Clicks on the yard behind the card do nothing. Motion: The card does not animate in. The yard and the title drone are already moving when the page appears. The start button has a color hover and no movement. 4. **Yard** — A closed yard the player cannot leave. Units are meters, Y is up, north is negative Z, and the origin is the center of the floor. Inner floor runs x from -14 to 14 and z from -11 to 11. Walls are 0.7 thick and 4.4 tall in Crate, with the inner faces on those bounds. Leave a 2.6 wide by 2.9 tall opening centered on the east wall and on the west wall, cap each opening with a lintel, and place a dark plug behind each opening in Yard Black so it reads as a bay. Collision still stops the player at the inner face. The floor is a slab from y -0.25 to 0 in Floor, roughness 0.94. Eight thin Panel plates, 0.02 tall, sit on the floor as visual seams and have no collision. Crates, with center y at half their height: A at (-6.2, 0.65, -2.2) size 1.5 x 1.3 x 1.5; B stacked on A at (-6.2, 1.75, -2.2) size 1.05 x 0.9 x 1.05; C at (5.6, 0.85, -5.2) size 2.3 x 1.7 x 1.25; D at (1.8, 0.45, 1.6) size 1.25 x 0.9 x 1.25; E at (-2.4, 0.6, -6.4) size 1.9 x 1.2 x 1.0; F at (7.2, 1.05, 2.6) size 1.35 x 2.1 x 1.35; G at (-8.4, 0.5, 3.8) size 1.7 x 1.0 x 1.7. Odd crates use Crate, even crates use Crate Dark, roughness 0.82. Low walls: (0.2, 0.52, -0.6) size 3.4 x 1.05 x 0.45; (-4.2, 0.52, 4.6) size 0.45 x 1.05 x 2.8; (6.4, 0.48, -1.2) size 2.6 x 0.95 x 0.4; all Crate Dark. The gantry deck is center (0, 3.15, -9.7) size 18 x 0.22 x 1.5 in Steel, metalness 0.45, roughness 0.48, with a rail along its south edge. Four posts, 0.28 x 3.04 x 0.28, stand at x -8, -2.5, 3.5, and 8, same z as the deck. The player collides with posts, crates, low walls, and the perimeter, and walks under the deck. No climbing. Layout: Four lamp poles stand at (-10.5, 3.7, -8.2), (10.5, 3.7, -8.2), (-10.5, 3.7, 7.4), and (10.5, 3.7, 7.4). Each pole is a 0.14 square column in Crate Dark, and each head is a 0.55 x 0.22 x 0.34 box, emissive Sodium Hot at intensity 1.6. A PointLight at each head uses Sodium, intensity 25, distance 18, decay 2. Add a HemisphereLight with sky #3A342C, ground #0C0B09, intensity 0.55, and one DirectionalLight from (12, 18, 8) in #F3D7B0 at intensity 0.85. That directional light casts a 1024 shadow map, bias -0.0003, from walls, crates, low walls, the gantry, drones, and cells, but not from the viewmodel. Turn the shadow map off when the viewport is under 768px. If the yard is blown out or nearly black, multiply the point, hemisphere, and directional intensities by one shared factor until crate faces under a lamp are clearly lighter than the corners and the corners stay near Floor. Do not add more world lights. Motion: The lamps do not flicker. Only the title drone, and later the combat drones, move in this scenery before the player does. 5. **Looking and moving** — The camera is a perspective camera, field of view 72, near 0.08, far 70, eye height 1.65. Spawn at (0, 1.65, 7.4), yaw 0, pitch 0, looking down negative Z so the title drone is centered. Pitch is clamped to ±1.05 rad. Mouse sensitivity is 0.0022 rad per pixel. Arrow keys yaw and pitch at 1.35 rad/s in every look mode. WASD moves relative to yaw at the round-rule speed, diagonals normalized, with no acceleration. Capsule radius is 0.36. Separate the axes on a hit so the player slides along crates and walls. The player is not pushed by drones and takes no damage from touching them. Space is prevented and does not jump. Prevent default on W, A, S, D, R, F, Esc, and the arrow keys so the page does not scroll. Layout: Look mode starts as touch when the viewport is under 768px or the primary pointer is coarse, and as lock otherwise. F fires and R reloads in every mode. On Enter the yard, resume the audio context, hide the title card, show the HUD, set state to playing, and start wave 1. In touch mode, do not request pointer lock; the sticks and buttons are the controls, and a keyboard still works if one is attached. In lock mode, call canvas.requestPointerLock inside try/catch from that click. If the call returns a promise, catch the rejection. Also listen for pointerlockerror. If the canvas is not document.pointerLockElement after 400 ms, use the same fallback. Fallback sets look mode to drag, does not throw, and does not call console.error, console.warn, or console.log. Show this hint under the top HUD for 4 seconds: Pointer lock was blocked. Drag the view to look, or use the arrow keys. In drag mode, holding the primary button on the canvas looks, and that button does not fire. Show the on-screen Fire and Reload buttons whenever look mode is drag, even on a wide screen. In lock mode, mouse movement looks, mouse button 0 fires, and those two buttons stay hidden. Esc during play calls exitPointerLock and opens pause. Set a flag around intentional exitPointerLock calls so the matching pointerlockchange does not open a second card. If the document becomes visible again during play, the look mode was lock, and the lock is gone, open pause. Motion: Head bob runs only in playing, only while speed exceeds 0.4 m/s, and only when reduced motion is off: vertical sin(time * 10.5) * 0.016 m, lateral sin(time * 5.25) * 0.008 m, roll sin(time * 5.25) * 0.004 rad. At rest, return to the level eye within 0.15 s. Reduced motion locks the camera at y 1.65 with roll 0. 6. **Carbine** — The on-screen name is [WEAPON], default Ash Spool. It is a blunt fictional tool, not a model of any real firearm: a receiver box 0.28 x 0.09 x 0.16 in Steel, a shroud 0.08 x 0.06 x 0.34 in Crate Dark on the forward end, a square magazine 0.06 x 0.12 x 0.07, and a top rib 0.03 x 0.025 x 0.2 with emissive Tracer at intensity 0.8. No scope, no maker mark, no text, and no stock copied from a known rifle. Parent it to the camera at local (0.26, -0.24, -0.52). The damaging ray starts at the camera center and travels 48 m. Test the drone body boxes, crates, walls, low walls, gantry, and floor. The first hit wins. A drone takes the round-rule damage and the crosshair flashes. A solid hit spawns 4 Tracer points that fade in 0.12 s, unless the viewport is under 768px or reduced motion is on, in which case skip those points. The visible tracer is a 0.018 square box in MeshBasicMaterial Tracer from the barrel tip to the hit point, or 48 m if nothing is hit, and it lasts 60 ms. A muzzle PointLight in Tracer, intensity 6, distance 3.5, lasts 40 ms and is skipped under reduced motion. Layout: The weapon stays in the lower right of the view and never covers the center crosshair. It does not cast a shadow. Ammo text is the live count, a space, a slash, a space, and 12. At 0 rounds the numeral uses Bolt. During reload the weapon name is replaced by RELOADING and a 104 by 3 track fills with Tracer across the reload duration. Motion: When reduced motion is off, a shot adds 0.008 rad of pitch and shifts the viewmodel 0.02 m back for 70 ms, then eases back. When reduced motion is on, the viewmodel stays put and the tracer still appears. 7. **Drones and waves** — One drone type, named from [DRONE], default Wick. The mesh is a body box 0.84 x 0.30 x 0.58 in #2A2824, metalness 0.42, roughness 0.46; two thruster boxes 0.2 x 0.14 x 0.2 at local x ±0.28 and y -0.2, emissive Sodium intensity 0.6; a fin 0.06 x 0.2 x 0.16 on top; and two front marks 0.07 cubes, emissive Sodium intensity 1.2. No legs, wheels, head, eye, wings, tripod, or skull. Raycast hits use the body box only. On the title screen one drone hovers at (0, 2.25, -4.2), yaws at 0.25 rad/s, bobs ±0.12 m at 0.8 Hz, and cannot shoot or take damage. When the round starts it becomes drone 0 of wave 1 and switches to combat bob after 0.4 s. The other drones of the wave spawn 0.45 s apart, alternating the west bay (x -12.4, y 2.15, z 0) and the east bay (x 12.4, y 2.15, z 0). If the live cap is full, keep the rest queued and spawn the next one 0.45 s after a slot opens. Never delete a queued drone. A wave ends only when every drone that belongs to it has been destroyed. The HUD then reads Wave clear for the whole 4.5 s breather. Bolts already in the air keep flying, and cell timers keep running. The next wave then starts and the label becomes Wave plus the new number. The first combat bolt from each drone waits 0.6 s plus slot index times 0.15 s, then uses the wave interval. Layout: Each drone stores a slot angle, starting at slot index times 2.2 rad, and walks that angle at speed divided by radius. Radius is 8.5 m plus (slot modulo 3) times 1.1 m. The desired point is the player position on XZ plus that offset, at y 2.15. If the path passes within 0.8 m of a solid, try a point 2 m to either side, otherwise hold for that frame. Inside 5.5 m, bias outward. Beyond 13 m, bias inward. Clamp drones to the inner yard inset by 1.2 m. Face the movement direction and bank at most 0.15 rad. Bolts are MeshBasicMaterial spheres, radius 0.11, color Bolt, fired from the front toward the player eye position at the moment of fire, with no homing. Remove a bolt after 3.2 s, on a solid, or on the player. Step bolts with a segment test so they cannot tunnel. A player hit uses the bolt damage rule. Bolts do not hurt other drones. On death, remove the mesh, add 1 to the dropped count, and emit sparks alternating Paper and Sodium. Desktop spark count is 18. Use 8 on a small or coarse-pointer screen. Reduced motion uses 6 sparks with no travel. Motion: Combat bob is ±0.1 m at 1.4 Hz, with a phase offset per slot, and amplitude 0 under reduced motion. Sparks travel 2.2 m and fade in 0.4 s, or fade in place over 0.25 s under reduced motion. No debris chunks and no smoke textures. 8. **Floor cells** — Two health cells and two shield cells. Health cells are emissive Health and sit at (-4.8, 0.4, 6.6) and (9.1, 0.4, -5.4). Shield cells are emissive Shield and sit at (3.6, 0.4, 6.5) and (-8.8, 0.4, -2.6). Each mesh is a 10-sided cylinder, radius 0.2 and height 0.62, plus a cap box 0.16 x 0.08 x 0.16. Emissive intensity is 1.3 and roughness is 0.35. There is no cross, no plus, and no red symbol. A pickup happens when horizontal distance to the player is under 1.0, the matching bar is below 100, and the state is playing. Add 40, clamp to 100, hide the mesh, play the pickup tone, and show the same cell again after 14 s. If the bar is already full, do not consume the cell. Layout: Cells rest on the floor in open gaps between the crates listed above. They cast shadows on desktop and none under 768px. They have no point lights of their own. Motion: Spin each cell on Y at 0.7 rad/s. Reduced motion freezes the rotation at 0 and leaves the emissive color steady. 9. **HUD** — Hidden during title, pause, and game over, except the short lock hint, which can show over play. Permanent labels, all US English and uppercase except the arena name: WAVE and the live number at top center; the arena name under it; DROPPED and the live count at top right; SHIELD and HEALTH at the bars; the weapon name above the ammo. During a breather the top-center word is Wave clear instead of the wave number. Ammo reads as 7 / 12 with the live count. At 0 rounds the number uses Bolt. During reload the weapon name becomes RELOADING. Layout: On a fine pointer at 768px or wider: top center is 20px from the top, Chakra Petch 13px weight 600, tracking 0.16em, Paper, with the arena in 12px Dust weight 500 underneath, not uppercase. Top right is DROPPED in 12px Dust, tracking 0.14em. Bottom left holds two 188 by 8 bars, radius 999px, track color Track, 6px apart, each with an 11px Dust label 4px above. Shield is the upper bar in Shield; health is the lower bar in Health. Fill width matches the percentage. Bottom center is the weapon name in 11px Dust tracking 0.16em, then the ammo in JetBrains Mono 28px weight 500 Paper, then a 104 by 3 reload track. The crosshair is four 8 by 1 rectangles, 5px from center, Paper at 0.8 opacity, fixed to the screen. It is hidden on title, pause, and game over. On a hit it turns Tracer for 80 ms. Below 768px, or with a coarse pointer: margins 14px, bars move to the top left at 132px wide so they clear the move stick, and the ammo drops to 22px and sits 18px above the safe-area inset between the sticks. The crosshair stays centered. Motion: Bar widths update on the frame damage or a pickup happens. The reload track scales across 950 ms. At 30 health or below, the resting vignette opacity is 0.18 and the health bar pulses unless reduced motion is on. A hit raises the vignette to 0.32 for 140 ms, including under reduced motion, then returns it to the resting value. Above 30 health the resting vignette is 0. 10. **Pause and game over** — Pause copy: heading Paused; line Wave and the live number; line [ARENA]; line [DRONE plural] dropped and the live count; buttons Resume and Retry; the sound toggle; the [CREDIT] link. Default examples of the patterned lines are Wave 4, Sodium Court, and Wicks dropped 9. Game-over copy: heading Yard lost; line Reached wave and the live number; line [DRONE plural] dropped and the live count; button Retry; the [CREDIT] link. A default example is Reached wave 6 and Wicks dropped 22. Esc pauses from play and resumes from pause. Esc does nothing on the title card and nothing on game over, but it is still preventDefault. Retry from either card resets health, shield, ammo, reload, dropped count, wave index, cell visibility, cell timers, player pose, and drones, then starts wave 1 immediately. It does not return to the title card. That click is a user gesture, so request pointer lock again with the same fallback rules, unless touch mode is active. Resume continues the frozen clock and requests pointer lock only if look mode was lock. Layout: Both cards reuse the title-card glass, centered, max-width 360px. The heading is Chakra Petch 40px weight 700 Paper. The stat lines are Source Sans 3 16px Dust. Resume and Retry on pause, and Retry on game over, use the sodium button. Retry on the pause card is the second button and is a ghost: transparent, 1px border rgba(244,239,230,0.3), Paper text. Opening pause or game over hides the crosshair and the touch controls, releases pointer lock through the guard flag, and freezes drones, bolts, reload, cell timers, the wave timer, and head bob. Game over also stops fire. Focus moves to the primary button. A dim layer rgba(8,7,6,0.45) sits behind the card only, and the yard remains visible. Motion: The sim clock does not advance while paused or on game over. Cards do not fade. Sound cues do not continue under a card. 11. **Touch controls** — Show the sticks and the Fire and Reload buttons during play when the viewport is under 768px or the primary pointer is coarse. Also show Fire and Reload, without sticks, when look mode is drag on a wide fine-pointer screen. Hide all of them on title, pause, and game over. Left stick moves. Deadzone is 0.15 of the radius, and full deflection equals the round-rule move speed. While the left stick is off-center, ignore WASD. Right stick looks at 1.55 rad/s at full deflection, same deadzone. Fire is hold-to-repeat at the 125 ms cadence. Reload is a tap and runs the same reload as R. Layout: The left stick is bottom-left and the right stick is bottom-right. Each outer circle is 112px, margin 16px plus the safe-area inset, background rgba(12,11,9,0.55), border 1px Paper at 0.2 opacity. The nub is 44px, Paper at 0.85 opacity, and stays inside the outer radius. Fire and Reload are 64px circles stacked above the right stick with a 10px gap, same glass, labels Fire and Reload in 12px Paper. Stop propagation on these controls so the page does not scroll. Motion: The nub follows the thumb with no extra easing. Reduced motion does not change the sticks. 12. **Sound** — All cues are short Web Audio tones generated in code. There are no audio files. Create one AudioContext inside the Enter the yard click, and resume it there. Master gain is 0.16. If the context stays suspended, stay silent and do not throw. The sound toggle sets the master gain to 0 or back to 0.16 and is stored in memory, default on. Shot: square oscillator from 170 Hz to 75 Hz over 0.05 s, gain 0.06. Dry click: square 900 Hz for 0.02 s, gain 0.035. Reload: sine 300 Hz for 0.03 s at the start and sine 460 Hz for 0.04 s at the end. Bolt: sine 120 Hz for 0.1 s, gain 0.045. Hurt: sawtooth 80 Hz for 0.08 s, gain 0.05. Drone break: squares at 1500, 1900, and 2300 Hz, each 0.035 s, staggered by 0.028 s. Pickup: sine from 400 Hz to 660 Hz over 0.13 s, gain 0.05. Wave start: sine 196 Hz for 0.18 s, gain 0.04. Layout: The toggle is the text button on the title card and on the pause card. It is not on the game-over card and not on the playing HUD. Motion: No audio-reactive camera motion. Reduced motion does not mute the cues. ## Assets - font: Self-host Chakra Petch (OFL-1.1, Indian Type Foundry) with @fontsource/chakra-petch weights 600 and 700 for the title, buttons, and HUD labels. List the package, author, and license in ASSETS.md. Do not load it from a font CDN. - font: Self-host Source Sans 3 (OFL-1.1, Adobe) with @fontsource/source-sans-3 weights 400 and 600 for the premise, legends, and stat lines. List it in ASSETS.md. - font: Self-host JetBrains Mono (OFL-1.1, JetBrains) with @fontsource/jetbrains-mono weight 500 for the ammo numerals. List it in ASSETS.md. - icon: Draw public/favicon.svg in code: a rounded square of #100F0C and a centered cyan bar of #3EE0D2. No icon package, no letters, and no downloaded SVG. ## Don'ts - No backend, server routes, database, auth, accounts, form posts, fetch, or third-party APIs. Keep the round in memory only. Do not use localStorage, sessionStorage, cookies, or indexedDB. - Build static files to dist/ with npm run build. Set the Vite base to './' and use relative asset paths. Ship no source maps and do not copy src into dist/. Keep dist/ under 20 MB. - Self-host the three Fontsource packages named in the stack. No fonts.googleapis.com, fonts.gstatic.com, Adobe Fonts, or any other CDN for fonts, scripts, audio, or images. No analytics. - No downloaded 3D models, textures, audio files, or photographs. Draw the yard, carbine, drones, cells, sparks, and favicon in code. Generate tones with Web Audio. - One page only: index.html. Do not add a marketing homepage, pricing, or a separate instructions page. If any internal link is added, point it at a file name. - Playable at 1440 by 900 and at 390 by 844 with no console errors and no uncaught rejections. Pointer lock is only for a top-level tab. Catch a rejected lock, including inside an iframe sandboxed with allow-scripts only, and fall back to drag look plus the arrow keys. Do not request fullscreen. Do not call alert. - Honor prefers-reduced-motion. Remove head bob, fire kick, hit shake, drone bob, cell spin, health-bar pulse, and traveling sparks. Gameplay numbers stay the same. - Under 768px, or with a coarse pointer, show a left move stick, a right look stick, and Fire and Reload buttons. Cap live drones at 4 and shorten the spark burst. Do not require hover. - The player never leaves the yard. One carbine, one drone type, no vehicles, no jump, no sprint, no second fire mode, and no win screen. Waves continue until health is 0. - Drone deaths are sparks only. No blood, gore, dismemberment, humans, creatures, pilots, or burning bodies. No red cross and no plus-shaped health item. Health and shield never regenerate on their own. - Do not use names, logos, weapons, HUDs, demons, or marine or hero silhouettes from Doom, Quake, Halo, Unreal Tournament, Overwatch, Titanfall, Destiny, Warframe, Apex Legends, Call of Duty, Serious Sam, Killing Floor, Gears of War, or Left 4 Dead. No super shotgun, BFG, plasma rifle, needler, energy sword, or gravity gun. Do not write the phrases rip and tear or finish the fight. No face portrait in the HUD. - Do not depict a Terminator endoskeleton, ED-209, an AT-ST, battle droids, probe droids, Sentinel squids, a Portal turret, a quadruped robot, Wall-E, or Necrons. Do not use a real firearm model name. No studio, agency, or space-agency insignia, including NASA and SpaceX marks. - No commercial fonts and no restricted component-library source. Do not install Aceternity UI, Tailwind Plus, or a paid template. This HUD needs no icon package. - All on-screen copy is US English. Do not mention VibeFather anywhere except the single [CREDIT] link on the title card, the pause card, and the game-over card. - No placeholder-image services and no hotlinked media. The hero is the live yard, not type on a flat background. --- — Prompt by VibeFather · https://vibefather.ai/t/sci-fi-arena-wave-survival-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: "Sci-Fi Arena Wave Survival Game"
colors:
yard_black: "#100F0C"
floor: "#1A1915"
panel: "#14130F"
crate: "#3A342C"
crate_dark: "#2E2B26"
steel: "#4A463E"
sodium: "#E8A15A"
sodium_hot: "#FFC27A"
paper: "#F4EFE6"
dust: "#A39C90"
ink: "#1A120C"
tracer: "#3EE0D2"
shield: "#7EB6FF"
health: "#F08A4B"
bolt: "#E7B15A"
track: "#241F1A"
glass: "rgba(12,11,9,0.78)"
hurt: "#C46B4A"
typography:
display: { family: "Chakra Petch", weights: [600, 700] }
body: { family: "Source Sans 3", weights: [400, 600] }
ammo: { family: "JetBrains Mono", weights: [500] }
spacing: "The canvas fills the viewport. Overlay panels sit 20px from the edges on viewports at least 768px wide, and 14px from the edges below that, plus env(safe-area-inset-*). The title card padding is 28px 32px. Stacked HUD rows use a 6px gap. Touch sticks are 112px across with 16px outer margins, and the Fire and Reload buttons have a 10px gap."
radius: "Title, pause, and game-over cards are 10px. Text buttons are 8px. Health bars, shield bars, sticks, and the round Fire and Reload buttons are pills at 999px."
---
# Sci-Fi Arena Wave Survival 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
- **Yard Black** `#100F0C` — Page background, renderer clear color, and fog
- **Floor** `#1A1915` — Main floor slab
- **Panel** `#14130F` — Thin inset floor plates, visual only
- **Crate** `#3A342C` — Perimeter walls and odd-numbered crates
- **Crate Dark** `#2E2B26` — Low walls, even-numbered crates, and the carbine shroud
- **Steel** `#4A463E` — Gantry and carbine receiver
- **Sodium** `#E8A15A` — Lamp light, eyebrow, primary buttons, and drone lamps
- **Sodium Hot** `#FFC27A` — Lamp emissive and primary-button hover
- **Paper** `#F4EFE6` — Title, HUD numbers, and the crosshair
- **Dust** `#A39C90` — Secondary labels, legends, and the credit line
- **Ink** `#1A120C` — Text on the sodium buttons
- **Tracer** `#3EE0D2` — The only cyan: tracers, weapon rib, reload fill, and hit-confirm crosshair
- **Shield** `#7EB6FF` — Shield bar and shield cells
- **Health** `#F08A4B` — Health bar and health cells
- **Bolt** `#E7B15A` — Enemy projectiles and the empty-magazine numeral
- **Track** `#241F1A` — Empty tracks behind the bars and the reload fill
- **Glass** `rgba(12,11,9,0.78)` — Title, pause, game-over, and HUD panels
- **Hurt** `#C46B4A` — Damage vignette only. Never a splatter decal
## Typography
- **Display** — Chakra Petch (OFL), weights 600/700. Self-host the font files.
- **Body** — Source Sans 3 (OFL), weights 400/600. Self-host the font files.
- **Ammo** — JetBrains Mono (OFL), weights 500. Self-host the font files.
## Spacing & shape
- Spacing: The canvas fills the viewport. Overlay panels sit 20px from the edges on viewports at least 768px wide, and 14px from the edges below that, plus env(safe-area-inset-*). The title card padding is 28px 32px. Stacked HUD rows use a 6px gap. Touch sticks are 112px across with 16px outer margins, and the Fire and Reload buttons have a 10px gap.
- Radius: Title, pause, and game-over cards are 10px. Text buttons are 8px. Health bars, shield bars, sticks, and the round Fire and Reload buttons are pills at 999px.
## Motion
- Before the round, the title drone yaws at 0.25 rad/s and bobs 0.12 m at 0.8 Hz. The bob amplitude is 0 when prefers-reduced-motion is set.
- While the player is moving faster than 0.4 m/s, the camera bobs 0.016 m vertically and 0.008 m laterally, with 0.004 rad of roll. A shot kicks pitch by 0.008 rad for 70 ms. A hit offsets the camera 0.012 m for 100 ms. Skip all three when prefers-reduced-motion is set.
- Floor cells spin at 0.7 rad/s on Y. Combat drones bob 0.1 m at 1.4 Hz. Both hold still when prefers-reduced-motion is set.
- A destroyed drone emits 18 sparks that travel 2.2 m and fade in 0.4 s. A viewport under 768px, or a coarse pointer, uses 8 sparks. Reduced motion uses 6 sparks that fade in place over 0.25 s and do not travel.
- The reload track fills linearly across 950 ms. A hit on a drone turns the crosshair Tracer for 80 ms. At 30 health or below, the health bar pulses from opacity 1 to 0.45 and back over 0.8 s, unless reduced motion is set, in which case the bar stays solid.
- Buttons only change background color on hover. They do not scale, bounce, or rise. Cards show and hide with no page transition.
## Imagery
No photographs, textures, or downloaded models. The first screen is the live yard: dark slabs, four warm lamp pools, crate stacks, a gantry, and one hovering drone, with the glass title card centered over that scene rather than a flat color field. The carbine, drones, bolts, cells, tracers, and sparks are three.js meshes and points. The only flat graphic is the favicon SVG.
## Tone
Dry and physical, like a notice posted at a test range. Short labels, no jokes, no exclamation marks, and no gore.
---
— Prompt by VibeFather · https://vibefather.ai/t/sci-fi-arena-wave-survival-game · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown
Make it yours
- A game design student: set BRAND and ARENA to your coursework project, rename DRONE to your enemy type, and keep the wave loop as the playable build.
- A small studio's internal test range: set OPERATOR to the studio name, label WEAPON as your prototype carbine, and use the retry card to show wave reached.
- A classroom WebGL exercise: keep the default yard, change the five names to your class theme, and use the static build to teach wave spawning.
- A tabletop or LARP group: set ARENA to your event arena and DRONE to the scenario's enemy, then share the static build as a between-session mini game.
Sci-Fi Arena Wave Survival Game: questions and answers
What happens if a browser blocks pointer lock in the Sci-Fi Arena Wave Survival Game?
The Sci-Fi Arena Wave Survival Game catches the refusal and switches to drag-look plus arrow keys, so the round still plays inside sandboxed frames. The start click requests pointer lock; if the browser denies it, looking moves to dragging the view and the arrow keys. Shooting, reloading, collecting cells, losing and retrying all stay available, and no console error appears.
How do the health and shield cells work in the Sci-Fi Arena Wave Survival Game?
Warm floor cells restore health and cool floor cells restore shield, and neither bar refills on its own. Enemy bolts empty the shield bar before they touch health. A taken cell returns on a timer, so the yard keeps offering pickups. Both bars sit in the dark glass HUD beside ammo, the wave number and the drone drop count.
Is there a final wave or a win screen in the Sci-Fi Arena Wave Survival Game?
There is no last wave. Drones arrive in numbered waves, each wave adds a few drones and a little speed, then leaves a short breather before the next. A round ends only when health reaches zero, and the retry card shows the wave reached and how many drones dropped. The score lives in memory and resets only when Retry runs.
How do I reskin the Sci-Fi Arena Wave Survival Game with my own names?
Five variables carry the naming: BRAND is the game title, OPERATOR the range operator, ARENA the yard name, WEAPON the carbine label above ammo, and DRONE the singular enemy name. Change them in the content file and rewrite the strings that name the range, keeping every number, layout and mechanic. The weapon stays a 12-round magazine carbine whatever WEAPON says.
Can I reuse the Sci-Fi Arena Wave Survival Game as a static demo or student project?
The Sci-Fi Arena Wave Survival Game builds to static files with no backend, server code or external APIs, so a developer or student can host it anywhere and reuse the lamps, bars and wave loop as a demo. The prompt and DESIGN.md are free for personal, non-commercial use; commercial or client work needs Pro, which also brings the source code.
How do I build a Sci-Fi arena wave survival game with AI?
Copy the prompt from this page or run npx vibefather add sci-fi-arena-wave-survival-game, replace [ARENA], [BRAND], [DRONE] and [WEAPON] 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 Sci-Fi Arena Wave Survival Game demo?
The Sodium yard range case was built by Grok 4.7 in Grok Build; the Brick kiln range 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 Sci-Fi Arena Wave Survival Game template use?
Sci-Fi Arena Wave Survival Game is a single-page site built with Tailwind CSS and 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 Sci-Fi Arena Wave Survival Game template for a client or a business?
The Sci-Fi Arena Wave Survival 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 Sci-Fi Arena Wave Survival Game template work on mobile?
Yes. Every Sci-Fi Arena Wave Survival 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.