Mission Brief
Something fundamental is shifting in how the world competes. Europe has deep reserves of engineering talent — and today, you’re going to prove it.
Your mission: build an AI bot that outplays every other team’s bot at Codenames. The team with the best win rate at 20:00 takes the crown.
The Game
Codenames is a 5×5 word association game played between two teams: Red and Blue.
Each team has two roles:
| Role | What they do |
|---|---|
| Spymaster | Sees which cards belong to their team. Gives a one-word clue + a number. |
| Guesser | Doesn’t know card types. Uses the clue to pick words from the board. |
Board layout: 9 Red cards, 8 Blue cards, 7 Neutral cards, 1 Assassin. Red goes first.
Winning:
- Reveal all your team’s cards → you win
- Reveal the Assassin → you lose immediately
- Guess a neutral or enemy card → your turn ends
The Guesser can make up to (clue count + 1) guesses per turn, or end their turn early.
Your Bot
Each team gets a Python bot template that handles the networking layer:
- Connects to the game server via Connect RPC
- Registers itself with your team token on startup
- Wires up the 4 game events:
GameStarted,GiveClue,MakeGuess,GameEnded
The rest is up to you. You’ll need to figure out how to track the board state across a game, how to give useful clues as Spymaster, and how to make good guesses as Guesser.
How the server talks to your bot
The game server calls your bot’s HTTP endpoints. Your bot must respond to four methods:
GameStarted — called once before any turns. Initialize your state here. GiveClue — called when it’s your turn as Spymaster. MakeGuess — called when it’s your turn as Guesser. GameEnded — called once when the game finishes. Clean up state here.
Important: reveals contains only the cards revealed since your last action — not the full board. You need to apply these deltas to your local state to keep an accurate picture of the board.
Step 1: Deploy your first bot
From the cloned repo root directory:
make deploy TEAM=<your-team-name> NAME=<your-bot-name> PORT=<port>
<port>can be one of:8001,8002,8003. If you deploy a bot with a port that another bot is already using, that bot will be stopped and unregistered. Then, the new bot will be deployed with that port.
This will:
- Copy your code to the VM
- Install dependencies
- Kill any bot already running on that port
- Start your bot and register it with the game server
Your bot will appear on the leaderboard once registered.
Step 2: Improve your bot
Open the template code and read through it. The starting point already wins some games — your goal is to make it win more. Think about:
- How does the Spymaster pick a clue word and decide how many cards to link?
- How does the Guesser decide which word to pick, and when to stop guessing?
When you’re ready to test a new version, redeploy:
make deploy TEAM=<your-team-name> NAME=<your-bot-name> PORT=<port> Step 3: Watch the leaderboard
Track your bot’s performance at hackathon.evroc.dev.
Scoring is win-rate-based — every game counts. The tournament runs continuously; your bot will be matched automatically as soon as it’s registered.
Tips
AI integration:
There is a API key for evroc think models on your VM at /etc/codenames/think_key. The API key is valid for all evroc LLM models available at https://models.think.evroc.com/v1. You can fetch the list of models by running:
curl -s https://models.think.evroc.com/v1/models \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $EVROC_THINK_API_KEY" You can fetch the API key by running
make fetchThinkKey TEAM=<team> Strategy ideas:
- Use word embeddings or an LLM to find semantic relationships between words
- As Spymaster, prioritize clues that avoid the Assassin even at the cost of fewer linked cards
- As Guesser, prefer ending your turn early over risking the Assassin
Reliability matters:
- Bots that time out or crash accumulate strikes (max 3 per game → disqualification)
- Keep your response time well under 30 seconds
- Make sure clue words and guesses are actual words from (or related to) the board
- Check logs if something seems wrong:
make fetchBotLogs TEAM=<your-team-name> PORT=8001
Run multiple bots:
- Deploy variants on ports 8001, 8002, 8003 to experiment with different implementations in parallel
Resources
- API Reference: full proto definitions for all request/response types
- API Examples: example sequence diagrams for the bot protocols