A Useful Messaging System

The ability to send game events as messages is a very useful thing indeed. In our projects, we produce different game systems at different times. Sound might be last, or we might add in a scoring system long after the initial game logic is completed. Messages are ideal for this type of scenario.

For instance, take the event of a raptor dying in Raptor Safari. One option–a bad one–is to explicitly reference all neccesary managers in the raptor scripts themselves. So, to add sound we would have to add a call to our sound manager, to add scoring we call a function on our scoring manager, and so on. The problem is we shouldn’t have to edit older scripts to enable functionality in new managers. This is a recipe for errors and programmer collisions (it will be harder to add in real raptor-specific functionality if there is a constant stream of edits to support other parts of the game).

A better paradigm is to have the raptor broadcast a message about its death. This message includes all relevant information: What killed the raptor, where it died, a reference to the raptor object itself, and so on. The message is broadcast with a specific category, like “raptor”, and interested parties sign up to consume messages about this category.

This means we can add functionality about an event without editing the original script. We could add a sound for our raptor’s death, include it in our scoring systems, spawn a particle effect, and more–all without touching the original raptor logic. Perfect! But how do we accomplish this is UnityScript?

C# includes a mechanism to do this called delegates, which is a type that references a method or methods. Unity’s JavaScript doesn’t support delegates, however, and in fact we’re better served with our own system anyway, since we can do additional logic where necessary. Here’s our solution:

Messenger Singleton

We need a single object to keep track of our lists of listeners. When a script wants to listen to some classification of events, like “item” events, it has to call a function on our messenger. The messenger then keeps track of which scripts should recieve messages for which types of events. This looks like:

Messenger.instance.Listen(“item”, this);

The actual collection of listeners is very basic. We use a Hashtable of ArrayLists. The Listen() function looks like:

/**
* Adds a listener for a particular type of message
*/

function Listen(listenerType:String, go:GameObject)
{ 
   // if there’s no array for this tracking category, make a new one
   if(listeners[listenerType] == null)
   {
      listeners[listenerType] = new ArrayList();
   }
   
   var listener:ArrayList = listeners[listenerType];
   
   // only add to the array if it isn’t already being tracked
   if(!listener.Contains(go))
   {
      listener.Add(go);
   }
}

/**
* Register implicitly with a Component instead of GameObject
*/

function Listen(listenerType:String, component:Component)
{
   Listen(listenerType, component.gameObject);
}

We use a second function signature that accepts a Component to allow scripts to use this to register as a listener.

Message Class Structure

All messages are their own classes. To send a message you simply instantiate the class. In Minotaur China Shop, a broadcast of the item delivered message looks like:

new MessageItemDelivered(item, this);

In this particular case, the message contains the item we delivered to a custom (the first argument), and the customer to which it was delivered (the second argument). Let’s take a look at the actual MessageItemDelievered.js file:

#pragma strict

class MessageItemDelivered extends Message
{
   // the item that was collected
   var item:Item;

   // which customer we delievered it to
   var customer:BaseCustomer;
   
   function MessageItemDelivered(item:Item, customer:BaseCustomer)
   {
      this.item = item;
      this.customer = customer;
      
      super(“item”);
   }
}

We use our message objects to store multiple references and values. Many times we will compute additional values. For instance, for a raptor death event we may calculate the impact of the event as a scalar from 0..1 and store that in the message. If other scripts want to know the severity of the impact they can use this value, while leaving us the flexibility to tune it in a single location. This is one reason delegates wouldn’t serve us very well.

The super(“item”) line calls the constructor on the parent class, Message. This is where we stick our category identifier. You can think of the line as saying “our message is now ready, send out to anyone interested in the item category”.

Receiving Messages

You’ll notice we don’t actually define the function name the message is calling anywhere. We do this implicitly based on the class name. The naming standards we use are messages look like MessageItemDelivered and their corresponding function names look like _ItemDelivered(). The leading underscore lets us know at a glance that the function will be called by the messenger.

The messenger calls the function and sends it the instance of the message. This allows messages to contain as much data as we want, and also to precompute anything expensive once (at message composition instead of per-listener). A listening object might look like:

/**
* Score an item being delievered
*/

function _ItemDelivered(msg:MessageItemDelivered)
{
   // do something here
   Debug.Log(“customer purchase # “ + msg.customer.itemsPurchased);
}

Because our code editing environment includes JavaScript autocomplete, it’s very easy to write these functions and see which variables a message provides without having to look it up.

Project Organization

One of the nice side effects of using one class per message is visible organization. We keep all of our messages in one folder, so it’s very easy to see which messages are available in a project. This allows collaborators to get an idea of how much functionality is exposed by other systems. If we need to create a new message–the sound designer would like to hook into something else–it’s easy to go in and add new messages, which may prove useful for other functionality later.

Adding New Messages

Adding a new message is relatively painless. We must:

  • Create a new MessageSomething class (we copy/paste an existing message)
  • Specify the category in the super() call
  • Listeners register with the Messenger singleton
  • Listeners implement _Something(msg:MessageSomething) function

Performance

Our actual broadcast functionality uses Unity’s SendMessage() function. This isn’t nearly as fast as calling functions directly with your code, but in practice it’s fast enough. You wouldn’t want to be calling multiple messages every frame, but for game events–enemy spawned, enemy killed, powerup acquired–it’s performant enough to be practical.

In our current implementation we also let null values accumulate in the ArrayLists of listeners. This hasn’t caused any problems, because we flush the Messenger along with scene changes. If you are incredibly performance-conscious, or developing for the iPhone, you may want to skip a messaging system altogether. The point of a messaging system isn’t programming performance, but production performance; it’s a fast and efficient way to get things done.

Sample Project

It’s not as complicated as it sounds, actually. In practice we create new messages in just a few minutes, and we haven’t updated the actual Messenger logic in two projects. Here’s a sample project to get you started. If you make any improvements or changes to the project, please let us know by leaving a comment!

Download Sample Project

Posted in Scripts | Tagged , | 6 Comments

Multi-Touch Handling on Unity iPhone

There are a lot of questions on the Unity forums about how to handle multi-touch on iPhone. We’ve done a few experiments with multi-touch–although nothing in a game yet–but here’s one solution. This had a few goals:

  • Avoid iPhoneTouchPhase, which is unreliable (particularly with the remote)
  • Abstract touch tracking logic from game logic
  • Use a minimal amount of code


Multi-Touch Example (Unity iPhone) from Matthew Wegner on Vimeo.

This solution breaks the problem up into two classes, a Tracker and a Manager.  The core of the manager uses a Hashtable to tie tracker objects to their finger IDs.  The logic looks like:

  1. Reset all trackers to “clean” state
  2. Loop through all touch events
    1. If we don’t have a tracker for this finger ID, create one (and assume touch has started)
    2. If we already have a tracker object for this finger ID, tell it to update
    3. Mark tracker as dirty
  3. Any trackers that are still marked clean are assumed to be ended

There is some logic separation here, although it isn’t as clean as it could be.  The code that’s spawning/moving cubes is placed directly into the TouchTracker class.  In production we would strive to split this up, so the grunt work of tracking touches is totally separate from any game logic.  You could have your game logic get notifications of new/ended touches, or you could subclass TouchTracker and set up functions like OnTouchStarted, OnTouchEnded, and OnTouchUpdated.  Unity presents a lot of options for situations like this.

Enjoy the example, and comment if you make any changes or improvements.  This is far from perfect, but I think it’s a good direction to take.

Download Multi-Touch Sample Project

Posted in Sample Projects | Tagged , | 5 Comments

Let’s Get This Party Started!

Welcome, everybody, to the Blurst technology blog!  This will be our oulet for sharing code, tutorials, and lessons learned from the Flashbang game mines.  We’re doing this to give back to the tremendous Unity community and to help out our fellow game developers.

Unity History

Unity is the engine that powers all of the games you see on Blurst.  It’s a fantastic piece of software, and we’re very happy to have found it.  I first discovered Unity back in December 2006.  At the time, we were still using Virtools, but were unhappy with the evolution of the software and the direction of their company.  I was actively researching other engines when I came across a development contest Unity was sponsoring.  It was the perfect opportunity to give Unity a test drive.  I worked with Adam Mechtley (now one of our in-house artists) and created I Hate Clowns.  I was hooked.

It took awhile to come back to Unity full-time, since we still had internal Virtools projects and external contract work.  In September, 2007, we finally shifted gears to making our own games and began hiring to expand the team.  The games we created eventually laid the foundation and vision for Blurst.  Today we have 6 guys and work with Unity on a daily basis.  It’s fantastic.

Lessons Learned

We’ve been using Unity for awhile now.  Next month we’re scheduled to launch our fifth major Unity game, Minotaur China Shop, along with three iPhone titles made with their new iPhone publishing features.  Needless to say, we’ve learned a lot about Unity.  Our goal here is to share scripts, code snippets, and full-fledged tutorials to help other developers accelerate their learning curve.  We’ve solved quite a few problems; it doesn’t make sense for other people to re-invent the wheel.

Topics

Specifically, we’ve done quite a lot with:

  • Physics
  • Shaders
  • Web integration

But we’ll also be sharing more general solutions to organizational challenges any Unity developer will face (editor/library scripts, how we manage messages, etc).

Blog Format

We’ll be posting snippets as we find time.  We’ll probably be quieter as we approach our deadlines, and then very active as we have more time to collect our thoughts and organize code.  We actually ran a very similar blog years ago, in the Virtools days, where we posted experiments along with source code (DevLab is still online, if anyone is curious).

If you guys have questions on anything we post, please post questions in the comments!  If you’d like to contact us directly to suggest a topic or prod us on any particular subject, we can easily be reached at [email protected].

Posted in Blog News | 5 Comments