Authentication & Sessions
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The Dreamcats platform utilizes a hybrid authentication and session management system designed to support both authenticated users and anonymous guests. Built on the Convex backend, the system manages user identity through @convex-dev/auth, allowing for persistent profiles, personalized preferences, and game state recovery across sessions.
The architecture ensures that players can seamlessly rejoin active games (both online and local hot-seat) even after browser refreshes or accidental disconnections. This is achieved by synchronizing local browser storage with server-side preference records.
Sources: convex/schema.ts, src/hooks/useSessionPersistence.ts:14-20
Data Models
The system relies on several tables within the Convex schema to track identity, connectivity, and user-specific configurations.
Database Schema Relationships
The following Entity Relationship Diagram illustrates how user identity links to game sessions and preferences.
Sources: convex/schema.ts:7-104
Table Definitions
| Table | Description | Key Fields |
|---|---|---|
users | Standard Convex Auth table for identity. | _id |
userPreferences | Stores UI settings and active session pointers. | userId, theme, activeRoomId, activeGameMode |
players | Tracks a user's presence within a specific game room. | roomId, playerId, userId, connected, lastSeenAt |
presence | High-frequency heartbeat table for real-time status. | roomId, playerId, status, lastPing |
| Sources: convex/schema.ts:40-96 |
Authentication Flow
The system supports multiple entry points, including guest play and full account creation. Authenticated users are managed via getAuthUserId(ctx) to ensure secure access to their data.
Identity Retrieval
Backend functions verify the user's status before allowing updates to preferences or game actions. If a userId is present, the system links the player's in-game playerId to their persistent account.
export const currentUser = query({
args: {},
handler: async (ctx) => {
const userId = await getAuthUserId(ctx);
if (!userId) {
return null;
}
const user = await ctx.db.get(userId);
return user;
},
});
Sources: convex/userPreferences.ts:7-18, convex/rooms.ts:12-14
Session Persistence & Rejoin Logic
Session persistence is handled by a combination of a React hook (useSessionPersistence) and server-side mutations.
Persistence Mechanism
- Online Games: When a player joins a room, their
roomIdandplayerIdare saved tolocalStorageand optionally synced to theuserPreferencestable if authenticated. - Hot-seat Games: The entire game state is debounced and saved to
localStorageevery 2000ms to allow resumption of local games. - Presence Heartbeat: The system calls
updatePlayerPresenceevery 10 seconds to maintain theconnectedstatus.
Rejoin Capability
The useUserPreferences hook provides a getActiveSession method that checks for existing session data in localStorage. This allows the UI to offer a "Rejoin Game" option upon returning to the site.
Sources: src/hooks/useUserPreferences.ts:84-110
User Preferences
Preferences are stored locally for immediate UI response and synced to the database for persistence across devices.
Managed Preferences
- Theme: Supports "light" and "dark" modes.
- Language: Synchronized with
i18nextlanguage settings. - Sound: Boolean toggle for game audio.
- Tutorial: Tracks
tutorialCompletedto avoid re-showing welcome guides.
Preference Synchronization
The backend provides mutations to update these fields, which are protected by authentication checks.
export const update = mutation({
args: {
displayName: v.optional(v.string()),
theme: v.optional(v.string()),
language: v.optional(v.string()),
soundEnabled: v.optional(v.boolean()),
},
handler: async (ctx, args) => {
const userId = await getAuthUserId(ctx);
if (!userId) throw new Error("Not authenticated");
// ... logic to patch or insert userPreferences
}
});
Sources: convex/userPreferences.ts:44-77, src/hooks/useUserPreferences.ts:28-60
Summary
The Authentication and Session system in Dreamcats provides a robust foundation for multiplayer gaming. By leveraging Convex's real-time capabilities and reactive database, the project maintains consistent player identity and game continuity. The architecture successfully bridges the gap between ephemeral guest sessions and persistent authenticated accounts through its dual-layered storage strategy (LocalStorage and Convex DB).