3.4 KiB
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
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.