werewolf
A game engine for playing werewolf within an arbitrary chat client.
Werewolf is a well known social party game, commonly also called Mafia.
See the Wikipedia article for a rundown on its
gameplay and history.
If you're here just to play werewolf, you may wish to skip straight to
chat interfaces.
Game description
Long has the woods been home to wild creatures, both kind and cruel.
Most have faces and are known to the inhabitants of Fougères in Brittany, France; but no-one from
the village has yet to lay eyes on the merciless Werewolf.
Each night Werewolves attack the village and devour the innocent.
For centuries no-one knew how to fight this scourge, however recently a theory has taken ahold that
mayhaps the Werewolves walk among the Villagers themselves...
Objective of the game:
For the Loners: complete their own objective.
For the Villagers: lynch all of the Werewolves.
For the Werewolves: devour all of the Villagers.
Roles
The implemented roles are split into four categories.
The Ambiguous:
No-one knows the true nature of the Ambiguous, sometimes not even the Ambiguous themselves!
The Ambiguous are able to change allegiance throughout the game.
The Loners:
The Loners look out for themselves and themselves alone.
The Loners must complete their own objective.
- Dullahan
- Fallen Angel
- Necromancer (and Zombie)
The Villagers:
Fraught with fear of the unseen enemy, the Villagers must work together to determine the truth and
eliminate the threat to Fougères.
The task before them will not be easy, but a certain few have learnt some tricks over the years that
may turn out rather useful.
The Villagers must lynch all of the Werewolves.
- Beholder
- Crooked Senator
- Druid
- Hunter
- Jester
- Lycan
- Medusa
- Oracle
- Protector
- Saint
- Scapegoat
- Seer
- Simple Villager
- Spiteful Villager
- True Villager
- Witch
The Werewolves:
Hiding in plain sight, the Werewolves are not a small trifle.
The Werewolves must devour all of the Villagers.
- Alpha Wolf
- Simple Werewolf
Variants
Variants alter how the game plays out.
- Standard
- No role knowledge (players are not informed of the roles in play at the start of a game)
- No role knowledge or reveal (players are not informed of the roles in play at the start of a game,
nor each others roles upon death)
- No role reveal (players are not informed of each others roles upon death)
- Spiteful village (the default Villager role becomes the Spiteful Villager)
Installing
Installing werewolf is easiest done using either
stack (recommended) or
Cabal.
Using stack:
stack install werewolf
export PATH=$PATH:~/.local/bin
Using Cabal:
cabal-install werewolf
export PATH=$PATH:~/.cabal/bin
Usage
This section covers how a chat interface interacts with the werewolf game engine.
All werewolf commands are designed to be run by a user from the chat client.
E.g., to start a game:
> werewolf --caller @foo --tag werewolf start --extra-roles seer @bar @baz @qux @quux @corge @grault
{"ok":true,"messages":[
{"to":null,"message":"A new game of werewolf is starting with @foo, @bar, @baz, @qux, @quux, @corge and @grault!"},
{"to":null,"message":"The roles in play are Seer (1), Simple Villager (4) and Simple Werewolf (2) for a total balance of -2."},
{"to":"@foo","message":"You're a Simple Villager.\nA simple, ordinary townsperson in every way. Some may be cobblers, others bakers or even nobles. No matter their differences though, the plight of Werewolves in Fougères unites all the Villagers in this unfortunate time.\nThe Simple Villager has no special abilities, they must use their guile to determine whom among them is not who they say they are."},
...,
{"to":null,"message":"Night falls, the village is asleep."},
{"to":null,"message":"The Seer wakes up."},
{"to":"@corge","message":"Whose allegiance would you like to `see`?"}
]}
In this example, user @foo ran the start
command with the player names as arguments.
Note that the calling user, @foo, was passed in to the --caller
option and a game tag,
werewolf, was passed in to the --tag
option.
All commands require these options (n.b., the tag option is arbitrary, it just enables multiple
games of werewolf to be running at once).
Any command ran returns a JSON result.
The result contains a boolean for whether the command was successful and a list of messages.
The to
header on a message may either be null
---for a public message---or have an intended
recipient.
It's the Seer's turn now.
> werewolf --caller @corge --tag werewolf see @grault
{"ok":true,"messages":[
{"to":"@corge","message":"@grault is aligned with the Werewolves."},
{"to":"@quux","message":"You feel restless, like an old curse is keeping you from sleep. It seems you're not the only one... @grault is also emerging from their home."},
{"to":"@grault","message":"You feel restless, like an old curse is keeping you from sleep. It seems you're not the only one... @quux is also emerging from their home."},
{"to":null,"message":"The Werewolves wake up, transform and choose a new victim."},
{"to":"@quux","message":"Whom would you like to `vote` to devour?"},
{"to":"@grault","message":"Whom would you like to `vote` to devour?"}
]}
Let's have the Werewolves, @quux and @grault, vote to devour a Villager.
> werewolf --caller @quux --tag werewolf vote @foo
{"ok":true,"messages":[
{"to":"@grault","message":"@quux voted to devour @foo."}
]}
> werewolf --caller @grault --tag werewolf vote @foo
{"ok":true,"messages":[
{"to":"@quux","message":"@grault voted to devour @foo."},
{"to":null,"message":"The sun rises. Everybody wakes up and opens their eyes..."},
{"to":null,"message":"As you open them you notice a door broken down and @foo's guts half devoured and spilling out over the cobblestones. From the look of their personal effects, you deduce they were a Simple Villager."},
{"to":null,"message":"As the village gathers in the square the Town Clerk calls for a vote."},
{"to":null,"message":"Whom would you like to `vote` to lynch?"}
]}
Too bad for @foo. Maybe the village can get some vengeance...
> werewolf --caller @corge --tag werewolf vote @grault
{"ok":true,"messages":[]}
This time, even though the command was successful, there are no messages.
> werewolf --caller @corge --tag werewolf vote @grault
{"ok":false,"messages":[{"to":"@corge","message":"You've already voted!"}]}
Here the command was unsuccessful and an error message is sent to @corge.
Even though the command was unsuccessful, the chat interface probably won't need to do anything
special.
Relaying the error message back to the user should suffice.
Thus a chat interface must implement the following:
- The ability to call werewolf commands. This includes passing the
--caller
and --tag
options
and arguments correctly. It is possible to only implement the interpret
command, which
interprets the caller's input.
- The ability to send resultant messages. Resultant messages may be to everyone or to a specific
user.
Commands
See werewolf --help
.
Chat interfaces
Click through for instructions on how to run a chat interface and play werewolf.