Presence & Chat Systems
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The Presence and Chat systems in Dreamcats provide the infrastructure for real-time multiplayer interaction and connectivity tracking. These systems ensure that players can communicate during gameplay and that the application can accurately reflect the online status of all participants in a game room.
Built on the Convex backend, these systems leverage real-time subscriptions to keep the client-side state synchronized with the global game state. The presence system specifically handles heartbeats to detect disconnected players, while the chat system manages message persistence and distribution across all connected clients in a specific room.
Presence System Architecture
The presence system is responsible for tracking player connectivity through a heartbeat mechanism. This is critical for real-time synchronization and detecting when players have left or lost connection to a game session.
Heartbeat Mechanism
The system utilizes a client-side heartbeat implemented in ConvexSync.tsx. When a player is in an "online" game mode, the client initiates an interval that triggers a mutation every 10 seconds. This mutation updates the player's "last seen" timestamp in the database.
The client also monitors the status of other players. If a player's lastSeenAt timestamp is older than 30 seconds, they are considered disconnected.
Sources: convex/rooms.ts:167-205, src/state/ConvexSync.tsx:90-108
Presence Data Model
The presence system relies on two primary tables defined in the schema: players and presence. The players table tracks the structural relationship between a user and a room, while the presence table tracks transient connectivity status.
| Field | Type | Description |
|---|---|---|
roomId | v.string() | The ID of the room the player is in. |
playerId | v.string() | The unique identifier for the player session. |
status | v.string() | Current status (e.g., "online", "away", "disconnected"). |
lastPing | v.number() | Timestamp of the most recent heartbeat. |
Sources: convex/schema.ts:17-30, convex/schema.ts:63-69
Chat System Implementation
The chat system enables players within the same room to send and receive text messages in real-time. It consists of a frontend interface, a centralized state management slice, and a Convex backend for persistence.
Data Flow
Chat messages are stored in a dedicated messages table. When a player sends a message, it is persisted to Convex. The ConvexSync component subscribes to the message list for the current room and updates the local Zustand store, which in turn triggers a re-render of the ChatBox component.
Components and Logic
The ChatBox component handles the display and submission of messages. It includes auto-scroll functionality to ensure users see the latest messages as they arrive.
- ChatBox.tsx: Provides the UI for viewing the message history and an input field for sending new messages.
- ConvexSync.tsx: Maps remote message objects (containing
_id,senderId,senderName,message, andtimestamp) to the localChatMessagetype. - store.test.ts: Validates that chat messages can be appended to the local state correctly.
Sources: src/components/ChatBox.tsx:11-35, src/state/ConvexSync.tsx:77-88, src/tests/store.test.ts:133-146
Chat Message Schema
Messages are indexed by roomId and timestamp to allow for efficient retrieval of the conversation history within a specific game session.
| Field | Type | Description |
|---|---|---|
roomId | v.string() | Identifier for the game room. |
senderId | v.string() | Player ID of the message sender. |
senderName | v.string() | Display name of the sender at the time of sending. |
message | v.string() | The text content of the message. |
timestamp | v.number() | Server-side timestamp of when the message was received. |
Sources: convex/schema.ts:54-61
Connectivity and Reconnection
The systems are designed to handle transient network issues. The application state includes a netStatus field that transitions between "connected", "connecting", "disconnected", and "error".
- Silent Rejoin: If a player refreshes their browser, the
ConvexSynccomponent attempts to restore theplayerIdandroomIdfrom session storage. If no game state is found but a session exists, it triggers ajoinRoommutation to re-establish the connection. - Network Feedback: The client calculates network status by filtering the
remotePlayerslist for those seen within the last 30 seconds.
Sources: src/state/ConvexSync.tsx:50-75, src/state/ConvexSync.tsx:101-107, src/tests/store.test.ts:233-243
Summary
The Presence & Chat systems provide the backbone for the multiplayer experience in Dreamcats. By utilizing a 10-second heartbeat mechanism and a real-time message subscription model, the project ensures that game rooms remain interactive and that player availability is accurately reflected across the network. These systems are tightly integrated with the Convex backend for authoritative state management and the Zustand store for responsive UI updates.