Architecture Overview
An interactive look at the components of a scalable, privacy-focused typing game. This section provides a high-level map of the system architecture. Click on any component below to explore its role and the technology behind it.
1. Frontend Client
HTML, CSS, Vanilla JS
2. Backend Server
Node.js, Socket.IO
3. Real-Time Data Store
Redis
4. Persistent Data Store
PostgreSQL
Frontend Client Details
The client-side application is built with standard web technologies. Its primary jobs are rendering the game, handling user input, and communicating with the backend via WebSockets. To protect privacy, it generates a unique UUID on first visit and stores it in `localStorage`. This UUID, along with the user's average WPM (their League Score), is used for matchmaking without requiring a login. All game history is stored locally.
Backend Server Details
A Node.js server using the Socket.IO library manages all real-time communication. It is designed to be stateless, meaning it doesn't store any game session data itself. This allows for horizontal scaling behind a load balancer to handle up to 10,000 concurrent users. Its main tasks are matchmaking, creating game rooms, and broadcasting player progress updates to others in the same room.
Real-Time Data Store Details
Redis serves as the central, high-speed memory for all active game data. This includes player progress, the status of game rooms, and the matchmaking queues. By storing this ephemeral state in Redis, any backend server instance can handle any player's request, making the entire system resilient and scalable. If a server instance fails, the user can reconnect to another and the game state is not lost.
Persistent Data Store Details
A PostgreSQL database stores static, long-term data that doesn't change frequently. This includes the library of typing texts used for the races, the definitions of the different leagues (e.g., Bronze: 0-40 WPM), and other configuration data. The backend servers query this database when creating a new game room to fetch a random text.
The Player's Journey
From landing on the page to finishing a race, the player's experience is managed by a seamless flow of events. This section breaks down the client-server interaction sequence. Click on any step to see a detailed explanation.
Step 1: Connection & Identification
Step 2: Matchmaking & Room Assignment
Step 3: Real-Time Progress Reporting
Step 4: Race Finish & League Update
The Backend Engine
The server-side logic is designed for high performance and scalability. This section visualizes the live matchmaking process, a core function of the backend. Players are sorted into queues based on skill to ensure fair races.
Live Matchmaking Queues
This chart simulates players waiting for a game. Click the button to add a new player, who will be randomly placed into a league queue based on their skill.
League Progression Simulator
The game uses a unique, stateless method for league advancement to protect user privacy. A player's matchmaking rating is stored locally and adjusted after each race. Interact with the simulator below to see how winning or losing affects a player's standing for their next game.
Player's Local State
Stored in `localStorage`
Matchmaking WPM Value
40
Next Game Placement
Determined by WPM
Matchmaking Queue
Bronze