Files
mtgonline/C++/ARCHITECTURE_ANALYSIS.md
akadmin a01e33eb5e Clean up backend folder - remove obsolete scripts and test files
Removed obsolete scripts that were not imported or used:
- card_interaction_rule_engine.py
- card_profile_extractor.py
- create_card_interaction_graph.py
- interaction_determinator.py
- interaction_pipeline.py
- interaction_recommender.py
- interaction_schema.py
- recommendation_engine.py
- migrate_complete.py
- migrate_schema.py
- test_interaction_determinator.py
- check_mtgjson_full.py
- check_mtgjson_status.py
- verify_integration.py
- verify_mtgjson_data.py
- sanity_check_mtgjson.py
- investigate_sets.py
- inspect_db.py
- code_review.md
- monitor/mtg_monitor.py

Removed test artifacts:
- test.db
- test_download.py
- test_system.py
- setup_db.py
- BACKEND_TESTING_SUMMARY.md
- CHAT_PROMPT_TEST.md
- CONTINUATION_PROMPT.md
- PORTED_STATE.md
- SPEC_synergy-mapping-engine.md
- STATE.md
- SUPPORTED_FILE_TYPES.md

Removed sensitive/environment files:
- .env.local
- state.json (backend)

Cleaned up:
- __pycache__ directories
- venv directory

Backend scripts/ directory now contains only essential data loading and maintenance scripts.
2026-07-22 03:00:04 +00:00

23 KiB

Cockatrice Architecture Analysis

Target: /home/wall-o/projects/mtgonline/C++

Date: 2026-07-20


1. Project Overview

Cockatrice (v3.1.0 "Graduation Day") is a mature open-source MTG online client/server application written in C++20 using Qt 5/6. It has been maintained for many years and represents a battle-tested implementation of an online card game.

Key Architectural Decisions:

  • Server-Client separation: The server (servatrice) is authoritative; the client (cockatrice) is a thin visualizer that sends commands through the server.
  • Protocol Buffers: All network communication uses .proto files — no custom serialization. This is the canonical contract between components.
  • Event-driven game loop: Qt signals/slots drive game state transitions.
  • Plugin-like library structure: Core logic lives in libcockatrice_* shared libraries.

2. Top-Level Directory Structure

Cockatrice/
├── CMakeLists.txt                    # Root build system (C++20, Qt5/6, Protobuf)
├── servatrice/                       # SERVER application
│   ├── src/
│   │   ├── servatrice.cpp/h          # Main server class
│   │   ├── serversocketinterface.cpp/h # Per-client socket handler (~106KB — single massive file)
│   │   ├── servatrice_database_interface.cpp/h # Database operations
│   │   ├── isl_interface.cpp/h       # Inter-server-link (cluster) support
│   │   ├── smtp/                     # Email support
│   │   └── main.cpp/h
│   ├── migrations/                   # DB schema migrations
│   └── resources/                    # Config, SQL init
├── cockatrice/                       # CLIENT application
│   ├── src/
│   │   ├── client/                   # Client network layer
│   │   │   ├── network/
│   │   │   │   ├── connection_controller/  # Connection lifecycle
│   │   │   │   ├── interfaces/           # Client-server interface abstractions
│   │   │   │   ├── parsers/              # Protocol message parsers
│   │   │   │   └── update/               # Auto-update checks
│   │   │   ├── sound_engine.cpp/h      # Audio feedback
│   │   │   └── settings/
│   │   ├── game/                     # GAME ENGINE
│   │   │   ├── abstract_game.h/cpp   # Game abstraction
│   │   │   ├── game.cpp/h            # Concrete game instance
│   │   │   ├── game_event_handler.cpp/h # Central event dispatch
│   │   │   ├── game_meta_info.h/cpp  # Game metadata (wraps protobuf)
│   │   │   ├── game_state.h/cpp      # Board state tracking
│   │   │   ├── phase.h/cpp           # Turn phase definitions
│   │   │   ├── player/               # Player logic
│   │   │   │   ├── player_actions.cpp/h     # Player commands
│   │   │   │   ├── player_event_handler.cpp/h
│   │   │   │   ├── player_logic.cpp/h       # Player AI/logic
│   │   │   │   ├── player_manager.cpp/h     # Multiplayer coordination
│   │   │   │   └── event_processing_options.h
│   │   │   ├── board/                # Board visualization state
│   │   │   │   ├── card_list.cpp/h
│   │   │   │   ├── card_state.cpp/h
│   │   │   │   └── counter_state.cpp/h
│   │   │   ├── zones/                # Zone logic
│   │   │   │   ├── card_zone_algorithms.h
│   │   │   │   ├── card_zone_logic.cpp/h
│   │   │   │   ├── hand_zone_logic.cpp/h
│   │   │   │   ├── pile_zone_logic.cpp/h
│   │   │   │   ├── stack_zone_logic.cpp/h
│   │   │   │   ├── table_zone_logic.cpp/h
│   │   │   │   └── view_zone_logic.cpp/h
│   │   │   ├── replay.cpp/h          # Game replay system
│   │   │   └── arrow_registry.cpp/h  # Card targeting arrows
│   │   ├── game_graphics/            # Visual rendering layer
│   │   │   ├── game_scene.cpp/h      # QGraphicsScene for the board
│   │   │   ├── game_view.cpp/h       # View controller
│   │   │   ├── board/
│   │   │   ├── deckview/
│   │   │   ├── dialogs/
│   │   │   ├── phases_toolbar.cpp/h  # Phase navigation UI
│   │   │   ├── player/
│   │   │   ├── tally/                # Life total displays
│   │   │   ├── z_value_layer_manager.h
│   │   │   └── z_values.h
│   │   ├── database/
│   │   │   └── interface/
│   │   ├── filters/                  # Deck/card filter system
│   │   │   ├── deck_filter_string.cpp/h
│   │   │   ├── filter_builder.cpp/h
│   │   │   └── filter_tree_model.cpp/h
│   │   ├── interface/                # UI/UX layer
│   │   │   ├── window_main.cpp/h     # Main application window
│   │   │   ├── layouts/
│   │   │   ├── widgets/
│   │   │   ├── theme_manager.cpp/h   # Theming system
│   │   │   ├── card_picture_loader/
│   │   │   ├── deck_loader/
│   │   │   ├── pixel_map_generator.cpp/h
│   │   │   ├── logger.cpp/h
│   │   │   └── palette_editor/
│   │   └── main.cpp/h                # Client entry point
├── oracle/                           # CARD DATABASE TOOL
│   └── (downloads card data from MTGJSON)
├── libcockatrice_card/               # Card data model library
│   └── libcockatrice/card/
│       ├── card_info.cpp/h           # Card information model
│       ├── database/                 # Card database access
│       ├── format/                   # Deck format support
│       ├── import/                   # Deck importers
│       ├── printing/                 # Printing history
│       ├── relation/                 # Card relationships
│       └── set/                      # Set data
├── libcockatrice_deck_list/          # Deck list management library
│   └── libcockatrice/deck_list/
│       ├── deck_list.cpp/h           # Core deck list class
│       ├── deck_list_node_tree.cpp/h # Tree structure for decks
│       ├── sideboard_plan.cpp/h      # Sideboarding
│       └── tree/
├── libcockatrice_network/            # Network protocol library
│   └── libcockatrice/network/
│       └── network/                  # TCP client/server
├── libcockatrice_protocol/           # Protocol definition library
│   └── libcockatrice/protocol/       # .proto file translations to C++
├── libcockatrice_rng/                # RNG library (SFMT)
├── libcockatrice_settings/           # Settings/preferences
├── libcockatrice_utility/            # Utility functions
├── docker-compose.yml                # Dev environment (MySQL + Servatrice)
└── doc/                              # Documentation (Doxygen)

3. Gameplay Engine Architecture

3.1 Core Game Loop — Event-Driven Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                        GAME ENGINE                                  │
│                                                                     │
│  ┌──────────────┐   ┌──────────────────┐   ┌───────────────────┐   │
│  │   Client     │   │   Game           │   │   Event Handler   │   │
│  │   (User Input)│──▶│   (AbstractGame) │◀──│   (Central Dispatch)│  │
│  └──────────────┘   └──────────────────┘   └───────────────────┘   │
│                          │                    │                     │
│                          ▼                    ▼                     │
│                  ┌─────────────┐      ┌──────────────────┐         │
│                  │  GameState  │      │ PlayerManager    │         │
│                  │ (Board State)│      │ (Multiplayer     │         │
│                  │             │      │  Coordination)   │         │
│                  └─────────────┘      └──────────────────┘         │
│                          │                                          │
│                          ▼                                          │
│                  ┌─────────────┐      ┌──────────────────┐         │
│                  │ CardZone    │      │ PlayerLogic      │         │
│                  │ (Hand/      │      │ (Actions, Rules  │         │
│                  │  Stack/     │      │  Processing)     │         │
│                  │  Table/     │      └──────────────────┘         │
│                  │  Graveyard) │                                      │
│                  └─────────────┘                                      │
└─────────────────────────────────────────────────────────────────────┘

3.2 Game Class Hierarchy

Class Role Key Data
AbstractGame Base game abstraction gameMetaInfo, gameState, gameEventHandler, playerManager
Game Concrete online/offline game Extends AbstractGame with client list
GameMetaInfo Wraps protobuf ServerInfo_Game gameId, maxPlayers, description, started, spectators settings
GameState Board state tracking currentPhase, activePlayer, hostId, gameTimer, clients
GameEventHandler Central event dispatch (~21KB handler) Processes all game events, prepares commands
Phase Turn phase definitions 11 phases with sub-phases, colors, sounds

3.3 Phase System (MTG Turn Structure)

Phases::phases[] array contains 11 phases:
1. Untap
2. Upkeep
3. Draw
4. Main 1
5. Combat (with sub-phases)
   - Beginning of Combat
   - Declare Attackers
   - Declare Blockers
   - Combat Damage
   - End of Combat
6. Main 2
7. End of Turn
8. Cleanup
(plus unknownPhase as sentinel)

Sub-phases are tracked via Phases::subPhasesEnd — the combat phase has 5 sub-phases.

3.4 Player System

Class Role File Size
PlayerManager Coordinates all players in a game ~2.5KB header
PlayerLogic Per-player game logic (actions, rules) ~10.7KB
PlayerActions Concrete player commands (play, tap, draw, etc.) ~64KB — single massive file
PlayerEventHandler Per-player event processing ~24KB
EventProcessingOptions Flags controlling event processing ~575B

3.5 Zone System

Zone File Description
CardZone card_zone_logic.cpp/h Base class for all zones
HandZone hand_zone_logic.cpp/h Player's hand (secret zone)
StackZone stack_zone_logic.cpp/h The stack ( spells, abilities)
TableZone table_zone_logic.cpp/h Battlefield (permanent zone)
PileZone pile_zone_logic.cpp/h Graveyard, exile, library
ViewZone view_zone_logic.cpp/h Shared view zones (for effects)
CardZoneAlgorithms card_zone_algorithms.h Search, shuffle, sort algorithms

Each zone type implements its own CardZoneLogic subclass.

3.6 Command/Event Architecture

User Action (GUI)
    │
    ▼
GameCommand (protobuf message)
    │
    ▼
GameEventHandler.processGameEventContainer()
    │
    ▼
PlayerLogic.handleCommand()
    │
    ▼
CardZoneLogic (state change)
    │
    ▼
GameEvent (sent to all clients)
    │
    ▼
Client receives & displays

3.7 Replay System

replay.cpp/h — Games are recorded as a stream of protobuf events and can be replayed identically. This is a direct serialization of GameReplay protobuf messages.

3.8 Card State on Board

Class Role
CardState Card face-up/face-down, tapped, counters
CardList Ordered/unordered collection of cards in a zone
CounterState Life total, poison counters, etc.
ArrowData Targeting arrow visual
ArrowRegistry Manages targeting arrows

4. Network Protocol Architecture

4.1 Communication Stack

┌─────────────────────────────────────────────────────────┐
│ Application Layer                                        │
│  - GameCommands (play, draw, tap, attack, etc.)          │
│  - GameEvents (state changes broadcast to all clients)    │
│  - Chat messages, user management                       │
│  - Deck management                                      │
│  - Room management                                      │
│  - Admin commands                                       │
├─────────────────────────────────────────────────────────┤
│ Protocol Layer                                           │
│  - Protocol Buffers (.proto files)                       │
│  - Message types: ServerInfo_Game, ServerInfo_Player,    │
│    Event_Join, Command_PlayCard, etc.                    │
├─────────────────────────────────────────────────────────┤
│ Network Layer                                            │
│  - TCP connections                                       │
│  - Connection pooling                                    │
│  - ISL (Inter-Server Link) for clustering                │
└─────────────────────────────────────────────────────────┘

4.2 Key Protocol Messages (from .pb files)

Category Example Messages
Game State ServerInfo_Game, ServerInfo_Player, Event_GameStateChanged
Player Actions Command_PlayCard, Command_Attack, Command_Damage, Command_DrawCard
Events Event_Join, Event_Leave, Event_SetActivePlayer, Event_SetActivePhase
User Management ServerInfo_User, Command_Acknowledge, Command_SpectateGame
Chat Event_GameSay, ServerInfo_Chat
Decks Deck list serialization, sideboard plans

4.3 Authority Model

  • Server is authoritative: All game state changes go through the server.
  • Client sends commands, server validates: The client cannot manipulate the game state directly.
  • Events are broadcast: Server sends GameEvent containers to all connected clients.
  • Replays are deterministic: Same command sequence produces identical game states.

5. Server Architecture (Servatrice)

5.1 Server Class Hierarchy

Class Role
Servatrice Main server class (~42KB) — manages connections, rooms, games
ServatriceDatabaseInterface Database operations (~58KB) — user accounts, decks, logs
ServerSocketInterface Per-client handler (~106KB) — handles all client messages
IslInterface Inter-server-link for clustering
ServerLogger Centralized logging

5.2 Server Features

  • Room management: Games are organized in rooms; rooms have game types.
  • User accounts: MySQL-backed with authentication, password reset, email.
  • Deck storage: Decks saved to database with versioning.
  • Game logging: Full game event logs for disputes.
  • Spectator system: Spectators can watch (with optional omniscient mode).
  • Admin commands: Kicking, banning, game management.
  • Clustering: ISL protocol for running multiple servers in a cluster.
  • Email: SMTP support for registration/password reset.

5.3 Database Schema (MySQL)

The servatrice.sql file defines the schema including:

  • User accounts, groups, bans
  • Deck lists with versioning
  • Game logs
  • Room/game state tables
  • Admin logs

6. Card Database (Oracle)

The oracle module downloads and maintains the card database:

  • Sources: MTGJSON data
  • Local storage: SQLite or file-based
  • Features: Card searching, printing history, set filtering
  • Updates: Periodic refresh capability

7. Deck Management

Component Role
DeckList Core deck data structure (cards, sideboard, categories)
DeckListNodeTree Tree structure for organizing decks
SideboardPlan Pre/post-sideboard plan management
DeckListHistoryManager Deck version history
DeckFilterString Card name filtering

Deck formats supported: Commander, Standard, Modern, Legacy, Vintage, etc.


8. UI/Rendering Architecture

8.1 Qt Graphics Framework

┌─────────────────────────────────────────────────────────┐
│ Window Main (window_main.cpp) — ~44KB                  │
│  ┌──────────┐  ┌──────────────┐  ┌──────────────────┐  │
│  │ Game     │  │ Chat/Log     │  │ Deck/Filter      │  │
│  │ Scene    │  │ Panel        │  │ Panel            │  │
│  │ (QScene) │  │              │  │                  │  │
│  └──────────┘  └──────────────┘  └──────────────────┘  │
│       │                                              │
│       ▼                                              │
│  GameScene (game_scene.cpp) — ~23KB                  │
│  GameView (game_view.cpp) — ~10KB                    │
│  PhasesToolbar — Phase navigation                     │
│  ZValueLayerManager — 2D depth ordering               │
└─────────────────────────────────────────────────────────┘

8.2 Theming System

  • SVG-based card back designs
  • Configurable themes (backgrounds, colors, layouts)
  • Card picture loading from external URLs
  • Custom counters and tally displays

9. Technology Stack Summary

Layer Technology
Language C++20
GUI Framework Qt 5 or Qt 6 (QtWidgets)
Network Protocol Protocol Buffers (3.21+)
Build System CMake 3.10+
Server Database MySQL
Card Database SQLite / file-based (Oracle)
Packaging CPack (DEB, RPM, NSIS, DMG)
Networking Qt TCP
Serialization protobuf
RNG SFMT (Sobol/Smirnov)
Translations Qt .ts files
Documentation Doxygen

10. Key Architectural Patterns

Pattern Where Used
MVC (via Qt) game_state (model), game_scene (view), GameEventHandler (controller)
Event Bus Qt signals/slots for all state transitions
Command Pattern Command_PlayCard, Command_Attack, etc. — all game actions are commands
Observer GameEventHandler emits signals to update UI on every state change
Strategy CardZoneLogic subclasses (Hand, Stack, Table, Pile, View)
Facade AbstractGame wraps all game subsystems behind a single interface
Adapter GameMetaInfo wraps protobuf messages with Qt-friendly getters
Singleton Settings cache, database interface
Memento DeckListMemento for undo/redo in deck editing
Repository ServatriceDatabaseInterface abstracts MySQL access
Plugin (debatable) ISL interface for adding server nodes

11. Strengths & Weaknesses (for modern web adaptation)

Strengths

  • Clear authority model: Server is always right — ideal for web multiplayer.
  • Deterministic replay: Game events are serialized, enabling perfect replays.
  • Zone abstraction: Each zone type is independently implementable.
  • Phase system: Well-defined MTG turn structure.
  • Command/Event separation: Clean separation between what a player wants to do and what happens.

Weaknesses (for web adaptation)

  • Desktop-first: Qt Widgets, not designed for browser deployment.
  • Massive files: serversocketinterface.cpp is 106KB — monolithic.
  • No web protocol: Only TCP, no WebSocket, no REST.
  • No mobile: No responsive design, no mobile clients.
  • Complex build: Qt + CMake + protobuf + MySQL — heavy dev environment.
  • No real-time scaling: Single-server architecture (ISL is clustering, not load balancing).
  • No card images built-in: External URL loading only.
  • No API: No REST/GraphQL for external integrations.

12. Relevance to Modern Web MTG App

What to Reuse (Architecture Patterns)

  1. Event-driven game state: Server authoritative, client event-driven UI.
  2. Zone abstraction: Hand/Stack/Table/Graveyard/Exile/Library as separate zone types.
  3. Command pattern: Player actions as discrete commands, validated server-side.
  4. Phase system: 11-phase MTG turn structure with sub-phases.
  5. Replay system: Serialize game events for replay capability.
  6. Card database: Structure for card info, sets, printing history.
  7. Deck management: Tree structure, sideboard plans, format support.

What to Modernize

  1. Protocol: Replace protobuf over TCP with WebSocket (or gRPC-Web) for browser.
  2. API: Add REST/GraphQL layer for external integrations.
  3. Frontend: Replace Qt Widgets with React/Next.js or Vue 3.
  4. State management: Replace Qt signals/slots with state machines (XState) or Zustand.
  5. Backend: Replace C++/MySQL with TypeScript/Node.js or Python/FastAPI + PostgreSQL.
  6. Card images: Bundle card images with the application or use CDN.
  7. Real-time: Use WebSocket for live game state sync.
  8. Mobile: Responsive design from the start.
  9. Testing: Unit test the game engine in isolation (no GUI dependency).

Suggested Tech Stack for Modern Web MTG

Component Recommendation
Frontend Next.js 14+ (React, TypeScript)
Game State XState (state machines) or Zustand
UI Rendering React Three Fiber (3D) or PixiJS (2D)
Backend FastAPI (Python) or Hono (TypeScript)
Database PostgreSQL (user data) + Redis (game state cache)
Real-time WebSocket (via FastAPI or Socket.IO)
Card Data MTGJSON v5 (already available in project)
Auth JWT + refresh tokens
Deployment Docker Compose (already used in project)