XMage is an open-source project that welcomes contributions of every kind — new card implementations, bug fixes, game-rule corrections, AI improvements, and UI enhancements. All changes flow through GitHub pull requests against theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/magefree/mage/llms.txt
Use this file to discover all available pages before exploring further.
master branch. The workflow below covers everything from forking the repository to getting a PR merged, including how to write and run tests and what CI checks must pass.
The XMage wiki has dedicated pages that supplement this guide:
Setting up your Development Environment,
Development Testing Tools,
Development Workflow, and
Development HOWTO Guides.
These pages contain additional detail on server configuration, cheat commands, and card-implementation patterns.
Contribution Flow
On GitHub, click Fork on magefree/mage to create your own copy. Then clone it locally:
Always work on a dedicated branch — never commit directly to
master. Use a short, descriptive name that indicates what the branch contains:# For a new card implementation
git checkout -b feat/lightning-bolt
# For a bug fix
git checkout -b fix/lifelink-interaction
# For a game-rule correction
git checkout -b fix/commander-damage-tracking
mvn install -DskipTests # fast build — confirms compilation
mvn test # runs the full Mage.Tests suite
If any tests fail before you make a change, note them — they are pre-existing failures unrelated to your work.
Mage.Sets/src/mage/cards/<letter>/Mage.Sets/src/mage/sets/Mage/src/main/java/mage/Mage.Server/src/main/java/mage/server/Mage.Client/src/main/java/mage/client/Mage.Server.Plugins/Mage.Game.<Name>/Mage.Server.Plugins/Mage.Player.AI*/For card implementations, the
Utils/gen-card.pl script scaffolds the boilerplate Java class from a template:The generated file lands in the correct
Mage.Sets/src/mage/cards/<letter>/ directory, ready for you to fill in abilities and effects.cards/abilities/ — keyword and activated ability tests
cards/continuous/ — layer and continuous-effect tests
cards/damage/ — damage prevention and assignment tests
combat/ — attack and block tests
commander/ — commander-format rule tests
game/ — general game-scenario tests
player/ — player-action tests
package org.mage.test.cards.abilities;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
public class LightningBoltTest extends CardTestPlayerBase {
@Test
public void testDealsDamageToPlayer() {
addCard(Zone.HAND, playerA, "Lightning Bolt");
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerB, 17);
}
}
Use a clear, imperative commit message that summarizes what the commit does and — for card implementations — includes the card name:
git add Mage.Sets/src/mage/cards/l/LightningBolt.java \
Mage.Tests/src/test/java/org/mage/test/cards/abilities/LightningBoltTest.java
git commit -m "Implement Lightning Bolt (deals 3 damage to any target)"
magefree/mage master as the base.XMage uses GitHub Actions (
.github/workflows/maven.yml). On every push and pull request targeting master, the workflow:mvn test -B with a custom log4j.properties for CI-friendly output.# From .github/workflows/maven.yml
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn test -B -Dxmage.dataCollectors.printGameLogs=false \
-Dlog4j.configuration=file:${GITHUB_WORKSPACE}/.travis/log4j.properties
Keeping Your Fork in Sync
Before starting new work, sync your localmaster with upstream to avoid merge conflicts:
master.
Bug Reports
Report bugs via GitHub Issues. A useful bug report includes:- XMage version (shown in the title bar of the client)
- Operating system and Java version (
java -version) - Steps to reproduce — ideally a minimal deck and sequence of plays
- Expected behavior vs. actual behavior
- Screenshots or log output if relevant
Feature Requests
Feature requests are also filed as GitHub Issues. When requesting a new feature:- Describe the desired behavior and the use case it serves.
- If it relates to a specific card or game rule, cite the card name and ruling.
- Check existing issues first to avoid duplicates.
Code Style
XMage follows the Java conventions already established in the codebase:- Indentation: 4 spaces (no tabs).
- Braces: on the same line as control statements (K&R style), always present even for single-statement blocks.
- Naming:
camelCasefor methods and variables;PascalCasefor class names;UPPER_SNAKE_CASEfor constants. - Card classes: one public class per file, class name matches the card name with all non-alphanumeric characters removed (e.g.,
"Swords to Plowshares"→SwordsToPlowshares.java). - No wildcard imports: prefer explicit
importstatements.
maven-compiler-plugin 3.8.1 with useIncrementalCompilation=false. There is no enforced checkstyle plugin in the root POM, but reviewers will flag style deviations in the PR.
Community Channels
- GitHub Issues: bug reports and feature requests — github.com/magefree/mage/issues
- Discord: https://discord.gg/Pqf42yn
- Reddit: r/XMage
- Gitter: gitter.im/magefree/mage
