# FF-TCG Digital - Architecture Design Document ## Overview This document describes the software architecture of the FF-TCG Digital implementation. ## Technology Stack - **Game Engine**: Godot 4.2+ - **Language**: GDScript - **Target Platform**: Linux Desktop - **Rendering**: Forward+ renderer with 3D isometric view ## Architecture Principles 1. **Separation of Concerns**: Game logic is separate from visual presentation 2. **Event-Driven**: State changes emit signals for loose coupling 3. **Data-Driven**: Card definitions loaded from JSON, not hardcoded 4. **Testable**: Core game logic can be tested independently of visuals ## System Architecture ``` ┌─────────────────────────────────────────────────────────────────┐ │ Main Scene │ ├─────────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Table Scene │ │ UI Layer │ │ Input Handler│ │ │ │ (3D View) │ │ (2D Canvas) │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ ├─────────────────────────────────────────────────────────────────┤ │ Autoload Singletons │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ GameManager │ │ CardDatabase │ │ │ └──────────────┘ └──────────────┘ │ ├─────────────────────────────────────────────────────────────────┤ │ Game State Engine │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────────────┐ │ │ │ GameState │ │ Player │ │ Zone │ │ TurnManager │ │ │ └────────────┘ └────────────┘ └────────────┘ └──────────────┘ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ CPPool │ │ Combat │ │ Stack │ │ │ └────────────┘ └────────────┘ └────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` ## Core Components ### Autoload Singletons #### GameManager (`scripts/autoload/GameManager.gd`) Central coordinator for game flow. Responsibilities: - Initialize new games - Coordinate between game state and visuals - Handle high-level game events - Manage scene transitions Signals: - `game_started()` - `game_ended(winner: int)` - `turn_changed(player_index: int)` - `phase_changed(phase: TurnPhase)` #### CardDatabase (`scripts/autoload/CardDatabase.gd`) Manages card definitions loaded from JSON. Responsibilities: - Load and parse `data/cards.json` - Provide card lookup by ID - Validate card data on load - Cache card textures Methods: - `get_card(id: String) -> CardData` - `get_cards_by_element(element: Element) -> Array[CardData]` - `get_cards_by_type(type: CardType) -> Array[CardData]` ### Game State Classes #### GameState (`scripts/game/GameState.gd`) Master game state container. Holds: - Two Player instances - Shared Stack for ability resolution - Current turn/phase information - Game rules enforcement #### Player (`scripts/game/Player.gd`) Individual player state. Contains: - Hand (Zone) - Deck (Zone) - Field - Forwards area (Zone) - Field - Backups area (Zone) - Damage Zone (Zone) - Break Zone (Zone) - Current CP pool #### Zone (`scripts/game/Zone.gd`) Base class for card containers. Types: - `DECK` - Hidden, ordered - `HAND` - Hidden from opponent - `FIELD_FORWARDS` - Public - `FIELD_BACKUPS` - Public, max 5 - `DAMAGE` - Public, ordered - `BREAK` - Public discard Methods: - `add_card(card: CardInstance)` - `remove_card(card: CardInstance)` - `get_cards() -> Array[CardInstance]` - `shuffle()` #### TurnManager (`scripts/game/TurnManager.gd`) Handles turn structure and phase progression. Phases (enum TurnPhase): 1. `ACTIVE` - Activate dull characters 2. `DRAW` - Draw cards 3. `MAIN_1` - Play cards/abilities 4. `ATTACK` - Combat 5. `MAIN_2` - Play cards/abilities 6. `END` - Cleanup #### CPPool (`scripts/game/CPPool.gd`) Tracks generated Crystal Points by element. Properties: - `cp: Dictionary` - Element -> count mapping Methods: - `add_cp(element: Element, amount: int)` - `spend_cp(cost: Dictionary) -> bool` - `can_afford(cost: Dictionary) -> bool` - `clear()` #### Combat (`scripts/game/Combat.gd`) Handles attack phase logic. States: - `IDLE` - `DECLARING_ATTACKER` - `WAITING_BLOCKER` - `RESOLVING_DAMAGE` ### Visual Components #### TableCamera (`scripts/visual/TableCamera.gd`) Isometric camera setup: - 45° rotation on Y axis - ~35° tilt down on X axis - Orthographic or perspective projection - Fixed position showing full board #### CardVisual (`scripts/visual/CardVisual.gd`) 3D card representation: - MeshInstance3D with PlaneMesh - Dynamic texture from card image - States: normal, highlighted, selected, dull - Animation support for movement #### ZoneVisual (`scripts/visual/ZoneVisual.gd`) Visual representation of card zones: - Manages card positioning - Handles card enter/exit animations - Supports stacking and spreading ## Data Flow ### Playing a Card ``` 1. Player clicks card in hand │ 2. InputHandler detects selection │ 3. GameManager.request_play_card(card) │ 4. GameState.validate_play(card) ├── Check phase (must be Main Phase) ├── Check CP requirements └── Check field limits │ 5. If valid: GameState.execute_play(card) ├── CPPool.spend_cp(card.cost) ├── Hand.remove_card(card) └── Field.add_card(card) │ 6. GameState emits card_played signal │ 7. Visual layer animates card movement ``` ### Combat Flow ``` 1. Attack Phase begins │ 2. Active player selects attacker ├── Must be active Forward └── Must be able to attack │ 3. Attacker is dulled │ 4. Defending player may select blocker ├── Must be active Forward └── Optional │ 5. Damage resolution ├── If blocked: Exchange damage equal to Power └── If unblocked: Deal 1 damage to player │ 6. Check for broken Forwards │ 7. Return to step 2 or end Attack Phase ``` ## File Organization ``` scripts/ ├── autoload/ │ ├── GameManager.gd # Game flow coordinator │ └── CardDatabase.gd # Card data management ├── game/ │ ├── GameState.gd # Master game state │ ├── Player.gd # Player state │ ├── Zone.gd # Zone base class │ ├── CardInstance.gd # Runtime card instance │ ├── TurnManager.gd # Turn/phase handling │ ├── CPPool.gd # CP tracking │ ├── Combat.gd # Combat resolution │ └── Enums.gd # Shared enumerations ├── visual/ │ ├── TableCamera.gd # Isometric camera │ ├── CardVisual.gd # 3D card rendering │ ├── ZoneVisual.gd # Zone rendering │ └── TableSetup.gd # Table scene setup └── ui/ ├── GameUI.gd # Main UI controller ├── CardDetailPanel.gd # Card info popup ├── CPDisplay.gd # CP pool display └── TurnIndicator.gd # Turn/phase display ``` ## Signals Reference ### GameManager Signals | Signal | Parameters | Description | |--------|------------|-------------| | `game_started` | none | New game initialized | | `game_ended` | `winner: int` | Game over | | `turn_changed` | `player: int` | Active player changed | | `phase_changed` | `phase: TurnPhase` | Phase advanced | ### GameState Signals | Signal | Parameters | Description | |--------|------------|-------------| | `card_played` | `card, player` | Card deployed to field | | `card_moved` | `card, from, to` | Card changed zones | | `damage_dealt` | `player, amount` | Player took damage | | `forward_broken` | `card` | Forward destroyed | ### Player Signals | Signal | Parameters | Description | |--------|------------|-------------| | `hand_changed` | none | Hand contents updated | | `cp_changed` | `pool` | CP pool updated | | `field_changed` | none | Field contents updated | ## Testing Strategy ### Unit Tests - Card data validation - CP calculation - Combat damage resolution - Zone operations ### Integration Tests - Full turn cycle - Complete game to win condition - Edge cases (deck empty, backup limit) ### Manual Testing - Visual correctness - Input responsiveness - Animation smoothness