diff --git a/Doxyfile b/Doxyfile index d6f0af2d2..b722f779f 100644 --- a/Doxyfile +++ b/Doxyfile @@ -2667,7 +2667,7 @@ DOT_NUM_THREADS = 0 # Minimum value: 1, maximum value: 1000, default value: 50. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_BATCH_SIZE = 500 +DOT_BATCH_SIZE = 50 # DOT_COMMON_ATTR is common attributes for nodes, edges and labels of # subgraphs. When you want a differently looking font in the dot files that diff --git a/doc/doxygen/extra-pages/developer_documentation/network/client/game_event_handler.md b/doc/doxygen/extra-pages/developer_documentation/network/client/game_event_handler.md index fbb298d3a..051823c6c 100644 --- a/doc/doxygen/extra-pages/developer_documentation/network/client/game_event_handler.md +++ b/doc/doxygen/extra-pages/developer_documentation/network/client/game_event_handler.md @@ -90,13 +90,13 @@ This keeps the handler independent of concrete UI implementations. `GameEventHandler` and `PlayerEventHandler` work together but have distinct roles: -| GameEventHandler | PlayerEventHandler | -|------------------|--------------------| -| Global game state | Per-player state | -| Turn / phase flow | Zones and cards | -| Player join/leave | Player actions | -| Spectator events | Player-specific events | -| Chat dispatch | Card and zone updates | +| GameEventHandler | PlayerEventHandler | +| ----------------- | ---------------------- | +| Global game state | Per-player state | +| Turn / phase flow | Zones and cards | +| Player join/leave | Player actions | +| Spectator events | Player-specific events | +| Chat dispatch | Card and zone updates | When a server event is associated with a specific player, `GameEventHandler` routes it to the corresponding `PlayerEventHandler`. Events without a player diff --git a/doc/doxygen/extra-pages/developer_documentation/network/game_event_handler.md b/doc/doxygen/extra-pages/developer_documentation/network/game_event_handler.md deleted file mode 100644 index fbb298d3a..000000000 --- a/doc/doxygen/extra-pages/developer_documentation/network/game_event_handler.md +++ /dev/null @@ -1,170 +0,0 @@ -@page game_event_handler GameEventHandler - -## Overview - -`GameEventHandler` is the central coordinator for **game-wide commands and events**. -It acts as the bridge between the networking layer (protobuf messages received from -the server) and the local game model and UI. - -Unlike `PlayerEventHandler`, which is responsible for player-scoped state and zones, -`GameEventHandler` handles: - -- Global game flow (turns, phases, host changes) -- Player and spectator lifecycle events -- Chat and logging events -- Dispatching incoming events to the appropriate subsystem -- Sending locally initiated commands to the server - -In short, it is the **top-level event dispatcher** for an active game. - ---- - -## Responsibilities - -`GameEventHandler` has four primary responsibilities: - -### 1. Sending game-wide commands - -UI actions that affect the game as a whole (e.g. advancing the turn, changing phases, -sending chat messages) are translated into protobuf commands and sent to the server -via this class. - -Examples include: - -- Advancing or reversing the turn order -- Conceding or unconceding -- Changing the active phase -- Leaving the game -- Sending chat messages - -These commands are wrapped in `PendingCommand` instances so their lifecycle and -responses can be tracked. - ---- - -### 2. Processing incoming game events - -Incoming server messages arrive as a `GameEventContainer`. -`GameEventHandler` is responsible for: - -- Emitting lifecycle signals before and after processing -- Dispatching each event to the correct handler -- Forwarding player-scoped events to `PlayerEventHandler` instances -- Handling spectator-only and game-global events directly - -This design keeps networking concerns isolated from game logic and UI code. - ---- - -### 3. Managing global game state transitions - -Certain events affect the entire game state and require coordinated updates across -multiple subsystems. Examples include: - -- Full game state synchronization -- Active player or phase changes -- Game host changes -- Game closure -- Turn reversal - -`GameEventHandler` ensures these events are processed in a consistent order and -that all interested systems are notified via Qt signals. - ---- - -### 4. Emitting UI and logging signals - -Rather than directly manipulating UI widgets, `GameEventHandler` emits -high-level signals that are consumed by: - -- Game widgets -- Player and spectator lists -- Message and event logs -- Status indicators (ready state, deck selection, connection state) - -This keeps the handler independent of concrete UI implementations. - ---- - -## Relationship to PlayerEventHandler - -`GameEventHandler` and `PlayerEventHandler` work together but have distinct roles: - -| GameEventHandler | PlayerEventHandler | -|------------------|--------------------| -| Global game state | Per-player state | -| Turn / phase flow | Zones and cards | -| Player join/leave | Player actions | -| Spectator events | Player-specific events | -| Chat dispatch | Card and zone updates | - -When a server event is associated with a specific player, `GameEventHandler` -routes it to the corresponding `PlayerEventHandler`. Events without a player -context are handled directly. - ---- - -## Event Processing Flow - -A typical incoming event flow looks like this: - -1. `AbstractClient` receives a `GameEventContainer` -2. `GameEventHandler::processGameEventContainer()` is called -3. `containerProcessingStarted()` is emitted -4. Each event is: - - Handled directly **or** - - Forwarded to a `PlayerEventHandler` -5. Logging and UI signals are emitted as needed -6. `containerProcessingDone()` is emitted - -This structured flow makes it easy to: - -- Suppress UI updates during replays -- Handle reconnections cleanly -- Detect flood protection or error states - ---- - -## Command Lifecycle - -Outgoing commands follow a similar structured path: - -1. UI action triggers a `handle*()` method -2. A protobuf command is constructed -3. The command is wrapped in a `PendingCommand` -4. `sendGameCommand()` sends it to the server -5. `commandFinished()` receives the response -6. Errors or flood conditions are handled centrally - -This approach avoids duplicated error handling across UI code. - ---- - -## Design Goals - -`GameEventHandler` is designed to be: - -- **Centralized** – one entry point for all game-wide events -- **UI-agnostic** – communicates via signals, not widgets -- **Predictable** – well-defined event ordering and lifecycle -- **Composable** – works in concert with `PlayerEventHandler` -- **Testable** – logic is separated from rendering - ---- - -## Related Classes - -- @ref GameEventHandler -- @ref PlayerEventHandler -- `GameEventContainer` -- `PendingCommand` -- `AbstractClient` -- `AbstractGame` - ---- - -## See Also - -- @ref GameLogic -- @ref PlayerEventHandler -- @ref GameState diff --git a/doc/doxygen/extra-pages/developer_documentation/network/player_event_handler.md b/doc/doxygen/extra-pages/developer_documentation/network/player_event_handler.md deleted file mode 100644 index 6878758da..000000000 --- a/doc/doxygen/extra-pages/developer_documentation/network/player_event_handler.md +++ /dev/null @@ -1,199 +0,0 @@ -@page player_event_handler PlayerEventHandler - -## Overview - -`PlayerEventHandler` is responsible for applying **player-scoped game events** -to a single `Player` instance. These events modify the player’s board state, -zones, cards, counters, arrows, and associated UI and logging output. - -Each `PlayerEventHandler` instance is bound **1:1 to a Player** and is invoked -exclusively by @ref GameEventHandler after basic routing and validation of -incoming server events. - -This class represents the lowest-level authoritative application of game state -changes on the client. - ---- - -## Scope and Authority - -`PlayerEventHandler` operates under the following guarantees: - -- All incoming events are **authoritative** and already validated by the server -- Events refer to valid players, zones, and card identifiers -- Ordering is guaranteed by the server and preserved by `GameEventHandler` - -As a result, the handler does **not** perform rule validation or permission -checks. Its responsibility is to *apply* state, not *decide* legality. - ---- - -## Responsibilities - -### 1. Applying player-specific state changes - -The primary responsibility of `PlayerEventHandler` is to mutate player-owned -state, including: - -- Cards (`CardItem`) -- Zones (`CardZoneLogic`) -- Counters (card-level and player-level) -- Attachments and arrows -- Zone configuration flags (reveal / peek behavior) - -Many handlers update both **logical state** and **visual/UI state** in tandem. - ---- - -### 2. Coordinating complex card movement - -Some events—most notably card movement—require coordinated updates across -multiple systems. For example, `eventMoveCard()`: - -- Removes the card from the source zone -- Updates ownership, visibility, and identity -- Handles attachments and arrow cleanup -- Emits undo-draw or move logs -- Inserts the card into the destination zone -- Updates menus, hover state, and graphics - -This makes `PlayerEventHandler` intentionally stateful and tightly coupled to -the board implementation. - ---- - -### 3. Emitting logging signals - -Rather than writing directly to logs or widgets, `PlayerEventHandler` emits -structured Qt signals describing *what happened*, including: - -- Chat messages -- Card movement -- Shuffles and randomization -- Reveals and peeks -- Counter and attribute changes - -These signals are consumed by logging systems and UI components, keeping -presentation concerns out of the handler. - -Logging signals may be emitted **before or after mutation**, depending on -whether later changes would invalidate log data (e.g. card identity). - ---- - -### 4. Handling cross-player interactions - -Although bound to a single player, some events necessarily affect other -players’ state, including: - -- Moving cards between players -- Attaching cards to another player’s permanents -- Creating arrows targeting other players or cards - -In these cases, `PlayerEventHandler` performs the minimal required mutation -while respecting ownership boundaries enforced elsewhere. - ---- - -## Event Dispatch Model - -`PlayerEventHandler` exposes a single public entry point: - -- `processGameEvent()` - -This method: - -1. Receives a generic `GameEvent` -2. Switches on `GameEventType` -3. Extracts the appropriate protobuf extension -4. Forwards the event to a typed handler - -This keeps the event routing centralized and makes it easy to audit coverage -when new game events are introduced. - -Unhandled events are logged as warnings. - ---- - -## Event Categories - -For clarity, event handlers are grouped conceptually into: - -- **Chat and randomization** - - Chat messages - - Shuffles - - Dice rolls - -- **Arrows and targeting** - - Create / delete arrows - -- **Card and token creation** - - Token generation - - Counter creation - -- **Card attributes and counters** - - Tapped state - - Power/toughness - - Annotations - - Card- and player-level counters - -- **Zone-level operations** - - Card movement - - Zone dumps - - Card destruction - - Attachments - -- **Draw and reveal** - - Drawing cards - - Reveals, peeks, and reveal windows - -- **Zone configuration** - - Always-reveal and always-look-at-top-card flags - -This grouping mirrors the structure of the header file and reflects the -conceptual responsibilities of the class. - ---- - -## Relationship to GameEventHandler - -`PlayerEventHandler` is never instantiated or invoked directly by UI code. -Instead: - -1. `GameEventHandler` receives a `GameEventContainer` -2. Player-scoped events are routed to the appropriate `PlayerEventHandler` -3. Global or spectator events are handled elsewhere - -This separation keeps game-wide logic decoupled from player board state and -makes reconnection and replay handling simpler. - ---- - -## Design Intent - -`PlayerEventHandler` is designed to be: - -- **Authoritative** – applies server state exactly as received -- **Stateful** – maintains consistency across cards, zones, and UI -- **Explicit** – one handler per event type -- **UI-aware** – updates views and menus as part of state mutation -- **Auditable** – easy to trace what code handles which event - ---- - -## Related Classes - -- @ref PlayerEventHandler -- @ref GameEventHandler -- `Player` -- `CardItem` -- `CardZoneLogic` -- `GameEvent` -- `GameEventContext` - ---- - -## See Also - -- @ref GameLogicPlayers -- @ref GameLogic diff --git a/doc/doxygen/extra-pages/user_documentation/card_pictures/custom_card_pictures.md b/doc/doxygen/extra-pages/user_documentation/card_pictures/custom_card_pictures.md index 3f1079661..bcea6db8b 100644 --- a/doc/doxygen/extra-pages/user_documentation/card_pictures/custom_card_pictures.md +++ b/doc/doxygen/extra-pages/user_documentation/card_pictures/custom_card_pictures.md @@ -69,17 +69,17 @@ the 'Deck Editor' tab, in the 'URL Download Priority' section. The following reference points are available: -| Reference point | Description | Example | -| ------------------------------- | ------------------------------- | -------------- | -| `!name!` | Card name | `Example Card` | -| `!name_lower!` | Card name, lower case | `example card` | -| `!corrected_name!` | Corrected card name | `ExampleCard` (instead of "Example // Card") | -| `!corrected_name_lower!` | Corrected card name, lower case | `examplecard` | -| `!sflang!` | Scryfall language code for the current client language; defaults to English when the language has no localized images | `en`, `zhs` | -| `!setcode!` / `!setcode_lower!` | Set code | `EXM` / `exm` | -| `!setname!` / `!setname_lower!` | Full set name | `Exemplary Set` / `exemplary set` | -| `!set:!` | A property of this printing, e.g. `muid` (Gatherer multiverse ID), `uuid` (Scryfall UUID), `num` (collector number), `rarity` | `373549` | -| `!prop:!` | A property of the card, e.g. `side` (front/back), `colors`, `cmc`, `coloridentity`, `type`, `pt`, and the format legality statuses | `front` | +| Reference point | Description | Example | +| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `!name!` | Card name | `Example Card` | +| `!name_lower!` | Card name, lower case | `example card` | +| `!corrected_name!` | Corrected card name | `ExampleCard` (instead of "Example // Card") | +| `!corrected_name_lower!` | Corrected card name, lower case | `examplecard` | +| `!sflang!` | Scryfall language code for the current client language; defaults to English when the language has no localized images | `en`, `zhs` | +| `!setcode!` / `!setcode_lower!` | Set code | `EXM` / `exm` | +| `!setname!` / `!setname_lower!` | Full set name | `Exemplary Set` / `exemplary set` | +| `!set:!` | A property of this printing, e.g. `muid` (Gatherer multiverse ID), `uuid` (Scryfall UUID), `num` (collector number), `rarity` | `373549` | +| `!prop:!` | A property of the card, e.g. `side` (front/back), `colors`, `cmc`, `coloridentity`, `type`, `pt`, and the format legality statuses | `front` | The `!set:...!` and `!prop:...!` reference points support two modifiers: