A cozy browser-based 2.5D online RPG (MMORPG-lite) — tiny animal couriers explore a shared magical forest, deliver parcels, fight monsters, craft gear, and build friendships. Server-authoritative, multiplayer, and always cozy.
- Engine: Phaser 4 (Canvas/WebGL, depth-sorted isometric/pseudo-3D)
- Language/Tooling: TypeScript, Vite 8
- UI: DOM-over-Canvas (HTML/CSS layered above the game canvas)
- Persistence: SQLite (server-side) — runtime/player databases live outside Git under the configured
persist/path; auth sessions persist locally for 24 hours while gameplay state never lives in browser storage - Server: Node/TS (separate process; HTTP + WebSocket, SQLite persistence)
- Tests: Vitest (client) + server test suite
- Hosting: single-process hosting — one Node server serves the built client + API + WebSocket on one port (Render/Fly.io/VPS/Oracle Always-Free; Vercel can host the client alone but not the game server — serverless can't hold long-lived WebSockets or write SQLite)
- VPS variant (pawsandparcels.agpstudios.org): Apache serves
dist/; the Node game server is a systemd service on127.0.0.1:3003behind Apache's/api+/wsreverse proxy (same-origin client). DB at/home/opc/pawsandparcels/data/; client runtime config isclient-config.txt. The Apache vhost is auto-generated by ASHAT Hub provisioning — re-provisioning overwrites it.
- OIDC issuer: ASHAT Hub — discovery
https://www.agpstudios.org/api/oauth/.well-known/openid-configuration, issuerhttps://www.agpstudios.org/api/oauth(RS256 id_tokens, verified against the Hub's JWKS) - Flow:
GET /api/auth/login-url→ Hub authorize page (login form) → redirect tooidc-callback.htmlwithcode→ game server exchanges it at the Hub token endpoint (PKCE) → verifies the id_token → upserts the account → mints the session JWT - Status: live end-to-end — the authorize form, PKCE code exchange, and id_token verification are all verified against the deployed Hub
- The Hub's
oauth_clientsrow forpaws-and-parcelsregisters the production callbackhttps://pawsandparcels.agpstudios.org/oidc-callback.html
The game runs its own power-managed LFM2.5-VL-450M instance (Q8 + vision projector) for monster decisions and NPC dialogue — deliberately separate from the ASHAT Hub's always-on model pair (ports 3001/3002, never touched). It spawns on demand, warms in ~5s, spins down after 10 minutes idle, and spins back up when a player joins or talks. Monster AI gets one world-brain call per zone per 5s (with an ASCII mini-map as vision); POST /api/npc/talk adds AI dialogue with an optional canvas screenshot for true VL vision. Every failure falls back to the deterministic monster AI / canned dialogue — the game never blocks on the model.
Config lives under ai in server_config.json (see server_config.example.json): enabled (default false), port (3101), modelPath/mmprojPath, idleMs (10 min), requestTimeoutMs (4s), and the NPC/monster token + rate-limit knobs. Server-side code: server/src/ai/ (ModelInstance, GameBrain, MonsterBrain, prompts, image).
| Command | Action |
|---|---|
npm ci |
Install the locked dependency set (CI/clean checkout) |
npm install |
Install dependencies |
npm run dev |
Start the Vite dev server (localhost:5173) |
npm run build |
Production build to dist/ |
npm run preview |
Preview the production build |
npm run typecheck |
TypeScript check (tsc --noEmit) |
npm test |
Run Vitest unit tests |
npm run validate |
Validate src/data content integrity |
npm run verify |
Run typecheck, tests, content validation, and production build |
npm run assets:inventory |
Rebuild the tracked asset inventory from the committed reference archive |
npm run assets:browse |
Generate the compact crawler-compatible /BrowseAssets catalog |
http://localhost:5173/BrowseAssets/ |
Open the compact crawler-compatible asset catalog after npm run dev |
npm run visual:review -- --image scripts/tiles-review.png |
Ask the local 450M VL for a dry-run 2.5D visual direction report |
npm run visual:latest |
Find the newest complete paws-visual-*.png/.json capture pair, review it, and archive the report under reports/ |
npm run visual:history |
Compare archived Visual Director reports and write recurring issues/trends to reports/visual-history.json |
| Ctrl+Shift+V in-game (Admin only) | Save a live paws-visual-*.png screenshot plus matching paws-visual-*.json scene metadata to the server's server/data/visual-captures/ directory for Visual Director review |
npm run dev:server |
Start the game/API server (localhost:3001) |
npm run start:server |
Same as dev:server (alias used by deploy configs) |
npm run test:watch |
Run Vitest in watch mode |
npm run tiles:render |
Render the authored tileset PNGs |
npm run tiles:review |
Ask the local AI for a tile-render review |
npm run tiles:loop |
Render tiles then review them in one pass |
npm run tiles:tune |
Auto-tune tile render parameters |
npm run migrate |
Apply SQLite migrations + static-content synchronization to the configured database |
http://localhost:<port>/admin.html |
Admin Control Panel — served by the game server in production; under npm run dev use http://localhost:5173/admin.html (same session as the game, admin tiers from the ASHAT Hub role) |
Runtime SQLite databases are created and migrated outside Git at the path configured in server_config.json (the example uses persist/paws-and-parcels.sqlite). Never commit production databases, account data, tokens, or secrets; Git is source control, not a production database backup or concurrent database service.
# 1. Clone (private repo — you must be added as a collaborator)
git clone https://github.com/buffbot88/Paws-Parcels.git
cd Paws-Parcels
# 2. Install Git LFS and pull the 3 large vector source files (~560 MB)
git lfs install
git lfs pull
# 3. Install dependencies
npm install
# 4. Create your local server config with real secrets
cp server_config.example.json server_config.json
# Edit server_config.json: fill in auth.jwtSecret (ask the repo owner
# for this — it is never committed), and the OIDC client details.
# 5. Run
npm run dev # client on localhost:5173
npm run dev:server # API + WebSocket on localhost:3001oraclehost_id_rsa, server_config.json, and public/server_config.json are intentionally not in the repo (SSH key + real DB/JWT secrets) — request them directly from the owner.
Windows note: the repo folder contains
&(Paws&Parcels), which breaks npm'snode_modules/.binPATH shims. Scripts call tools via explicitnode node_modules/...paths — keep them that way.
The world is drawn in 3D by default (three.js billboards on a fixed 3/4 perspective
camera over the authored tile data). The sprite renderer that preceded it is still
shipped and still correct — append ?renderer=2d to the client URL to compare the
same zone, camera framing, placements and HUD in either renderer. The choice is a
non-authoritative local preference (URL only); nothing about it is sent to the server.
public/ Static web assets (favicon, OIDC callback, client config)
reference/assets/ Raw art archive (PNGs, Aseprite/Illustrator/EPS sources, map sources); three >100 MB vector sources are Git LFS
Asset Catalog/ Browsable local image catalog and classification review site
admin.html Admin Control Panel entry (second Vite build entry)
src/
data/ Content JSON (npcs, items, quests, upgrades, dialogue) + maps/
entities/ Player, NPC (placeholder blobs + name tags)
game/ GameConfig, ErrorLog, GameConstants, Maps registry, Tiles catalog, camera framing, terrain/prop sizing/composition
render3d/ three.js world renderer (locked 3/4 camera, billboard cutouts, ground/fringe/plaza quads, shadows)
scenes/ Boot → Preloader → Overworld (zone-capable world scene)
styles/ tokens, global/primitives, game UI, profile/map/login/admin CSS
systems/ ContentValidator + MapValidator + InputSystem + InteractionSystem + DialogueService
ui/ DOM panels, menus, inventory, map, dialogue, HUD, and account flows
admin/ Admin Control Panel (screens, router, API client, design tokens)
types/ Typed data models matching src/data schemas
tests/ Vitest suites (content, map, systems)
scripts/ Content validation and asset-inventory CLIs
design/ Locked decisions, world map, NPC cards, architecture, DB schema, protocol, classes, etc.
server/ Node/TS game server (HTTP + WebSocket, SQLite persistence, migrations)
src/admin/ Admin barrel (tiers, audit model, runtime bridge)
src/routes/admin.ts Admin API handlers (tier-gated, fully audited)
Internal management surface for the live game (foundation + player tools slice). Access is derived from the ASHAT Hub account role (admin.roleTiers in server_config.json maps roles → tiers: none < support < moderator < admin < developer), layered with the per-role permission matrix (Roles & Permissions screen). Every mutation writes to the append-only admin_audit_log with before/after state, reason, environment, and request ID. Suspend/ban immediately blocks HTTP + WS auth for the account and disconnects live sessions. Dangerous actions require typed confirmation (BAN <username>) and, for Level 3 operations (suspend/ban, item archive), a fresh single-use step-up token behind a re-auth prompt; admin mutations are CSRF-checked and settings changes require a reason + confirm.
The Item Database and Item Editor screens author the item catalog directly: search/filter the catalog, edit presentation and equipment stats, see an item's usage blast radius, and archive/restore with full audit. Panel edits live in item_definitions and survive the boot-time JSON sync, and archived items stop dropping and no longer satisfy quest hand-ins.
Full picture:
ROADMAP.md· Authoritative plan:BuildPlan.md
Client foundation (old single-player plan, built ✅):
- Phase 0 — Pre-Production: ✅ complete
- Phase 1 — Project Foundation: ✅ complete (Vite + TS + Phaser 4 boot, placeholders, responsive layout)
- Phase 2 — World & Player Movement: ✅ complete (both zones, WASD/touch, collision, camera, transitions)
- Phase 3 — NPCs & Interaction: ✅ complete (5 NPCs, DOM dialogue panel, mailbox & signs, interaction prompt)
Online plan (new):
- Phase 0 — Pivot Documentation: ✅ complete (this documentation migration)
- Phase 1 — Online Foundation: ✅ built (server + SQLite + ASHAT Hub OIDC auth)
- Phase 2 — Multiplayer Village: ✅ built (client WS hookup, courier desk, presence + movement sync)
- Phases 2–8: see
BuildPlan.md §19
| Doc | What |
|---|---|
BuildPlan.md |
Authoritative build plan — online RPG, phases, scope, architecture overview |
design/decisions.md |
Locked decisions (2.5D, authority, classes, zones) |
design/architecture.md |
Client/server/SQLite responsibilities, HTTP, WS, lifecycle |
design/database-schema.md |
SQLite entities, PK/FK, ownership, auth/secrets |
design/network-protocol.md |
WS/HTTP messages (13 C→S + 15 S→C), payload shapes, validation, failure cases |
design/network-ownership.md |
Transport vs. game-facing network ownership and staged extraction boundaries |
design/classes.md |
Bear Warrior · Cat Mage · Fox Archer cards |
design/combat.md |
Damage, health, defeat, respawn, validation |
design/quests.md |
Quest chains, prerequisites, gated deliveries |
design/monsters.md |
Happy Valley critter family, spawn, loot, respawn |
design/dungeons.md |
Instance lifecycle, encounters, rewards |
design/crafting.md |
Materials, recipes, station, validation |
design/equipment.md |
Inventory, six gear slots, equip/unequip validation, courier effects |
design/engine-evaluation.md |
3D engine path evaluation (isometric Phaser recommended) |
design/AI-HANDOFF.md |
Current implementation, incomplete systems, protected boundaries, and safe next areas for visual iteration |
AGENTS.md |
Repository rules for future AI and engineering changes |
VOWS.md— development practices that bind all work heredesign/world-map.md,design/npcs.md— legacy references retained for current map and NPC/lore content