Kotan Code 枯淡コード

In search of simple, elegant code

Menu Close

Tag: traits

Traits, Multiple Inheritance, and Actors in Scala

I’ve been experimenting with traits, multiple inheritance (mixins), and Actors in Scala and I’ve found it difficult to merge all 3 aspects of the language. If you’ve been reading any of my posts that I’ve written while attempting to build a MUD, you may have noticed that the architecture is starting to get a little muddy when it comes to having multiple message handlers.

Rather than use a MUD as an example, I want to use an even simpler example to make my problem easier to describe. Let’s say I want to create an Actor. This actor is highly overworked and as such, he is the chief cook and bottle washer. Cooks can respond to the CookThis message. Bottle washers can respond to the WashThis message. The chief cook and bottle washer can also respond to a message instructing him to DoWork.

Constantly in search for an elegant, simple, and clean solution to this problem I immediately think about trying to solve it using traits. My first stab at a solution looks like the code below, where I’ve created Traits for Cook and Bottlewasher and the main Actor also has its own message handling logic:

import scala.actors._
import scala.actors.Actor._

case class CookThis(item:String)

trait ChiefCook extends Actor {
	override def act() = {
		loop {
			react {
				case CookThis(item) => println("I'm cookin' "+ item)
			}
		}
	}
}

case class WashThis(item:String)

trait BottleWasher extends Actor {
	override def act() = {
		loop {
			react {
				case WashThis(item) => println("I'm washin' " + item)
			}
		}
	}
}

case class DoWork(item:String)

class Overworked extends Actor with ChiefCook with BottleWasher
{
	override def act() = {
		loop {
			react {
				case DoWork(item) => println("I'm workin' on " + item)
			}
		}
	}
}

val worker = new Overworked
worker.start

worker ! DoWork("code")
worker ! WashThis("plate")
worker ! CookThis("hot dog")

Logically, if Traits gave us true multiple inheritance, we would expect that when we run this application we will see three messages as our overworked Actor does everything from coding to washing plates to cooking hot dogs. What we actually see is the Actor responding only to the DoWork message.

This is because of how Traits are actually used to generate the underlying code that belongs to container classes within the JVM. What’s happening is that each trait is overriding the act() function and the Overworked class is also doing an override. Because this class is the outermost parent in a hierarchy of contained classes (as seen by the JVM, not by the Scala programmer), it makes the other act() implementations vanish.

What can I do to fix this? What if I use some other method and call it from act(), adopt the abstract superclass style? The problem is this: if the alternate method has the same name in every trait, that method will suffer from the same vanishing that we saw with the original solution and our overworked Actor won’t respond to all of the appropriate messages.

One option is to make the outermost containing Actor handle all of the messages and forward them to the trait implementations via trait-specific methods like this:

def act() = {
  loop {
    react {
      case DoWork(item) => doWork(item)
      case WashThis(item) => washThis(item)
      case CookThis(item) => cookThis(item)
  }
}
}

This solves one problem but creates another. We’re now able to arbitrarily mix in traits that provide functionality that should be invoked in response to an incoming message, but now we have an SRP (Single Responsibility Principle) and LSP (Liskov Substitution Principle) failure in our design. Our Overworked class needs explicit knowledge of every single message that each trait should respond to and how it should respond. This means that every time any of the traits is expanded to handle new messages, every single class with that trait must also modify its pattern matching inside the act() method!

So now what can we do? At this point I felt like I was so close, I knew that Scala could handle this problem in an elegant way and, as it turns out, I was right. I refactored my initial solution to one that was much smaller. I gave each trait it’s own message handler method (to avoid name-collision-driven method vanishing) and then chained them together using the orElse function, like this:

case class CookThis(item:String)

trait ChiefCook {
	protected val handleCookMessages: PartialFunction[Any, Unit] = {
		case CookThis(item) => println("I'm cookin " + item)
	}
}

case class WashThis(item:String)

trait BottleWasher {
	protected val handleBottleWasherMessages: PartialFunction[Any, Unit] = {
		case WashThis(item) => println("I'm washin' " + item)
	}
}

case class DoWork(item:String)

class Overworked extends Actor with ChiefCook with BottleWasher
{
	def handleMessages : PartialFunction[Any, Unit] = {
		case DoWork(item) => println("I'm workin' on " + item)
	}

	def act() = {
		loop {
			react {
				handleMessages orElse handleBottleWasherMessages orElse handleCookMessages
			}
		}
	}
}

val worker = new Overworked
worker.start

worker ! DoWork("code")
worker ! WashThis("plate")
worker ! CookThis("hot dog")

There are a couple of really powerful things happening here this time. First, you may have noticed that my new traits no longer extend Actor – meaning that they don’t have to be Actors to process messages, allowing the traits to be mixed into any class. Next, the individual message handling methods are protected, which makes it obvious to anyone reading the trait that it’s perfectly OK to create derived child traits with their own message handlers and still invoke the base/parent message handler.

Finally, the orElse function lets me chain all of the trait message handlers together. While the Overworked actor still has to know the name of the message handler function from the mixed-in trait, a simple naming convention of handle[TraitName]Messages makes this easily taken care of. Now, rather than bleeding responsibility out of the traits and into the parent containing class, all the real Actor needs to know is which traits are being mixed in.

The only visible drawback here is that if you have two traits that both want to handle the same message, the trait whose message handler appears earlier in the orElse chain will win and the other trait will never receive the message.

There may be a way to simplify this even more but as it is, I really like this pattern and it allows me to mix in arbitrary message handlers to any Actor. My next step will be go to back into my MUD code and refactor it all to clear up roles and responsibilities.

Building a MUD in Scala, Part 5: Refactoring and Idiomatic Scala

So far, so good. My quest to learn Scala by virtue of attempting to build a MUD in that language is going pretty well. At this point, I can telnet to the game server, I can log in (albeit without validation or persistence), and in my last post I added the ability for players to be granted commands like ‘who’, ‘cmdsoul’ (to see the command souls assigned to them), ‘broadcast’, etc.

When we learn new programming languages, we always look at the new language through the filter of our past experiences. This isn’t a sign of a bad programmer – this is merely human nature. It’s how we learn and how our brains filter everything we see, do, and hear. As a result, if we approach a new language like Scala from the point of view of someone who has been doing hard-core OOP for the past several years and only tinkering with functional programming – we tend to rely on certain crutches or conventions.

For example, I have an Actor (a Player, to be exact) and that Actor has multiple mix-in traits. One of these traits manages the list of commands currently available for the player. I am exposing the list of commands as a public field so that the Wizard Command Soul can tell wizards which command souls are attached (this ability is supremely helpful for debugging chained command parsing.. trust me..):

var commandSouls: Map[String, CommandSoul] = Map.empty[String, CommandSoul]

And in the Wizard Command Soul, I do a couple of really hideous things in order to display this list of command souls to the wizard:

val cmdIssuer = soulOwner.asInstanceOf[CommandIssuer]
...
cmdIssuer.commandSouls.foreach( ... )

The first problem with this code is that I’m doing a very classic OOP-style typecast. I’m coercing the soul’s owner (the Actor to which the command soul has been attached) to the trait type CommandIssuer. This means that my Wizard Command Soul now has to have explicit knowledge of how I built my application. In short, it needs to know that the CommandIssuer trait is the one that carries a public field named commandSouls.

Allowing other objects unfettered access to a ‘var’ (mutable) field in Scala just seems wrong. It’s certainly not thread-safe and it feels just wrong to me. This blog is about the pursuit of elegant simplicity and this seems neither elegant nor simple.

I could pull out another classic OOP principle: encapsulation, and wrap that var in a function that returns an immutable map:

	def getCommandSouls = {
		val cmdTemp = commandSouls.toMap
		cmdTemp
	}

When you call toMap and assign that value to a val , it automatically gives you an immutable map. This takes care of some of our thread-safety issues and also prevents other people from tampering with the internal list of commands. But, it’s still just a method wrapper and I still don’t like it because I still have to coerce the actor into the CommandIssuer trait/mixin type. If I decide to move the storage of command maps to a different trait during some future refactor, this code will break.

My next thought, then was to send a message to the soul owner (the player) and I would then expect a message back containing the information I need. This is far more Scala-looking than anything I’ve done so far:

	def handleCommandSoul(verb: String, extParams: List[String]) : Boolean = {
		//val cmdIssuer = soulOwner.asInstanceOf[CommandIssuer]
		var string = "\nCurrently Attached Command Souls:\n"
		soulOwner ! QueryCommandSouls
		self.receiveWithin(500) {
			case rep: CommandSoulReply => {
				rep.souls.foreach( mapitem => string += mapitem._1 + " - " + mapitem._2.describe()._2 + "\n")
				soulOwner ! TextMessage(string)
			}
			case TIMEOUT => {
				soulOwner ! TextMessage("Woah, your command issuer is roasted")
			}
			case somethingElse =>
			{
				println(somethingElse)
				soulOwner ! TextMessage("received a bizarro message!")
			}
		}
		true
	}

I’ve got a couple extra guards in there because I’ve never done this before and have no idea what to expect. What I assume is going to happen here is that the looping react pattern matcher I have in the player will eventually get to the partial function in CommandIssuer and handle the request to query the list of command souls. At that point, it will reply to the sender with the information I’m looking for, using this code:

	case QueryCommandSouls => {
		println(sender + " just asked me for the list of command souls!")
                val souls = commandSouls.toMap // Create an immutable copy!! encapsulation FTW
		sender ! CommandSoulReply(souls)
		}

When I compile and run the MUD this time and I type cmdsoul into my telnet client,  I get something entirely unexpected. The message that my receiveWithin(500) pattern match received was QueryCommandSouls! As it turns out, the wizard command soul is attached to the same player (Actor) that has the CommandIssuer trait. So, basically I’m sending myself the QueryCommandSouls message and immediately after that, I start a receive block. In short, I’m catching my own message before the rest of my reactors can see it.

Remember that Actors in Scala are really nothing more than objects backed by a queue (message box) and every message you send to an Actor is really just dumped into the queue and then pulled out of that queue synchronously or asynchronously using pattern matching syntax. So, when I called receive after sending myself the QueryCommandSouls message, I just received the message I sent a nanosecond ago. I need to refactor this some more to make this more asynchronous to allow the player’s reactors to handle things in the right order.

Here’s my new handleCommandSoul function:

def handleCommandSoul(verb: String, extParams: List[String]) : Boolean = {
		soulOwner ! QueryCommandSouls(this)
	}

Note that I had to change the query message into a case class instead of a case object. This is because if I send the message without any parameters, the sender object on the other end will be the player and not my command soul. To get the reply to come back exactly where I want it, I have to pass the object with the message (unless I actually want the player to handle the reply). This is looking much better – it looks much more idiomatic than my previous attempts.

Now I need to handle the reply in a react loop in my act method in the command soul:

def act() : Unit = {
	loop {
		react {
			case rep:CommandSoulReply => {
				var string = "\nCurrently Attached Command Souls:\n"
				rep.souls.foreach( mapitem => string += mapitem._1 + " - " + mapitem._2.describe()._2 + "\n")
				soulOwner ! TextMessage(string)
			}
		}
	}
}

At this point I can compile and run my MUD again and the cmdsoul command works just as it did before (at least from the player’s point of view) but the internal plumbing has been changed so that it now operates in a thread-safe, asynchronous fashion that looks far more like it belongs in Scala than it does in Java.

The whole point of this blog post is, first and foremost, strive for simplicity. My code looked convoluted, complex, and difficult to read. In addition, I knew it wasn’t thread-safe and violated encapsulation rules. I refactored a couple times and still wasn’t happy. With my final solution of asynchronous messaging between two traits attached to a single parent Actor, I am actually pleased with the result.

Building a MUD in Scala, Part 4: Command Processing

In many traditional MUDs, the list of things a player or an administrator can do is fixed at compile-time. In a standard Zork-style adventure you might be able to do the typical things like enter ‘north’, ‘south’, ‘get’, ‘attack’, ‘kill’, ‘drop’, ‘quit’, etc. In a MUD you get some additional commands that might be relevant in a multi-player environment like ‘who’ or ‘say’ or ‘tell’ and even some fancy muds let you emote with commands like ‘bow’, ‘praise’, ‘introduce’, ‘wave’, etc.

While I’m perfectly OK with that list of commands, I’ve never liked how the player is given those commands. In almost all MUDs that I’ve encountered, the game engine knows about the fixed list of available commands and the execution of said commands takes place somewhere at the low engine level. This totally violates my feelings toward the single responsibility principle (SRP), encapsulation, and domain-bleeding.

The following sample scenarios should make it clear why I hate the idea of the engine having built-in commands:

Scenario 1: A player is in a MUD and they enter a disco. While inside this disco, the player can type ‘disco’ to get their 70s funk on. The ‘disco’ command is only available to the player while they are in this one room out of the thousands of rooms that make up the MUD. Do we really want to go modify the command parser at the engine level in order to grant the player the ‘disco’ command in a single room? What happens if that room gets deleted … now we have orphaned, scar tissue code sitting in our engine that serves no purpose. This might not seem like a big deal for a game, but it illustrates a very good point about designing large applications with large domain models.

Scenario 2: A player in that same MUD stumbles across a sword. The sword has an inscription on it and when the player types the words from that inscription into the console, the sword bursts into flames and does an extra bajillion points of damage. In this case, the command is even more situational than the disco room. Only when the player is wielding this sword are they granted the ability to type the secret word ‘clambake’ into the console that will activate the sword’s secret powers.

So, what I’m envisioning here is I want to be able to send the Player actor a message whenever I grant them the ability to type a command and likewise, send them another message when they no longer have the ability to type that command. Consider the following functions that we might find in the Holy Clambake Sword:


def onWielded(player: Player) : Unit = {
    player ! AddCommand(List("clambake"), handleClambake)
}

def handleClambake(verb: String, extParams: List[String]): Boolean = {
    player ! TextMessage("You have activated the mighty abilities of the Holy Clambake Sword!")
    player ! Emote("has activated the mighty abilities of the Holy Clambake Sword!")
    isFlaming = true
    true
}

To be able to send Player’s the AddCommand message, I’m going to create a trait called CommandIssuer. This trait can be mixed into any Actor that is capable of issuing commands to the system. This includes NPCs and other interactive entities within the game. For now, since I haven’t coded NPCs, we can just start with players. Here’s the code for the CommandIssuer trait:

package com.kotancode.mud.engine

import scala.actors._
import scala.actors.Actor._

sealed abstract class CommandRequest
case class AddCommand(verbs: List[String], executor: Function2[String, List[String], Boolean],
	cmdSoul: CommandSoul = null) extends CommandRequest
case class RemoveCommand(verbs: List[String], cmdSoul: CommandSoul = null) extends CommandRequest
case class ExecuteCommand(verb: String, extParams: List[String]) extends CommandRequest

trait CommandIssuer extends Actor
{	                             // CMD verbs , Func to call
	private var commandMap: Map[List[String], Function2[String, List[String], Boolean]] =
		Map.empty[List[String], Function2[String, List[String], Boolean]]

	var commandSouls: Map[String, CommandSoul] = Map.empty[String, CommandSoul]

	protected val handleCommandMapping : PartialFunction[Any, Unit] = {
		case req: AddCommand => {
			commandMap += req.verbs -> req.executor
			if (req.cmdSoul != null) {
				commandSouls += req.cmdSoul.describe()._1 -> req.cmdSoul
			}
		}
		case req: RemoveCommand => {
			commandMap -= req.verbs
			if (req.cmdSoul != null)
				cmdSouls -= req.cmdSoul.describe()._1
		}
		case exec: ExecuteCommand => {
			val toExecute = commandMap.filter(m => m._1.contains(exec.verb))
			if (toExecute.size == 0) {
				self ! TextMessage("What?\n")
			}
			else {
				toExecute.foreach( m => m._2(exec.verb, exec.extParams))
			}
		}
	}
}

If we add the CommandIssuer trait to our Player class (or any other class we want to be able to issue commands, either from a terminal or at the behest of other Actors) then we can send Players the AddCommand, RemoveCommand, and ExecuteCommand messages. The code that reads in lines of text from the player’s attached socket can now invoke ExecuteCommand after splitting the input line into a head and tail (how LISPy is that??):

val tokens = line.split(' ').toList
this ! ExecuteCommand(tokens.head, tokens.tail)

Finally, I want to mention Command Souls. Command souls are logically bundled groups of command handlers that are also bundled with the code that attaches and removes the commands from targets. This provides a neat and tidy way of packaging logically related commands like the stock commands that belong to all mortals (who, quit, say, get, look, etc), stock commands that belong to wizards (broadcast, cmdsoul to inspect commands, destroy, teleport, etc). Command souls are part of what I consider a MUD’s library code, logically and physically separated from the MUD’s engine code. This concept neither original nor mine – I first encountered it when I was an Archwizard of Code on the LPmud Genesis.

Take a look at the code for the Wizard command soul, a classic example of what Scala should look like when done in clean, tidy, small modules:

/*
 * Wizard Command Soul
 * Commands granted to all wizards
 */
package com.kotancode.mud.lib.wizard

import com.kotancode.mud.engine._
import scala.actors._
import scala.actors.Actor._

class WizardCommandSoul extends CommandSoul
{
	private var soulOwner : Actor = null

	def attachTo(target:Actor) : Unit = {
		soulOwner = target
		target ! AddCommand( List("cmdsoul"), handleCommandSoul, this )
		target ! AddCommand( List("broadcast", "bcast"), handleBroadcast, this)
	}

	def detachFrom(target:Actor) : Unit = {
		soulOwner = null
		target ! RemoveCommand( List("cmdsoul"), this)
		target ! RemoveCommand( List("broadcast", "bcast"), this)
	}

	def describe() : (String, String) = {
		("Wizard", "Standard commands available to all Wizards")
	}

	def handleCommandSoul(verb: String, extParams: List[String]) : Boolean = {
		val cmdIssuer = soulOwner.asInstanceOf[CommandIssuer]
		var string = "\nCurrently Attached Command Souls:\n"
		cmdIssuer.commandSouls.foreach( mapitem => string += mapitem._1 + " - " + mapitem._2.describe()._2 + "\n")
		soulOwner ! TextMessage(string)
		true
	}

	def handleBroadcast(verb:String, extParams: List[String]) : Boolean = {
		var text = "[Broadcast from " + soulOwner.asInstanceOf[Player].name + "]: "
		text += extParams.reduceLeft(_ + " " + _)
		PlayerRegistry.allPlayers.foreach(p => p ! TextMessage(text))
		true
	}
}

And finally, to prove that I’m not just blowing hot air, here’s a screenshot of a session I had while logged into the MUD. My prototype MUD auto-grants every user both Mortal and Wizard command souls and doesn’t care what you type for a name. In the future, it will have to ask for a username and a password, look that person up from storage, and load their profile, yadda yadda … For now, this is what I’ve got:

Sample MUD Session, Illustrating Command Processing

Sample MUD Session, Illustrating Command Processing

Overall I’m still fairly pleased with Scala. A few times I’ve been slapped in the face by the strong-typing because I’m not used to that when everything else feels so functional and lightweight – side-effects of Scala’s Frankenstein/hybrid nature. Still, even with a few syntactic bits of ugliness, I continue to keep forging ahead with this to get a real feel for what it’s like to work with Scala to solve practical problems.

Building a MUD in Scala, Step 3: Refactoring and Pub/Sub

As I mentioned in the previous blog post, I left some ugliness lying around in the code last time. The biggest problem in the last version of the code was that every time a player logged in, the Player actor iterated through the connected player list, accessed a variable specific to networking (the socket writer), and then sent text directly to that player. Not only did that violate encapsulation, but it violated the laws of good taste. It wasn’t elegant, simple, or clean enough for me. I had to fix this and I had to fix it now!

First, before I did the coupling fix, I extracted my code into multiple files. I now have an engine directory which contains the Player.scala and GameServer.scala files. I put them both in the com.kotancode.mud.engine package. This made me feel a little better – at least I was getting some proper organization out of this and I was no longer cramming everything into a single file.

Next, to address the encapsulation problem. After thinking about the problem for a little while I realized that the issue was one of pub/sub (publish/subscribe). I wanted the Player actors to simply publish the fact that they have logged in and then any interested party could then respond to that. Great, I’ll make the PlayerRegistry subscribe to a player login event and then publish that same event. The reason why I can’t have players subscribing to that event on other player objects is that players don’t know about other players (at least until after they’ve logged in) – it’s a chicken and the egg problem that only the singleton PlayerRegistry object can fix.

To give my Actors the ability to publish and subscribe, I used a Trait as a mixin called ActorPublisher (which you can find at this great blog post here by Jim McBeath). So now my engine directory has the following class files:

  • Player.scala
  • ActorPublisher.scala
  • GameServer.scala

GameServer has now become ridiculously small and the only change I’ve made is that instead of calling the message sent to the Player actor echo, I now call it StartTextProcessing. I love the fact that the act of reading commands from the player over a socket in a multi-threaded fashion is just taken care of me by the very nature of actors in Scala.

Let’s take a look at Player.scala, which now contains a revised Player actor that publishes notification of logins and subscribes to notifications of other players logging in from the PlayerRegistry object, which is acting as a multiplexer for this type of notification.

/*
 * com.kotancode.mud.engine
 *
 * Player class and related goodies
 */
package com.kotancode.mud.engine

import java.net._
import java.io._

import scala.actors._
import scala.actors.Actor._

case class StartTextProcessing(socket: Socket)

class Player extends Actor with Subscriber[PlayerMessage] with ActorPublisher[PlayerMessage] {
 var name = "";
 var inReader: BufferedReader = null
 var outWriter: PrintWriter = null

 implicit def inputStreamWrapper(in: InputStream) =
  new BufferedReader(new InputStreamReader(in))

 implicit def outputStreamWrapper(out: OutputStream) =
  new PrintWriter(new OutputStreamWriter(out))

 def processText(in: BufferedReader, out: PrintWriter) {
   inReader = in
   outWriter = out
   PlayerRegistry ! Subscribe(this.asInstanceOf[Subscriber[PlayerMessage]])
   out.println("\nWho be ye?")
   out.flush()
   name = in.readLine();
   out.println("\nWelcome to the KotanMUD, " + name)
   publish(PlayerLoggedInMessage(this.asInstanceOf[Player]))
   out.println("Other people currently playing:")

   PlayerRegistry.allPlayers.foreach( p => out.println(p.name) )
   out.flush()
   while (true) {
       val line = in.readLine()
       out.println(name + ": " + line)
       out.flush()
  }
 }

private val handleOther : PartialFunction[Any,Unit] = {
	case StartTextProcessing(socket) => actor { processText(socket.getInputStream(), socket.getOutputStream()) }
	case PlayerLoggedInMessage(player) => {
		if (this != player) {
			outWriter.println(player.name + " logged in.")
			outWriter.flush()
		}
	}
}

def act() {
	loop {
		react (handleSubscribe orElse handleOther)
	}
}
}

sealed abstract class PlayerMessage
case class PlayerLoggedInMessage(source:Player) extends PlayerMessage

object PlayerRegistry extends Actor with Subscriber[PlayerMessage] with ActorPublisher[PlayerMessage]
{
	start
	var allPlayers = List[Player]()
	def getPlayer() : Player = {
		val newPlayer = new Player()
		allPlayers ::= newPlayer
		newPlayer ! Subscribe(this.asInstanceOf[Subscriber[PlayerMessage]])
		newPlayer
	}

	private val handleMessage : PartialFunction[Any, Unit] = {
		case m:PlayerLoggedInMessage => {
			println(m.source.name + " logged in.") // output to console
   			publish(PlayerLoggedInMessage(m.source)) // republish the message
			}
	}

	def act() {
		loop {
			react (handleSubscribe orElse handleMessage)
		}
	}
}

So now I will compile my new MUD with the following command (as I add files it adds a bit more complexity to my ability to rapidly run my MUD… at some point I’m going to have to upgrade to a build tool to automate this… but that’s a topic for another post):

scalac engine/ActorPublisher.scala engine/Player.scala engine/GameServer.scala

And then I run my MUD with:

scala com.kotancode.mud.engine.GameServer

I can now verify that I am able to handle incoming connections the same way I used to, the multi-threading and thread-local storage is all working properly and most importantly, I am now able to let other players know that a player has logged in using a more elegant publish/subscribe approach.

Building a MUD in Scala Part 2 – Shared State

In the previous post, I explained a little bit about my reasoning behind experimenting with a MUD as a way of learning a new language. As a result, I’ve been poking around a little with Scala. Whenever you’re learning a new language it helps to have a goal in mind rather than building a bunch of disparate “hello world” samples. My goal is a MUD.

Last time I build a telnet server that prompts the user for their name and then acts as an echo server thereafter. In this post, I’m going to experiment with how I can add some global state. I want to be able to keep track of who is currently logged into the MUD. In addition, I want to be able to send messages to all connected players and let them know that another player has connected.

To do this, I’m going to modify my original Scala script from the previous post to make it look like the following:

/*
 * Pathetically simple Scala echo server
 * Step 2 on the road to making a MUD - maintaining player list
 */
import java.net._
import java.io._

import scala.actors._
import scala.actors.Actor._

case class Echo(socket: Socket)

class Player extends Actor {
 var name = "";
 var inReader: BufferedReader = null
 var outWriter: PrintWriter = null

 implicit def inputStreamWrapper(in: InputStream) =
  new BufferedReader(new InputStreamReader(in))

 implicit def outputStreamWrapper(out: OutputStream) =
  new PrintWriter(new OutputStreamWriter(out))

 def echo(in: BufferedReader, out: PrintWriter) {
   inReader = in
   outWriter = out
   out.println("Who be ye?")
   out.flush()
   name = in.readLine();
   out.println("Welcome to the Echo Server, " + name)
   out.println("Other people currently playing:")
   PlayerRegistry.allPlayers.foreach( p=>
	{
		out.println(p.name)
		if (p.name != name)
			p.outWriter.println(name + " just logged in.")
		p.outWriter.flush()
	})
   out.flush()
   while (true) {
       val line = in.readLine()
       out.println(name + ": " + line)
       out.flush()
  }
 }

 def act() {
  loop {
   receive {
    case Echo(socket) =>
     actor {
      echo(socket.getInputStream(), socket.getOutputStream())
     }
   }
  }
 }

}

object PlayerRegistry
{
	var allPlayers = List[Player]()
	def getPlayer() : Player = {
		val newPlayer = new Player()
		allPlayers ::= newPlayer
		newPlayer
	}
}
// Singleton object for the echo server.
object EchoServer {
 val serverSocket = new ServerSocket(8888)

 def start() {
  while(true) {
   println("Awaiting connection...")
   val clientSocket = serverSocket.accept()
//   val player = new Player()
   val player = PlayerRegistry.getPlayer()
   player.start
   player ! Echo(clientSocket)
   println("Spun off echo handler for player")
  }
 }
}

EchoServer.start

The new code here is the PlayerRegistry object. Object’s in Scala are a first-class implementation of the singleton pattern. Simply by declaring something an ‘object’ rather than a ‘class’ Scala automatically takes care of the plumbing involved in setting that up as a singleton. The PlayerRegistry singleton contains a method called getPlayer, which is responsible for instantiating a new player as well as adding that new player object to a list. Note that as we change properties on the player object, that will be reflected in the global player list because we’re making changes to the same object (aren’t pointers awesome?).

The logic behind what I’ve done is pretty simple. The PlayerRegistry singleton object keeps track of all players currently in the game. When someone logs in, I iterate through the list of players. If the player object in the current iteration is not the player doing the logging in, I send the “(player) logged in.” message.

Veteran programmers and programmers with some measure of good taste will realize that I’m violating some patterns here. When a player logs in, I shouldn’t be looping through the player list and manually doing the notifications. What I should be doing is sending messages and letting the player object handle the message accordingly. I’ll take care of refactoring this in the next blog post. For now, take a look at this screenshot from a terminal session logged into my ‘game’ server:

Using My Scala MUD

Using My Scala MUD

Building a MUD in Scala, Step 1: The Echo Server

If you’re reading this then you’re probably familiar with the fundamental, driving force behind this blog: elegant simplicity. This concept is what I strive for in my code, in my architectures, and generally in my life. Lately I’ve been doing a little experimenting with Scala and the more I play with it, the more I see potential for elegant simplicity in that language that is just not achievable with standard Java. My goal is to find out if Scala can really meet my need for 枯淡 (kotan).

You might be thinking: MUD? WTF? Didn’t those go extinct with the dinosaurs?? No. People are often surprised by this but, MUDs (Multi-User Dungeon/Dimension – old-school online text adventure games) require a lot of their developers. MUDs require developers to think about a lot of things that they don’t normally have to worry about with simple “Hello World” samples, such as:

  • Concurrency – performing multiple tasks on multiple threads in a way that doesn’t destroy data
  • Concurrency and Load – supporting multiple connected users to the same central process without slowing the process down.
  • Multi-threading – MUDs make extensive use of thread-local data, especially those MUDs whose text is exposed via Telnet.
  • Push Notifications – Good MUDs sent blurbs of text letting players know when other players enter and exit rooms, when someone draws a weapon, when another player does a dance. Developers can learn all kinds of useful techniques when they try and create domain models and networking code that supports this kind of behavior.
  • OOD and DDD – Designing the class hierarchy for a MUD is actually a great mental exercise and I highly recommend that every developer do it every time they feel that their experience has grown or changed.
  • Near-Real-Time Data – some of the better MUDs I used to work on “back in the day” had weather systems that would make thunder crackle (text-based thunder, but still…) at different times and the “noise” would radiate out, notifying only those players that are within earshot of the storm. This kind of design has applications in real-world business scenarios as well.
  • Testability – Writing code for a MUD should require a developer to write tests for their code since they can’t count on the fact that players will be able to walk around their areas, trodding on all that can be trod and poking all that can be poked, etc. This is also a very real-world scenario : we can’t expect our end users to find all the edge cases.
  • API Design – MUD developers typically build a game engine and then a core library. The core library is essentially an API that allows “wizards” (players who have gotten powerful enough to decide to add to the game) to build their own content. The API created by the original MUD developers needs to be simple enough that even the most junior of developers can utilize it to create fun areas. In real-world business scenarios, knowing how to create and test high-quality APIs is an essential skill for architects and senior developers.

Still think MUDs are worthless toy relics left over from the 80s and 90s? Hopefully not. One of my litmus tests for good, expressive, elegant languages is their ability to allow me to create a MUD that adheres to my “code as data” policy. Rather than reading rigid crap from weapons.xml, weapons should be first-class language objects and the use of the game library is what creates instances of swords, daggers, or laser cannons.

To get myself started, I wanted to see how hard it would be to write the networking server. This is a smoke test. If any part of this is difficult or I feel like I’m spending all my time writing ceremony (like I would if I was writing a telnet server in POSIX C) then I will stop right away.

The requirements for my networking server are as follows:

  • Accept connections from a seemingly (limited by infrastructure and memory) unlimited number of clients
  • Each connection should have connection-private data, such as the player’s name. This proves that I can maintain private player state even while multiple players are connected
  • Everything the player types, after supplying their name, will be echo’d back to them. This proves that I can respond to commands with text that only the command issuer can see.
  • I fully intend to throw away much or all of this code in future refactors, as such – I don’t want to write a lot of code.

Thankfully, I was able to write some Scala that achieved all of these goals. Here is my simple echo server that also supports the prompting for and thread-local storing of player names (some of this is cobbled together from various echo server implementations I found via Google):

/*
 * Pathetically simple Scala echo server
 * Step 1 on the road to making a MUD
 */
import java.net._
import java.io._

import scala.actors._
import scala.actors.Actor._

case class Echo(socket: Socket)

class Player extends Actor {
 var name = "";

 implicit def inputStreamWrapper(in: InputStream) =
  new BufferedReader(new InputStreamReader(in))

 implicit def outputStreamWrapper(out: OutputStream) =
  new PrintWriter(new OutputStreamWriter(out))

 def echo(in: BufferedReader, out: PrintWriter) {
   out.println("Who be ye?")
   out.flush()
   name = in.readLine();
   out.println("Welcome to the Echo Server, " + name)
   out.flush()
   while (true) {
       val line = in.readLine()
       out.println(name + ": " + line)
       out.flush()
  }
 }

 def act() {
  loop {
   receive {
    case Echo(socket) =>
     actor {
      echo(socket.getInputStream(), socket.getOutputStream())
     }
   }
  }
 }

}

// Singleton object for the echo server.
object EchoServer {
 val serverSocket = new ServerSocket(8888)

 def start() {
  while(true) {
   println("Awaiting connection...")
   val clientSocket = serverSocket.accept()
   val player = new Player()
   player.start
   player ! Echo(clientSocket)
   println("Spun off echo handler for player")
  }
 }
}

EchoServer.start

When I run this application by just typing scala EchoServer.scala, it starts up a listener on port 8888. Then I telnet to localhost, port 8888. I am prompted with the text, “Who Be Ye?” to which I reply with my name. From there after, everything is echoed back to me, prefixed by the name I entered at the start of my session. I can fire up as many terminal windows as I like and log in with as many different names as I like. All of these connections have separate instances of the Player actor and that instance has a variable called name. This meets all of my requirements. It didn’t take me that much code, it looks clean, I’m not so attached to this code that I can’t throw it away, and I can support a (virtually) unlimited number of connections and each of those connections gets their own echo server loop.

Looks like I’m well on my way. The next thing I’ll want to do is add some kind of rudimentary command processing so that I can move beyond a simple Echo Server. At this point, I’m pretty pleased with the elegant simplicity of Scala and I think it’ll really start looking amazing once I start writing in-game objects like weapons, rooms, items, and building combat systems – where I get to (hopefully) start making extensive use of Traits and Actors, two of the most appealing aspects of Scala to me.