CS Web.
First-person 3D Counter-Strike in the browser with real-time multiplayer over WebSockets, plus a round system with economy and a buy menu. First to five wins.

CS Web is a first-person 3D Counter-Strike duel that runs entirely in the browser. Two players connect over WebSockets and fight authoritative 1v1 rounds with an economy, a buy menu and CS 1.6 weapon feel, first to five round wins. The whole client is hand-written Three.js in ES modules with no bundler, and the server is a single Node process with exactly one dependency.
The architecture is split cleanly between a thin authoritative server and a predictive client. The Node server (server.js plus a static file server, a mode-agnostic room registry and a matchmaking lobby) holds the source of truth for HP, armor, money, score and round phase. Clients simulate their own movement and shooting locally and report hit events, then modes/duel.js validates them, caps damage, applies armor and headshot rules, awards kill and round money and drives the round state machine. Game modes are pluggable: rooms carry a mode object exposing startMatch and handleMessage, so a second mode such as bomb defuse slots in without touching matchmaking or combat.
Combat is genuine hitscan. weapons.js fires a Three.js raycaster from the eye against per-body-part hitboxes, distinguishing head from body, and folds in a real first-person shooting model: per-weapon base spread, a movement penalty that scales with 2D speed, vertical recoil with horizontal drift, distance falloff and shotgun pellet spread. The AWP is laser-accurate only while scoped and standing still and sprays like a no-scope the moment you move, and a knife backstab is a lethal hit that punches straight through kevlar. The constants file is pure data, so every weapon and price is tunable in one place.
Movement is a custom kinematic controller, not a physics library. movement.js does axis-wise AABB collision with sliding along walls, step-up onto low boxes, ramp following, jump and gravity, all built on a documented height grid where half boxes (1 m) are jumpable and full boxes (2 m) require a ramp. The map itself is procedural: map.js builds the arena geometry, a decorative city skyline and a border with deterministic canvas textures, and exposes builder functions plus a surfaceHeight() query that the controller and the remote player both read.
The remaining systems are equally deliberate. The remote player is interpolated with position and angle lerping, animated legs and distance-scaled footstep and gunshot audio, and peer shots are replayed locally as tracers and impact decals. Audio layers real CS 1.6 samples over a WebAudio synthesizer that fills in while samples load and generates the UI and kill music. There is no build step at all: the client loads Three.js r160 through an import map from a CDN and ships raw ES modules. It is also an installable PWA with a service worker, and a self-contained mobile overlay emulates keyboard and mouse so desktop play stays byte-for-byte identical. Three test harnesses back it up: a two-client WebSocket protocol test, a headless Chrome rendering test and a synthetic-touch mobile end-to-end test.