Back to Projects

Stock Ticker

Real-time multiplayer board game simulating stock market trading with strategic gameplay

Role: Full-Stack Developer
Timeline: May 2025 - Present
Status: Live
Stock Ticker project screenshot

01. Overview

Stock Ticker is a full-stack real-time multiplayer board game that simulates stock market trading with strategic gameplay mechanics. Built with React and Node.js, the game supports multiple concurrent sessions where players compete in synchronized gameplay, making investment decisions based on dice rolls, market conditions, and player actions. The game features live synchronization via Socket.IO, ensuring all players experience the same game state simultaneously with minimal latency.

The project demonstrates enterprise-level full-stack development, combining real-time game mechanics with financial market concepts. It includes three distinct game modes (Traditional, Modern, and Limited Supply), AI players with multiple personas and strategies, a comprehensive achievement system, ELO rating system, friends system, leaderboards, and a complete admin panel. All game state is persisted in PostgreSQL with automatic recovery after server restarts.

02. Problems & Challenges

Building a real-time multiplayer game presented several significant challenges:

  • Real-Time Synchronization: Ensuring all players see the same game state simultaneously across multiple concurrent game sessions was critical. Any delay or desynchronization would break the game experience. I needed to handle WebSocket connections, manage game state on the server, broadcast updates efficiently, and handle player reconnections gracefully.
  • Modular Game Mode Architecture: Implementing three distinct game modes (Traditional, Modern, Limited Supply) with a flexible architecture that allows modes to be combined (e.g., Modern + Limited Supply) required careful design. I needed to create a base GameMode class with proper inheritance and delegation patterns.
  • AI Player System: Building multiple AI personas with different strategies (Conservative, Aggressive, Balanced, Dividend Farmer, Speculator) that could play intelligently required implementing decision-making algorithms that consider game state, player positions, and market conditions.
  • Game State Persistence & Recovery: Implementing automatic game state saving with debouncing and the ability to recover games after server restarts required careful serialization of complex game objects and efficient database storage using JSONB fields in PostgreSQL.
  • ELO Rating System: Implementing a multi-player ELO rating system that adjusts for game size and handles edge cases (ties, AI players, 2-player games) required understanding rating algorithms and ensuring atomic database transactions.
  • Comprehensive Security: Implementing JWT authentication, rate limiting (API, auth, Socket.IO), password security (bcrypt, complexity requirements, history tracking), input validation, file upload security (magic bytes, MIME types), and admin role-based access control required multiple layers of security measures.
  • Performance Under Load: With multiple concurrent games and players, the server needed to handle actions, validate moves, update statistics, and broadcast updates without lag. Optimizing database queries, implementing debounced saves, and managing Socket.IO connections efficiently was essential.
  • Complex Achievement System: Building a comprehensive achievement system that tracks dozens of statistics (stocks bought/sold per stock, dice rolls, placements, etc.) and calculates achievements efficiently required careful database schema design with JSONB fields and efficient querying patterns.

Critical Challenge: Race Conditions & State Consistency

One of the most difficult problems was preventing race conditions when multiple players tried to perform actions simultaneously. For example, if two players tried to buy the same stock at the same time in Limited Supply mode, the system needed to handle this correctly without data corruption or inconsistent game state. Additionally, ensuring game state consistency across server restarts and handling edge cases like players leaving mid-game required careful transaction management and state serialization.

03. Solutions & Implementation

I addressed these challenges through careful architecture and implementation:

  • Server-Authoritative Architecture: The server maintains the single source of truth for game state. All player actions are sent to the server, validated, processed, and then broadcast to all clients. This prevents cheating and ensures consistency. The Game class encapsulates all game logic, with specialized handlers for dice, turns, state, players, AI, and lifecycle management.
  • Modular Game Mode System: Implemented a base GameMode class with three concrete implementations (TraditionalGameMode, ModernGameMode, LimitedSupplyGameMode). Limited Supply mode uses a decorator pattern to wrap base modes, allowing combinations like Modern + Limited Supply. Each mode handles its own initialization, turn/round events, and game-specific logic.
  • AI Persona System: Created multiple AI personas (Conservative Charles, Aggressive Alex, Balanced Bella, Dividend Diana, Speculative Sam) with distinct strategies. Each persona uses a strategy function that analyzes game state and makes decisions based on their personality. The GameAIHandler manages AI turn processing and integrates seamlessly with the game loop.
  • Debounced Game State Persistence: Implemented automatic game state saving with 2-second debouncing to avoid excessive database writes. Games are serialized to JSONB and stored in PostgreSQL, allowing full game recovery after server restarts. The GameManager handles persistence and game lifecycle management.
  • Multi-Player ELO Rating System: Implemented an ELO system that adjusts for game size using a logarithmic factor (fN = log2(N) / 3). The system handles edge cases like ties, AI players (excluded from ELO), and 2-player games. All rating updates use database transactions to ensure atomicity.
  • Comprehensive Security Layers: Implemented JWT authentication with token expiration, rate limiting (200 req/15min API, 5 req/15min auth, 60 events/min Socket.IO), password security (bcrypt hashing, complexity requirements, history tracking to prevent reuse), input validation with express-validator, file upload security (magic byte checking, MIME type validation, size limits), and admin middleware for role-based access control.
  • Socket.IO with Rooms & Reconnection: Used Socket.IO for WebSocket connections, which handles reconnection automatically and provides rooms for game sessions. Each game session is a Socket.IO room, making it easy to broadcast to all players in a game. The system handles player disconnections gracefully and restores state on reconnection.
  • Efficient Achievement Calculation: The achievement system uses JSONB fields in PostgreSQL to store complex statistics efficiently. Achievements are calculated on-demand with caching of stat values to avoid repeated computation. The system tracks dozens of metrics including per-stock statistics, dice roll distributions, and game outcomes.

Game State Management & Persistence

The GameManager class handles all game lifecycle operations, including creation, persistence, and recovery. Games are automatically saved with debouncing (2 seconds after last change) to balance performance with data safety. The entire game state is serialized to JSONB, allowing full recovery after server restarts. Here's how the game state is saved:

GameManager.js
// Save game state to database (debounced)
async saveGameState(game, immediate = false) {
  // Skip saving completed games
  if (game.status === 'complete') {
    return;
  }

  // Debounce saves to avoid excessive database writes
  if (!immediate) {
    const existingTimer = this.saveDebounceTimers.get(game.id);
    if (existingTimer) {
      clearTimeout(existingTimer);
    }

    const timer = setTimeout(async () => {
      await this._saveGameState(game);
      this.saveDebounceTimers.delete(game.id);
    }, 2000); // Save 2 seconds after last change

    this.saveDebounceTimers.set(game.id, timer);
    return;
  }

  // Immediate save
  await this._saveGameState(game);
}

04. Key Learnings

This project taught me valuable lessons about building real-time applications:

  • Real-Time Architecture: I learned the importance of server-authoritative design for multiplayer games. Trusting the client for game logic leads to cheating and inconsistent states. The server must validate all actions and maintain the single source of truth.
  • Modular Architecture Patterns: Building a flexible game mode system taught me about inheritance, composition, and the decorator pattern. Creating a base GameMode class with specialized implementations allowed for extensibility while maintaining clean code.
  • AI Decision-Making Systems: Implementing multiple AI personas with different strategies taught me about decision trees, state evaluation, and algorithm design. Each AI persona needed to make intelligent decisions based on game state, market conditions, and player positions.
  • Database Design for Complex Data: Using JSONB fields in PostgreSQL for storing complex nested game data and statistics taught me when to use structured vs. unstructured data. I learned to balance query performance with flexibility.
  • Rating Systems & Algorithms: Implementing a multi-player ELO rating system taught me about rating algorithms, statistical adjustments, and handling edge cases. The system needed to be fair across different game sizes and handle ties appropriately.
  • Security Best Practices: Implementing comprehensive security (JWT, rate limiting, password security, input validation, file upload security) taught me about defense in depth. Each layer of security addresses different attack vectors, and they work together to create a robust system.
  • Performance Optimization: Implementing debounced saves, efficient database queries, and optimized Socket.IO broadcasting taught me about balancing performance with data safety. Premature optimization is bad, but strategic optimization is essential for real-time applications.
  • State Persistence & Recovery: Building a system that can recover games after server restarts taught me about serialization, state management, and graceful degradation. The system needed to handle partial state, corrupted data, and edge cases gracefully.
  • Testing Complex Systems: Writing tests for real-time multiplayer systems taught me about mocking WebSocket connections, testing async operations, and ensuring test isolation. The project has Jest tests for backend and Vitest for frontend, though coverage is an ongoing effort.

Major Takeaway

The biggest lesson was understanding that building a production-ready real-time multiplayer game requires thinking about the entire system holistically. It's not just about WebSockets or game logic—it's about security, performance, data persistence, user experience, and maintainability. This project taught me to consider edge cases, handle failures gracefully, and design for scale from the beginning. The modular architecture I built allows for easy extension (new game modes, AI strategies, features) while maintaining code quality.

05. Tech Stack

Frontend

React 19 JavaScript (ES6+) TailwindCSS Material UI Axios Socket.IO Client React Router Recharts

Backend

Node.js Express 5 PostgreSQL Sequelize ORM Socket.IO JWT Bcrypt Winston

Security & Middleware

Rate Limiting Express Validator CORS Multer Nodemailer

Development & Testing

Vite Jest Vitest Playwright Docker ESLint

06. Results & Impact

Stock Ticker successfully demonstrates enterprise-level full-stack development:

  • Real-Time Multiplayer: Supports multiple concurrent game sessions with real-time synchronization via Socket.IO. All players see the same game state simultaneously with minimal latency, and the system handles disconnections and reconnections gracefully.
  • Multiple Game Modes: Implements three distinct game modes (Traditional, Modern, Limited Supply) with a flexible architecture that allows modes to be combined. Each mode has unique mechanics and gameplay rules.
  • AI Player System: Features five AI personas with distinct strategies (Conservative, Aggressive, Balanced, Dividend Farmer, Speculator) that make intelligent decisions based on game state and market conditions.
  • Comprehensive Achievement System: Tracks dozens of statistics including per-stock metrics, dice roll distributions, game outcomes, and player progression. Achievements are calculated efficiently using JSONB fields and caching.
  • ELO Rating System: Implements a multi-player ELO rating system that adjusts for game size and handles edge cases. All rating updates use database transactions for atomicity.
  • Social Features: Includes a friends system (friend requests, acceptance, rejection), user profiles with avatars and bios, and comprehensive leaderboards with multiple categories.
  • Admin Panel: Features a complete admin interface for managing users, games, system settings, activity logs, announcements, and analytics. Includes role-based access control and audit logging.
  • Game State Persistence: Automatically saves game state with debouncing and can recover games after server restarts. Games are serialized to JSONB for efficient storage and retrieval.
  • Security: Implements comprehensive security including JWT authentication, rate limiting (API, auth, Socket.IO), password security (bcrypt, complexity requirements, history tracking), input validation, file upload security, and admin middleware.
  • Testing Infrastructure: Includes Jest tests for backend (24% coverage, targeting 100%), Vitest for frontend, and Playwright for E2E testing. Test coverage tracking and comprehensive test suites for critical functionality.

The project showcases my ability to build complex, production-ready real-time applications with comprehensive features, security, and scalability considerations. It demonstrates full-stack development skills from database design and API architecture to real-time communication and frontend state management. The modular architecture allows for easy extension and maintenance, making it a solid foundation for a multiplayer gaming platform.

Screenshot