init
Please analyze this codebase and create a CLAUDE.md file, which will be given to future instances of Claude Code to operate in this repository.
What to add:
Usage notes:
# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Your account does not have access to Claude Code. Please run /login.
Caveat: The messages below were generated by the user while running local commands. DO NOT respond to these messages or otherwise consider them in your response unless the user explicitly asks you to.
Caveat: Caveat: The messages below were generated by the user while running local commands. DO NOT respond to these messages or otherwise consider them in your response unless the user explicitly asks you to.
login
Login successful
Stdout: Login successful
init
Please analyze this codebase and create a CLAUDE.md file, which will be given to future instances of Claude Code to operate in this repository.
What to add:
Usage notes:
# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Let me analyze this codebase to understand its structure, build system, testing approach, and architecture. I'll start by exploring the top-level files and directories.
I'll analyze the codebase in parallel to understand its structure, build system, and architecture.
Perfect! Now I have enough information to provide a comprehensive codebase exploration report. Let me compile all the findings:
## Comprehensive Codebase Exploration Report: XMage
### 1. PROJECT OVERVIEW
**Project Name:** XMage (Magic, Another Game Engine)
**Description:** XMage is a digital implementation of Magic: The Gathering that allows players to play against one or more online players or computer opponents. It includes:
- Full rules enforcement for 28,000+ unique Magic cards and 73,000+ reprints
- Support for multiple game modes (duel, multiplayer, standard, modern, commander, pauper, oathbreaker, etc.)
- Both client and server components
- AI players for single-player matches
- Tournament support with different formats
**Repository:** https://github.com/magefree/mage
**Current Version:** 1.4.58
**Active Development:** Yes (recent commits from Feb 2026)
---
### 2. BUILD SYSTEM
**Build Tool:** **Apache Maven** (primary)
- Root pom.xml at `/mnt/dest-btrfs/home/jc/src/mage/pom.xml` (380 lines)
- Hierarchical multi-module project structure
- Java 1.8 (Java 8) target version for backward compatibility
**Alternative Build Tools:**
- **Makefile** at `/mnt/dest-btrfs/home/jc/src/mage/Makefile` for convenience commands
- **Perl scripts** in `/mnt/dest-btrfs/home/jc/src/mage/Utils/` for card code generation and data processing
**Makefile Targets:**
- `make clean` - Runs `mvn clean`
- `make build` - Runs `mvn install package -DskipTests`
- `make package` - Creates zip distributions for both Client and Server
- `make install` - Full clean build and package (alias to: clean → build → package)
**Maven Key Plugins:**
- `maven-compiler-plugin` (v3.8.1): Java source/target 1.8
- `maven-surefire-plugin` (v3.1.2): Test execution with JUnit 5 platform
- `jacoco-maven-plugin` (v0.8.11): Code coverage analysis
- `protoc-jar-maven-plugin` (v3.11.4): Protocol Buffer code generation
- `maven-jar-plugin`, `maven-install-plugin`, `maven-deploy-plugin`
- `exec-maven-plugin`: Run applications via command line
**Key Build Properties:**
```xml
<java.version>1.8</java.version>
<mage-version>1.4.58</mage-version>
<jacoco.formats>XML,HTML</jacoco.formats>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
```
**Code Coverage:**
- JaCoCo configured for code coverage reports
- Outputs to: `./Mage.Reports/target/site/jacoco-aggregate/`
- Formats: XML (for SonarQube), HTML (for offline view), CSV
- Enable with: `mvn install -Djacoco.skip=false -Dmaven.test.failure.ignore=true`
---
### 3. TESTING SETUP
**Test Framework:**
- **JUnit 5** (with JUnit 4 compatibility via junit-vintage-engine)
- **AssertJ** (v3.21.0) for fluent assertions
- Test scope: `test` (only run during test phase)
**Test Organization:**
- Test module: `/mnt/dest-btrfs/home/jc/src/mage/Mage.Tests/`
- 1,947 Java test files
- Test location: `Mage.Tests/src/test/java/org/mage/test/`
- Test data: `Mage.Tests/src/test/data/`
- Deck files: `.dck` format (example: `RB Aggro.dck`, `CommanderDuel.dck`)
**Test Organization by Category:**
- `org.mage.test.AI.basic/` - AI player tests
- `org.mage.test.cards/` - Card functionality tests
- `org.mage.test.cards.battle/` - Battle mechanics
- `org.mage.test.cards.triggers/` - Triggered ability tests
- Other specialized test packages
**Test Base Classes:**
- `CardTestPlayerBase` - Basic card testing framework
- `CardTestPlayerBaseAI` - AI player testing
- `CardTestPlayerBaseWithAIHelps` - AI assistance testing
- Test framework supports: game state setup, card testing, combat simulation, AI decision testing
**Running Tests:**
```bash
# CI/Travis build command
mvn test -B -Dxmage.dataCollectors.printGameLogs=false -Dlog4j.configuration=file:${TRAVIS_BUILD_DIR}/.travis/log4j.properties
# Standard Maven test
mvn test
# With code coverage
mvn install -Djacoco.skip=false -Dmaven.test.failure.ignore=true
# With tree view report
mvn install -Dxmage.build.tests.treeViewRunnerShowAllLogs=true
```
**Test Configuration:**
- Maven Surefire tree reporter enabled for readable test output
- Custom Log4J config at `.travis/log4j.properties` for CI builds
- Database cleanup plugin configured in Mage.Tests pom.xml
---
### 4. DIRECTORY STRUCTURE
**Top-Level Modules:**
```
/mnt/dest-btrfs/home/jc/src/mage/
├── Mage/ # Core framework (3,662 Java files)
│ └── src/main/java/mage/
│ ├── abilities/ # Spell and ability implementations
│ ├── cards/ # Card definitions
│ ├── game/ # Game engine core
│ └── ...
├── Mage.Common/ # Shared utilities (131 Java files)
├── Mage.Sets/ # Card set definitions (31,366 Java files)
│ # Largest module - contains all Magic sets
├── Mage.Client/ # GUI client (299 Java files)
│ └── src/main/java/mage/client/
│ ├── cards/
│ ├── chat/
│ ├── combat/
│ ├── components/
│ ├── deck/
│ └── ...
├── Mage.Server/ # Server application (72 Java files)
│ └── src/main/java/mage/server/
│ ├── draft/
│ ├── game/
│ ├── managers/
│ ├── tournament/
│ └── ...
├── Mage.Server.Console/ # Server CLI tool
├── Mage.Server.Plugins/ # Pluggable game components (233 Java files)
│ ├── Mage.Game.* (20+ game variants)
│ ├── Mage.Player.AI/ # AI implementations
│ ├── Mage.Player.AI.DraftBot/
│ ├── Mage.Player.AIMCTS/
│ ├── Mage.Player.Human/
│ ├── Mage.Tournament.* # Tournament formats
│ └── Mage.Deck.* # Deck management
├── Mage.Plugins/ # Client plugins (2 Java files)
├── Mage.Tests/ # Test suite (1,947 Java files)
│ ├── src/test/java/org/mage/test/
│ ├── src/test/data/ # Test fixtures
│ └── *.dck files # Deck definitions
├── Mage.Verify/ # Card data verification tool
├── Mage.Reports/ # Test coverage aggregation
├── Utils/ # Development utilities
│ ├── build-and-package.pl # Perl-based build script
│ ├── gen-card.pl # Card code generator
│ ├── gen-card-test.pl # Test generator
│ ├── mtg-cards-data.txt # Magic card database
│ ├── mtg-sets-data.txt # Magic sets database
│ ├── *.tmpl # Code templates
│ └── ...scripts
├── repository/ # Local Maven repository
├── .github/ # GitHub configuration
│ ├── workflows/
│ ├── dependabot.yml
│ └── labeler.yml
├── .travis.yml # Travis CI configuration
├── pom.xml # Root POM (380 lines)
├── Makefile # Build convenience targets
└── readme.md # Documentation
```
**Module Dependencies:**
```
Mage.Tests → Mage.Server + Mage.Sets + Mage (core)
Mage.Client → Mage.Common + Mage
Mage.Server → Mage.Sets + Mage.Common + Mage
Mage.Server.Plugins → All above
Mage.Verify → Mage.Client + Mage.Server + Mage.Sets + Mage
```
**Key Subdirectories:**
- **Mage/src/main/proto/** - Protocol Buffer definitions for serialization
- **Mage.Sets/src/** - Generated card files for all Magic sets
- **Mage.Client/plugins/** - Image cache and plugin data (gitignored)
- **Mage.Server/config/** - Server configuration files
- **Mage.Server/extensions/** - Server plugin extensions (gitignored)
---
### 5. AI & CODE RULES FILES
**Status:** No AI instructions files found
The project does NOT contain any of the following:
- `CLAUDE.md`
- `.cursorrules`
- `.cursor/` directory
- `.github/copilot-instructions.md`
The project uses standard GitHub issue and wiki documentation for development guidance.
---
### 6. PROJECT LANGUAGE & FRAMEWORK
**Primary Language:** Java 8+ (100% Java)
- ~37,775 total Java files across the project
- Target JDK: Java 1.8 (compatible with Java 8+)
- Module JDK requirement: OpenJDK 17+ for Travis CI
**Key Dependencies:**
- **Google Guava** (v33.4.8-jre) - Collections, utilities
- **Google Gson** (v2.13.2) - JSON serialization
- **Google Protobuf** (v3.25.8) - Data serialization
- **ORM Lite** (v5.7) - Object-relational mapping
- **H2 Database** (v1.4.197) - Embedded SQL database (critical: v1.4.197 for compatibility)
- **JUnit** (v5.8.1 platform with v4 compatibility)
- **AssertJ** (v3.21.0) - Test assertions
- **SLF4J + Reload4J** (v2.0.17) - Logging
- **JSoup** (v1.21.2) - HTML parsing
- **JAXB** (v2.3.1/3.0.2) - XML binding for config files
**Architecture:**
- Traditional multi-tier Java application
- MVC pattern for client-server communication
- Pluggable architecture for game variants and AI players
- Protocol Buffer for network communication
- H2 embedded database for game state persistence
---
### 7. CI/CD CONFIGURATION
**Primary CI: Travis CI (Legacy)**
File: `.travis.yml`
```yaml
language: java
jdk: openjdk17
dist: jammy
git:
depth: 3
submodules: false
before_install:
- echo "MAVEN_OPTS='-Xmx2g'" > ~/.mavenrc
script:
- mvn test -B -Dxmage.dataCollectors.printGameLogs=false \
-Dlog4j.configuration=file:${TRAVIS_BUILD_DIR}/.travis/log4j.properties
cache:
directories:
- $HOME/.m2
```
**GitHub Actions**
Directory: `.github/workflows/`
Three workflows configured:
1. **labeler-auto.yml** - Auto-label pull requests
- Trigger: `pull_request_target`
- Uses: `actions/labeler@v5`
- Config: `.github/labeler.yml`
2. **labeler-manual.yml** - Manual PR labeling
- Trigger: `workflow_dispatch` (manual trigger)
- Allows labeling old PRs
3. **mtg-fetch-cards.yml** - MTG Card Reference Bot
- Trigger: `issue_comment`, `issues`, `pull_request_review`, `pull_request_review_comment`
- Uses: `ldeluigi/mtg-fetch-action@v1`
- Automatically fetches and displays MTG card references in comments
**Dependency Management:**
File: `.github/dependabot.yml`
```yaml
version: 2
updates:
- package-ecosystem: 'github-actions'
directory: '/'
schedule: weekly
- package-ecosystem: 'maven'
directory: '/'
schedule: weekly
```
**Code Quality:**
- **SonarCloud** Integration configured
- Project key: `magefree_mage`
- Organization: `magefree`
- Runs: Code coverage analysis, static analysis
- Upload command: `mvn -e sonar:sonar -Dsonar.projectKey=magefree_mage -Dsonar.organization=magefree -Dsonar.host.url=https://sonarcloud.io`
**Build Badges:**
- Travis CI status badge
- SonarCloud code quality metrics
- Coverage reports
- Technical debt tracking
- Release version badge
- Commits since latest release
---
### 8. PROJECT METADATA
**Project Configuration:**
- **Group ID:** `org.mage`
- **Artifact ID (Root):** `mage-root`
- **Packaging:** Multi-module Maven project (pom)
- **Version:** 1.4.58
- **Source Encoding:** UTF-8
- **Build Timestamp Format:** `yyyy-MM-dd'T'HH:mm:ss'Z'`
**Repository Configuration:**
- JBoss Public Repository (for dependency resolution)
- Local project repository at `./repository/`
- Daily snapshot update policy
- Never update policy for releases (caching)
**Test Infrastructure:**
- Database: H2 (embedded)
- Logging: Log4J via SLF4J facade
- Test cleanup: Automatic `db` directory cleanup between test runs
- Tree-view test reporter for readable output
**Distribution & Packaging:**
- Client package: `Mage.Client/target/mage-client.zip`
- Server package: `Mage.Server/target/mage-server.zip`
- Distribution handled by Maven Assembly plugin
- Perl script `Utils/build-and-package.pl` bundles artifacts into single distribution zip
---
### 9. DEVELOPMENT TOOLS & UTILITIES
**Utilities Directory** (`/mnt/dest-btrfs/home/jc/src/mage/Utils/`):
**Build & Packaging:**
- `build-and-package.pl` - Main build script (creates full distribution)
- `build-and-package-console.pl` - Server console build
- `version-bump.pl` - Version update utility
**Card Code Generation:**
- `gen-card.pl` - Generate card implementation boilerplate
- `gen-card-test.pl` - Generate test cases for cards
- Template files:
- `cardClass.tmpl` - Card implementation template
- `cardExtendedClass.tmpl` - Extended card template
- `cardSplitClass.tmpl` - Split card template
- `cardTest.tmpl` - Test template
- `cardInfo.tmpl`, `issue_tracker.tmpl`
**Card Data Management:**
- `mtg-cards-data.txt` (12.4 MB) - Complete Magic card database
- `mtg-sets-data.txt` - Magic set information
- `known-sets.txt` - Known set listings
- `keywords.txt` - Magic keyword glossary
- `find_new_cards.pl` - Find newly released cards
- `cut.pl` - Card data processing utility
- `de-dup-cards-data.py` - Remove duplicate card entries
- `CubeCobraDownloader.py` - Download cube data
- `gen-existing-cards-by-set.pl` - Card inventory by set
- `gen-list-implemented-cards-for-set.pl` - Implemented card tracking
- `gen-list-unimplemented-cards-for-set.pl` - Missing card tracking
**Documentation & Analysis:**
- `extract_in_wiki_format.pl` - Convert to wiki format
- `readme.txt` - Utility documentation
**Release Directory:**
- `release/` subdirectory for release artifacts
---
### 10. PROJECT STATISTICS
| Metric | Value |
|--------|-------|
| Total Java Files | 37,775 |
| Mage Framework | 3,662 |
| Mage.Sets (Cards) | 31,366 |
| Mage.Tests | 1,947 |
| Mage.Server.Plugins | 233 |
| Mage.Client | 299 |
| Mage.Common | 131 |
| Mage.Server | 72 |
| Root POM Lines | 380 |
| Build Profiles | 11 modules |
| Test Categories | 10+ |
---
### 11. DEVELOPMENT WORKFLOW
**Based on Wiki & Documentation:**
1. **Environment Setup:**
- Java 8 or later required
- Maven 3.6+ recommended
- IDE: IntelliJ IDEA, Eclipse, or VS Code
2. **Build Commands:**
```bash
# Full build with tests
mvn clean install
# Build without tests
mvn clean install -DskipTests
# Package for distribution
mvn clean package assembly:single
# Run using Makefile
make clean
make build
make package
```
3. **Testing:**
```bash
# Run all tests
mvn test
# Run specific test class
mvn test -Dtest=ClassName
# Run with coverage
mvn clean install -Djacoco.skip=false
```
4. **Code Generation:**
- New cards use `Utils/gen-card.pl` for boilerplate
- Tests generated with `Utils/gen-card-test.pl`
- Requires Magic card database from Scryfall/gatherer
5. **Documentation:**
- Main docs: `readme.md`
- Wiki: GitHub wiki pages
- Development guides available in wiki
---
### SUMMARY
XMage is a large, mature Java project implementing Magic: The Gathering. It uses:
- **Apache Maven** as the primary build system
- **Java 8** target with JUnit 5 testing framework
- **Multi-module architecture** with ~37K Java files
- **Travis CI + GitHub Actions** for CI/CD
- **SonarCloud** for code quality analysis
- **H2 embedded database** for persistence
- **Protocol Buffers** for efficient serialization
- Extensive **automated card code generation** tools
- No AI-specific instructions files (uses standard GitHub documentation)
The project is well-organized with clear separation between framework (Mage), game rules/sets, client UI, server backend, and plugins for extensibility.
agentId: ac3444f (for resuming to continue this agent's work if needed)
<usage>total_tokens: 50308
tool_uses: 42
duration_ms: 175655</usage>Perfect! Now I have enough information. Let me compile a comprehensive report.
## XMage/Mage Engine - Deep Architecture Analysis
I've conducted a thorough exploration of the XMage source code architecture. Here are my detailed findings:
### 1. MAIN SOURCE CODE DIRECTORIES AND PURPOSES
The project uses a multi-module Maven structure:
**Root Modules:**
- `/Mage/` - Core game engine (28,000+ unique cards, 73,000+ reprints)
- `/Mage.Client/` - GUI client (Swing-based desktop application)
- `/Mage.Server/` - Central server (RMI/Remoting-based)
- `/Mage.Common/` - Shared utilities between client and server
- `/Mage.Sets/` - Card implementations for all Magic sets
- `/Mage.Tests/` - Comprehensive testing framework
- `/Mage.Server.Plugins/` - Pluggable game types (28+ game formats), deck validators, AI players
- `/Mage.Plugins/` - Client-side plugins
- `/Utils/` - Build and utility scripts
- `/Mage.Verify/` - Card verification tools
- `/Mage.Reports/` - Code coverage and analysis
### 2. KEY PACKAGES/MODULES AND RELATIONSHIPS
**Core Engine Structure** (`/Mage/src/main/java/mage/`):
```
mage/
├── abilities/ # Core ability system (1,236 classes)
│ ├── Ability (interface) - Base for all abilities
│ ├── AbilityImpl (abstract)
│ ├── ActivatedAbility/TriggeredAbility/StaticAbility
│ ├── SpellAbility - Casting spells
│ ├── effects/ # Effect implementations
│ │ ├── Effect (interface)
│ │ ├── OneShotEffect - One-time effects
│ │ ├── ContinuousEffect - Ongoing effects (7 layers)
│ │ ├── ReplacementEffect
│ │ ├── RestrictionEffect
│ │ └── CostModificationEffect
│ ├── keyword/ # Keyword abilities (Flying, Deathtouch, etc.)
│ ├── common/ - Common ability patterns
│ ├── costs/ # Mana and non-mana costs
│ ├── triggers/ # Triggered ability patterns
│ ├── conditions/ # Conditional logic
│ ├── dynamicvalue/ # X-value calculators
│ └── mana/ # Mana abilities
├── cards/ # Card definitions
│ ├── Card (interface)
│ ├── CardImpl (abstract base)
│ ├── repository/ # Card database
│ ├── decks/ # Deck management
│ └── basiclands/ # Token/basic land generation
├── game/ # Game rules engine
│ ├── Game (interface)
│ ├── GameImpl (abstract)
│ ├── GameState # Full game state snapshot
│ ├── permanent/ # Battlefield permanents
│ ├── stack/ # Stack management
│ ├── combat/ # Combat mechanics
│ ├── turn/ # Turn structure
│ ├── events/ # Game events (648+ event types)
│ └── command/ # Special objects (Emblems, Planes, Dungeons)
├── target/ # Targeting system
│ ├── Target (interface)
│ ├── TargetPermanent/TargetPlayer/TargetCard
│ └── targetpointer/ # Target resolution
├── filter/ # Card/object filtering
│ ├── Filter (interface)
│ ├── FilterImpl
│ ├── predicate/ # Composable filters
│ └── common/ # Pre-built filters
├── counters/ # Counter system (50+ counter types)
├── watchers/ # Event watchers for abilities
├── constants/ # Game constants (57 enums)
│ ├── CardType, SubType, SuperType
│ ├── Zone (Hand, Graveyard, Battlefield, etc.)
│ ├── AbilityType, EffectType
│ └── Layer (7-layer effect system)
└── players/ # Player state management
```
### 3. CORE ABSTRACTIONS AND DESIGN PATTERNS
**Design Patterns Used:**
1. **Command Pattern** - Abilities are commands with:
- Costs (mana and non-mana)
- Effects (one-shot or continuous)
- Targets
- Conditions
2. **Composite Pattern** -
- Abilities contain Effects
- Abilities can have Modes (multiple choices)
- Effects can be combined with conditions
3. **Strategy Pattern** -
- Different ability implementations (Activated, Triggered, Static)
- Different effect types (OneShotEffect, ContinuousEffect)
- Pluggable AI strategies
4. **Observer Pattern** -
- Watchers observe GameEvents
- ContinuousEffects track state changes
- Event listeners for UI updates
5. **Factory Pattern** -
- CardRepository creates Card instances
- GameFactory creates game instances
- PluginClassLoader for dynamic game/AI loading
6. **Layer/Intercepting Filter Pattern** -
- 7-layer effect system for continuous effects
- Effects are applied in strict order (Copy → Control → Text → Type → Color → Ability → PT)
- Dependency tracking between effects
**Core Class Hierarchy:**
```
MageItem
├── MageObject (interface) - All game objects (cards, permanents)
│ └── MageObjectImpl (abstract)
│ └── CardImpl (abstract)
│ ├── Card implementations (28,000+ card classes)
│ └── PermanentCard (battlefield version)
Ability (interface)
├── AbilityImpl (abstract)
│ ├── ActivatedAbilityImpl
│ ├── TriggeredAbilityImpl
│ ├── StaticAbility
│ ├── SpellAbility (casting spells)
│ └── PlayLandAbility
Effect (interface)
├── EffectImpl (abstract)
│ ├── OneShotEffect (immediate resolution)
│ └── ContinuousEffect (ongoing, 7-layer system)
Game (interface)
└── GameImpl (abstract)
├── TwoPlayerDuel
├── CommanderDuel
├── FreeForAll
└── (28+ game types as plugins)
```
### 4. HOW GAME LOGIC WORKS
**Game Execution Flow:**
1. **Game Initialization**
- Create Game instance (e.g., TwoPlayerDuel)
- Initialize players with decks
- Mulligan phase
- Set starting player
2. **Game Loop (in GameImpl)**
```
while (!game.hasEnded()) {
applyEffects() // Apply continuous effects in layers
processStack() // Resolve spells/abilities
playerTakePriority() // Player decisions
checkStateBasedActions()// Kill creatures, etc.
}
```
3. **Turn Structure** (GameState.turn)
- Untap Step
- Upkeep Step
- Draw Step
- Main Phase 1
- Combat Phase (Beginning → Declare Attackers → Declare Blockers → Damage → End)
- Main Phase 2
- Ending Phase (End Step → Cleanup Step)
4. **Spell/Ability Resolution**
- Player casts/activates (SpellAbility or ActivatedAbility)
- Cost payment validation
- Target selection/validation (Target.canChoose())
- Effect execution (Effect.apply())
- Check for replacement effects (ReplacementEffect)
- Generate game events (GameEvent)
- Trigger abilities listening to those events
5. **Event System**
- 648+ event types (SPELL_CAST, CREATURE_BLOCKED, DAMAGE_DEALT, etc.)
- Watchers listen and set conditions
- Triggered abilities check event type and trigger conditions
- Effects can be conditional (if condition is met)
6. **Continuous Effects (Layer System)**
- Layer 1: Copy effects
- Layer 2: Control-changing effects
- Layer 3: Text-changing effects
- Layer 4: Type-changing effects
- Layer 5: Color-changing effects
- Layer 6: Ability-adding/removing effects
- Layer 7: Power/toughness modifications
- Applied in strict dependency order (handles circular dependencies)
### 5. HOW CARD IMPLEMENTATIONS ARE STRUCTURED
**Card Implementation Pattern:**
Each card is a concrete class extending CardImpl:
```java
// Example: AAT1 card
public final class AAT1 extends CardImpl {
public AAT1(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo,
new CardType[]{CardType.ARTIFACT, CardType.CREATURE},
"{1}{W}{U}{B}");
this.subtype.add(SubType.DROID);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Add abilities
this.addAbility(new RepairAbility(4));
// Create custom triggered ability
Effect effect = new DoIfCostPaid(
new LoseLifeTargetEffect(1),
new ManaCostsImpl<>("{W/B}")
);
Ability ability = new CustomTriggeredAbility(effect);
this.addAbility(ability);
}
private AAT1(final AAT1 card) {
super(card);
}
@Override
public AAT1 copy() {
return new AAT1(this);
}
}
```
**Ability Pattern:**
Abilities are added to cards and can be:
- **ActivatedAbility**: "{2}{B}: Do something" - costs + effects + targets
- **TriggeredAbility**: "Whenever X happens, do Y" - event listener + effect
- **StaticAbility**: "Creatures you control get +1/+1" - continuous effect
- **SpellAbility**: Base casting ability (auto-added to non-lands)
- **PlayLandAbility**: Play land ability (auto-added to lands)
**Custom Ability Example (Triggered):**
```java
private static class CustomTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.COUNTER_REMOVED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
// Validate trigger conditions
return shouldTrigger;
}
@Override
public CustomTriggeredAbility copy() {
return new CustomTriggeredAbility(this);
}
}
```
**Effect Pattern:**
```java
public class MyEffect extends OneShotEffect {
public MyEffect(Outcome outcome) {
super(outcome);
}
@Override
public boolean apply(Game game, Ability source) {
// Get targets and apply effect
for (UUID targetId : getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.tap(source, game);
}
}
return true;
}
@Override
public MyEffect copy() {
return new MyEffect(this);
}
}
```
### 6. SERVER/CLIENT ARCHITECTURE
**Client-Server Communication:**
- **Protocol**: JBoss Remoting (RMI-like remote method invocation)
- **Transport**: Bisocket (TCP-based, bi-directional)
- **Main Interface**: `MageServer` (implemented by `MageServerImpl`)
**Server Architecture** (`MageServerImpl`):
```
Main.java
├── Server startup & configuration
├── Plugin loading (PluginClassLoader)
├── Card database scanning (CardScanner)
├── ManagerFactory instantiation
└── TransporterServer setup
MageServerImpl
├── Session management (SessionManager)
├── User management (UserManager)
├── Table management (TableManager)
├── Game management (GameFactory)
├── Tournament management
├── Chat management (ChatManager)
├── Deck validation (DeckValidatorFactory)
└── AI creation (PlayerFactory)
```
**Client Architecture** (`MageFrame.java`):
```
MageFrame (main GUI)
├── Game panels (table view, hand, graveyard, etc.)
├── Chat panel
├── Cards panel
├── Deck editor
├── Session handler (remote method invocation)
└── Components (various UI components)
```
**Key Server Managers:**
1. **SessionManager** - Manages user sessions and authentication
2. **UserManager** - User accounts and stats
3. **TableManager** - Game tables (matches/tournaments)
4. **GameFactory** - Creates game instances from plugins
5. **PlayerFactory** - Creates human/AI players
6. **TournamentFactory** - Tournament management
**Game Flow on Server:**
```
Client connects
↓
Authentication/Registration
↓
Game creation (Table with MatchOptions)
↓
Player setup (decks, mulligans)
↓
Game loop (GameImpl.playGame())
↓
Send game state updates to clients (GameView)
↓
Receive player actions (priority, targets, choices)
↓
Apply actions to game
↓
Check for win condition
↓
Game over
```
### 7. KEY BASE CLASSES AND INTERFACES
**Foundation Interfaces:**
| Interface | Purpose | Key Methods |
|-----------|---------|-------------|
| `Ability` | Everything is an ability | getSourceId(), getCosts(), getEffects(), canActivate() |
| `Effect` | Effects modify game | apply(), getOutcome(), getText() |
| `ContinuousEffect` | Ongoing effects | apply(Layer, SubLayer, ...), hasLayer(), getDuration() |
| `Card` | Any card object | getAbilities(), getOwner(), getSpellAbility() |
| `Permanent` | Battlefield card | tap(), transform(), addCounter() |
| `Target` | Target selection | canChoose(), possibleTargets(), isChosen() |
| `Filter` | Card filtering | match(), add(Predicate) |
| `Game` | Game state | getObject(), getPlayers(), getState() |
| `Watcher` | Event observer | watch(), conditionMet() |
**Important Implementation Classes:**
| Class | Purpose |
|-------|---------|
| `AbilityImpl` | Base for all abilities |
| `ActivatedAbilityImpl` | Abilities you activate |
| `TriggeredAbilityImpl` | Abilities that trigger |
| `StaticAbility` | Always-on abilities |
| `CardImpl` | Base for all card implementations |
| `GameImpl` | Base game implementation |
| `GameState` | Current game state snapshot |
| `ContinuousEffects` | Manages all effect layers |
| `FilterImpl` | Base filter implementation |
### 8. PLUGINS AND EXTENSIONS
**Plugin System:**
Located in `/Mage.Server.Plugins/`:
1. **Game Types (28+ plugins)**
- `Mage.Game.TwoPlayerDuel` - Standard 1v1
- `Mage.Game.CommanderDuel` - Commander 1v1
- `Mage.Game.CommanderFreeForAll` - 4-player Commander
- `Mage.Game.FreeForAll` - Multiplayer free-for-all
- `Mage.Game.MomirDuel` - Momir Basic (random card generator)
- Plus formats: Tiny Leaders, Oathbreaker, Brawl, etc.
2. **Deck Validators**
- `Mage.Deck.Constructed` - Standard, Modern, Legacy, etc.
- `Mage.Deck.Limited` - Sealed, Draft
3. **AI Players**
- `Mage.Player.AI` - ComputerPlayer7 (rules-based)
- `Mage.Player.AIMCTS` - Monte Carlo Tree Search
- `Mage.Player.AI.DraftBot` - Draft AI
4. **Tournament Types**
- `Mage.Tournament.BoosterDraft`
- `Mage.Tournament.Sealed`
- `Mage.Tournament.Constructed`
**Extension Loading:**
```java
// In Main.java
private static final File pluginFolder = new File("plugins");
private static final File extensionFolder = new File("extensions");
// Plugins loaded via PluginClassLoader:
public static final PluginClassLoader classLoader = new PluginClassLoader();
// Game types registered in plugin:
// Each game plugin must implement and register a GameType
new DeckValidatorFactory().addDeckValidator(...);
GameFactory.getInstance().addGameType(new MyGameType(), ...);
```
**Plugin Interface Pattern:**
Each game type plugin creates a class extending `GameImpl`:
```java
public class MyCustomGame extends GameImpl {
@Override
public MatchType getGameType() {
return new MyGameType();
}
@Override
protected void init(UUID choosingPlayerId) {
super.init(choosingPlayerId);
// Custom initialization
}
}
```
### 9. TEST STRUCTURE AND RUNNING TESTS
**Test Framework** (`/Mage.Tests/`):
```
Mage.Tests/
├── org/mage/test/
│ ├── serverside/base/
│ │ ├── CardTestPlayerBase # Base test class
│ │ ├── CardTestPlayerAPIImpl # Test API implementation
│ │ └── impl/
│ ├── cards/ # Card-specific tests (650+ tests)
│ ├── combat/ # Combat mechanics
│ ├── multiplayer/ # Multiplayer scenarios
│ ├── AI/ # AI behavior tests
│ ├── load/ # Card loading tests
│ └── utils/ # Test utilities
```
**Base Test Class:**
```java
public abstract class CardTestPlayerBase extends CardTestPlayerAPIImpl {
public CardTestPlayerBase() {
deckNameA = "RB Aggro.dck";
deckNameB = "RB Aggro.dck";
}
@Override
protected Game createNewGameAndPlayers() throws GameException {
Game game = new TwoPlayerDuel(
MultiplayerAttackOption.LEFT,
RangeOfInfluence.ONE,
MulliganType.GAME_DEFAULT.getMulligan(0),
60, 20, 7
);
playerA = createPlayer(game, "PlayerA", deckNameA);
playerB = createPlayer(game, "PlayerB", deckNameB);
return game;
}
}
```
**Test Commands** (CardTestPlayerAPIImpl):
```
// Constants:
ALIAS_PREFIX "@" // Card aliases
CHECK_PREFIX "check:" // Assertions
ACTIVATE_ABILITY "activate:" // Activate abilities
ACTIVATE_CAST "activate:Cast " // Cast spells
ACTIVATE_PLAY "activate:Play " // Play lands
MANA_ACTIVATE "manaActivate:" // Activate mana
AI_PREFIX "ai:" // AI commands
// Examples:
"check:LIFE#playerA#20" // Check life total
"check:PERMANENT_COUNT#2" // Check permanent count
"check:PT#@creature#5#5" // Check power/toughness
"activate:Cast @card_name" // Cast specific card
"check:ABILITY#@card#Some Ability" // Check ability exists
```
**Writing a Test:**
```java
@Test
public void testMyCard() {
addCard(Zone.BATTLEFIELD, playerA, "My Card");
addCard(Zone.HAND, playerB, "Target Card");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "My Card", "Target Card");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerB, 18);
assertTapped("My Card", true);
}
```
**Running Tests:**
```bash
# Run all tests
mvn test
# Run specific test class
mvn test -Dtest=OutcomesTest
# Run specific test method
mvn test -Dtest=OutcomesTest#test_FromEffects_Single
# Run with coverage
mvn install -Djacoco.skip=false
```
**Key Test Utilities:**
- `addCard(Zone, Player, cardName)` - Add card to zone
- `castSpell(turn, step, player, cardName)` - Cast spell
- `activateAbility(turn, step, player, ability)` - Activate ability
- `setStopAt(turn, step)` - Stop execution at step
- `execute()` - Run game
- `assertLife(player, expected)` - Check life total
- `assertPermanentCount(player, expected)` - Check permanent count
- `assertHandCount(player, expected)` - Check hand size
**Test Categories:**
1. **Card-Specific Tests** - Test individual card mechanics
2. **Ability Tests** - Test ability types and interactions
3. **Combat Tests** - Combat scenarios and blocking
4. **Multiplayer Tests** - Multi-player edge cases
5. **Rollback Tests** - Save/load game state
6. **AI Tests** - AI decision making
7. **Performance Tests** - Large game simulations
### SUMMARY: Architecture Strengths
1. **Separation of Concerns** - Core engine, cards, server, client well separated
2. **Extensibility** - Plugin system for new game types without core changes
3. **State Management** - GameState can be copied/restored for simulations and rollback
4. **Event-Driven** - Everything is based on game events and watchers
5. **Layered Effects** - Sophisticated continuous effect system handles complex interactions
6. **Comprehensive** - 28,000+ cards implemented with full rules enforcement
7. **Testable** - Extensive testing framework for card and game logic
8. **Performance** - Optimizations for AI simulations and large multiplayer games
The architecture is mature, well-designed for a complex rules engine, and supports everything from casual play to competitive formats with proper rules enforcement.
agentId: a8d21e4 (for resuming to continue this agent's work if needed)
<usage>total_tokens: 78205
tool_uses: 62
duration_ms: 116983</usage>Now let me look at a few more specific things to make the CLAUDE.md accurate and useful. Let me check the Makefile directly and also look at test examples more closely.
Now let me read a few key files directly for accuracy.
Async agent launched successfully. agentId: a3064fb (internal ID - do not mention to user. Use to resume later if needed.) The agent is working in the background. You will be notified automatically when it completes. Continue with other tasks. output_file: /tmp/claude-1000/-mnt-dest-btrfs-home-jc-src-mage/tasks/a3064fb.output To check progress before completion (optional), use Read or Bash tail on the output file.
Let me wait for the background agent to complete before writing the CLAUDE.md file.
The agent failed but it returned a lot of useful data. Let me read a few more files directly to fill in the gaps - a simple card implementation and a simple test.
The agent hit an error but returned useful data. Let me read a few more key files directly.
Now let me check the Mage.Tests pom.xml for surefire configuration and how to run a single test.
Let me also look at how sets register their cards and the card file naming convention.
Now I have enough information. Let me create the CLAUDE.md file.
Created CLAUDE.md with:
make build, mvn test, single test execution with -Dtest= and -pl Mage.TestsbyDescription() for card code vs fromString() for tests onlyThe background agent failed but I had already gathered all the information I needed from it and other sources. The CLAUDE.md file has been created successfully at the repository root.