Geometry TD is a high-performance, co-op capable tower defense game played directly in the web browser for up to 4 players. It combines intense real-time battles, state-of-the-art web graphics (WebGL), and a robust multiplayer architecture featuring a server-side authoritative game simulation.
The visual design is built around a neon-cybernetic cyber-glassmorphism theme, accompanied by smooth particle effects and a reactive soundtrack in the main menu.
- GPU-Accelerated Rendering (PixiJS v8): Pure WebGL rendering engine. Utilizes advanced techniques such as sprite pooling (for projectiles and particles) and isolated
RenderGroupsto prevent stuttering and CPU overhead. - Network Synchronization & Co-op (Up to 4 Players): Real-time multiplayer combining WebSockets (Socket.io) and WebRTC Peer-to-Peer for co-op play. Features:
- Dynamic Map Division: The map splits dynamically into halves (2 players), thirds (3 players), or quadrants (4 players) based on player count.
- Automated Tower Relocation: Shifts in boundaries trigger a relocation phase (game paused, full refund sell values) for towers left outside the player's new zone.
- Individual Budgets: Gold is split equally upon player connection. Wave completion bonuses are shared, and enemy bounties are awarded based on tower damage contribution.
- Aesthetics & Glows: Cyber-glowing neon lines partition the game board. Towers emit player-colored glowing rings, and upgrade tooltips display ownership.
- Authoritative Headless Host System: To prevent cheating, the core game physics and state calculations run on a server-side headless browser (Puppeteer/Chromium). Clients receive validated delta updates and interpolate them smoothly.
- Headless Health-Check & Clean-up System: The backend runs a health check every 30 seconds to clean up orphaned browser instances (e.g., when all human players leave the lobby), abort browsers stuck in the launching state (> 45s), and restart crashed instances.
- Persistent Progress System: Secure registration and login via JWT-based authentication (stored in secure HttpOnly cookies). Progress, unlocked skins, achievements (with confetti animations), and high scores are saved in a PostgreSQL database.
- Reactive Music Visualization: Background music frequencies are analyzed in real time via the Web Audio API (
AnalyserNode) to render an animated equalizer in the main menu. - In-Game Encyclopedia (Lexicon): Integrated overview of all tower classes and enemy types, including detailed attribute progress bars and lore descriptions.
- Interactive Balancing Dashboard: Dedicated local visualization tool built with Chart.js. Allows designers to dynamically tweak tower damage/cost scaling models, inspect upgrade efficiency curves (splitting at Level 10) with adjustable x and y axes scaling, and simulate build DPS configurations against exponential enemy EHP waves.
- Frontend: HTML5, CSS3 (Modular Vanilla CSS with glassmorphism effects), TypeScript, PixiJS (v8), Vite
- Backend: Node.js, Express, Socket.io, Puppeteer-Core, tsx (TypeScript Execute), JWT auth, cookie-parser, bcrypt
- Database: PostgreSQL (via
pg-promise) - Infrastructure & Deployment: Docker, Docker Compose, Nginx (for static web serving and reverse proxying)
geometry-td/
โโโ backend/ # Server application (Express, WebSockets, Headless Puppeteer)
โ โโโ src/
โ โ โโโ routes/ # REST endpoints (Auth, Game Stats)
โ โ โโโ auth.ts # Token verification & auth helper functions
โ โ โโโ db.ts # Database connection & schema initialization
โ โ โโโ headless.ts # Puppeteer control (headless Chromium host instances)
โ โ โโโ schemas.ts # Zod validation schemas for WebSocket payloads
โ โ โโโ socket.ts # Socket handler with Zod schema validation
โ โ โโโ state.ts # Global in-memory server state
โ โ โโโ types.ts # Common TypeScript interfaces & types
โ โ โโโ server.ts # Main server entry point
โ โโโ Dockerfile.dev # Development Dockerfile with Chromium pre-installed
โ โโโ Dockerfile.prod # Production Dockerfile (Multi-stage build)
โ โโโ tsconfig.json
โโโ frontend/ # Client application (Game & Main Menu)
โ โโโ public/ # Static assets (Audio tracks, Changelog, Web fonts)
โ โโโ src/
โ โ โโโ css/ # Modular stylesheets (Portal, Menu, Mobile, Game)
โ โ โโโ js/ # Game engine, entities (towers/enemies), UI & WebRTC P2P
โ โ โโโ core/ # Core systems (Game loop, state, map, achievements, pool)
โ โ โโโ entities/ # Game entities (Towers, Enemies, Projectiles)
โ โ โโโ fx/ # Visual effects, particles, and graphics
โ โ โโโ ui/ # User interface components, HUD, modals, and tooltips
โ โ โโโ types.ts # Client-side TypeScript interfaces & types
โ โโโ default.conf # Nginx configuration for production (Proxying & Gzip)
โ โโโ Dockerfile.dev # Development Dockerfile
โ โโโ Dockerfile.prod # Production Dockerfile with Nginx server
โ โโโ index.html # Main entry page
โ โโโ game.html # Game board page (also loaded by the headless host)
โ โโโ balancing.html # Interactive tower & wave balancing dashboard
โ โโโ vite.config.js
โโโ tsconfig.json # Root solution-style configuration for multi-package IDE support
โโโ docker-compose.yaml # Local container configuration (development services only)
โโโ docker-compose.example.yaml # Template for Dev & Prod services (including volumes/networks)
โโโ package.json # Global npm scripts for code validation
The project is fully orchestrated using Docker Compose.
- Docker and Docker Compose installed on the host system.
- A
.envfile in the root directory of the project with the following configuration:# PostgreSQL database password DB_PASSWORD=your_secure_password_here # Secret key for signing JWT tokens JWT_SECRET=your_secure_jwt_secret_here # Host filesystem path to the project root directory (crucial for Docker volumes) PROJECT_ROOT=C:\path\to\geometry-td # On Windows # PROJECT_ROOT=/home/user/geometry-td # On Linux/macOS
Starts the development containers with live-reloading enabled for the frontend (Vite) and the backend (tsx watch).
Start the development services:
docker compose up -d db-dev backend-dev frontend-dev- Frontend: Available at
http://localhost:7777(proxied internally to Vite dev server on port5173). - Backend API: Port
7676(internal Express server on port3000with tsx). - Database: PostgreSQL runs on port
5432(data is persisted locally in thedb_data_devDocker volume or directory).
Important
Important note on docker-compose.yaml:
By default, docker-compose.yaml in this repository only defines the development services (*-dev).
The template file docker-compose.example.yaml contains the full configuration for both development and production.
To deploy in production, copy the production services (frontend-prod, backend-prod, db-prod) along with their corresponding networks and volumes from docker-compose.example.yaml into your active docker-compose.yaml.
Once the configuration has been merged, you can deploy:
docker compose up -d --build frontend-prod backend-prod db-prodTip
Automated Production Deployment (GitHub Actions & Tailscale):
- Continuous Deployment Pipeline: Every push to the
mainbranch triggers the GitHub Actions workflow defined in.github/workflows/deploy.yml. - Automated Quality Check: The pipeline automatically runs
npm run check-allto validate backend TypeScript types, frontend lints, Prettier checks, and production builds before deploying. - Secure Tailscale SSH Deploy: Upon successful validation, GitHub Actions securely connects to the NAS over Tailscale VPN (without public router port exposure) and executes
deploy.shto pull code, rebuild production containers, and prune unused Docker images.
- Frontend Nginx (
frontend-prod): Accessible externally on port8181. Nginx serves the compiled static web assets, applies Gzip compression, and acts as a reverse proxy forwarding API requests (/api/) and WebSocket traffic (/socket.io/) to the backend container. - Backend API (
backend-prod): Runs internally on port3000as the unprivilegednodeuser and is exposed on host port7171. - Database (
db-prod): Isolated within the internal bridge network (gtd-prod-network) and accessible only to the backend container. Data is persisted in thedb_data_prodvolume.
The game uses a SSOT balancing system (Single Source of Truth) defined in config.ts. All upgrade costs, damage stats, and enemy HP scaling curves are calculated dynamically from this file.
- Base (Standard): Low-cost all-rounder. Specializations at level 10:
- Homing Missiles: Fires target-seeking missiles.
- Heavy Ammo: Increases direct damage at the cost of fire rate.
- Sniper: Infinite range. Specializations at level 10:
- Ricochet: Projectiles bounce to neighboring enemies.
- Bounty Hunter: Generates bonus gold on enemy kills.
- Bomb: Massive area-of-effect (AoE) damage. Specializations at level 10:
- Nuke: Leaves a radioactive ground aura that damages and slows passing enemies.
- Cluster: Projectiles explode into multiple sub-bombs.
- Tesla: Chain lightning. Specializations at level 10:
- High Voltage: Increases direct chain lightning damage.
- Shock Stun: Brief stun effect on hit.
- Prisma: Continuous laser beam with damage scaling over time. Specializations at level 10:
- Meltdown Overdrive: Triggers a massive explosion once maximum laser charge is reached.
- Refraction Split: Splits the laser beam across multiple nearby targets.
- Booster: Support tower that does not attack directly, but amplifies the range, damage, or fire rate of all nearby towers (excluding other Boosters) inside its radius. Specializations at level 10:
- Frequency Modulation: Boosts the attack speed of nearby towers by +40% (Mastery: +75%).
- Amplitude Amplifier: Boosts the damage of nearby towers by +40% and range by +20% (Mastery: +80% damage, +35% range).
- Generator: Passive economic tower that generates gold during active waves. Does not target or shoot at enemies. Purchase cost scales dynamically (+300g per built Generator). Specializations at level 10:
- Investment Bank: Yields a flat payout of +80g (Mastery: +400g) at the end of each wave instead of generating gold passively during waves.
- Industrial Production: Multiplies passive gold income by 1.5x (Mastery: 3.0x).
Automated checks should be executed before committing code to ensure type safety and code quality.
- Validate Entire Project (Frontend & Backend):
Runs type checks in the backend, and lints, Prettier checks, and production builds in the frontend.
npm run check-all
- Validate Frontend Only:
npm run check-all:frontend
- Validate Backend Only:
npm run check:backend
If the validation check fails on code formatting, format all frontend files automatically with:
cd frontend
npm run formatThe backend manages Puppeteer browser instances to serve as authoritative game hosts.
- Source Code: Managed in headless.ts.
- Launch Arguments: Puppeteer launches Chromium inside the container (executable path
/usr/bin/chromium) with arguments like--disable-gpuand--disable-dev-shm-usageto minimize resource consumption. - Health Checks:
A background check runs every 30 seconds:
- Stuck Preventer: Any instance stuck in the
launchingstate for longer than 45 seconds is forcefully terminated and deleted. - Orphan Clean-up: If a room has no human players remaining (
playerCount === 0), the headless host is stopped. - Crash Recovery: If a running browser becomes unresponsive (i.e.
browser.version()times out), the instance is closed, marked asfailed, and a new host is spawned for the room.
- Stuck Preventer: Any instance stuck in the
All tower attributes (damage, range, fire rate, upgrade costs, and specialization features) are configured inside a single data-driven lookup table:
- Path:
frontend/src/js/core/config/tower-database.ts
This allows for surgery-like fine-tuning of each level (from 1 to 20) and specialization path without altering code logic or math formulas.
Copyright ยฉ 2026. All rights reserved.
The source code is provided solely for demonstration and portfolio purposes. Reproduction, modification, or commercial use of the code (specifically hosting the game on your own platforms) is not permitted without explicit permission.