Skip to content

banjtheman/spirecomm

 
 

Repository files navigation

Slay-AI: LLM-Powered Slay the Spire Agent

An AI agent that plays Slay the Spire using Large Language Models. Unlike traditional RL approaches, this agent is controllable through natural language - you can change its strategy with prompts!

Features

  • 🤖 Multiple LLM Providers - Gemini, OpenAI, AWS Bedrock, Ollama (local)
  • 🎮 Controllable Behavior - Change strategy through prompts
  • 📊 Structured Logging - JSON logs of all AI decisions
  • ⚙️ Config-Based - Easy to switch models and strategies
  • 🔧 Extensible - Add new providers easily

Setup Guide

Step 1: Install Game Requirements

You need Slay the Spire with modding support:

  1. Slay the Spire - Purchase from Steam
  2. ModTheSpire - Download from GitHub
  3. BaseMod - Download from Steam Workshop or GitHub
  4. CommunicationMod - Download from GitHub

Copy all .jar mod files to your ModTheSpire mods directory.

Step 2: Install Python Dependencies

pip install -r requirements.txt

Or install only what you need:

pip install python-dotenv    # Required for all providers

# Then install your chosen provider:
pip install google-genai     # For Gemini
pip install openai           # For OpenAI
pip install boto3            # For AWS Bedrock
pip install langchain-ollama # For local Ollama models
pip install anthropic        # For Anthropic Claude (direct API)

Step 3: Set Up API Keys (Using .env File)

⚠️ Important: The agent runs as a subprocess launched by the game, NOT from your terminal. Environment variables exported in your shell won't be available. You must use a .env file!

Create a .env file in the spirecomm/ directory (same folder as main.py):

# .env file

# Google Gemini
GEMINI_API_KEY=your-gemini-api-key

# OpenAI
OPENAI_API_KEY=your-openai-api-key

# Anthropic Claude (direct API)
ANTHROPIC_API_KEY=your-anthropic-api-key

# AWS Bedrock (uses AWS credentials from ~/.aws/credentials or these env vars)
AWS_ACCESS_KEY_ID=your-aws-key
AWS_SECRET_ACCESS_KEY=your-aws-secret
AWS_DEFAULT_REGION=us-east-1

Only include the keys you need for your chosen provider.

For Ollama (Local - No API Key Needed):

# Install Ollama from https://ollama.ai
ollama pull nemotron-3-nano:30b  # Or your preferred model
# Make sure Ollama is running: ollama serve

Step 4: Configure Communication Mod

Communication Mod needs to know how to run your Python agent. Edit the config file:

Config file location:

  • Windows: %LOCALAPPDATA%\ModTheSpire\CommunicationMod\config.properties
  • Mac: ~/Library/Preferences/ModTheSpire/CommunicationMod/config.properties
  • Linux: ~/.config/ModTheSpire/CommunicationMod/config.properties

Set the config contents:

command=/path/to/python /path/to/spirecomm/main.py
runAtGameStart=true
verbose=true

Example (Mac with conda):

command=/Users/yourname/miniconda3/bin/python /Users/yourname/projects/spirecomm/main.py
runAtGameStart=true
verbose=true

Example (Windows):

command=C\:\\Python311\\python.exe C\:\\Projects\\spirecomm\\main.py
runAtGameStart=true
verbose=true

⚠️ Note: On Windows, backslashes and colons must be escaped (\\ and \:).

Step 5: Configure the Agent

Edit main.py to select your config:

config_path = "configs/agent_config_gemini_aggressive.json"

Available configs:

  • agent_config_gemini_aggressive.json - Google Gemini, aggressive playstyle
  • agent_config_bedrock_haiku.json - AWS Bedrock Claude Haiku 4.5
  • agent_config_gpt52.json - OpenAI GPT-5.2
  • agent_config_ollama.json - Local Ollama models

Step 6: Run the Game

Launch Slay the Spire with ModTheSpire:

# From your Slay the Spire installation directory
jre/bin/java -jar ModTheSpire.jar

Or use the ModTheSpire launcher if you installed via Steam Workshop.

The AI agent will automatically start when you begin a new run!

Configuration

Config File Structure

{
  "agent_name": "MyAgent",
  "provider": "gemini",
  "provider_config": {
    "model": "gemini-3-flash-preview",
    "temperature": 0.7
  },
  "use_ai_for": {
    "combat": true,
    "map": true,
    "rest": true,
    "events": true,
    "shop": true,
    "card_rewards": true,
    "boss_relics": true,
    "potions": false,
    "grid_selection": true
  },
  "prompts": {
    "combat": {
      "system_additions": "Be aggressive! Prioritize damage over defense."
    }
  }
}

Provider Options

Provider Config Value Model Examples
Google Gemini "gemini" gemini-3-flash-preview, gemini-2.0-flash
OpenAI "openai" gpt-5.2-mini, gpt-4o
AWS Bedrock "bedrock" us.anthropic.claude-haiku-4-5-20251001-v1:0 (Claude Haiku 4.5)
Ollama "ollama" nemotron-3-nano:30b, llama3.3, qwen2.5

Customizing Prompts

You can inject custom instructions to change agent behavior:

{
  "prompts": {
    "combat": {
      "system_additions": "Focus on blocking. Only attack when you have excess energy."
    },
    "map": {
      "strategy": "Avoid elite fights until Act 2. Prioritize rest sites when below 50% HP."
    },
    "events": {
      "strategy": "High HP = take risks for rewards. Low HP = play safe."
    }
  }
}

Architecture

┌─────────────────┐
│   Slay the      │ ← Game (with Communication Mod)
│   Spire         │
└────────┬────────┘
         │ Game State (JSON)
         ↓
┌─────────────────┐
│  Communication  │ ← Bridge
│     Layer       │
└────────┬────────┘
         │ 
         ↓
┌─────────────────┐
│   LLM Agent     │ ← Your AI (configurable!)
│   (llmAgent.py) │
└────────┬────────┘
         │ Decision
         ↓
┌─────────────────┐
│  LLM Provider   │ ← Gemini/OpenAI/Bedrock/Ollama
└─────────────────┘

Adding New Providers

To add a new LLM provider, edit neuralNet/llm_providers.py:

class MyProvider(LLMProvider):
    def __init__(self, config):
        super().__init__(config)
        self.model_name = config.get("model_name", "default-model")
        # Initialize your client
    
    def generate(self, prompt: str) -> str:
        # Call your LLM and return the response
        return response_text

Then register it in the create_provider function.

Structured Logging

All AI decisions are logged to ai_logs/ in JSONL format:

{
  "timestamp": "2026-01-15T10:30:45.123",
  "phase": "combat",
  "model": {
    "name": "gemini-3-flash-preview",
    "input_tokens": 245,
    "output_tokens": 45
  },
  "decision": {
    "action": "Strike",
    "target_index": 0,
    "reasoning": "Enemy is low HP, finish it off"
  },
  "game_state": {
    "hp": 65,
    "max_hp": 80,
    "floor": 5
  }
}

File Structure

spirecomm/
├── .env                       # ⚠️ YOUR API KEYS GO HERE (create this!)
├── requirements.txt           # Python dependencies
├── main.py                    # Entry point
├── configs/                   # Agent configurations
│   ├── agent_config_gemini_aggressive.json
│   ├── agent_config_bedrock_haiku.json
│   ├── agent_config_gpt52.json
│   └── agent_config_ollama.json
├── neuralNet/
│   ├── llm_providers.py       # LLM provider implementations
│   └── structured_logger.py   # Logging utilities
└── spirecomm/
    └── ai/
        ├── llmAgent.py        # Main LLM agent
        ├── agent.py           # Base agent class
        ├── nnAgent.py         # Legacy neural net agent
        └── simpleAgent.py     # Simple heuristic agent

Why LLM Agents?

Traditional RL agents learn optimal strategies but can't be easily controlled. They optimize for a fixed reward function.

LLM agents offer:

  • Natural language control - "Be more aggressive", "Focus on poison builds"
  • Explainable decisions - See the reasoning for each action
  • Easy customization - Change strategy with prompts, not retraining
  • Flexible providers - Switch models without code changes

Requirements

  • Python 3.8+
  • Slay the Spire with Communication Mod
  • python-dotenv package (for loading API keys)
  • API key for your chosen LLM provider (or local Ollama)
  • A .env file with your API keys (see setup instructions above)

Troubleshooting

Game Hangs for 10 Seconds, Then Agent Quits

Communication Mod is not receiving the "ready" signal from the Python process.

Common causes:

  • Wrong Python path in config.properties
  • Wrong path to main.py in config.properties
  • Missing Python dependencies

Debug: Check communication_mod_errors.log in your Slay the Spire directory for error details.

"API key not found" Error

The agent runs as a subprocess from the game, NOT from your terminal. Environment variables you export in your shell won't work!

Solution: Create a .env file in the spirecomm/ directory with your API keys.

Agent Not Responding

Check neuralNet.log for error messages. Common issues:

  • Missing .env file
  • Wrong API key format
  • Model name typo in config
  • Ollama not running (for local models)

Bedrock Authentication

AWS Bedrock uses your AWS credentials. Make sure you have either:

  1. AWS credentials in ~/.aws/credentials
  2. Or set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in .env

Where Are the Logs?

  • Agent decisions: ai_logs/ directory (JSONL files)
  • General agent log: neuralNet.log
  • Communication Mod errors: communication_mod_errors.log (in game directory)
  • ModTheSpire console: Shows real-time stdout from the agent

License

MIT License - See LICENSE file

Credits

  • Original spirecomm package: ForgottenArbiter
  • LLM agent extensions: Banjo Obayomi

About

A package for interfacing with Slay the Spire through Communication Mod, plus a simple AI

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 100.0%