A React application built with Vite that serves as the entry point for users. Provides both interactive gameplay and spectator modes.
- Framework: React + TypeScript
- Build Tool: Vite
- Styling: Tailwind CSS
- Auth: Supabase Auth Helpers
- WebSockets: Native WebSocket API
-
src/pages/GameView.tsx- Interactive game mode- Connects to Play WebSocket (
ws://localhost:3001) - Requires authentication
- Handles WASD/Arrow key input
- Sends
SET_DIRECTIONmessages to server - Displays facing direction with arrow indicators
- Connects to Play WebSocket (
-
src/pages/WatchView.tsx- Spectator mode- Connects to Watch WebSocket (
ws://localhost:3002) - No authentication required
- Read-only view of the world
- Shows entity count and debug logs
- Connects to Watch WebSocket (
src/components/Grid.tsx- Renders the game grid (16px cells)src/components/Cell.tsx- Individual grid cell (white background)src/components/EntityDot.tsx- 2x2 entity visualization with facing arrowssrc/components/ConversationUI.tsx- Overlay for managing conversation requests and active chatssrc/components/ConnectionStatus.tsx- WebSocket connection indicator
src/contexts/AuthContext.tsx- Manages Supabase login statesrc/lib/supabase.ts- Client-side Supabase configuration
- Login: Users authenticate via Supabase (email/password)
- Connect: Client opens WebSocket to port 3001, sends auth token
- Join: Server validates token, spawns player at saved position
- Sync: Client receives
SNAPSHOTinitially, thenEVENTSfor updates - Input:
- Key down: Add to pressed keys stack, send
SET_DIRECTION - Key up: Remove from stack, send updated direction
- Server tick (10Hz): Processes movement based on current direction
- Key down: Add to pressed keys stack, send
- Render: Entities displayed as colored circles with directional arrows
- Connect: Client opens WebSocket to port 3002 (no auth)
- Snapshot: Receives full world state immediately
- Updates: Receives
EVENTSbroadcast from play server - Render: Same visualization as play mode, but no input handling
The client handles these server events:
SNAPSHOT- Full world state (map + all entities)EVENTS- Array of world events:ENTITY_JOINED/ENTITY_LEFT/ENTITY_MOVED/ENTITY_TURNEDENTITY_STATE_CHANGED- State updates (e.g., entering conversation)CONVERSATION_REQUESTED- Incoming request from another entityCONVERSATION_STARTED/CONVERSATION_ENDEDCONVERSATION_ACCEPTED/CONVERSATION_REJECTED
ERROR- Server-side error messageWELCOME- Successful join confirmation (play mode only)
Create a .env file:
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-public-keynpm install
npm run devApp runs on http://localhost:3000
/- Redirects to/watch/play- Interactive game (requires login)/watch- Spectator mode (no login)/login- Authentication page
Display player names:
// In GameView.tsx or WatchView.tsx
{entityHere && (
<>
<EntityDot {...props} />
<span className="text-xs">{entityHere.displayName}</span>
</>
)}Add chat system:
- Create
src/components/ChatBox.tsx - Add WebSocket message type
CHATin server - Send messages via
ws.send(JSON.stringify({ type: 'CHAT', message }))
Improve styling:
- Grid is currently 16px cells (see
Grid.tsx) - Entities are 2x2 cells with absolute positioning
- TailwindCSS classes can be modified for themes
- Check WebSocket connection: Browser DevTools → Network → WS tab
- View state: Add
console.log(entities)in render - Test reconnection: Close/reopen browser tab
- Simulate lag: Chrome DevTools → Network → Throttling