Bird
Raised Fist0
LLDsystem_design~7 mins

Move validation in LLD - System Design Guide

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
Problem Statement
Without proper move validation, a game system can accept illegal moves, causing inconsistent game states and unfair advantages. This leads to confusion, bugs, and a poor user experience as players see impossible or invalid game progressions.
Solution
Move validation checks each player's move against the game's rules before accepting it. It ensures only legal moves update the game state, preventing errors and cheating. This validation can be centralized in a dedicated component that verifies moves and rejects invalid ones.
Architecture
┌───────────────┐       ┌───────────────┐       ┌───────────────┐
│ Player Client │──────▶│ Move Validator│──────▶│ Game State DB │
└───────────────┘       └───────────────┘       └───────────────┘
         │                      │                      ▲
         │                      │                      │
         └──────────────────────┴──────────────────────┘

This diagram shows the flow where the player sends a move to the Move Validator, which checks the move and updates the Game State database only if the move is valid.

Trade-offs
✓ Pros
Prevents illegal moves, maintaining consistent and fair game state.
Centralizes rule enforcement, simplifying debugging and updates.
Improves user experience by rejecting invalid actions immediately.
✗ Cons
Adds processing overhead for each move, potentially increasing latency.
Requires comprehensive rule implementation, which can be complex for some games.
If centralized, can become a bottleneck or single point of failure.
Use when game rules are complex enough that client-side validation is insufficient or untrustworthy, especially in multiplayer or competitive games with thousands of moves per second.
Avoid if the game is very simple with trivial moves or single-player where trust in the client is sufficient and performance is critical.
Real World Examples
Chess.com
Validates each chess move server-side to prevent illegal moves and cheating in online matches.
Blizzard Entertainment
In games like Hearthstone, validates card plays and moves to enforce game rules and prevent exploits.
Epic Games
In Fortnite, validates player actions to prevent cheating and maintain fair gameplay.
Code Example
The before code applies moves directly without checking if they are legal, risking invalid game states. The after code introduces a MoveValidator that checks each move against game rules before applying it, ensuring only valid moves update the game state.
LLD
### Before: No validation
class Game:
    def __init__(self):
        self.state = {}

    def make_move(self, move):
        # Directly apply move without checks
        self.state.update(move)


### After: With move validation
class MoveValidator:
    def __init__(self, rules):
        self.rules = rules

    def is_valid(self, move, state):
        # Check move against rules and current state
        return all(rule(move, state) for rule in self.rules)

class Game:
    def __init__(self, validator):
        self.state = {}
        self.validator = validator

    def make_move(self, move):
        if self.validator.is_valid(move, self.state):
            self.state.update(move)
            return True
        else:
            return False
OutputSuccess
Alternatives
Client-side validation
Validation happens on the player's device before sending moves to the server.
Use when: Use when trust in client is high and performance is critical, but risk of cheating is low.
Hybrid validation
Initial quick validation on client, followed by authoritative validation on server.
Use when: Use when balancing user experience with security and fairness.
Summary
Move validation prevents illegal or cheating moves from corrupting the game state.
It works by checking each move against game rules before applying it.
Proper validation improves fairness and user experience in multiplayer games.

Practice

(1/5)
1. What is the primary purpose of move validation in a system design context?
easy
A. To create user interfaces
B. To speed up the system by skipping checks
C. To store user data securely
D. To ensure changes follow rules and prevent invalid actions

Solution

  1. Step 1: Understand move validation role

    Move validation checks if a requested change or move follows system rules.
  2. Step 2: Identify its main goal

    The goal is to prevent invalid or harmful actions that could break system logic or data.
  3. Final Answer:

    To ensure changes follow rules and prevent invalid actions -> Option D
  4. Quick Check:

    Move validation = Prevent invalid moves [OK]
Hint: Move validation means checking rules before allowing changes [OK]
Common Mistakes:
  • Confusing validation with data storage
  • Thinking validation speeds up by skipping checks
  • Mixing validation with UI creation
2. Which of the following is a correct basic check in move validation logic?
easy
A. if move.position = max_position: return True
B. if move.position == 'any': return True
C. if move.position < 0 or move.position > max_position: return False
D. if move.position > max_position then return False

Solution

  1. Step 1: Check syntax correctness

    if move.position < 0 or move.position > max_position: return False uses proper comparison operators and syntax for boundary check.
  2. Step 2: Identify errors in other options

    if move.position == 'any': return True uses string instead of number, C uses assignment (=) instead of comparison (==), D uses invalid syntax 'then'.
  3. Final Answer:

    if move.position < 0 or move.position > max_position: return False -> Option C
  4. Quick Check:

    Boundary check uses < and > with proper syntax [OK]
Hint: Use proper comparison operators and syntax for validation checks [OK]
Common Mistakes:
  • Using assignment '=' instead of comparison '=='
  • Using invalid keywords like 'then'
  • Checking position against wrong data types
3. Given the code snippet for move validation, what will be the output if move.position = 5 and max_position = 4?
def validate_move(move, max_position):
    if move.position < 0 or move.position > max_position:
        return False
    return True

print(validate_move(move, max_position))
medium
A. True
B. False
C. Error
D. null

Solution

  1. Step 1: Evaluate condition with given values

    move.position = 5, max_position = 4, so 5 > 4 is true.
  2. Step 2: Determine return value

    Since condition is true, function returns False.
  3. Final Answer:

    False -> Option B
  4. Quick Check:

    5 > 4 triggers False return [OK]
Hint: Check boundary conditions carefully to predict output [OK]
Common Mistakes:
  • Assuming 5 <= 4 is true
  • Confusing return values
  • Ignoring condition logic
4. Identify the bug in this move validation function:
def validate_move(move, max_position):
    if move.position <= 0 or move.position >= max_position:
        return False
    return True
medium
A. It incorrectly disallows move.position = 0
B. It allows move.position = max_position which should be invalid
C. It uses wrong comparison operators for boundaries
D. It returns true for all positions

Solution

  1. Step 1: Analyze boundary conditions

    Condition disallows move.position <= 0, so position 0 is invalid.
  2. Step 2: Check if position 0 should be allowed

    Usually position 0 is valid boundary, so disallowing it is a bug.
  3. Final Answer:

    It incorrectly disallows move.position = 0 -> Option A
  4. Quick Check:

    Check boundary inclusiveness carefully [OK]
Hint: Check if boundary conditions exclude valid edge values [OK]
Common Mistakes:
  • Confusing < and <= in conditions
  • Assuming 0 is always invalid
  • Ignoring inclusive vs exclusive boundaries
5. In a system where moves must be validated for both boundary and occupancy, which design approach best ensures scalability and maintainability?
hard
A. Use separate modular validators for boundary and occupancy checks, composed in sequence
B. Combine all validation logic in a single monolithic function
C. Skip occupancy checks to improve performance
D. Validate moves only after applying them to the system state

Solution

  1. Step 1: Consider modular design benefits

    Separating boundary and occupancy checks into modules improves clarity and reusability.
  2. Step 2: Evaluate scalability and maintainability

    Modular validators can be updated independently and composed flexibly, aiding scalability.
  3. Final Answer:

    Use separate modular validators for boundary and occupancy checks, composed in sequence -> Option A
  4. Quick Check:

    Modular design = scalable and maintainable [OK]
Hint: Modular validation improves system scalability and clarity [OK]
Common Mistakes:
  • Combining all logic makes code hard to maintain
  • Skipping important checks reduces reliability
  • Validating after applying moves risks inconsistent state