Werewolf
Seven players in a village: two werewolves, a seer, a doctor and three villagers. At night the werewolves pick a victim, the doctor protects someone and the seer learns one player's role; by day everyone talks and votes someone out. The villagers win when the werewolves are gone, the werewolves when they match the villagers. This is the seven-player default variant in kaggle-environments 1.33.0, using its own engine and agent interface. It is not the current eight-player Game Arena preset.
This table’s rules
The pinned engine is authoritative: 2 werewolves, 1 seer, 1 doctor and 3 villagers. The doctor cannot protect themselves, but can protect the same person on consecutive nights. The seer learns an exact role. Werewolves vote in sequence, see earlier wolf votes and can only target non-wolves; they do not need unanimous agreement. The highest vote wins and ties are random.
Each living player speaks once per day and then votes in sequence. Self-votes and abstentions are legal. Ties are random; if everyone abstains, the engine still eliminates a random eligible player, both by day and at night. Eliminations reveal roles. There is no witch, hunter, sheriff election, last-words phase or private wolf chat in this preset. Doctor and seer actions are private; successful protection identifies a non-wolf only to the doctor.
The Game Arena announcement describes an eight-player preset with different night consensus and consecutive-protection rules. Those must not be silently substituted into this seven-player game.
Your bot
Exactly a kaggle-environments Werewolf agent: main.py with def agent(obs, config). obs.raw_observation holds your role and team, the day and detailed_phase, the players alive, the announcements you are allowed to see and your requests (vote, chat, heal, inspect), each with its valid targets. Return one of the game's actions as a dict, {"action_type": "VoteAction", "kwargs": {...}}, as the built-in agents do. Your bot may be a program or call no model at all; here it runs with no network. Each move has 3 seconds; your bot is a process of its own for the whole check, so reset what you keep when a new game starts.
Scoring
Version 2 plays three rounds of seven games against each field opponent. The candidate takes every seat and covers the role mix (two wolf games, one seer, one doctor, three villager games per round); all other roles are privately shuffled anew for each game. Public gameplay seeds do not determine the hidden deal. Only public timing and rule configuration reaches a bot, never the full player-role map or the deal seed. Keep memory only from your own observations and reset on a new game_start.
Your score is the share of games your side wins, with separate role scores. Finite samples vary between checks; these results are not Game Arena ratings. Version 1 used fixed role positions and sent the complete role configuration to seat processes. Its numbers, including the old starter baseline, are not comparable and are retained only as historical results.
The field, season 2
| Bot | What it does |
|---|---|
evidence |
Recommended fixed computer: tracks its own evidence, cross-checks public seer claims against revealed roles, reasons over possible wolf teams, remembers inspections, coordinates wolf votes, protects credible information sources and accounts for sequential ballot ties; no model or network |
deterministic |
kaggle-environments' built-in deterministic agent: always one fixed thing (the starter is the same) |
random |
kaggle-environments' built-in random agent |
Play live
A room is one game played live, with people, agents and bots at the seven seats: seat 0 to 6 is Player 1 to 7 (1号 to 7号 on the table), and the engine deals the roles at random (or from the room's seed). A bot seat runs a route's or a field bot's main.py in a process of its own, as the checks do. A seat on auto, a player out of time and a bot that fails are played by the evidence rule computer, with a separate memory for each seat. Everyone sees the public game: phases, the judge's announcements, speeches, day votes, the tally, who is out and their revealed role. Each seat is also told what only it may know: its role card (and, for a werewolf, the other wolf), the wolves' night picks, the seer's results and the doctor's own heals. When the game ends every role is shown, the winning side's seats score 1, and the game is kept as a match.
When it is your seat's turn you get your role and team, your wolf teammates, the day and phase, who is alive, what you have been told, the public events so far, your time limit, and Kaggle's own raw observation, so a Kaggle agent can play from it as it is. Answer with one of the legal actions:
| Asked | Legal actions | You answer |
|---|---|---|
speak (chat) |
{"type": "chat", "message": ""} |
the same with your speech in message (at most 600 characters; left empty, you pass) |
day vote (vote) |
{"type": "vote", "target": "3"} for each living seat (self included), and {"type": "vote", "target": null} to abstain |
one of them |
werewolf's night pick (kill) |
{"type": "kill", "target": "4"} for each living non-wolf, and {"type": "kill", "target": null} to abstain |
one of them |
doctor (heal) |
{"type": "heal", "target": "2"} for each other living seat |
one of them |
seer (inspect) |
{"type": "inspect", "target": "5"} for each other living seat |
one of them |
Any answer may carry "reasoning", which the replay shows in the god view. An agent can also answer with the Kaggle action its agent(obs, config) returns. A speech gets three times the room's time limit (90 seconds by default). An explicitly seeded local room is a reproducible practice game, not a secret-deal competitive room; normal platform rooms choose an undisclosed random seed.
Try one on your machine, playing seat 0 from the terminal against the starter and the field:
SS_INPUT=$PWD python3 kit/roomcli.py --room '{"seats": {"0": {"kind": "human", "name": "me"}, "1": {"kind": "bot", "dir": "routes"}, "2": {"kind": "bot", "field": "random"}}}' -- bash referee/room.sbatch
Seats the room does not name are played by the stand-in. --seat 0 --pick random answers for you; a speech then passes.
The platform offers four entry modes: online multiplayer (wait in the lobby, then explicitly start), play your own connected agent, play a platform route bot, and play the fixed-rule computer. In a seven-seat game the other seats still need participants or explicitly selected computer fill. evidence is the default computer; deterministic and random remain available as simpler opponents.
The rule computer understands a bounded set of explicit Chinese/English role and inspection statements, not arbitrary language. It treats them as claims, not system facts. It can bluff as a wolf, and it does not read another seat’s private observations. It is a useful offline opponent, not a claim of expert human-level play.
Verify locally
Run .venvs/werewolf/bin/python games/werewolf/referee/test_rules.py from the repository root. This runs the real pinned engine, an actual bot child, and an entire live room through its request/answer protocol in temporary directories. The audit and the limited strength comparison are documented in docs/research/2026-10-23-werewolf-audit.md.
The table
viewer/ is the 狼人杀 table people know from NetEase's app: numbered coin seats down both sides, a moon or sun medallion with 第N夜 / 第N天, one status line ("【4号】发言中…… 47秒"), the judge's cards, the exile vote board with the tally written the Chinese way ("①②④⑦ → ⑤"), a full-screen role card at the start and "X阵营 胜利" at the end. For watching agents it adds a god view (each seat's role tag, the night's moves and each agent's reasoning in grey italics), a log, and a timeline split by nights and days with speed control. Replays play night by night. In a room (viewer/index.html?live) a seated person gets their role card, types a speech, or taps a seat and confirms to vote, heal, inspect or pick a victim. A spectator sees only what is public until the game ends. To watch a replay from a clone, run python3 -m http.server and open viewer/index.html?replay=../replays/<file>.
Credits
The engine, the rules and the built-in agents are from kaggle-environments 1.33.0, © Kaggle, under the Apache-2.0 licence. The referee, the room and the table are this project's, under MIT. The table's role art and small icons are Microsoft's Fluent Emoji (MIT), its seat portraits DiceBear's Notionists by Zoish (CC0), its markers icons by Lorc and Delapouite from game-icons.net (CC BY 3.0), and its judge's lettering a subset of Noto Serif SC (SIL OFL 1.1); viewer/NOTICE has each licence.
