# slither.ts 🐍 A full **slither.io clone** written in TypeScript — authoritative Node.js + WebSocket server, Canvas 2D client, zero asset files (every texture is generated at runtime, every sound is synthesized with the Web Audio API). ## Run it ```bash npm install npm run build npm start ``` Then open **http://localhost:8080** in your browser. Open more tabs (or other machines on your LAN) for more human players — the arena is automatically filled to 12 snakes with AI bots. For development: `npm run dev` builds and starts the server. ## Features - **Smooth movement** — 30 Hz authoritative simulation, 15 Hz snapshots, client-side dead reckoning (the client runs the same movement model every frame) with decaying snapshot-correction offsets, plus dt-based exponential camera smoothing - **Grow by eating glowing pellets** scattered across the arena - **Boost** with `SPACE` (or hold left mouse / second touch finger) — moves ~2× faster while burning your length and shedding pellets from your tail - **Eliminations** — make others crash into your body; you cannot collide with yourself - **Death explosions** — dead snakes burst into glowing pellets along their whole body for everyone else to harvest - **Live leaderboard** (top 10, updates in real time) + score / rank / kills HUD - **Instant respawning** — click or hit `Enter`, no countdown - **Large circular arena** with a glowing red border that kills on contact - **Minimap** showing the entire map, all players and your position - **Slither.io-style background** — dark grey gradient, repeating hexagon grid, faint glowing hexagon outlines, soft ambient light + vignette - **AI bots** with pellet-seeking, obstacle avoidance and hunting behaviour - **Main menu** with nickname entry, **settings** (volume, quality, minimap), and **fullscreen** support — all persisted to localStorage - **Sound effects** (eat, boost whoosh, death explosion, UI clicks) and **particle effects** (eat sparkles, boost bubbles, death bursts) ## Controls | Input | Action | | ---------------- | ------------------------------- | | Mouse / touch | Steer (snake follows cursor) | | `SPACE` / click | Boost (drains length) | | `Enter` | Instant respawn when dead | ## Project layout ``` shared/ constants + protocol shared by client & server server/ world simulation (movement, collisions, bots) + HTTP/WS server client/src/ renderer, background, minimap, particles, audio, UI, input public/ index.html, style.css and the compiled client JS scripts/ smoke.mjs — end-to-end WebSocket smoke test ``` ## How it works The server simulates everything at 30 ticks/s and broadcasts compact JSON snapshots at 15 Hz (snake bodies as flat integer arrays; pellets as incremental add/remove deltas after a one-time full list). The client does **not** render the snapshots directly — it runs the same movement model locally every frame (dead reckoning): your own snake is steered straight from your input angle with the server's turn-rate limit (zero perceived input latency), remote snakes use headings estimated from snapshot deltas. Each snapshot captures the prediction error as per-point correction offsets that decay smoothly over the following frames, so server authority is kept without any visible steps. Collision and eating use a uniform-grid spatial hash, so the sim stays fast with a full arena of long snakes.