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.