diff --git a/src/java/com/threerings/parlor/turn/TurnGameController.java b/src/java/com/threerings/parlor/turn/TurnGameController.java
new file mode 100644
index 000000000..340947bab
--- /dev/null
+++ b/src/java/com/threerings/parlor/turn/TurnGameController.java
@@ -0,0 +1,38 @@
+//
+// $Id: TurnGameController.java,v 1.1 2001/10/12 00:30:10 mdb Exp $
+
+package com.threerings.parlor.turn;
+
+import com.threerings.presents.dobj.*;
+
+import com.threerings.parlor.Log;
+import com.threerings.parlor.game.GameController;
+
+/**
+ * Extends the basic game controller with support for turn-based games.
+ */
+public abstract class TurnGameController extends GameController
+{
+ // documentation inherited
+ public void attributeChanged (AttributeChangedEvent event)
+ {
+ super.attributeChanged(event);
+
+ // handle turn changes
+ if (event.getName().equals(TurnGameObject.TURN_HOLDER)) {
+ turnDidChange((String)event.getValue());
+ }
+ }
+
+ /**
+ * Called when the turn changed. This indicates the start of a turn
+ * and the user interface should adjust itself accordingly (activating
+ * controls if it is our turn and deactivating them if it is not).
+ *
+ * @param turnHolder the username of the new holder of the turn.
+ */
+ protected void turnDidChange (String turnHolder)
+ {
+ Log.info("Turn changed [holder=" + turnHolder + "].");
+ }
+}
diff --git a/src/java/com/threerings/parlor/turn/TurnGameManager.java b/src/java/com/threerings/parlor/turn/TurnGameManager.java
new file mode 100644
index 000000000..c8110e6f6
--- /dev/null
+++ b/src/java/com/threerings/parlor/turn/TurnGameManager.java
@@ -0,0 +1,76 @@
+//
+// $Id: TurnGameManager.java,v 1.1 2001/10/12 00:30:10 mdb Exp $
+
+package com.threerings.parlor.turn;
+
+import com.threerings.crowd.data.BodyObject;
+import com.threerings.crowd.server.CrowdServer;
+
+import com.threerings.parlor.Log;
+import com.threerings.parlor.game.GameManager;
+import com.threerings.parlor.util.MathUtil;
+
+/**
+ * Extends the basic game manager with support for turn-based games.
+ */
+public class TurnGameManager extends GameManager
+{
+ // documentation inherited
+ protected void didStartup ()
+ {
+ super.didStartup();
+
+ // obtain a casted reference to our turn game object
+ _turnGame = (TurnGameObject)_plobj;
+ }
+
+ // documentation inherited
+ protected void gameDidStart ()
+ {
+ super.gameDidStart();
+
+ // figure out who will be first
+ setFirstTurnHolder();
+
+ // and set the turn indicator accordingly
+ int boid = _playerOids[_turnIdx];
+ BodyObject body = (BodyObject)CrowdServer.omgr.getObject(boid);
+ if (body != null) {
+ _turnGame.setTurnHolder(body.username);
+ } else {
+ Log.warning("Unable to start game; first player isn't around " +
+ "[boid=" + boid + "].");
+ }
+ }
+
+ /**
+ * This is called to determine whichi player will take the first
+ * turn. The default implementation chooses a player at random.
+ */
+ protected void setFirstTurnHolder ()
+ {
+ // TODO: sort out a better random number generator and make it
+ // available via the parlor services
+ _turnIdx = MathUtil.random(_playerOids.length);
+ }
+
+ /**
+ * This is called to determine which player will next hold the turn.
+ * The default implementation simply rotates through the players in
+ * order, but some games may need to mess with the turn from time to
+ * time. This should update the _turnIdx field, not set
+ * the turn holder field in the game object directly.
+ */
+ protected void setNextTurnHolder ()
+ {
+ // next!
+ _turnIdx = (_turnIdx + 1) % _playerOids.length;
+ }
+
+ /** A reference to our game object. */
+ protected TurnGameObject _turnGame;
+
+ /** The offset into the _playerOids array of the current turn holder
+ * or -1 if it's no one's turn. */
+ protected int _turnIdx = -1;
+}
diff --git a/src/java/com/threerings/parlor/turn/TurnGameObject.dobj b/src/java/com/threerings/parlor/turn/TurnGameObject.dobj
new file mode 100644
index 000000000..554ecd8d6
--- /dev/null
+++ b/src/java/com/threerings/parlor/turn/TurnGameObject.dobj
@@ -0,0 +1,27 @@
+//
+// $Id: TurnGameObject.dobj,v 1.1 2001/10/12 00:30:10 mdb Exp $
+
+package com.threerings.parlor.turn;
+
+import com.threerings.parlor.game.GameObject;
+
+/**
+ * Extends the basic game object with support for turn-based games.
+ */
+public class TurnGameObject extends GameObject
+{
+ /** The field name of the turnHolder field. */
+ public static final String TURN_HOLDER = "turnHolder";
+
+ /** The username of the player who is currently taking their turn in
+ * this turn-based game or null if no user currently holds the
+ * turn. */
+ public String turnHolder;
+
+ /** Requests that the turnHolder field be set to the
+ * specified value. */
+ public void setTurnHolder (String turnHolder)
+ {
+ requestAttributeChange(TURN_HOLDER, turnHolder);
+ }
+}