A one-hour playable slice of a reactive role-playing game, built as a tiny browser game with raw HTML5 Canvas and TypeScript. The point is the engineering skeleton, not the graphics: a shared world state drives a clock, NPC routines, reputation, and reputation-dependent dialogue. The visuals are deliberately throwaway — coloured circles and rectangles in a top-down view.
See assignment.md for the full design brief.
Slim, role-owned documents that describe the game so the project can scale to a team:
docs/VISION.md— the one-page vision, pillars, scope, and asset list (Direction)docs/STORY_BIBLE.md— setting and one sheet per character (Narrative → Art)docs/QUEST_FLOW.md— the three paths as a branching flowchart (Design)docs/TESTING.md— automated + manual test plan (QA)
- Node 20 or newer (developed on Node 26). Check with:
If you need to upgrade on macOS:
node --version
brew install node(or use nvm). - A modern browser (Chrome, Firefox, Safari, or Edge).
No Docker, no Python venv, no game framework — Node plus a browser is the entire toolchain.
From the project root:
npm install # first time only — installs dependencies into node_modules/
npm run dev # starts the Vite dev server with hot reloadThen open the printed URL (usually http://localhost:5173) in your browser. The page hot-reloads as you edit files in src/.
| Command | What it does |
|---|---|
npm run dev |
Start the dev server with hot reload (use this to play/develop). |
npm run build |
Type-check (tsc) and produce a production build in dist/. |
npm run preview |
Serve the built dist/ locally to verify the production bundle. |
You need the storeroom key before the temple gate closes at 14:00. The in-game clock advances automatically (a real minute or two covers the whole morning). Three townspeople can each get you the key a different way.
Controls
- Arrow keys — move your character.
- E (or click near an NPC) — talk / interact.
The three paths to the key
- Honest — return Aravindan the Steward's lost prayer beads (found by the well); he hands you the key.
- Trade — buy a garland from Manimekalai the Merchant to earn goodwill, then she'll sell you a duplicate key. Lie or short her and she refuses.
- Stealth — Kovalan the Guard leaves his post for the midday meal from 12:00 to 12:30. Slip into the storeroom in that window.
Win: obtain the key before the gate closes. The debug panel (top of the page) shows the live clock, reputation, and flags as you play.
src/
main.ts entry point: build initial state, start the loop
types.ts shared interfaces (WorldState, NpcState, ...)
engine/gameLoop.ts fixed-timestep loop: advance clock, tick NPCs, render
sim/ pure game logic (reputation, npcs, dialogue, quests, winCheck)
data/ initial world, NPC schedules, dialogue lines
render/ throwaway canvas view + HTML debug panel
input/ keyboard/click input -> intents
The architecture rule: only sim/, data/, and engine/ know game logic. render/ and input/ never change game rules — input emits intents, the simulation decides what happens. The shared WorldState object is the single source of truth.