#System Architecture
#High-Level Overview
The SPGG bot system follows a layered architecture where each component has a specific responsibility:
┌──────────────────────────────────────────────────────────────┐
│ WebSocket Server (Cloud) │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ Match Queue │ │ Stream Mgmt │ │ Log Collector │ │
│ └──────┬──────┘ └──────┬───────┘ └────────┬────────┘ │
└─────────┼────────────────┼───────────────────┼──────────────┘
│ │ │
──────┼────────────────┼───────────────────┼──────────
│ Network │ │
──────┼────────────────┼───────────────────┼──────────
│ │ │
┌─────────▼────────────────▼───────────────────▼──────────────┐
│ Local Machine │
│ │
│ ┌─────────────────┐ ┌─────────────────────────────┐ │
│ │ GUI Launcher │────▶│ Bot Script │ │
│ │ (Thread Holder) │ │ (Main Automation) │ │
│ │ fc25-gui.py │ │ fc25.py │ │
│ └─────────────────┘ └──────────┬──────────────────┘ │
│ │ │
│ ┌─────────────────┐ ┌──────────▼──────────────────┐ │
│ │ Focus Monitor │ │ Screen Comparator │ │
│ │ focus.py │ │ (Template Matching) │ │
│ └─────────────────┘ └──────────┬──────────────────┘ │
│ │ │
│ ┌─────────────────┐ ┌──────────▼──────────────────┐ │
│ │ OBS Studio │◀────│ Memory Reader │ │
│ │ (RTMP Streaming) │ │ FC25Memory.py │ │
│ └─────────────────┘ └──────────┬──────────────────┘ │
│ │ │
│ ┌──────────▼──────────────────┐ │
│ │ Game Process │ │
│ │ (FC25.exe / Undisputed) │ │
│ └─────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘#Component Responsibilities
#1. GUI Launcher (Thread Holder)
The GUI launcher is a Tkinter application that serves as the primary control interface. Its main roles:
- Process Management: Start/stop bot scripts via batch files
- PID Tracking: Persist process IDs to JSON for reliable cleanup
- Memory Validation: Verify Cheat Engine addresses before starting
- WebSocket Listener: Accept remote start/stop/git-pull commands
- Settings Management: UUID and match duration configuration
The GUI does NOT run the bot logic directly. It launches
start.bat/fc25-start.bat/und-start.batwhich in turn runs the Python bot script.
#2. Bot Script (Main Logic)
The bot script is the core automation engine:
- WebSocket Client: Connects to the server to receive match instructions
- Screen Comparator: Continuously monitors the game screen using template matching
- Input Automation: Sends keystrokes/mouse movements via
pyautoguiandpynput - Memory Reader: Reads real-time match data from game process memory
- OBS Control: Manages RTMP streaming through OBS WebSocket
#3. Memory Reader
Each game has its own memory reader class that:
- Reads game memory using
pymem - Extracts scores, match time, ball position, statistics
- Handles pointer chains and dynamic memory addresses
- Validates that Cheat Engine scripts are active
#4. Screen Comparator
A shared class (ScreenComparator) that:
- Captures screenshots using
PIL.ImageGrab - Compares against pre-made template images
- Uses pixel-by-pixel comparison with configurable threshold
- Supports mask colors (red
#ff0000for FC24/FC25, green#22ff00for Undisputed) - Fires callbacks when screen state changes
#5. Shared Modules
| Module | Purpose |
|---|---|
play.py |
Replay recorded JSON event sequences (mouse/keyboard) |
read.py |
OCR-based team selection reading (FC24 only) |
focus.py |
Window focus monitoring loop (FC24 only) |
#Data Flow: Match Lifecycle
Server sends "new-match" event with team data
│
▼
Bot receives event → stops OBS stream
│
▼
Bot waits for stream restart → begins team selection
│
▼
ScreenComparator detects league/team screens
│
▼
Bot navigates to correct teams using OCR + key presses
│
▼
Match starts → Memory listener thread begins
│
▼
Memory thread reads scores/stats every 0.5s
│
▼
Bot emits "match-data" to server continuously
│
▼
ScreenComparator detects "finished" or "winniewinner" screen
│
▼
Bot emits "end-match" → navigates to next match
│
▼
Server sends next "new-match" → cycle repeats