diff --git a/Changelog.md b/Changelog.md
new file mode 100644
--- /dev/null
+++ b/Changelog.md
@@ -0,0 +1,19 @@
+# 0.3.0.0 - 2015-06-08
+
+* `PlayerSet` moved to new module, `Haverer.PlayerSet`
+* `PlayerSet` now implements `Foldable` and `Traversable`
+* New `rotate` and `randomize` methods for `PlayerSet`
+
+# 0.2.0.0 - 2015-06-08
+
+* `Deck` uses associated types for whether or not it is complete
+* New `FullType` alias for `Deck 'Complete`
+* Burn card is the *first* card from the deck, rather than the first card
+  after players have been dealt.
+* Burn card is now available for finished rounds (`Haverer.Round.getBurnCard`)
+* A list of survivors of each round can be obtained, once the round is over
+  (`Haverer.Round.survivors`)
+
+# 0.1.0.0 - 2015-06-07
+
+Initial release.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,74 @@
+# Haverer
+
+Haverer is a simple implementation of the excellent card game,
+[Love Letter](http://boardgamegeek.com/boardgame/129622/love-letter).
+
+It follows the original Japanese rules, rather than the newer American ones.
+
+## Running
+
+At the moment, you'll need to compile from source, which means you'll need to
+get set up with `cabal`. The easiest way to do this is to install the
+[Haskell Platform](https://www.haskell.org/platform/).
+
+Once you've done that, run the following commands:
+
+```
+$ git clone https://github.com/jml/haverer.git
+$ cd haverer
+$ cabal sandbox init
+$ cabal configure
+$ cabal install --dependencies-only
+$ cabal run
+```
+
+That last command, `cabal run`, will run a command-line version of the game.
+
+## License
+
+This code is copyright Jonathan M. Lange, 2014-2015, and is made available
+under the Apache License, version 2.0. See LICENSE for details.
+
+## Roadmap
+
+0. Procrastinate endlessly learning new Haskell tricks
+1. Wrap this whole thing in an API server
+2. Make that server available to the public
+3. Put a nice-ish web frontend in front
+
+## Bugs
+
+Please file issues on the
+[Github issue tracker](https://github.com/jml/haverer/issues)
+
+## Patches
+
+Are most welcome.
+
+## History
+
+The original implementation of this game is called
+[loveletter](https://github.com/jml/loveletter) and is written in
+[Rust](http://www.rust-lang.org/).
+
+## Thanks
+
+Thanks to the following people, who have helped with advice, kindness, or by patiently
+smiling and nodding while I've rambled on about this project:
+
+* metagnome
+* RAOF
+* @mithrandi
+* pjdelport
+* tomprince
+* radix
+* teh
+* simpson
+* joliette
+
+Any infelicities are my own.
+
+If you are one of these people and would like to be referred to in another way
+(perhaps you'd like me to link to your Github page?), please contact me. You
+know how.
+
diff --git a/haverer.cabal b/haverer.cabal
--- a/haverer.cabal
+++ b/haverer.cabal
@@ -16,7 +16,7 @@
 -- see http://haskell.org/cabal/users-guide/
 
 name:                haverer
-version:             0.2.0.0
+version:             0.3.0.0
 synopsis:            Implementation of the rules of Love Letter
 description:         Implementation of the rules of Love Letter
 license:             Apache-2.0
@@ -27,6 +27,8 @@
 category:            Game
 build-type:          Simple
 cabal-version:       >=1.10
+extra-source-files:  README.md
+                   , Changelog.md
 
 source-repository head
   type: git
@@ -56,6 +58,7 @@
                  , Haverer.Internal.Error
                  , Haverer.Internal.Ring
                  , Haverer.Player
+                 , Haverer.PlayerSet
                  , Haverer.Round
                  , Haverer.Testing
                  , Haverer.ValidMoves
diff --git a/lib/Haverer.hs b/lib/Haverer.hs
--- a/lib/Haverer.hs
+++ b/lib/Haverer.hs
@@ -47,6 +47,8 @@
   getDiscards,
   getHand,
   isProtected,
+  PlayerSet,
+  PlayerSetError(..),
   toPlayers,
   toPlayerSet,
   ) where
@@ -68,9 +70,13 @@
   Player,
   getDiscards,
   getHand,
-  isProtected,
+  isProtected)
+import Haverer.PlayerSet (
+  PlayerSetError(..),
+  PlayerSet,
   toPlayers,
-  toPlayerSet)
+  toPlayerSet
+  )
 import Haverer.Round (
   BadAction,
   Result(..),
diff --git a/lib/Haverer/CLI/CommandLine.hs b/lib/Haverer/CLI/CommandLine.hs
--- a/lib/Haverer/CLI/CommandLine.hs
+++ b/lib/Haverer/CLI/CommandLine.hs
@@ -33,7 +33,8 @@
 
 import Haverer.Action (Play(..), viewAction)
 import Haverer.Deck (Card(..))
-import Haverer.Player (PlayerSet, getDiscards, isProtected, toPlayers)
+import Haverer.Player (getDiscards, isProtected)
+import Haverer.PlayerSet (PlayerSet, toPlayers)
 import Haverer.Round (
   Event(..),
   Result(..),
diff --git a/lib/Haverer/Engine.hs b/lib/Haverer/Engine.hs
--- a/lib/Haverer/Engine.hs
+++ b/lib/Haverer/Engine.hs
@@ -31,7 +31,7 @@
 import Haverer.Deck (Card)
 import qualified Haverer.Game as Game
 import qualified Haverer.Round as Round
-import Haverer.Player (PlayerSet)
+import Haverer.PlayerSet (PlayerSet)
 
 
 class Monad m => MonadEngine m playerId where
diff --git a/lib/Haverer/Game.hs b/lib/Haverer/Game.hs
--- a/lib/Haverer/Game.hs
+++ b/lib/Haverer/Game.hs
@@ -33,8 +33,9 @@
 import Control.Monad.Random (MonadRandom)
 
 import Haverer.Deck (FullDeck, newDeck)
-import Haverer.Player (
+import Haverer.PlayerSet (
   PlayerSet,
+  rotate,
   toPlayers,
   )
 import Haverer.Round (Round)
@@ -75,11 +76,15 @@
 newRound game = newRound' game <$> newDeck
 
 -- | Indicate that the specified players won.
+--
+-- Since 0.3, will also rotate the order of play, so the person to the left of
+-- the previous first person is now the first.
 playersWon :: Ord playerId => Game playerId -> [playerId] -> Either (Outcome playerId) (Game playerId)
 playersWon game ps =
-  bumpRoundsPlayed <$> onCounter game (`Counter.incrementMany` ps)
+  rotatePlayers . bumpRoundsPlayed <$> onCounter game (`Counter.incrementMany` ps)
   where
     bumpRoundsPlayed g = g { _roundsPlayed = _roundsPlayed g + 1 }
+    rotatePlayers g = g { _playerSet = rotate (_playerSet g) }
 
 -- | Return the number of rounds played.
 roundsPlayed :: Game playerId -> Int
diff --git a/lib/Haverer/Player.hs b/lib/Haverer/Player.hs
--- a/lib/Haverer/Player.hs
+++ b/lib/Haverer/Player.hs
@@ -17,7 +17,6 @@
 
 module Haverer.Player (
   bust,
-  Error(..),
   discardAndDraw,
   eliminate,
   getDiscards,
@@ -25,35 +24,17 @@
   isProtected,
   makePlayer,
   Player,
-  PlayerSet,
   playCard,
   protect,
   swapHands,
-  toPlayers,
-  toPlayerSet,
   unprotect
   ) where
 
 import BasicPrelude
 import Control.Lens hiding (chosen)
-import Control.Monad.Except
 
 import Haverer.Deck (Card)
 
-
-data Error a = InvalidNumPlayers Int | DuplicatePlayers [a] deriving (Show, Eq)
-
-
-newtype PlayerSet a = PlayerSet { toPlayers :: [a] } deriving (Show, Eq)
-
-
-toPlayerSet :: Ord a => [a] -> Either (Error a) (PlayerSet a)
-toPlayerSet playerIds
-  | numPlayers /= numDistinctPlayers = throwError (DuplicatePlayers playerIds)
-  | numPlayers < 2 || numPlayers > 4 = throwError (InvalidNumPlayers numPlayers)
-  | otherwise = (return . PlayerSet) playerIds
-  where numPlayers = length playerIds
-        numDistinctPlayers = (length . nub . sort) playerIds
 
 
 data Player = Active {
diff --git a/lib/Haverer/PlayerSet.hs b/lib/Haverer/PlayerSet.hs
new file mode 100644
--- /dev/null
+++ b/lib/Haverer/PlayerSet.hs
@@ -0,0 +1,67 @@
+-- Copyright (c) 2014-2015 Jonathan M. Lange <jml@mumak.net>
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+{-# LANGUAGE DeriveTraversable #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module Haverer.PlayerSet (
+  PlayerSet
+  , PlayerSetError(..)
+  , toPlayerSet
+  , toPlayers
+  , randomize
+  , rotate
+  ) where
+
+
+import BasicPrelude
+import Control.Monad.Except
+import Control.Monad.Random
+import Data.Foldable (Foldable)
+import Data.Traversable (Traversable)
+import System.Random.Shuffle
+
+
+data PlayerSetError a = InvalidNumPlayers Int | DuplicatePlayers [a] deriving (Show, Eq)
+
+
+newtype PlayerSet a = PlayerSet { toPlayers :: [a] } deriving (Show, Eq, Functor, Traversable, Foldable)
+
+
+toPlayerSet :: Ord a => [a] -> Either (PlayerSetError a) (PlayerSet a)
+toPlayerSet playerIds
+  | numPlayers /= numDistinctPlayers = throwError (DuplicatePlayers playerIds)
+  | numPlayers < 2 || numPlayers > 4 = throwError (InvalidNumPlayers numPlayers)
+  | otherwise = (return . PlayerSet) playerIds
+  where numPlayers = length playerIds
+        numDistinctPlayers = (length . nub . sort) playerIds
+
+
+-- | Rotate the order of the PlayerSet
+--
+-- The player who was first is now last, whoever was second is now third,
+-- whoever was third is now second, etc.
+--
+-- Since 0.3
+rotate :: PlayerSet a -> PlayerSet a
+rotate (PlayerSet (x:xs)) = PlayerSet (xs ++ [x])
+rotate _ = error "Empty PlayerSet is impossible"
+
+
+-- | Randomize the order of the PlayerSet
+--
+-- Since 0.3
+randomize :: MonadRandom m => PlayerSet a -> m (PlayerSet a)
+randomize = map PlayerSet . shuffleM . toPlayers
+
diff --git a/lib/Haverer/Round.hs b/lib/Haverer/Round.hs
--- a/lib/Haverer/Round.hs
+++ b/lib/Haverer/Round.hs
@@ -84,12 +84,15 @@
   makePlayer,
   playCard,
   Player,
-  PlayerSet,
   protect,
   swapHands,
-  toPlayers,
   unprotect
   )
+import Haverer.PlayerSet (
+  PlayerSet,
+  toPlayers
+  )
+
 
 import Haverer.Internal.Error (assertRight)
 import Haverer.Internal.Ring (Ring, advance1, currentItem, dropItem1, makeRing, nextItem)
diff --git a/lib/Haverer/Testing.hs b/lib/Haverer/Testing.hs
--- a/lib/Haverer/Testing.hs
+++ b/lib/Haverer/Testing.hs
@@ -34,7 +34,7 @@
 
 import Haverer.Action (Play(..))
 import Haverer.Deck (baseCards, Card(..), FullDeck, makeDeck)
-import Haverer.Player (PlayerSet, toPlayerSet)
+import Haverer.PlayerSet (PlayerSet, toPlayerSet)
 import Haverer.Round (
   Round
   , Result(..)
diff --git a/tests/test.hs b/tests/test.hs
--- a/tests/test.hs
+++ b/tests/test.hs
@@ -19,7 +19,7 @@
 import Test.Tasty
 
 import qualified CLI
-import qualified Player
+import qualified PlayerSet
 import qualified Ring
 import qualified Round
 
@@ -28,7 +28,7 @@
 suite =
   testGroup "Test Suite" [
     CLI.suite
-    , Player.suite
+    , PlayerSet.suite
     , Ring.suite
     , Round.suite
     ]
