Bird
Raised Fist0
LLDsystem_design~10 mins

Extensibility (NxN board, multiple players) in LLD - Scalability & System Analysis

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Scalability Analysis - Extensibility (NxN board, multiple players)
Growth Table: Extensibility for NxN Board with Multiple Players
ScaleBoard SizeNumber of PlayersGame State SizeServer LoadLatency Impact
100 users3x3 to 5x52-4 playersSmall (few KB)Low, single server sufficientMinimal
10,000 users5x5 to 10x102-6 playersMedium (tens of KB)Moderate, multiple servers with load balancerNoticeable if unoptimized
1,000,000 users10x10 to 20x202-10 playersLarge (hundreds of KB)High, horizontal scaling neededNeeds optimization (caching, async updates)
100,000,000 users20x20+Multiple players (10+)Very large (MBs per game)Very high, distributed system with shardingCritical to optimize network and data flow
First Bottleneck

The first bottleneck is the game state storage and synchronization. As the board size (NxN) and number of players increase, the amount of data to store and update grows quickly. This stresses the database and network bandwidth, causing delays in state updates and player experience degradation.

Scaling Solutions
  • Horizontal scaling: Add more game servers behind a load balancer to handle more concurrent games and players.
  • State partitioning (sharding): Split game states by game ID or player groups to distribute database load.
  • Caching: Use in-memory caches (e.g., Redis) for frequently accessed game state to reduce DB hits.
  • Event-driven updates: Use message queues or pub/sub to asynchronously update players, reducing synchronous load.
  • Efficient data structures: Store only diffs or changes instead of full board state to reduce data size.
  • CDN and edge computing: For static assets or game logic, reduce latency by serving closer to players.
Back-of-Envelope Cost Analysis

Assuming 1 million users playing simultaneously with average 5 players per game:

  • Games running concurrently: ~200,000 (1,000,000 / 5)
  • Requests per second (QPS): Each player sends ~1 move per 5 seconds -> 200,000 moves/sec total
  • Database QPS: 200,000 updates/sec is too high for single DB instance (max ~10,000 QPS)
  • Bandwidth: Each update ~1 KB -> 200 MB/s outbound bandwidth needed
  • Storage: Each game state ~100 KB, 200,000 games -> 20 GB in memory or fast storage
Interview Tip

Start by defining the core components: game state, players, and board size. Discuss how increasing board size and players affects data size and update frequency. Identify the database and network as bottlenecks early. Propose clear scaling strategies like sharding and caching. Always relate solutions back to the bottleneck you identified.

Self Check Question

Your database handles 1000 QPS. Traffic grows 10x to 10,000 QPS. What do you do first?

Answer: Introduce read replicas and caching to reduce load on the primary database. Also consider sharding the game state by game ID to distribute writes across multiple database instances.

Key Result
The main scalability challenge is managing the growing game state size and update frequency as board size and player count increase. Early bottlenecks appear in database write capacity and network bandwidth, which require sharding, caching, and horizontal scaling to resolve.

Practice

(1/5)
1. What is the main benefit of designing a game system with an NxN board and support for multiple players?
easy
A. It allows the game to be easily extended to different board sizes and more players without major code changes.
B. It limits the game to only two players and a fixed board size.
C. It makes the game run faster by using fixed-size arrays only.
D. It removes the need for input validation.

Solution

  1. Step 1: Understand extensibility in game design

    Extensibility means the system can grow or change easily without rewriting code.
  2. Step 2: Apply extensibility to NxN board and multiple players

    Using flexible data structures and modular code allows changing board size and player count easily.
  3. Final Answer:

    It allows the game to be easily extended to different board sizes and more players without major code changes. -> Option A
  4. Quick Check:

    Extensibility = Easy growth [OK]
Hint: Extensibility means easy to add features later [OK]
Common Mistakes:
  • Thinking fixed size is more extensible
  • Ignoring input validation importance
  • Assuming extensibility means faster code
2. Which of the following code snippets correctly initializes a flexible NxN board in Python for any given size n?
easy
A. board = [[0]*n]*n
B. board = [[0 for _ in range(n)] for _ in range(n)]
C. board = [0]*n
D. board = [0 for _ in range(n)]

Solution

  1. Step 1: Understand list initialization for 2D board

    Using list comprehension creates independent inner lists for each row.
  2. Step 2: Compare options for correct 2D board creation

    board = [[0 for _ in range(n)] for _ in range(n)] creates a list of lists with separate inner lists, avoiding shared references.
  3. Final Answer:

    board = [[0 for _ in range(n)] for _ in range(n)] -> Option B
  4. Quick Check:

    Independent rows = board = [[0 for _ in range(n)] for _ in range(n)] [OK]
Hint: Use nested list comprehensions for independent 2D lists [OK]
Common Mistakes:
  • Using [[0]*n]*n causes shared inner lists
  • Initializing only 1D list for 2D board
  • Confusing list multiplication with comprehension
3. Given a game system supporting multiple players, what will be the output of this Python snippet?
players = ['Alice', 'Bob', 'Carol']
turns = 5
for i in range(turns):
    current = players[i % len(players)]
    print(current)
medium
A. Bob Carol Alice Bob Carol
B. Alice Bob Carol Carol Carol
C. Alice Alice Alice Alice Alice
D. Alice Bob Carol Alice Bob

Solution

  1. Step 1: Understand modulo for cycling players

    The modulo operator cycles index through player list length (3).
  2. Step 2: Trace each iteration's player

    i=0 -> Alice, i=1 -> Bob, i=2 -> Carol, i=3 -> Alice, i=4 -> Bob.
  3. Final Answer:

    Alice Bob Carol Alice Bob -> Option D
  4. Quick Check:

    Modulo cycles players = Alice Bob Carol Alice Bob [OK]
Hint: Use modulo to cycle through players repeatedly [OK]
Common Mistakes:
  • Not using modulo causes index errors
  • Assuming players list is longer than turns
  • Confusing player order in output
4. Identify the bug in this code snippet for initializing a variable-sized board and multiple players:
def setup_game(n, players):
    board = [[None]*n]*n
    for p in players:
        print(f"Player: {p}")
    return board

setup_game(3, ['A', 'B'])
medium
A. The board rows are references to the same list, causing shared updates.
B. The players list is not printed correctly.
C. The function does not return anything.
D. The board size is fixed to 3 regardless of input.

Solution

  1. Step 1: Analyze board initialization

    Using [[None]*n]*n creates rows that reference the same list object.
  2. Step 2: Understand impact of shared references

    Changing one cell affects all rows because they share the same inner list.
  3. Final Answer:

    The board rows are references to the same list, causing shared updates. -> Option A
  4. Quick Check:

    Shared inner lists cause bugs = The board rows are references to the same list, causing shared updates. [OK]
Hint: Avoid list multiplication for nested lists [OK]
Common Mistakes:
  • Ignoring shared reference problem
  • Thinking players print is incorrect
  • Assuming function returns nothing
5. You are designing a turn-based game with an NxN board and support for multiple players. Which design approach best supports easy extensibility for future features like variable board sizes, more players, and custom rules?
hard
A. Write all game logic in one large function for simplicity.
B. Use fixed-size arrays and hardcoded player count with separate functions for each board size.
C. Use flexible data structures (lists/dictionaries), modular functions, and validate inputs dynamically.
D. Use global variables for board and players to avoid passing parameters.

Solution

  1. Step 1: Identify extensibility requirements

    Extensibility needs flexible data structures and modular code to adapt easily.
  2. Step 2: Evaluate design options

    Use flexible data structures (lists/dictionaries), modular functions, and validate inputs dynamically. uses lists/dictionaries and modular functions with input validation, supporting future changes well.
  3. Final Answer:

    Use flexible data structures (lists/dictionaries), modular functions, and validate inputs dynamically. -> Option C
  4. Quick Check:

    Modular + flexible data = extensible design [OK]
Hint: Modular code + flexible data = easy extensibility [OK]
Common Mistakes:
  • Using fixed sizes limits future changes
  • Writing monolithic functions reduces flexibility
  • Using globals causes maintenance issues