planet-wars-rts

๐Ÿช PlanetWars AI Competition โ€“ Submission Instructions

Welcome to the PlanetWars AI competition! This document describes how to package and submit your entry. Your agent should run as a WebSocket server and respond to JSON-formatted messages. Each submission must include a Dockerfile that builds and runs your agent.

We support entries in Kotlin/Java or Python.
However, you may use any language as long as your agent speaks WebSocket and uses JSON.

If youโ€™re entering a competition linked to a conference, please create a set of slides following the instructions here: Slides Instructions

For Kotlin/Java and Python, we provide example servers and agent wrappers so you can focus entirely on your agent logic.


๐ŸŽฎ Simulation-Based AI Support

The Kotlin framework includes a Forward Model to enable simulation-based AI methods such as Monte Carlo Tree Search (MCTS).
The Python version currently supports reactive agents, with forward model support a possibility for future releases.
The Python option may be more suitable for neural network-based agents, as it allows you to use libraries like PyTorch or TensorFlow.


๐Ÿ“ฆ Submission Format

Each submission must:

  1. Contain all necessary code and dependencies to build and run your agent.
  2. Include a working Dockerfile that listens on port 8080 and runs your agent server.
  3. Be able to receive JSON game states and return legal actions via WebSocket on port 8080.
  4. Be self-contained โ€” your Docker image must not require internet access at runtime.

โ˜• Kotlin/Java Submission

Your Kotlin or Java project must produce a single .jar file that runs the WebSocket server.

Important: Your Dockerfile should be self-contained and handle all building internally. This is the recommended approach:

# ---------- Stage 1: Build with Gradle ----------
FROM gradle:8.5.0-jdk20 AS builder

WORKDIR /home/gradle/project

# Copy entire project into container
COPY . .

# Run Gradle build (skip tests for speed)
RUN gradle :app:build -x test

# ---------- Stage 2: Runtime with Java only ----------
FROM eclipse-temurin:20-jdk

WORKDIR /app

# Copy JAR from builder stage
COPY --from=builder /home/gradle/project/app/build/libs/*.jar app.jar

# Expose WebSocket port
EXPOSE 8080

# Run the agent
CMD ["java", "-jar", "app.jar"]

Legacy Dockerfile (Still Supported)

For backward compatibility, the simple Dockerfile is still supported (expects pre-built JAR):

FROM eclipse-temurin:20-jdk
WORKDIR /app
COPY app/build/libs/client-server.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]

Note: With this approach, the submission system will automatically run ./gradlew build before building the Docker image. However, we recommend migrating to the self-contained approach above.

In your Gradle build file (build.gradle.kts), make sure to specify the correct entry point:

application {
    mainClass.set("competition_entry.RunEntryAsServerKt") // Adjust to match your actual package and file
}

Example Kotlin Server Main

package competition_entry

import games.planetwars.agents.random.CarefulRandomAgent
import json_rmi.GameAgentServer

fun main() {
    val server = GameAgentServer(port = 8080, agentClass = CarefulRandomAgent::class)
    server.start(wait = true)
}

โ˜• Python Submission

As for the Kotlin/Java submission, your Python project must produce a single Docker image that runs the WebSocket server.

Example Agent

Use greedy_heuristic_agent.py as your starting point. It shows the correct pattern: subclass PlanetWarsPlayer, implement get_action and get_agent_type, and do not override prepare_to_play_as unless you include the opponent parameter in the signature:

# Only override if you need custom setup โ€” must include opponent parameter:
def prepare_to_play_as(self, player: Player, params: GameParams, opponent=None) -> str:
    self.player = player
    self.params = params
    return self.get_agent_type()

Example Dockerfile

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8080

CMD ["python", "main.py"]

A copy of this Dockerfile is available as Dockerfile.python in this repo.

Example main.py

import asyncio
from client_server.game_agent_server import GameServerAgent
from agents.my_agent import MyAgent   # replace with your agent class

if __name__ == "__main__":
    asyncio.run(GameServerAgent(host="0.0.0.0", port=8080, agent=MyAgent()).start())

Your requirements.txt must list all Python dependencies. websockets and pydantic are required at minimum.


๐Ÿ“ค Submitting Your Agent via GitHub Issue

To enter the competition, simply create a new GitHub Issue in the submissions repository.

Your issue must contain a YAML block describing your submission, like this, noting the opening and closing triple backticks::

```yaml
id: another-awesome-agent
repo_url: https://github.com/SimonLucas/planet-wars-rts/commit/9c1133cd88217abf99a892e89d95bae6fd0ed66b
commit: 9c1133cd88217abf99a892e89d95bae6fd0ed66b  # optional
```

Important Notes:

You will receive comments on your issue as your submission is processed, including:

image


Let us know if you have any questions. Good luck, and may the best agent win! ๐Ÿš€