A 3D tower-defense skeleton for Ship Shit Games — you play the Wardens, holding a single lane against the Scourge horde. Built with Vite + TypeScript
- Three.js, no framework, no external art (Three.js primitives only).
Hold the line. Build towers. Stop the Scourge.
- An angled perspective camera looks down over a grid board with one lane from the Scourge spawn to your base.
- Click an empty cell to build a tower (costs gold). Towers can't sit on the lane or on each other.
- The Scourge spawns in escalating waves and walks the lane.
- Towers auto-target the nearest in-range creep and fire ember projectiles.
- Killing a creep grants gold. A creep that reaches the base costs 1 Base HP.
- Clear all waves to win. Hit 0 Base HP and the line is lost.
The HUD shows Gold, Wave / Total, Base HP, and a build hint with the current tower cost.
Pure DOOM (see the studio DESIGN.md): void-black scene, gunmetal lane and
tower bodies, hellfire turret heads + projectiles, blood-red Scourge
creeps with a sickly toxic bio-glow, and a bone/hellfire base marker.
npm install
npm run dev # local dev server (http://localhost:5173)
npm run build # static production build -> dist/
npm run preview # serve the built dist/
buildis intentionallyvite buildonly (notsc) so a deploy never blocks on a type nit. Runnpx tsc --noEmityourself for a full typecheck.
Push to a repo and import it on Vercel — it auto-detects Vite
(build vite build, output dist/). No config needed.
A thin Game class owns shared GameState and a few systems, driven by one
requestAnimationFrame loop with a clamped delta. Tunables live in a single
data-driven CONSTANTS object.
index.html # canvas + plain-DOM HUD overlay
src/
main.ts # entry: mounts the Game on the canvas
game.ts # Game class: owns state, runs the loop + wave director
constants.ts # CONSTANTS (board/economy/tower/creep/waves) + COLORS
types.ts # GameState + entity interfaces
board.ts # grid <-> world math, lane waypoints, path-cell set
styles.css # DOOM HUD styling
systems/
render.ts # Three.js scene, camera, board art, hover highlight
entities.ts # towers / creeps / projectiles: spawn, target, move, combat
input.ts # pointer raycast -> grid cell, hover + click
hud.ts # DOM overlay updates (no framework)
Everything balance-related is in src/constants.ts: board size & lane shape,
starting gold / tower cost / rewards, base HP, tower range / fire rate / damage,
creep HP & speed and their per-wave growth, wave count / pacing, and camera.
- The Wardens — engineers and gunners who hold the lanes with towers and attrition.
- The Scourge — the endless mutating horde that pours from the breaches.
This is a playable skeleton, not a finished game: one tower type, one creep type, a fixed lane. The systems are structured so adding tower/creep types, multiple lanes, or upgrades is mostly data + a new branch.