Together is a browser-based, persistent multiplayer cozy life simulator for Couple and Friends households. Players create a household, choose a home in Amaya Bay, live in an embodied first-person world (with switchable third-person), work gentle physical jobs, shop, cook, clean, decorate, explore, spend time together, experience authored life stories, and preserve shared history in a private Memory Book.
docs/PRD.md is the authoritative product source. If this README conflicts with the PRD, the PRD wins.
This repository is a substantial V1 implementation and handoff build, not a claim of release-complete production art. The implemented code includes:
- WebGPU-first Three.js renderer architecture with WebGL2 fallback;
- Rapier kinematic player physics, first/third-person cameras, gamepad and remappable keyboard input;
- a ~900m × 900m Amaya Bay world split into 128m chunks, with a shared streamed world-space road/path/promenade network;
- 7 major districts, 28 named subareas/colonies, 45 distributed everyday venues, terrain/elevation, streamed neighborhood dressing and vegetation;
- five starter home shells and persistent furniture/surface customization;
- 92 furniture/decor definitions, including 20 greenery options;
- Couple/Friends household creation, six-character invite codes, property voting and Socket.IO presence;
- eight embodied chore families and a reusable micro-action framework;
- 23 grocery/household items, 20 recipes and persistent co-op cooking sessions;
- server-authoritative personal/shared wallets, transaction idempotency and five job definitions;
- bicycle, scooter, kayak and auto-rickshaw transport foundations;
- 8 persistent leisure activities with shared sessions;
- 12 named persistent NPCs with schedules, memory flags and authored contextual dialogue, plus an instanced ambient city population;
- 36 data-driven household stories (20 shared, 8 Couple, 8 Friends) and seven life stages;
- private manual/automatic Memory capture, captions and share-card export;
- renovation and moving flows with voting, packing decisions and moving memories;
- WebRTC household/proximity voice architecture with Socket.IO signaling and authenticated server-issued TURN credentials;
- sticky notes, accessibility controls, quality tiers, performance diagnostics and debug tooling foundations.
See the October 1 project audit for current findings and prioritized remaining work. Local full verification passes; current browser CI and six-player startup acceptance fail. docs/IMPLEMENTATION_STATUS.md and docs/KNOWN_LIMITATIONS.md retain detailed system and historical acceptance notes.
- Node.js 24 LTS
- pnpm 12.4.1 through Corepack
- a modern desktop browser with WebGPU or WebGL2
The connected CI baseline uses Node 24, Corepack and the committed dependency graph with pnpm install --frozen-lockfile. For local development, use the same major runtime and package-manager versions rather than copying node_modules across platforms.
corepack enable
pnpm install --frozen-lockfile
pnpm verify
pnpm test:e2ecp .env.example .env
pnpm install
pnpm devDefault local URLs:
- Client:
http://localhost:5173 - Server:
http://localhost:3001
Without Supabase credentials, development uses the in-memory repository and local private Memory image storage. Production intentionally requires Supabase server credentials.
Authoritative connected gate:
pnpm typecheck
pnpm lint
pnpm test
pnpm validate
pnpm validate:repo
pnpm build
pnpm test:e2eAs of 2026-09-20, runtime HEAD 5c08f8106ab1fa1914afee3ca1bf59aa9b1ea073 passes the complete GitHub Actions gate in run 35490206098, including solo playable-frame/movement/camera acceptance, two-browser Couple household movement replication, and a six-browser Friends movement + reconnect acceptance in explicit WebGL2 compatibility mode. Normal product startup remains WebGPU-first.
node tools/verify-sandbox.mjs remains available as a reduced offline diagnostic, but it is no longer the authoritative verification record. See docs/VERIFICATION.md.
together/
client/ React/Vite UI + framework-independent Three.js game runtime
server/ Express + Socket.IO + authoritative game services + persistence adapters
shared/ Runtime-validated contracts and pure deterministic game rules
content/ Typed recipes, NPCs, stories, jobs/activities and validation
tools/ Repository and sandbox verification utilities
docs/ PRD, audit, build plan, architecture, status and handoff documentation
Important runtime boundaries:
- React owns menus/panels/HUD, not per-frame transforms.
- Three.js owns the real-time world and frame loop.
- persistent consequences are server-authoritative.
- movement remains locally responsive and synchronizes through snapshots.
- content is data-driven and validated.
- hidden needs/relationship state is never presented as numeric HUD meters.
Set server variables in .env:
SUPABASE_URL=
SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
DATABASE_URL=
SUPABASE_MEMORY_BUCKET=together-memories
Enable Supabase anonymous sign-in for the V1 client identity flow. Client builds also require VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY.
Build the server and run DATABASE_URL=... pnpm --filter @together/server migrate to apply migrations 001 through 012 with advisory locking/checksum protection.
STUN works without application credentials. Production-grade NAT traversal requires server-side TURN configuration:
STUN_URL=stun:stun.l.google.com:19302
TURN_URL=
TURN_SHARED_SECRET=
TURN_TTL_SECONDS=3600
The browser authenticates to /api/voice/ice-config and receives short-lived credentials. Never expose TURN_SHARED_SECRET through a VITE_* variable. Voice audio is never stored by the application.
Start here:
docs/PRD.md— authoritative product requirements.docs/REPO_AUDIT_AGAINST_PRD.md— old prototype audit.docs/BUILD_PLAN.md— dependency-ordered implementation plan.docs/IMPLEMENTATION_STATUS.md— actual phase status and evidence.docs/ARCHITECTURE.md— actual implemented architecture.docs/DEVELOPMENT.md— install/run/test/service setup.docs/ASSET_REQUIREMENTS.md— final production asset replacement requirements.docs/KNOWN_LIMITATIONS.md— explicit unfinished/blocked work.HANDOFF.mdandCONTINUATION_PROMPT.md— continuation state.