Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d389b6e
werewolf game in progress
Keyu-He Sep 21, 2025
8b8850d
werewolf game in progress
Keyu-He Sep 21, 2025
2cc3990
updated prompt
Keyu-He Oct 31, 2025
22ae860
Fix custom/local model support bugs
Keyu-He Nov 13, 2025
3a9f689
current progress
Keyu-He Nov 13, 2025
df62578
fix mypy errors
Keyu-He Nov 13, 2025
f482b60
To run the local models
Keyu-He Nov 13, 2025
b453633
Design Social Game class, werewolf demo working in progress
Keyu-He Nov 14, 2025
7de839b
Merge branch 'main' into feature/social-game-support
Keyu-He Nov 20, 2025
ff49e41
update on the SocialGame class / SocialDeductionGame class
Keyu-He Nov 26, 2025
71711b6
fix mypy errors
Keyu-He Nov 26, 2025
39bb4e3
debugging on the prompts
Keyu-He Nov 30, 2025
eff40bf
refactor SocialDeductionGame for real-time history and fix some visib…
Keyu-He Dec 3, 2025
ca835c3
werewolf game debug
Keyu-He Dec 4, 2025
c0f7866
Refactor social_game.py and update werewolves example
Keyu-He Dec 7, 2025
089b30c
Add Social Game Engine documentation
Keyu-He Dec 7, 2025
4ce9d6c
Delete examples/experimental/negotiation_arena/NegotiationArena_1_Buy…
Keyu-He Dec 7, 2025
39f46cd
Restore sotopia/cli/install/redis-data/dump.rdb to match origin/main
Keyu-He Dec 7, 2025
aacd07a
Revert unnessarily changes in the uniform_sample and server.py
Keyu-He Dec 7, 2025
f676238
Minor update on werewolf prompt, Compatibility on uniform sampler and…
Keyu-He Dec 7, 2025
67dc7db
update uniform_sampler and server.py to the correct versions
Keyu-He Dec 7, 2025
d48f71d
move visibility prompt inside werewolf game's config
Keyu-He Dec 7, 2025
a74bdbe
Fix premature termination and LiteLLM schema validation errors
Keyu-He Dec 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,5 @@ redis-data/*
sotopia/cli/install/redis-data/*
redis-stack-server-*/
examples/experimental/negotiation_arena/redis-data/*
*.rdb
*.dot
3 changes: 3 additions & 0 deletions docs/pages/experimental/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
},
"agents": {
"title": "Agents"
},
"social_game": {
"title": "Social Game Engine"
}
}
1 change: 1 addition & 0 deletions docs/pages/experimental/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ The experimental APIs are in different states:

Here are the experimental APIs:
- [Agents](/experimental/agents) (*implemented*): aact-based asynchronous agents that don't follow OpenAI Gym's turn-based formulation.
- [Social Game Engine](/experimental/social_game) (*implemented*): Engine for complex multi-agent social deduction games (e.g., Werewolves).
- Engines (*planned*): aact-based asynchronous environment engines. This would include
- [Orchestrator](https://github.com/sotopia-lab/sotopia/issues/231): an engine base class for engines that dictates the orders and turns of the agents.
- [Evaluator](https://github.com/sotopia-lab/sotopia/issues/232): an engine base class for engines that evaluates the agents' performance.
Expand Down
42 changes: 42 additions & 0 deletions docs/pages/experimental/social_game.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Social Game Engine

The Social Game Engine is a new experimental module in Sotopia designed for creating complex, multi-agent social simulations with structured phases, roles, and secret information.

## Overview

Unlike standard dyadic interactions, social games often involve:
- **Multiple Agents**: More than 2 agents interacting simultaneously.
- **Roles & Teams**: Agents have distinct roles (e.g., Villager, Werewolf) and conflicting goals.
- **Dynamic Eras/Phases**: Games progress through distinct states (e.g., Day Discussion, Night Action).
- **Private Information**: Agents have secrets and limited visibility of others' actions.

## Key Classes

### `SocialGame`
The abstract base class for any multiplayer social game. It handles:
- **Turn Management**: Supports `round-robin` (sequential) or `simultaneous` (parallel) actions.
- **State Transitions**: Manages the flow of the game through defined states.

### `SocialDeductionGame`
A subclass specialized for games like Werewolves, Undercover, or Spyfall.
- **Action Masking**: Enforces who can act in which phase.
- **Visibility System**: Controls who sees what messages (Public, Team-only, Private).
- **Environment Notifications**: Automatically broadcasts state changes to all agents, ensuring valid context even during private phases.

## Example: Duskmire Werewolves

We have implemented a full working example of a 6-player Werewolves game using this engine.

<Callout type="info">
You can find the code and run the example at `examples/experimental/werewolves`.
See the [README](https://github.com/sotopia-lab/sotopia/tree/main/examples/experimental/werewolves/README.md) in that directory for details.
</Callout>

### Key Features Demonstrated
- **Sequential Discussion**: Agents speak one-by-one during the day, referencing previous speakers.
- **Hidden Roles**: Role information is concealed upon elimination.
- **Complex Logic**: Seer inspections, Witch potions, and Werewolf voting integration.

## Usage

To use the Social Game engine, you typically subclass `SocialDeductionGame`, define your states in `config.json`, and implement custom `EnvironmentProfile`s.
69 changes: 69 additions & 0 deletions examples/experimental/spyfall/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"scenario": "Spyfall",
"description": "A social deduction game where players are at a specific location, but one player is a Spy who doesn't know where they are. GAME STRUCTURE: One Spy, multiple Non-Spies. WIN CONDITIONS: Non-Spies win by identifying the Spy. The Spy wins by guessing the location or avoiding detection. PHASES: (1) Questioning: Players ask each other questions to prove they know the location without giving it away to the Spy. (2) Voting: Players vote to eliminate the suspected Spy. STRATEGY: Non-Spies must be subtle; Spies must listen and blend in.",
"role_goals": {
"Non-Spy": "Identify the Spy without revealing the location too clearly.",
"Spy": "Figure out the location and blend in as a Non-Spy."
},
"role_secrets": {
"Non-Spy": "The location is: Space Station.",
"Spy": "You are the Spy. You do NOT know the location."
},
"agents": [
{
"name": "Alice",
"role": "Non-Spy",
"team": "Non-Spies"
},
{
"name": "Bob",
"role": "Spy",
"team": "Spy"
},
{
"name": "Charlie",
"role": "Non-Spy",
"team": "Non-Spies"
},
{
"name": "David",
"role": "Non-Spy",
"team": "Non-Spies"
}
],
"initial_state": "Round_questioning",
"state_transition": {
"Round_questioning": "Round_vote",
"Round_vote": "Round_questioning"
},
"state_properties": {
"Round_questioning": {
"actions": [
"speak"
],
"visibility": "public"
},
"Round_vote": {
"actions": [
"action"
],
"action_order": "simultaneous",
"visibility": "public"
}
},
"end_conditions": [
{
"type": "team_eliminated",
"team": "Spy",
"winner": "Non-Spies",
"message": "[Game] The Spy has been caught! Non-Spies win."
},
{
"type": "parity",
"team": "Spy",
"other": "Non-Spies",
"winner": "Spy",
"message": "[Game] The Spy has evaded capture! Spy wins."
}
]
}
69 changes: 69 additions & 0 deletions examples/experimental/undercover/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"scenario": "Undercover",
"description": "A social deduction game where players describe a secret word. Most players (Civilians) have the same word, but one player (Undercover) has a different but related word. GAME STRUCTURE: One Undercover, multiple Civilians. WIN CONDITIONS: Civilians win by eliminating the Undercover. The Undercover wins if they survive until only two players remain. PHASES: (1) Description: Players take turns describing their word using one sentence, without revealing the word itself. (2) Voting: Players vote to eliminate the suspected Undercover. STRATEGY: Civilians must be vague enough to not help the Undercover but specific enough to prove their identity. The Undercover must infer the Civilians' word and blend in.",
"role_goals": {
"Civilian": "Describe your word subtly and identify the player with the different word.",
"Undercover": "Infer the Civilians' word and blend in without being caught."
},
"role_secrets": {
"Civilian": "Your secret word is: Cat.",
"Undercover": "Your secret word is: Dog."
},
"agents": [
{
"name": "Alice",
"role": "Civilian",
"team": "Civilians"
},
{
"name": "Bob",
"role": "Undercover",
"team": "Undercover"
},
{
"name": "Charlie",
"role": "Civilian",
"team": "Civilians"
},
{
"name": "David",
"role": "Civilian",
"team": "Civilians"
}
],
"initial_state": "Round_description",
"state_transition": {
"Round_description": "Round_vote",
"Round_vote": "Round_description"
},
"state_properties": {
"Round_description": {
"actions": [
"speak"
],
"visibility": "public"
},
"Round_vote": {
"actions": [
"action"
],
"action_order": "simultaneous",
"visibility": "public"
}
},
"end_conditions": [
{
"type": "team_eliminated",
"team": "Undercover",
"winner": "Civilians",
"message": "[Game] The Undercover has been eliminated! Civilians win."
},
{
"type": "parity",
"team": "Undercover",
"other": "Civilians",
"winner": "Undercover",
"message": "[Game] The Undercover has survived! Undercover wins."
}
]
}
43 changes: 43 additions & 0 deletions examples/experimental/werewolves/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Duskmire Werewolves

A text-based social deduction game built on top of `sotopia`. This experimental example demonstrates how to implement complex game phases (Day/Night), roles, and turn-based interactions using the Sotopia framework.

## Overview

In this 6-player game, players are assigned roles (Villager, Werewolf, Seer, Witch) and compete to eliminate the opposing team.

- **Villagers**: Must identify and vote out Werewolves.
- **Werewolves**: Must deceive Villagers and eliminate them at night.
- **Seer**: Can inspect one player's role each night.
- **Witch**: Has one potion to save a victim and one to poison a suspect.

## Features

- **Sequential Discussion**: Utilizes `round-robin` action order during the day, ensuring agents speak one after another and can reference previous arguments.
- **Simultaneous Action**: Night phases and voting are simultaneous to preserve secrecy/fairness.
- **Global Event Notifications**: Players receive system messages about state transitions (e.g., "Entering Night Phase") regardless of their role visibility settings.
- **Safe Elimination**: Role information is hidden from players upon elimination to simulate realistic uncertainty (roles are only revealed in admin logs).

## Running the Game

1. Ensure you have the `sotopia` environment set up.
2. Run the main script:
```bash
python examples/experimental/werewolves/main.py
```
*Note: Ensure your Redis server is running.*

## Configuration

The game is configured via `config.json`. Key settings include:

- **`state_properties`**: Defines the phases (Day/Night).
- `action_order`: Set to `"round-robin"` for sequential phases (e.g., `Day_discussion`), or `"simultaneous"` for others (e.g., `Day_vote`).
- `visibility`: Controls who sees messages (`"public"`, `"team"`, `"private"`).
- **`agents`**: Defines the roster and roles.

## Extending

To modify the game logic, check:
- `main.py`: Handles game initialization and elimination logic (`_check_eliminations`).
- `config.json` and `sotopia/envs/social_game.py`: Adjusts game balance, roles, and state transitions.
115 changes: 115 additions & 0 deletions examples/experimental/werewolves/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
{
"scenario": "Werewolves Game",
"description": "This game is called Werewolves (also known as Mafia), which is a social deduction game. GAME STRUCTURE: This game contains six players: two villagers, two werewolves, one seer, and one witch. Each cycle consists of Night phases followed by Day phases. WIN CONDITIONS: Villagers win by eliminating all Werewolves. Werewolves win when they equal or outnumber the Villagers. NIGHT PHASES: (1) Werewolves wake and privately choose one Villager to kill using 'kill NAME'. (2) The Seer wakes and inspects one player using 'inspect NAME' to learn if they are a Werewolf or Villager. (3) The Witch wakes and may use their one-time save potion with 'save NAME' (if someone died tonight) or their one-time poison potion with 'poison NAME' to kill someone. DAY PHASES: (1) Dawn: All players learn who died during the night (if any). (2) Discussion: All living players go *one* round of public discussion to discuss and debate who might be a Werewolf. Use 'speak' to share your thoughts and suspicions. (3) Voting: Each player votes to eliminate one suspected Werewolf using 'vote NAME'. The player with the most votes is executed. (4) Twilight: The execution result is announced and night returns. COMMUNICATION RULES: All day discussions are public. Dead players cannot speak or act. If 'action' is available, use commands like 'kill NAME', 'inspect NAME', 'save NAME', 'poison NAME', or 'vote NAME'. Note: Player actions in the nights are not seen by players of other roles (e.g. only wolves can see other wolves' actions). Day discussion is public. Voting requires an 'action' beginning with 'vote'.\n\n The players in this game are: {agent_names}, and during the day, they speak in the same order as they are listed.",
"role_goals": {
"Villager": "Act openly and collaboratively to identify werewolves.",
"Werewolf": "Deceive others, avoid detection, and eliminate villagers.",
"Seer": "Discreetly inspect players at night to uncover werewolves.",
"Witch": "Use save/poison potions strategically to aid villagers."
},
"role_secrets": {
"Werewolf": "I am a werewolf."
},
"agents": [
{
"name": "Aurora",
"role": "Villager",
"team": "Villagers"
},
{
"name": "Bram",
"role": "Werewolf",
"team": "Werewolves"
},
{
"name": "Celeste",
"role": "Seer",
"team": "Villagers"
},
{
"name": "Dorian",
"role": "Werewolf",
"team": "Werewolves"
},
{
"name": "Elise",
"role": "Witch",
"team": "Villagers"
},
{
"name": "Finn",
"role": "Villager",
"team": "Villagers"
}
],
"initial_state": "Night_werewolf",
"state_transition": {
"Night_werewolf": "Night_seer",
"Night_seer": "Night_witch",
"Night_witch": "Day_discussion",
"Day_discussion": "Day_vote",
"Day_vote": "Night_werewolf"
},
"state_properties": {
"Night_werewolf": {
"acting_roles": [
"Werewolf"
],
"actions": [
"action"
],
"visibility": "team"
},
"Night_seer": {
"acting_roles": [
"Seer"
],
"actions": [
"action"
],
"visibility": "private"
},
"Night_witch": {
"acting_roles": [
"Witch"
],
"actions": [
"action"
],
"visibility": "private",
"internal_state": {
"save_available": true,
"poison_available": true
}
},
"Day_discussion": {
"actions": [
"speak"
],
"action_order": "round-robin",
"visibility": "public"
},
"Day_vote": {
"actions": [
"action"
],
"action_order": "simultaneous",
"visibility": "public"
}
},
"end_conditions": [
{
"type": "team_eliminated",
"team": "Werewolves",
"winner": "Villagers",
"message": "Villagers win; no werewolves remain."
},
{
"type": "parity",
"team": "Werewolves",
"other": "Villagers",
"winner": "Werewolves",
"message": "Werewolves win; they now match the village."
}
]
}
Loading