diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,12 @@
 
 ### Upcoming
 
+### v0.5.0.0
+
+*Major*
+
+* Added required `--tag` option for enabling multiple games at once. ([#29](https://github.com/hjwylde/werewolf/issues/29))
+
 ### v0.4.12.0
 
 *Minor*
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -110,7 +110,7 @@
 E.g., to start a game:
 
 ```bash
-> werewolf --caller @foo start --extra-roles seer @bar @baz @qux @quux @corge @grault
+> 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, @grault!"},
     {"to":null,"message":"The roles in play are Seer (1), Simple Villager (4), Simple Werewolf (2) for a total balance of -2."},
@@ -123,8 +123,10 @@
 ```
 
 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.
-All commands require this option.
+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.
@@ -134,7 +136,7 @@
 It's the Seer's turn now.
 
 ```bash
-> werewolf --caller @corge see @grault
+> 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 are also emerging from their homes."},
@@ -148,11 +150,11 @@
 Let's have the Werewolves, _@quux_ and _@grault_, vote to devour a Villager.
 
 ```bash
-> werewolf --caller @quux vote @foo
+> werewolf --caller @quux --tag werewolf vote @foo
 {"ok":true,"messages":[
     {"to":"@grault","message":"@quux voted to devour @foo."}
     ]}
-> werewolf --caller @grault vote @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..."},
@@ -165,14 +167,14 @@
 Too bad for _@foo_. Maybe the village can get some vengeance...
 
 ```bash
-> werewolf --caller @corge vote @grault
+> werewolf --caller @corge --tag werewolf vote @grault
 {"ok":true,"messages":[]}
 ```
 
 This time, even though the command was successful, there are no messages.
 
 ```bash
-> werewolf --caller @corge vote @grault
+> werewolf --caller @corge --tag werewolf vote @grault
 {"ok":false,"messages":[{"to":"@corge","message":"You've already voted!"}]}
 ```
 
@@ -182,9 +184,9 @@
 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` option and arguments
-  correctly. It is possible to only implement the `interpret` command, which interprets the
-  caller's input.
+* 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.
 
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -46,31 +46,31 @@
 run :: [String] -> IO ()
 run args = handleParseResult (execParserPure werewolfPrefs werewolfInfo args) >>= handle
 
-interpret :: Text -> [Text] -> IO ()
-interpret callerName args = do
-    let result = execParserPure werewolfPrefs werewolfInfo (map T.unpack $ "--caller":callerName:args)
+interpret :: Text -> Text -> [Text] -> IO ()
+interpret callerName tag args = do
+    let result = execParserPure werewolfPrefs werewolfInfo (map T.unpack $ "--caller":callerName:"--tag":tag:args)
 
     case result of
         Success options -> handle options
-        _               -> handle (Options callerName . Help . Help.Options . Just $ Help.Commands False)
+        _               -> handle (Options callerName tag . Help . Help.Options . Just $ Help.Commands False)
 
 handle :: Options -> IO ()
-handle (Options callerName command) = case command of
-    Choose options                      -> Choose.handle callerName options
-    Boot options                        -> Boot.handle callerName options
-    Circle options                      -> Circle.handle callerName options
-    End options                         -> End.handle callerName options
-    Heal                                -> Heal.handle callerName
-    Help options                        -> Help.handle callerName options
-    Interpret (Interpret.Options args)  -> interpret callerName args
-    Pass                                -> Pass.handle callerName
-    Ping                                -> Ping.handle callerName
-    Poison options                      -> Poison.handle callerName options
-    Protect options                     -> Protect.handle callerName options
-    Quit                                -> Quit.handle callerName
-    Reveal                              -> Reveal.handle callerName
-    See options                         -> See.handle callerName options
-    Start options                       -> Start.handle callerName options
-    Status                              -> Status.handle callerName
+handle (Options callerName tag command) = case command of
+    Choose options                      -> Choose.handle callerName tag options
+    Boot options                        -> Boot.handle callerName tag options
+    Circle options                      -> Circle.handle callerName tag options
+    End options                         -> End.handle callerName tag options
+    Heal                                -> Heal.handle callerName tag
+    Help options                        -> Help.handle callerName tag options
+    Interpret (Interpret.Options args)  -> interpret callerName tag args
+    Pass                                -> Pass.handle callerName tag
+    Ping                                -> Ping.handle callerName tag
+    Poison options                      -> Poison.handle callerName tag options
+    Protect options                     -> Protect.handle callerName tag options
+    Quit                                -> Quit.handle callerName tag
+    Reveal                              -> Reveal.handle callerName tag
+    See options                         -> See.handle callerName tag options
+    Start options                       -> Start.handle callerName tag options
+    Status                              -> Status.handle callerName tag
     Version                             -> Version.handle callerName
-    Vote options                        -> Vote.handle callerName options
+    Vote options                        -> Vote.handle callerName tag options
diff --git a/app/Werewolf/Command/Boot.hs b/app/Werewolf/Command/Boot.hs
--- a/app/Werewolf/Command/Boot.hs
+++ b/app/Werewolf/Command/Boot.hs
@@ -34,16 +34,16 @@
     { argTarget :: Text
     } deriving (Eq, Show)
 
-handle :: MonadIO m => Text -> Options -> m ()
-handle callerName (Options targetName) = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> Options -> m ()
+handle callerName tag (Options targetName) = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = bootCommand callerName targetName
 
     case runExcept (runWriterT $ execStateT (apply command >> checkStage >> checkGameOver) game) of
         Left errorMessages      -> exitWith failure { messages = errorMessages }
-        Right (game', messages) -> writeGame game' >> exitWith success { messages = messages }
+        Right (game', messages) -> writeGame tag game' >> exitWith success { messages = messages }
diff --git a/app/Werewolf/Command/Choose.hs b/app/Werewolf/Command/Choose.hs
--- a/app/Werewolf/Command/Choose.hs
+++ b/app/Werewolf/Command/Choose.hs
@@ -39,13 +39,13 @@
     { args :: [Text]
     } deriving (Eq, Show)
 
-handle :: MonadIO m => Text -> Options -> m ()
-handle callerName (Options args) = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> Options -> m ()
+handle callerName tag (Options args) = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = case game ^. stage of
             ScapegoatsTurn  -> Scapegoat.chooseCommand callerName args
@@ -56,4 +56,4 @@
 
     case runExcept (runWriterT $ execStateT (apply command >> checkStage >> checkGameOver) game) of
         Left errorMessages      -> exitWith failure { messages = errorMessages }
-        Right (game, messages)  -> writeGame game >> exitWith success { messages = messages }
+        Right (game, messages)  -> writeGame tag game >> exitWith success { messages = messages }
diff --git a/app/Werewolf/Command/Circle.hs b/app/Werewolf/Command/Circle.hs
--- a/app/Werewolf/Command/Circle.hs
+++ b/app/Werewolf/Command/Circle.hs
@@ -34,13 +34,13 @@
     { optIncludeDead :: Bool
     } deriving (Eq, Show)
 
-handle :: MonadIO m => Text -> Options -> m ()
-handle callerName (Options includeDead) = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> Options -> m ()
+handle callerName tag (Options includeDead) = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = circleCommand callerName includeDead
 
diff --git a/app/Werewolf/Command/End.hs b/app/Werewolf/Command/End.hs
--- a/app/Werewolf/Command/End.hs
+++ b/app/Werewolf/Command/End.hs
@@ -34,17 +34,17 @@
     { optForce :: Bool
     } deriving (Eq, Show)
 
-handle :: MonadIO m => Text -> Options -> m ()
-handle callerName (Options force) = do
-    unlessM doesGameExist $ exitWith failure { messages = [noGameRunningMessage callerName] }
+handle :: MonadIO m => Text -> Text -> Options -> m ()
+handle callerName tag (Options force) = do
+    unlessM (doesGameExist tag) $ exitWith failure { messages = [noGameRunningMessage callerName] }
 
     unless force $ do
-        game <- readGame
+        game <- readGame tag
 
         unless (doesPlayerExist callerName game) $
             exitWith failure { messages = [playerCannotDoThatMessage callerName] }
 
-    deleteGame
+    deleteGame tag
 
     exitWith success { messages = [gameEndedMessage] }
     where
diff --git a/app/Werewolf/Command/Heal.hs b/app/Werewolf/Command/Heal.hs
--- a/app/Werewolf/Command/Heal.hs
+++ b/app/Werewolf/Command/Heal.hs
@@ -29,16 +29,16 @@
 import Werewolf.Game
 import Werewolf.Messages
 
-handle :: MonadIO m => Text -> m ()
-handle callerName = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> m ()
+handle callerName tag = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = healCommand callerName
 
     case runExcept (runWriterT $ execStateT (apply command >> checkStage >> checkGameOver) game) of
         Left errorMessages      -> exitWith failure { messages = errorMessages }
-        Right (game', messages) -> writeGame game' >> exitWith success { messages = messages }
+        Right (game', messages) -> writeGame tag game' >> exitWith success { messages = messages }
diff --git a/app/Werewolf/Command/Help.hs b/app/Werewolf/Command/Help.hs
--- a/app/Werewolf/Command/Help.hs
+++ b/app/Werewolf/Command/Help.hs
@@ -45,28 +45,28 @@
     { optAll :: Bool
     } deriving (Eq, Show)
 
-handle :: MonadIO m => Text -> Options -> m ()
-handle callerName (Options (Just (Commands optAll))) = do
-    mGame <- ifM (doesGameExist &&^ return (not optAll)) (Just <$> readGame) (return Nothing)
+handle :: MonadIO m => Text -> Text -> Options -> m ()
+handle callerName tag (Options (Just (Commands optAll))) = do
+    mGame <- ifM (doesGameExist tag &&^ return (not optAll)) (Just <$> readGame tag) (return Nothing)
 
     exitWith success
         { messages = map (privateMessage callerName) (commandsMessages callerName mGame)
         }
-handle callerName (Options (Just (Roles optAll))) = do
-    roles <- (sortBy (compare `on` view Role.name) . nub) <$> ifM (doesGameExist &&^ return (not optAll))
-        (toListOf (players . roles) <$> readGame)
+handle callerName tag (Options (Just (Roles optAll))) = do
+    roles <- (sortBy (compare `on` view Role.name) . nub) <$> ifM (doesGameExist tag &&^ return (not optAll))
+        (toListOf (players . roles) <$> readGame tag)
         (return allRoles)
 
     exitWith success
         { messages = map (privateMessage callerName . roleMessage) roles
         }
-handle callerName (Options (Just (Rules optAll))) = do
-    mGame <- ifM (doesGameExist &&^ return (not optAll)) (Just <$> readGame) (return Nothing)
+handle callerName tag (Options (Just (Rules optAll))) = do
+    mGame <- ifM (doesGameExist tag &&^ return (not optAll)) (Just <$> readGame tag) (return Nothing)
 
     exitWith success
         { messages = map (privateMessage callerName) (rulesMessages mGame)
         }
-handle callerName (Options Nothing) = exitWith success
+handle callerName _ (Options Nothing) = exitWith success
     { messages = map (privateMessage callerName) helpMessages
     }
 
diff --git a/app/Werewolf/Command/Pass.hs b/app/Werewolf/Command/Pass.hs
--- a/app/Werewolf/Command/Pass.hs
+++ b/app/Werewolf/Command/Pass.hs
@@ -29,13 +29,13 @@
 import Werewolf.Game
 import Werewolf.Messages
 
-handle :: MonadIO m => Text -> m ()
-handle callerName = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> m ()
+handle callerName tag = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = case game ^. stage of
             DevotedServantsTurn -> DevotedServant.passCommand callerName
@@ -45,4 +45,4 @@
 
     case runExcept (runWriterT $ execStateT (apply command >> checkStage >> checkGameOver) game) of
         Left errorMessages      -> exitWith failure { messages = errorMessages }
-        Right (game', messages) -> writeGame game' >> exitWith success { messages = messages }
+        Right (game', messages) -> writeGame tag game' >> exitWith success { messages = messages }
diff --git a/app/Werewolf/Command/Ping.hs b/app/Werewolf/Command/Ping.hs
--- a/app/Werewolf/Command/Ping.hs
+++ b/app/Werewolf/Command/Ping.hs
@@ -27,13 +27,13 @@
 import Werewolf.Game
 import Werewolf.Messages
 
-handle :: MonadIO m => Text -> m ()
-handle callerName = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> m ()
+handle callerName tag = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = pingCommand callerName
 
diff --git a/app/Werewolf/Command/Poison.hs b/app/Werewolf/Command/Poison.hs
--- a/app/Werewolf/Command/Poison.hs
+++ b/app/Werewolf/Command/Poison.hs
@@ -34,16 +34,16 @@
     { argTarget :: Text
     } deriving (Eq, Show)
 
-handle :: MonadIO m => Text -> Options -> m ()
-handle callerName (Options targetName) = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> Options -> m ()
+handle callerName tag (Options targetName) = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = poisonCommand callerName targetName
 
     case runExcept (runWriterT $ execStateT (apply command >> checkStage >> checkGameOver) game) of
         Left errorMessages      -> exitWith failure { messages = errorMessages }
-        Right (game', messages) -> writeGame game' >> exitWith success { messages = messages }
+        Right (game', messages) -> writeGame tag game' >> exitWith success { messages = messages }
diff --git a/app/Werewolf/Command/Protect.hs b/app/Werewolf/Command/Protect.hs
--- a/app/Werewolf/Command/Protect.hs
+++ b/app/Werewolf/Command/Protect.hs
@@ -34,16 +34,16 @@
     { argTarget :: Text
     } deriving (Eq, Show)
 
-handle :: MonadIO m => Text -> Options -> m ()
-handle callerName (Options targetName) = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> Options -> m ()
+handle callerName tag (Options targetName) = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = protectCommand callerName targetName
 
     case runExcept (runWriterT $ execStateT (apply command >> checkStage >> checkGameOver) game) of
         Left errorMessages      -> exitWith failure { messages = errorMessages }
-        Right (game', messages) -> writeGame game' >> exitWith success { messages = messages }
+        Right (game', messages) -> writeGame tag game' >> exitWith success { messages = messages }
diff --git a/app/Werewolf/Command/Quit.hs b/app/Werewolf/Command/Quit.hs
--- a/app/Werewolf/Command/Quit.hs
+++ b/app/Werewolf/Command/Quit.hs
@@ -27,16 +27,16 @@
 import Werewolf.Game
 import Werewolf.Messages
 
-handle :: MonadIO m => Text -> m ()
-handle callerName = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> m ()
+handle callerName tag = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = quitCommand callerName
 
     case runExcept (runWriterT $ execStateT (apply command >> checkStage >> checkGameOver) game) of
         Left errorMessages      -> exitWith failure { messages = errorMessages }
-        Right (game', messages) -> writeGame game' >> exitWith success { messages = messages }
+        Right (game', messages) -> writeGame tag game' >> exitWith success { messages = messages }
diff --git a/app/Werewolf/Command/Reveal.hs b/app/Werewolf/Command/Reveal.hs
--- a/app/Werewolf/Command/Reveal.hs
+++ b/app/Werewolf/Command/Reveal.hs
@@ -29,16 +29,16 @@
 import Werewolf.Game
 import Werewolf.Messages
 
-handle :: MonadIO m => Text -> m ()
-handle callerName = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> m ()
+handle callerName tag = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = revealCommand callerName
 
     case runExcept (runWriterT $ execStateT (apply command >> checkStage >> checkGameOver) game) of
         Left errorMessages      -> exitWith failure { messages = errorMessages }
-        Right (game', messages) -> writeGame game' >> exitWith success { messages = messages }
+        Right (game', messages) -> writeGame tag game' >> exitWith success { messages = messages }
diff --git a/app/Werewolf/Command/See.hs b/app/Werewolf/Command/See.hs
--- a/app/Werewolf/Command/See.hs
+++ b/app/Werewolf/Command/See.hs
@@ -34,16 +34,16 @@
     { argTarget :: Text
     } deriving (Eq, Show)
 
-handle :: MonadIO m => Text -> Options -> m ()
-handle callerName (Options targetName) = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> Options -> m ()
+handle callerName tag (Options targetName) = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = seeCommand callerName targetName
 
     case runExcept (runWriterT $ execStateT (apply command >> checkStage >> checkGameOver) game) of
         Left errorMessages      -> exitWith failure { messages = errorMessages }
-        Right (game', messages) -> writeGame game' >> exitWith success { messages = messages }
+        Right (game', messages) -> writeGame tag game' >> exitWith success { messages = messages }
diff --git a/app/Werewolf/Command/Start.hs b/app/Werewolf/Command/Start.hs
--- a/app/Werewolf/Command/Start.hs
+++ b/app/Werewolf/Command/Start.hs
@@ -47,9 +47,9 @@
 data ExtraRoles = None | Random | Use [Text]
     deriving (Eq, Show)
 
-handle :: MonadIO m => Text -> Options -> m ()
-handle callerName (Options extraRoles playerNames) = do
-    whenM (doesGameExist &&^ (hasn't (stage . _GameOver) <$> readGame)) $ exitWith failure
+handle :: MonadIO m => Text -> Text -> Options -> m ()
+handle callerName tag (Options extraRoles playerNames) = do
+    whenM (doesGameExist tag &&^ (hasn't (stage . _GameOver) <$> readGame tag)) $ exitWith failure
         { messages = [gameAlreadyRunningMessage callerName]
         }
 
@@ -65,7 +65,7 @@
 
     case result of
         Left errorMessages      -> exitWith failure { messages = errorMessages }
-        Right (game, messages)  -> writeGame game >> exitWith success { messages = messages }
+        Right (game, messages)  -> writeGame tag game >> exitWith success { messages = messages }
 
 randomExtraRoles :: MonadIO m => Int -> m [Role]
 randomExtraRoles n = liftIO . evalRandIO $ do
diff --git a/app/Werewolf/Command/Status.hs b/app/Werewolf/Command/Status.hs
--- a/app/Werewolf/Command/Status.hs
+++ b/app/Werewolf/Command/Status.hs
@@ -27,13 +27,13 @@
 import Werewolf.Game
 import Werewolf.Messages
 
-handle :: MonadIO m => Text -> m ()
-handle callerName = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> m ()
+handle callerName tag = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = statusCommand callerName
 
diff --git a/app/Werewolf/Command/Vote.hs b/app/Werewolf/Command/Vote.hs
--- a/app/Werewolf/Command/Vote.hs
+++ b/app/Werewolf/Command/Vote.hs
@@ -36,13 +36,13 @@
     { argTarget :: Text
     } deriving (Eq, Show)
 
-handle :: MonadIO m => Text -> Options -> m ()
-handle callerName (Options targetName) = do
-    unlessM doesGameExist $ exitWith failure
+handle :: MonadIO m => Text -> Text -> Options -> m ()
+handle callerName tag (Options targetName) = do
+    unlessM (doesGameExist tag) $ exitWith failure
         { messages = [noGameRunningMessage callerName]
         }
 
-    game <- readGame
+    game <- readGame tag
 
     let command = case game ^. stage of
             VillagesTurn    -> Villager.voteCommand callerName targetName
@@ -52,4 +52,4 @@
 
     case runExcept (runWriterT $ execStateT (apply command >> checkStage >> checkGameOver) game) of
         Left errorMessages      -> exitWith failure { messages = errorMessages }
-        Right (game', messages) -> writeGame game' >> exitWith success { messages = messages }
+        Right (game', messages) -> writeGame tag game' >> exitWith success { messages = messages }
diff --git a/app/Werewolf/Game.hs b/app/Werewolf/Game.hs
--- a/app/Werewolf/Game.hs
+++ b/app/Werewolf/Game.hs
@@ -17,7 +17,7 @@
     startGame, createPlayers, padRoles,
 
     -- ** Working with an existing
-    defaultFilePath, readGame, writeGame, deleteGame, doesGameExist,
+    filePath, readGame, writeGame, deleteGame, doesGameExist,
 ) where
 
 import Control.Lens         hiding (cons)
@@ -26,6 +26,7 @@
 
 import Data.List.Extra
 import Data.Text       (Text)
+import qualified Data.Text       as T
 
 import Game.Werewolf
 
@@ -55,20 +56,20 @@
         simpleVillagerRoles = replicate simpleVillagersCount simpleVillagerRole
         simpleWerewolfRoles = replicate simpleWerewolvesCount simpleWerewolfRole
 
-defaultFilePath :: MonadIO m => m FilePath
-defaultFilePath = (</> defaultFileName) <$> liftIO getHomeDirectory
+filePath :: MonadIO m => Text -> m FilePath
+filePath tag = (</> ".werewolf" </> T.unpack tag) <$> liftIO getHomeDirectory
 
-defaultFileName :: FilePath
-defaultFileName = ".werewolf"
+readGame :: MonadIO m => Text -> m Game
+readGame tag = liftIO . fmap read $ filePath tag >>= readFile
 
-readGame :: MonadIO m => m Game
-readGame = liftIO . fmap read $ defaultFilePath >>= readFile
+writeGame :: MonadIO m => Text -> Game -> m ()
+writeGame tag game = liftIO $ filePath tag >>= \tag -> do
+    createDirectoryIfMissing True (dropFileName tag)
 
-writeGame :: MonadIO m => Game -> m ()
-writeGame game = liftIO $ defaultFilePath >>= flip writeFile (show game)
+    writeFile tag (show game)
 
-deleteGame :: MonadIO m => m ()
-deleteGame = liftIO $ defaultFilePath >>= removeFile
+deleteGame :: MonadIO m => Text -> m ()
+deleteGame tag = liftIO $ filePath tag >>= removeFile
 
-doesGameExist :: MonadIO m => m Bool
-doesGameExist = liftIO $ defaultFilePath >>= doesFileExist
+doesGameExist :: MonadIO m => Text -> m Bool
+doesGameExist tag = liftIO $ filePath tag >>= doesFileExist
diff --git a/app/Werewolf/Options.hs b/app/Werewolf/Options.hs
--- a/app/Werewolf/Options.hs
+++ b/app/Werewolf/Options.hs
@@ -40,6 +40,7 @@
 
 data Options = Options
     { optCaller  :: Text
+    , optTag     :: Text
     , argCommand :: Command
     } deriving (Eq, Show)
 
@@ -89,6 +90,10 @@
     <$> fmap T.pack (strOption $ mconcat
         [ long "caller", metavar "PLAYER"
         , help "Specify the calling player's name"
+        ])
+    <*> fmap T.pack (strOption $ mconcat
+        [ long "tag", metavar "TAG"
+        , help "Specify the game tag (for running multiple games at once)"
         ])
     <*> subparser (mconcat
         [ command "boot"        $ info (helper <*> boot)        (fullDesc <> progDesc "Vote to boot a player")
diff --git a/werewolf.cabal b/werewolf.cabal
--- a/werewolf.cabal
+++ b/werewolf.cabal
@@ -1,5 +1,5 @@
 name:           werewolf
-version:        0.4.12.0
+version:        0.5.0.0
 
 author:         Henry J. Wylde
 maintainer:     public@hjwylde.com
