Commit graph

6 commits

Author SHA1 Message Date
aa68343ac2
feat(balance): 30-wave campaign, 5 new enemy types, steeper per-wave scaling
The campaign was too easy: a handful of un-upgraded towers stopped
everything. This makes the game substantially harder across three axes.

Campaign extended from 20 to 30 hand-tuned waves (endless now starts at
31). Victory messages, HUD label (via store.totalWaves synced from
TOTAL_WAVES), start screen, lobby and README updated.

Five new enemy types debut in later waves, each with a hand-drawn
canvas look:
- Brute (wave 8): fast tank hybrid, 130 HP, 2 lives
- Phantom (wave 12): fast flyer with real HP, 2 lives
- Scorpion (wave 14): very fast ground, 2 lives
- Golem (wave 18): walking bunker, 560 HP, 3 lives
- Dragon (wave 22): flying boss, 950 HP, 3 lives, gets its own top
  boss health bar like the boss

Per-wave HP scaling steepened (1 + 0.16m + 0.025m², was 0.18m + 0.02m²):
wave 10 now ~4.6x (was 4.2x), wave 20 ~13.2x (was 11.6x), wave 30 ~29x.
Late waves mix the new types into heavy compositions; wave 30 is the
final wall (3 bosses, 2 dragons, 4 golems, 12 scorpions). Endless waves
scale all ten types with bosses every 5 and dragons from endless+2.

Balance validated with the headless greedy-bot simulation: the bot
(capped around tower level 5 on fixed spots) previously trivially won
the campaign and now dies at wave 29 — clearing wave 30 requires
evolved towers (level 6+), research bonuses and good placement. The
sim docs were updated to describe this new tuning philosophy.

New render smoke test (npm test): draws all ten enemy kinds through
the real renderer with a stub 2D context, two frames each with slow/
DoT/flash effects active, guarding every drawEnemy code path. 55 checks
green, build clean. Browser-verified: campaign starts and HUD shows
"Welle x/30".
2026-08-17 20:29:47 +02:00
69fbb015ab
feat(admin): live admin dashboard with solo presence tracking
Solo games run entirely in the browser, so the server previously had no
idea who was playing right now (it only saw logins and finished games).
This adds lightweight presence reporting and an admin dashboard.

Presence (server):
- POST /api/presence (logged-in users): heartbeat while a solo game runs,
  stores username, map (validated), difficulty, wave, since/lastSeen per
  user; entries expire automatically after 90s without a heartbeat
- POST /api/presence/stop: explicit removal when the player exits

Admin API (ADMIN_USERS env, comma-separated usernames):
- GET /api/admin/overview: live solo players, multiplayer room summaries
  (code, mode, map, players — the server already tracks rooms), and
  global stats (accounts, rounds, crystals in circulation)
- GET /api/admin/users?limit=100: user list with stats, newest login first
- publicUser now carries an admin flag; non-admins get 403

Admin UI (src/components/AdminDashboard.vue, served at /admin):
- Login gate for guests/non-admins (guest profiles are detected via
  isLoggedIn, not just user presence)
- KPI cards, live solo table (player, map, difficulty, wave, duration),
  room table, and account table; auto-refresh every 5 seconds
- App.vue renders the dashboard for /admin instead of the game and runs
  a screen watcher that starts/stops the solo presence heartbeat

Config: ADMIN_USERS documented in docker-compose.yml and README.

Tests: 6 new integration checks (admin flag, presence report/stop,
403 guard, overview contents, user list) — 37/37 green, build clean.
Verified end-to-end in the browser: guest gate, admin login, and a live
second player (map/difficulty/wave) appearing in the dashboard.
2026-08-17 15:07:02 +02:00
4f8400c480
feat: add 9-level tower evolution system with distinct tier abilities
Extend all 5 towers to 9 upgrade levels, divided into 3 visual and
functional evolution tiers:
- Tier 1 (L1-3, Yellow): Base stats (damage, range, rate).
- Tier 2 (L4-6, Orange): First major ability evolution with pulsing orange aura.
- Tier 3 (L7-9, Blue): Final devastating evolution with blue aura.

Evolutions per tower:
- Arrow Tower:
  * L4-6 (Orange): Multishot firing 2-3 arrows simultaneously at distinct targets.
  * L7-9 (Blue): 4-arrow multishot + Poison DoT (up to 28 dmg/s).
- Cannon:
  * L4-6 (Orange): Incendiary shells applying Burn DoT in splash radius.
  * L7-9 (Blue): Flak shells hitting flying units with full splash + burn damage.
- Frost Tower:
  * L4-6 (Orange): Permafrost - every 3rd pulse completely freezes enemies (speed = 0).
  * L7-9 (Blue): Shatter - frozen enemies receive +50% damage from all sources.
- Tesla Tower:
  * L4-6 (Orange): Chain lightning applies stun on each hit.
  * L7-9 (Blue): Lightning Storm - every 4th shot strikes and stuns ALL enemies in range.
- Laser Tower:
  * L4-6 (Orange): Prism refraction splitting the beam onto 2-3 secondary targets.
  * L7-9 (Blue): Piercing beam penetrating all enemies in a line up to 280px range.

Engine & Renderer updates:
- Added DoT tick handling (poison/burn) and freeze/stun status effects.
- Added visual indicators for frozen enemies (ice spikes) and DoT particles.
- Added 3-slot tier-colored pips on tower base plates + pulsating evolution auras.
- Updated TowerPanel with 9-star tier display (★★★ yellow, ★★★ orange, ★★★ blue)
  and dynamic special ability descriptions.

Testing & Validation:
- Added `scripts/test-evolution.mts` covering all 10 evolved mechanics (all green).
- Verified lockstep multiplayer determinism via `scripts/test-mp.mts`.
- Verified solo campaign balance preservation via `scripts/sim.mts`.
- Full TypeScript typecheck and production build passing.
2026-08-16 13:54:09 +02:00
4ec0e483aa
feat(server): add security hardening for public hosting
- Add CSP, frame and referrer headers for served static files
- Enforce WebSocket origin check to prevent cross-site hijacking
- Trust X-Forwarded-For only when the peer is from a private proxy network
- Limit concurrent connections (500 total / 20 per IP) and rooms (300)
- Add ALLOWED_ORIGINS env var for additional WebSocket origins
- Document reverse proxy setup (NPM/NPMplus) in README
- Add scripts/security-test.mjs to verify origin and limit behavior
2026-08-16 13:16:20 +02:00
b506ffad55
feat(docker): add self-hosted all-in-one container setup
- Add Dockerfile (multi-stage build, unprivileged user, healthcheck),
  docker-compose.yml and .dockerignore
- Server now serves static dist/ frontend and WebSocket relay on a
  single port (PORT, default 3001) with path-traversal protection,
  immutable asset caching and SPA fallback
- Client connects via same origin in production; dedicated ws port is
  only used for vite dev/preview
- Document Docker usage, env vars and manual production mode in README
2026-08-16 12:15:52 +02:00
c4347f8420
feat: initialize TRXTD browser tower defense 2026-08-15 16:07:09 +02:00