Kotan Code 枯淡コード

In search of simple, elegant code

Menu Close

Tag: ScalaMUD

Speaking at ScalaDays 2012 in London

I am honored to have been invited to speak at ScalaDays 2012 in London this year. For a guy who for years was considered a “Microsoft guy” and then for a few years after that considered an “Apple guy”, this is great validation that I’m not a Microsoft guy or an Apple guy or even a Java guy – I am just a guy who spends most of his spare technical resources searching for things that exemplify Kotan – elegant simplicity, and that includes Scala.

The talk I will be giving is about my experience learning Scala and Akka 2.0 through my ScalaMUD project. Here is the description of my talk from the ScalaDays 2012 website:

When learning a new language, one of the first things I do is try and build a game in that language because games are a lot more fun than progressively complicated “hello world” samples. In this experience report, I discuss my learning process and experience, that of a developer who has spent the last 11 years in the Microsoft world. I am exploring Scala by building a simple network text adventure game that uses many language features and Akka 2.0 and encounters surprisingly real-world problems from many other industries, including finance. My focus in learning languages is on creating clean, simple, elegant code and, as always, justifying to others why this language is worth the learning curve.
The code I’ve been writing as part of this experiment is open-sourced and available on GitHub.

Looking forward to meeting a bunch of fellow Scala enthusiasts and being able to present on this compelling language.

Refactoring Imperative Code to List Comprehensions in Scala

In my other series of posts about ScalaMUD, I’ve been writing a lot of code – some of it good, some of it ugly as hell. The reason a lot of the code looks ugly is that, as a C#, Java, and Objective-C developer my gut instinct is to do things in an imperative style with if statements, for loops, and other such constructs that simply don’t look at home in a hybrid functional language like Scala.

Here’s the code I originally produced, which scans through a list of NLP-tagged words and retrieves the first verb. If the list is empty then we need to return an empty string and if the list has no verbs then we assume that the first (or only) word in the list is a verb. For example, if I type “who” or “uptime” into the game then these should be considered verbs for command dispatching, even though NLP says they’re not verbs per se.

Ugly as Sin Code:

def firstVerb = {
if (words.size == 1)
words.head.value
else {
val outWords = words.filter( word => word.pos == Verb)
if (outWords == Set.empty)
words.head.value
else
outWords.head.value
}
}

And thanks to the geniuses over at Stack Overflow, they were able to guide me to this incredibly simple, elegant refactoring:

Refactored Code:

words find(_.pos == Verb) orElse words.headOption map(_.value) getOrElse ""

My hope is that someday I will think in terms of the second, more clean and refactored version and not instinctively reach for my imperative crutches.

ScalaMUD – More Multi-Threaded Command Parsing via Akka

In the last blog post on ScalaMUD, I showed how I was able to take advantage of a third party NLP library so that I could tag player input with the appropriate parts of speech like Verb, Noun, Adjective, etc. My goal here is to eventually use this information to match words in player input sentences with physical objects in the game so that when someone types ‘kill the blue dragon’, I will be able to find the ActorRef for the blue dragon, and find a verb handler for kill, and then initiate combat.

In this blog post, I’ve come one step closer to that goal by enabling the dispatching of commands. As players enter input, that input is sent off to a Commander actor which tags up the input with parts of speech. Once the Comander is finished with it, it wraps the tagged words in an EnrichedCommand message and sends that to the player, which now has the trait Commandable, allowing the player to respond to enriched commands. This has an added benefit of allowing NPCs to be scripted in the future by allowing them to pretend to ‘type’ things like “kill player”, etc.

Eventually rooms will add commands to players when they enter the room to allow them to type the name of the exit (e.g. north, south, up, window) as a verb. Mortals and Wizards alike each have a unique set of commands they need to be able to type and these commands are grouped into “command libraries” (my old alma mater MUD, Genesis, an LPMUD, called them command souls). For example, here’s the first version of the Mortal command lib:

package com.kotancode.scalamud.core.cmd

import com.kotancode.scalamud.core.ServerStats
import com.kotancode.scalamud.core.TextMessage
import com.kotancode.scalamud.Game
import com.kotancode.scalamud.core.Implicits._
import akka.actor._
import akka.routing._

abstract class CommandLibMessage
case class AttachCommandLib extends CommandLibMessage

class MortalCommandLib extends Actor {
	def receive = handleMortalCommands

	def handleMortalCommands: Receive = {
		case cmd:EnrichedCommand if cmd.firstVerb == "who" => {
			handleWho(cmd.issuer)
		}
		case AttachCommandLib => {
			attachToSender(sender)
		}
	}

	def handleWho(issuer: ActorRef) = {
		println("player "+ issuer.name + " typed who.")
		var stringOut = "Players logged in:\n"
		for (p: ActorRef <- Game.server.inventory) {
			stringOut += p.name + "\n"
		}
		issuer ! TextMessage(stringOut)
	}

	def attachToSender(sender:ActorRef) = {
		sender ! AddCommand(Set("who"), self)
	}

}

Those of you who program in iOS or Cocoa might recognize some of the “Delegate Pattern” here… when the command lib attaches itself to something capable of issuing commands (anything that carries the Commandable trait, like a player or NPC), it just passes the implicit sender ActorRef so that actor can now dispatch commands to that lib.

Here’s the code in the Commander object that sends enriched commands to the actor that “typed” (virtually or for real) the command:

package com.kotancode.scalamud.core.cmd

import akka.actor._
import akka.routing._

import com.kotancode.scalamud.core.lang.EnrichedWord
import java.util.ArrayList
import edu.stanford.nlp.ling.Sentence
import edu.stanford.nlp.ling.TaggedWord
import edu.stanford.nlp.ling.HasWord
import edu.stanford.nlp.tagger.maxent.MaxentTagger
import scala.collection.JavaConverters._
import scala.collection.mutable.ListBuffer
import com.kotancode.scalamud.core.cmd._

class Commander extends Actor {
	def receive = {
		case s:String => {
			val words = s.split(" ");
			val wordList = new java.util.ArrayList[String]();
			for (elem <- words) wordList.add(elem)
		    val sentence = Sentence.toWordList(wordList);
		    val taggedSentence = Commander.tagger.tagSentence(sentence).asScala.toList

			var enrichedWords = new ListBuffer[EnrichedWord]
		    for (tw : TaggedWord <- taggedSentence) {
				val ew = EnrichedWord(tw)
				println(ew)
				enrichedWords += ew
			}

			sender ! HandleCommand(EnrichedCommand(enrichedWords, sender))
	}
}
}

object Commander {
	val tagger = new MaxentTagger("models/english-bidirectional-distsim.tagger")
}

The important bit is that the player gets the HandleCommand message, which then goes through a dispatch process in the Commandable trait, and eventually registered verb handlers (like those registered via attached command libraries) get invoked via messages. Here’s the Commandable trait:

package com.kotancode.scalamud.core.cmd

import akka.actor._
import akka.routing._
import scala.collection.mutable.HashMap
import scala.collection.mutable.HashSet

sealed abstract class CommandMessage
case class AddCommand(verbs:Set[String], handlerTarget:ActorRef) extends CommandMessage
case class Removecommand(verb:String) extends CommandMessage
case class HandleCommand(command:EnrichedCommand) extends CommandMessage

trait Commandable {

	private val verbHandlers: HashMap[Set[String], ActorRef] = new HashMap[Set[String], ActorRef]

	def handleCommandMessages:akka.actor.Actor.Receive = {
		case AddCommand(verbs, handlerTarget) => {
			verbHandlers.put(verbs, handlerTarget)
		}

		case HandleCommand(cmd) => {
			dispatch(cmd)
		}
	}

	def dispatch(cmd:EnrichedCommand) = {
		println("handled a command "+ cmd +".")
		println("command's first verb: " + cmd.firstVerb)
		val targetHandlers = verbHandlers.filterKeys(key => key.contains(cmd.firstVerb))
		targetHandlers foreach {case (key, value) => value ! cmd}
	}
}

The dispatching actually happens in the targetHandlers foreach … line where the command is sent to every command handler that declared interest in that verb. In our case, we have a mortal command verb who that displays the list of connected users and the wizard command verb uptime that displays the length of time the server app has been running.

The following is sample session output from telnetting to the game:

Welcome to ScalaMUD 1.0

Login: Kevin
Welcome to ScalaMUD, Kevin
who
Kevin: who
Players logged in:
Bob
Kevin
Kevin
uptime
Kevin: uptime
Server has been up for 6 mins 39 secs.

Now that I can log in with multiple players, see who is online, and dispatch commands to handlers as well as differentiate between mortal and wizard abilities, this game is finally starting to feel like the beginnings of a real MUD.

ScalaMUD – Consuming Java from Scala and NLP Tagging

Last night I upgraded ScalaMUD’s POM file to point to the recently-available Akka 2.0-RC1. I was previously using M3 an was happy to note that all of my Akka 2.0 code continued working just fine without change from M3 to RC1. If the Akka RC is like most other RCs then there should be no further API changes, only fixes and tightening.

While I had the MUD code open I decided to start working on the problem of accepting player input. Sure, I have a socket reader that accepts text from players but what does one do with this text?

In the old days, I would’ve tokenized the string. By tokenized here I mean just splitting it blindly on spaces. Then I would have considered the first word in the array to be the verb and then dispatched the remaining parameters to some function in the MUD code that knows how to respond to that verb. For example, if I typed kill dragon then I would’ve tagged kill as the verb and dragon as the “rest”. This would have eventually found its way to some kill() method on a player that takes an array of strings as parameters.

Thankfully this isn’t the old days.

Instead what I did was declare a Maven dependency on the Stanford NLP (Natural Language Processing) project. To be specific, I wanted to use the Stanford non-linear Parts of Speech tagger. Why should I deal with parsing strings in a dumb way when someone else has spent years creating a powerful, well-trained NLP engine that can tag every sentence my player types with parts of speech?

This way, instead of relying on forcing players to type in pidgin dialects (e.g. kill dragon or cast spell or move north) I can let them type complete English sentences (if they want). I will then tag those sentences with the appropriate parts of speech and infer what they wanted to do from that.

I want this parsing to take place in the background. Once the player’s sentence has been enriched with parts of speech, I want to send the enriched sentence back to whatever typed it so that the command can be dispatched. To do this, I created a new Actor called Commander:

package com.kotancode.scalamud.core

import akka.actor._
import akka.routing._

import com.kotancode.scalamud.core.lang.EnrichedWord
import java.util.ArrayList
import edu.stanford.nlp.ling.Sentence
import edu.stanford.nlp.ling.TaggedWord
import edu.stanford.nlp.ling.HasWord
import edu.stanford.nlp.tagger.maxent.MaxentTagger
import scala.collection.JavaConverters._

class Commander extends Actor {
	def receive = {
		case s:String => {
			val words = s.split(" ");
			val wordList = new java.util.ArrayList[String]();
			for (elem <- words) wordList.add(elem)
		    val sentence = Sentence.toWordList(wordList);
		    val taggedSentence = Commander.tagger.tagSentence(sentence).asScala.toList

			var enrichedWords = new ArrayList[EnrichedWord]
		    for (tw : TaggedWord <- taggedSentence) {
		//		println(tw.value + "/" + tw.tag)
				val ew = EnrichedWord(tw)
				println(ew)
				enrichedWords.add(ew)
			}
	}
  }
}

object Commander {
	val tagger = new MaxentTagger("models/english-bidirectional-distsim.tagger")
}

At this point I’m just building the array of enriched words and I’m not actually sending the command back to the player (I’ll do that tonight or tomorrow, time permitting .. as always, you can check out the GitHub repo for the latest changes to the MUD). One of the interesting bits here is how I’m using a Java library from Scala. This is usually a pretty painless task but sometimes there are issues. In this case, the Stanford NLP library class Sentence has a bunch of overloads for the toWordList method. Java knows how to pick which overload but Scala doesn’t if I just use type inference and default Scala types. To get it to pick the right toWordList method I had to manually construct an ArrayList[String] because passing an Array[String] doesn’t let Scala know which overload to pick. It’s a little annoying but if I can keep the Scala->Java bridge points like this minimal then it’s not bad.

The flip side of this is that I’m getting back a regular Java array list in response to toWordList, which doesn’t support pretty Scala-native iteration because it doesn’t contain a foreach method, which is the underpinning that supports all the syntactic sugar around iteration. To deal with that, I imported the Java converters package implicits so that I could get the asScala function, which lets me call toList, which gives me a nice Scala list that I can use for easy iteration.

Here’s some sample output when I connect to the MUD and enter a sample sentence, which is then tokenized and tagged with parts of speech:

[EnrichedWord: word=attack, tag=VB, pos=Verb]
[EnrichedWord: word=the, tag=DT, pos=DontCare]
[EnrichedWord: word=green, tag=JJ, pos=Adjective]
[EnrichedWord: word=dragon, tag=NN, pos=Noun]
[EnrichedWord: word=with, tag=IN, pos=DontCare]
[EnrichedWord: word=the, tag=DT, pos=DontCare]
[EnrichedWord: word=yellow, tag=JJ, pos=Adjective]
[EnrichedWord: word=sword, tag=NN, pos=Noun]

The real goal here is that I will be taking the tagged nouns in the sentence and scanning through the player’s inventory and the environment in which the player stands for objects which have names that match the nouns and then using adjectives to disambiguate them if collisions occur. That way, when I type “kick blue bottle” I will be able to scan the surroundings for objects called “bottle” and if I find more than one, I’ll only gather up the ones that are blue.

In case you’re wondering what the EnrichedWord class looks like, which has some helper code that identifies only the parts of speech I care about, here it is:

package com.kotancode.scalamud.core.lang

import edu.stanford.nlp.ling.TaggedWord

case class PartOfSpeech
case object Noun extends PartOfSpeech
case object Verb extends PartOfSpeech
case object Adjective extends PartOfSpeech
case object DontCare extends PartOfSpeech

class EnrichedWord(value:String, tag:String, val pos:PartOfSpeech) extends TaggedWord(value, tag) {

	override def toString = "[EnrichedWord: word=" + value +", tag=" + tag + ", pos=" + pos + "]"
}

object EnrichedWord {
	def apply(hw: TaggedWord) = {
		val ew = new EnrichedWord(hw.value, hw.tag, rootTypeOf(hw.tag))
		ew
	}

	def rootTypeOf(s:String) = {
		s match {
			case "VB" | "VBD" | "VBG" | "VBN" | "VBP" | "VBZ" => Verb
			case  "NN" | "NNS" | "NNP" | "NNPS" => Noun
			case "JJ" | "JJR" | "JJS" => Adjective
			case _ => DontCare
		}
	}
}

Note that the EnrichedWord Scala class inherits from the Stanford TaggedWord Java class.

I really, really, love the syntax of the string pattern matcher I use to obtain the POS root (adjective, verb, noun, don’t care) from the Penn Treebank Tags that are used by the Stanford NLP POS tagger.

The takeaway I got from this exercise is further reinforcement of my rule to never re-invent the wheel because there are wheel experts out there who have dedicated their lives and careers to building wheels more awesome than I could ever hope to build. Hence I declare a Maven dependency on the NLP library and in a single night, I’ve got a MUD that can intelligently POS-tag player sentences which I can then use to identify potential targets of player commands. In addition, I don’t have to create a pidgin dialect for interacting with the MUD. English works and the MUD should be able to deal with “I kill the dragon with the blue sword because I am the shizzle” with the same ease as “kill dragon with sword”.

Adding State to Actors with the Pimp My Class Pattern

In my last blog post, I talked about how the new Akka 2.0 actor system hides an enforces the inaccessibility of the actual class of the underlying actor. For example, if you have a class called Zombie that is of type Actor, then when you use the actor system to start that actor, what you get back is an ActorRef, and (without cheating), there is no way to typecast or otherwise gain access to the Zombie type from an instance of ActorRef. While it felt limiting, once I embraced the design principle that necessitated that enforcement, I understood.

That said, I am building a MUD here and I’m going to need state. My rooms need names, descriptions, and exits. My NPCs are going to need combat stats and inventories, my players are going to need names, descriptions, races, genders, etc. This is all basic stuff but – if I can’t get to a game object reference from an ActorRef, how am I going to get at their internal state?

Easy! Don’t use internal state.

Remembering back to my first post where I upgraded my old Scala MUD to use Akka actors, I noted that every actor in a system has a unique path string that denotes its position within a hierarchy of supervisory actors much like the way supervisors and processes exist in an Erlang system. That gave me the idea to store the state for my actors in a big in-memory hash (which I could then upgrade to some kind of distributed or CouchDB-type store later).

With that problem solved, the only real problem now was that my ActorRef instances didn’t have concrete properties. One of my favorite features of Scala, which is also used in building DSLs, is the pimp my class or pimp my library pattern. This works very much like class extensions in C#. I can create a class that encapsulates or enriches an underlying class type by providing methods that operate on or with that class. In my case, I wanted strongly typed accessors like name and description that actually deferred the backing store to this singleton, in-memory hash.

Here’s my scala file that contains an Implicits object that enriches the ActorRef type with the wrapper class and the wrapper class provides a getter and setter for name.

package com.kotancode.scalamud.core

import akka.actor.ActorRef
import scala.collection.mutable.{Map,
    SynchronizedMap, HashMap}

object Implicits {
	implicit def enrichActorRef(value: ActorRef) = new WrappedActorRef(value)
}

/*
 * Singleton containing a hash map keyed on the Actor Ref path
 * which contains additional hash maps.
 * There is one hash map for every actorref that needs state
 */
object StateMap {

   // Creates a thread-safe hash map
   def makeMap: Map[String, HashMap[String,String]] = {
       new HashMap[String, HashMap[String,String]] with
           SynchronizedMap[String, HashMap[String,String]]
   }

   private var stateMap = makeMap

   def getState(key:String):HashMap[String,String] = {
   	 if (!stateMap.contains(key))
	     stateMap.put(key, new HashMap[String,String])
	 stateMap(key)
   }

   def setState(key:String, propertyName:String, value:String) = {
		var state: HashMap[String,String] = null
		val result = stateMap.get(key)
		result match {
			case Some(x) => state = x
			case None => state = new HashMap[String,String]
		}
		state.put(propertyName, value)
		stateMap.put(key, state)
   }
}

class WrappedActorRef(val actorRef: ActorRef) {

	def name:String = StateMap.getState(actorRef.path.toString)("name")
	def name_=(value:String) { StateMap.setState(actorRef.path.toString, "name", value) }
}

An obvious refactoring opportunity here would be to move the StateMap class out to its own separate Scala file but I’ve always been a huge fan of the agile process of getting something working first and refactoring afterward.

Now, to use my newly enhanced ActorRef (with state) class all I have to do is add the following import

import com.kotancode.scalamud.core.Implicits._

To the top of my Scala file and below anywhere the type ActorRef is known, I can read and write the name property, as shown here:

	private def handlePlayerLogin(player:ActorRef) = {
		println("Player logged in: " + player)
		allPlayers ::= player
		for (p: ActorRef <- allPlayers) {
			p ! TextMessage(player.name + " logged in.")
	    }

Because ActorRef has been pimped to use the external state provider, I can use player.name in my code and it works!

ScalaMUD – Updated to Akka 2.0-M3

Tonight I decided to dig back into my tiny little MUD sample (which doesn’t have much in common with a real MUD at this point… but that will change soon) and upgrade it to work with the current milestone of Akka, 2.0-M3 which came out just last week from what I can tell.

There is actually quite a bit of difference in complexity and power between Akka 1.3 and Akka 2.0. There’s a detailed blog post here that covers some details on the breaking changes between 1.2/1.3 and 2.0.

The biggest thing that concerns me is that Akka 2.0 has this concept of an actor system, which is really a tree-like hierarchy of actors. Some actors act in a supervisory capacity over other child actors and this tree is query able at runtime. If this sounds like Erlang’s supervisor process system to you that’s no accident… the philosophy guiding the development of Akka 2.0’s actor system is very Erlang-ish.

So when I create my top-level Game singleton object, I now need to create an instance of an Actor System and fire up a top level actor (I can have multiple top-level actors):

package com.kotancode.scalamud

import akka.actor._
import akka.routing._

/*
 * Root-level Game singleton
 * Creates the Akka Actor System for all subsequent game objects
 */
object Game extends App {
	val system = ActorSystem("ScalaMUD")
	val server = system.actorOf(Props(new GameServer()), "server")
	println("System Starting")
	server ! ServerStart()
}

Note here the use of system.actorOf. If I want to create a subordinate (child) actor within the context of the parent actor doing the creation, then I would use context.actorOf. I can give each of my actors a unique name so that they have descriptive path names when they appear in the actor system tree.

So far I was happy with the upgrade and I didn’t have too much trouble. Then I got to the point where I was creating anonymous actors in order to execute my while loops for accepting sockets and reading input from a socket in the background… Akka 2.0 has removed the spawn { } syntax and replaced it with some severe limitations, namely you can no longer create anonymous actors that do not implement a receive method. This means the old spawn { // do something } construct is impossible, replaced with this snippet from my GameServer class:

case s:ServerStart => {
	context.actorOf(Props(new Actor {
		def receive = {
			case ss:ServerStart => {
				startSocketListener
			}
		}
	})) ! s

If you’re thinking OMGWTFBBQ at this point, you’re not alone. Basically what I’m doing is creating an anonymous actor, defining a receive method that receives a specific message and does something in response to that message and then sending a message to my anonymous actor. This is actually the way the documentation tells you to spawn off asynchronous background tasks without using named actors.

Before you start the flame war here – it is worth taking a minute to think hard about the fact that everything that occurs asynchronously within Akka is supposed to be an asynchronous event-driven, message-passing construct. In short, if I was really anal about this, I would have spawned off an actor that reads from the input socket stream in its own private loop and I would have spawned off another actor that encapsulates the output writer. When the input reader has read a line, it should send a message indicating that a line has been read and when something needs to send text to a player, it should do so through its output writer actor.

At this point I’m not that anal and I don’t need that level of complexity, so I’m leaving it out. I only mention this alternative to ease the pain of the new way of doing anonymous actors.

In short, I did get the MUD running on Akka 2.0-M3 and, while a little put off by the anonymous actor syntax, I understand its need and I applaud the type safe people for forcing actors to receive messages.

If you want to follow the code for the MUD as I continue working on it, check out my GitHub repo.