Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time
Mar 29, 2021
Nov 7, 2020
Nov 7, 2020


Build Status Discord Documentation

This is a simulator and game server for Spellsource, a community-authored card game, licensed under the Affero GPLv3.

Download for your platform here.

Steam keys for the Alpha are available for bonafide testers. Contact us in the Discord.

Please see the Issues tab to report bugs or request functionality.


Read the latest changes here or the deployed changes on the website.


The Spellsource-Server project is a 2-player card battler that supports hosted, networked gameplay. It features rudimentary matchmaking, collection management and support for game mechanics that persist between matches.

See the complete code reference here.

Getting Around

Cards are located at cards/src/main/resources/cards/custom.

To implement new effects (called Spells inside Spellsource) add a new Spell subclass to game/src/main/java/net/demilich/metastone/game/spells.

You can learn more about the Spellsource AI as implemented in the GameStateValueBehaviour class.

The server application starts in Clustered. ./gradlew netRun uses LocalClustered.

The client is private, please contact for access on the Discord.


$ ./gradlew tasks --group spellsource

> Task :tasks

Tasks runnable from root project

Spellsource tasks
bumpVersion - Bumps the server version
cloneMongo - Connects to the production database, dumps its database file, then restores the database to your local mongo.
deployAll - Deploys the server, the client and the website
distAndroid - Builds and uploads the Android project to Google Play
distIOS - Builds and uploads to Testflight the iOS project
distSteam - Uploads the macOS and Windows builds to Steam
distSwarm - Deploys to a Docker Swarm
distWebGL - Uploads the WebGL build to
distWWW - Builds and deploys the website (requires npm, python, the .venv virtualenv installed)
netRun - Starts the Spellsource server
netRunDebug - Starts the Spellsource server attachable as a Remote debug target from IntelliJ
swagger - Generates sources from the client/swagger-api.yaml. Run this whenever you change that file.
testAll - Runs all tests. When testing custom cards, failed fuzzing results are put in cards/src/test/resources/traces by testRandomMassPlay.

To see all tasks and more detail, run gradle tasks --all

To see more detail about a task, run gradle help --task <task>

Cloning this repository

Typically you do not have access to the private submodules. Use the following commands to clone the repository:

git clone
cd Spellsource

This repository uses Git Submodules. This means, if you have the proper authorization, you'll be able to access all the source code using:


Make sure longpaths is enabled on Windows. Run a bash or other command prompt as administrator, and then execute git config --system core.longpaths true.

All platforms
git lfs install
git clone --recurse-submodules
cd Spellsource
git submodule update --init --recursive unityclient/src/unity

Failures are normal if you do not have permissions to the repositories.

If you have the permissions, you will need to add your SSH key to the private repositories, for both BitBucket and GitHub, to access all of them. Contact us on the Discord at the start of this document if you'd like to contribute to private work like the game client.

You cannot use the GitHub Desktop app to download this repository.

Getting started with Development on macOS

Requirements: Java 11 or later and Docker. Check your current version of Java using java --version.

  1. Install dependencies:
    # XCode binaries
    xcode-select --install
    # Brew
    /bin/bash -c "$(curl -fsSL"
    # Docker. Look carefully at any messages brew tells you and do them
    brew cask install docker
    # Java (if required)
    brew install openjdk@11
    # Not sure why brew doesn't just do this for you
    sudo ln -sfn /usr/local/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
    brew link --force openjdk@11
  2. Clone the repository:
    git clone
    cd Spellsource
    # If you have access
    git submodule update --init --recursive unityclient/src/unity
  3. See Spellsource-specific tasks using ./gradlew tasks --group spellsource.
  4. Run tests using ./gradlew --no-parallel test
  5. Start a local server using ./gradlew netRun
  6. Generate project files using ./gradlew idea, then open the project with IntelliJ Community Edition. You can install this with brew cask install intellij-idea-ce.

Getting started with Development on Windows

Requirements: Java 11 or later, Docker, bash and GNU binutils like MinGW that comes with git.

  1. Install dependencies:

    1. Java AdoptOpenJDK 11.0.9 or later. During installation, choose to set JAVA_HOME and add java to your PATH.
    2. Docker for Windows Desktop. You will be prompted to enable and install Windows Subsystem for Linux 2 (WSL2) features, carefully follow those instructions including the new MSI it downloads into your downloads folder.
    3. Git 2.29.2 or later. During installation, choose Use Git and optional Unix tools from the Windows Command Prompt.
    4. PuTTY 0.74 or later. Then, follow the instructions from here starting with "Installing SSH Tools" to get authorization configured for GitHub.
    5. dotnet [3.1](
    6. git lfs 2.12.2 or later. ) or later.
  2. Right click in the folder where you'd like to store your Spellsource files, then choose Git Bash Here. Then, clone the repository:

    git lfs install
    I have private repo access
    git clone --recurse-submodules
    cd Spellsource
    git submodule update --init --recursive unityclient/src/unity
    I am a public user
    git clone
    cd Spellsource
  3. See Spellsource-specific tasks using TERM=mintty ./gradlew tasks --group spellsource.

  4. Run tests using TERM=mintty ./gradlew --no-parallel test

  5. Start a local server using TERM=mintty ./gradlew netRun

  6. Generate project files using TERM=mintty ./gradlew idea, then open the project with IntelliJ Community Edition. You can install this from here.

Unfortunately, it's true, you have to prefix every gradlew command with TERM=mintty until a bug in Gradle is fixed.

Contributing Cards

Visit the Contribution Guide for more about contributions, including guidelines.


Use ./gradlew tasks --group spellsource to see all deployment related tasks. You will need to be an Administrative user for these.


I cannot clone the repository.

The GitHub Desktop app is not supported. Please use the git command line commands to clone the repository:

git clone

I am having issues with Git Submodules, like failures to download

Public users do not have access to the private repositories that fail to download. You can safely ignore those errors. If you'd like to contribute to the private repositories, like the game client, please use the Discord invite link above and discuss with the team there.

I am seeing issues with too many files open.

On macOS, issue the following commands to increase your per-process limits:

sudo sysctl -w kern.maxfiles=5242880
sudo sysctl -w kern.maxfilesperproc=524288
ulimit -n 200000
sudo launchctl limit maxfiles 524288 5242880

testTraces is failing.

You had failures in testRandomMassPlay, the fuzzer for Spellsource. These are real issues.

I uploaded to Steam, but I do not see the build.

Visit the Steam partner's page and promote the build.

I uploaded to TestFlight but the build isn't public yet.

Make sure the Public group is added here.

The Discord bot will not compile due to an error that reads, in part, "Classes that should be initialized at run time got initialized during image building"

Add the class or the package containing it to end of the list of classes in the Args = --initialize-at-build-time=... line to

You may have to regenerate reflection config using sdkman's Graal distributable. The following commands will fix this issue:

sdk use java 20.1.0.r11-grl
./gradlew --no-daemon clean
./gradlew --no-daemon discordbot:genReflectionProps

./gradlew distSwarm fails with the message of the form:

#13 71.30 FAILURE: Build failed with an exception.
#13 71.30 
#13 71.30 * What went wrong:
#13 71.30 Could not determine the dependencies of task ':net:shadowJar'.
#13 71.30 > Could not resolve all dependencies for configuration ':net:runtimeClasspath'.
#13 71.30    > Could not resolve project :vertx-redis-cluster.
#13 71.30      Required by:
#13 71.30          project :net
#13 71.30       > Unable to find a matching configuration of project :subproject:
#13 71.30           - None of the consumable configurations have attributes.

Make sure to add the sub project directory and any others that need to be visible to Docker to .dockerignore in the form of !directory/*.

discordbot Swarm build (./gradlew distSwarm) fails with$NativeImageError: Image build request failed with exit status 137

On macOS and Windows, allocate more memory to your Docker host.

./gradlew net:run hangs with error Caused by: org.testcontainers.containers.ContainerLaunchException: Timed out waiting for log output matching '.*waiting for connections on port.*'

Make sure to use your local docker context using docker context use default.

I receive an error starting the server with gradle net:run of the form:

main ERROR o.t.d.DockerClientProviderStrategy Could not find a valid Docker environment. Please check configuration. Attempted configurations were:
Exception in thread "main" 20200811T112136 main ERROR o.t.d.DockerClientProviderStrategy     UnixSocketClientProviderStrategy: failed with exception InvalidConfigurationException (ping failed). Root cause NoSuchFileException (/var/run/docker.sock)
org.testcontainers.containers.ContainerLaunchException: Container startup failed
main ERROR o.t.d.DockerClientProviderStrategy As no valid configuration was found, execution cannot continue

Restart Docker. Make sure Docker is running.

The MongoDB container doesn't start with gradle net:run with the following error: Timed out waiting for log output matching '.*waiting for connections on port.*'

Try deleting your local database which is automatically bind-mounted to the container at .mongo:

rm -rf .mongo/

I cannot connect to the Hidden Switch cluster to deploy the servers.

You need special authorization for this. It is accessed via an audited API key.

I receive an error related to (sharp:42678): GLib-CRITICAL **: 17:17:14.186: g_hash_table_lookup: assertion 'hash_table != NULL' failed

Delete the NPM modules folder: rm -rf www/npm_modules, then rerun ./gradlew distWWW.

Autocomplete, code insight, intellisense or other code completion features are missing when I am trying to write code accessing the generating protobufs definitions, like or

In IntelliJ, visit the Help > Edit Custom Properties... menu, then add the following lines:

# custom IntelliJ IDEA properties

Special Thanks


YourKit supports open source projects with its full-featured Java Profiler.

YourKit, LLC is the creator of YourKit Java Profiler and YourKit .NET Profiler, innovative and intelligent tools for profiling Java and .NET applications.