live

Words Are Snake

Word-Steered Snake Game

A word game with a twist: the letters in your typed word steer the snake — U goes up, D goes down, L goes left, R goes right. Chain combos to spawn bonus fruit and score. A daily shared board resets at Oslo midnight and lets everyone compare scores on a leaderboard, with optional push notifications for players who want a reminder. Duel mode pits you against an AI opponent or, in PvP, another player over an invite link — the server is the sole authority on PvP state, so neither client can influence the result.

A companion project to Words Are Snake Devlog.

Daily challenge
Daily challenge
Dark theme
Dark theme
Game over
Game over
Duel mode
Duel mode
Settings
Settings
Leaderboard
Leaderboard
Word-steered snake movement with combo scoring (palindromes, alphabetical streaks, triple turns, and more)
Daily challenge with an Oslo-midnight reset, streaks, and opt-in push reminders
AI duel and PvP duel — PvP is fully server-authoritative, joined via invite link or QR code
Word preview assist in AI duel — see your snake's projected path before you submit
Shareable recap image after every game, with rank and real fruit icons
Full English and Norwegian (Bokmål) support, including separate letter-rarity and combo tables
SvelteKit 2 Framework
SSR + API routes in one app; strict layer boundaries — components never touch the engine or DB directly
Svelte 5 UI reactivity
Runes-based stores wrap a pure, dependency-free TypeScript engine
TypeScript Language
Strict mode throughout
Drizzle ORM + PostgreSQL Database
Leaderboards, PvP game state, push subscriptions
Railway Hosting
App, Postgres, and a small scheduled service that dispatches push notifications

A SvelteKit app split into four strict layers: Svelte components never touch game logic directly, reactive stores wrap a pure, dependency-free TypeScript engine (movement, collisions, combos, scoring), and only server routes touch PostgreSQL via Drizzle. Daily and AI-duel games run entirely client-side; PvP duel is the exception — the engine runs server-side and the server is the sole authority over state, so neither player's client can influence the result. A small scheduled Railway service dispatches web push notifications on an hourly cron, working around the platform's scheduler only being able to run a command, not call a URL.

The stack didn't survive contact with duel mode. What started as a React/Vite prototype with Supabase for the leaderboard got rebuilt on SvelteKit and Postgres once PvP needed a server that could be the sole authority over game state — a two-player game can't trust either client's copy of the board.

PvP duel was the hardest design problem in the whole project: two browsers, a server-sent-event stream instead of polling, a canonical game state expressed from the host's perspective and re-mirrored for the guest, and a turn-timeout/fallback-word system that had to feel fair rather than punitive. None of that came from AI suggestions — it needed hand-drawn state diagrams before any code got written.

Where AI genuinely helped: the daily-rhythm work (Oslo-midnight resets, a countdown instead of a dead end, push notifications dispatched through a scheduled service) and the shareable recap image — an OG-style canvas render with real fruit icons and rank — were both areas where the first-pass suggestions were close to right.

All projects
EXP-005 →
Skills