Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
A mobile-first, Galaga-style arcade shooter with a dinosaur theme, hosted entirely on Val Town. One HTML file for the game, one HTTP val for hosting + the live leaderboard (Val Town SQLite).
Play it: https://tinyurl.com/29c4qac2 (full URL: https://d303--38aae36265c411f1bc951607ee4eb77e.web.val.run/)
index.html— the complete game client (HTML + CSS + JS, no build step, no external assets).main.http.tsx— Val Town HTTP handler: serves the game at/and provides the API.
GET /— the game.GET /api/leaderboard?limit=50— top scores (sorted score desc, wave desc, created_at asc).POST /api/score—{ name, score, wave, duration_ms, client_id, session_id }→{ ok, rank, score }.POST /api/session— creates a game session id (one score submission per session).GET /api/health— health check.
Server-side validation: name required/sanitized/max 24 chars, score 0..50,000,000, wave >= 1, sane duration, plausibility cap on points-per-second, light per-client rate limiting. Duplicate submissions for the same session are acknowledged without re-inserting.
- Desktop: Arrow keys / A,D to move (W,S for limited vertical), Space to shoot, P pause, M mute, Enter start.
- Mobile: drag anywhere to fly (ship floats above your finger), auto-fire while touching, big pause/mute buttons.
export PATH="$HOME/.deno/bin:$PATH" vt push # from this directory vt tail # watch logs during the event
The live URL comes from the Val Town files API (links.endpoint of main.http.tsx):
VAL_ID="$(python3 -c "import json;print(json.load(open('.vt/state.json'))['val']['id'])")" curl -s "https://api.val.town/v2/vals/$VAL_ID/files?path=&recursive=true" | python3 -m json.tool