MVVM for Game Tools

The MVVM (Model-View-ViewModel) software pattern is a very powerful architecture that can benefit game tool development, particularly in the area of usability. MVVM separates the UI from the underlying data through a kind of interface class, the view model. The view model handles all the manipulation in the model (the data), and serves the data to the view (the UI) in a way that the view can understand. Because of the added view model layer, the view can be more easily written with the end-user in mind, instead of in a way that best fits the data.

You would think that adding this middle layer would complicate the development process for the programmer, leading to a longer development time, but in fact, it allows the interface for the tool and the complex interactions behind the tool to be developed in parallel by the most appropriate persons. Splitting the development process in two parts, between an engineer and a designer, allows the engineer to focus on the hard programming tasks while the design expert works out the hard usability and design tasks. The two come together within the glue of the view model. This takes the time-consuming task of iterating on the UI with the feedback of the end-users off the shoulders of the programmer, and puts it onto someone in a role closer to that of the end-users, themselves.

Facilitating this relationship between tool designer and software engineer requires development tools that can bring these two worlds together. Fortunately, the most common framework for developing MVVM-based applications, WPF, has the tools to do so. WPF is a .NET UI library and a replacement for the older WinForms library. It uses a a declarative language called XAML, which is based on XML. Because of its declarative nature, XAML can be easily created with a graphical editor such as Expression Blend, which is well suited to designers, and works almost seamlessly with Visual Studio.

MVVM allows programmers and designers to come together in a way that they never have before, allowing them to shorten development time and increase tool quality by putting each task into the hands of the person best suited to it. Leveraging this power will give game developers the ability to create better interfaces for editing game data, and improve the development process overall.

Using XML Schema for Tools

XML is the de facto standard for game data, at least for intermediate data. Just about every programming language commonly in use has robust libraries for reading, writing and manipulating XML data. There are also some interesting general purpose tools for XML that not many people know very well such as XSLT (which I’ve discussed previously) and XML schema.
XML schema is most often associated with error checking (AKA validation), and that is a very powerful feature of schema. XML schema acts as a data definition language for well-formed XML data, so, once your schema is defined, you can test your XML file against it, to make sure that thew data follows the definition. This is particularly useful in situations where the data is potentially hand edited (a big no-no), corruption of data can occur, or where the definition of the data is in flux.
In the case where data definition is changing while the data is being worked on (we’ve all been there), you could use a versioning scheme that included versioned schema files to automatically fix your data, removing data that was old, and adding new data with default values defined in the schema.
And that’s not all.
The second and possibly more interesting use for schema is to add metadata to types using the annotation field using the appinfo element. The appinfo can contain any well formed XML and can be read directly by your application. This can be useful in customizing your editor to display unique controls for each data element being edited. For instance, you might have something like this:

<xs:schema xmlns:xs="http://www.roboticarmsoftware.com">
<xs:complexType name ="Unit" abstract="false">
  <xs:annotation>
    <xs:appinfo>
      <attribute name="Name" editor="TextField"/>
      <attribute name="Type" editor="EnumList" values="Infantry,Artillery,Hovercraft"/>
      <attribute name="HP" editor="Slider" range="1,100"/>
    </xs:appinfo>
  </xs:annotation>
  <xs:complexContent>
    <xs:attribute name="Name" type="xs:string" default="None"/>
    <xs:attribute name="Type" type="UnitType" default="Infantry"/>
    <xs:attribute name="HP" type="xs:integer" default="0"/>
  </xs:complexContent>
 </xs:complexType>
</xs:schema>

In our code, we’d read the appinfo and initialize the various controls for each property of the Unit type as defined above, that way, instead of just showing generic property editing controls, we can truly customize it to fit the data being edited. This is just a simple example, but you can easily come up with much more interesting (and hopefully useful) uses of the concept. You can find more detailed info on the W3Schools and MSDN websites.

Reason 4 of 6 – Complicating the Interface

This ongoing series delves more deeply into each of the “six reasons your game development tools suck” as argued in my very first post.

A lot of clutter in a tool’s user interface can be very confusing. When a user needs to scan the toolbar for a specific button to do something very routine, that’s time wasted. Going about this search my result in a context switch that causes the user to momentarily loose track of what he was doing beforehand, causing a further loss in productivity. Minimizing these effects should be considered when designing a tool’s interface and there are at least two environments where this interface bloat tends to occur.

The first is the tool built on top of another tool. Building a tool on top of a 3D package, like Max or Maya, for instance, leads massive clutter. The interface itself is already complex, and adding to it just creates more of a problem.

To get around this issue in Max or Maya you can edit a few scripts to remove some of the standard interface items that users of your tool will never use. If you’re creating tools on top of other packages, there may be customization options to remove elements there, as well.

The second case is the uber-tool environment, in which all tools (outside of commercial packages) are built inside the same interface. Creating UI and AI in the same interface may not make the most sense, after all.

You can tackle the uber-tool issue in several ways. Try creating custom views that specify which tools are available for each user group. This is especially easy if the tools are all built on top of a plug-in architecture — Simply install the correct set of plug-ins for each user. This also has the benefit of less memory overhead, and possibly a quicker load time. On the other hand, if it’s important for your organization to have a consistent interface for every user for the sake of collaboration, try creating different modes for each interface that are easy to move in and out of.

In general, you should probably only add the most commonly used items to a toolbar, and keep everything else just in the menu. This will reduce clutter and make it easy for users to do what they need to do quickly most of the time. Allowing more advanced users to customize the interface to their personal taste is also a good idea, as they’ll have a better idea of what is easiest for themselves, keeping the default interface as simple as possible.

Implementing Undo

One of the most basic of usability features, undo/redo is also fairly straightforward to implement.  Most engineers will tell you that undo functionality needs to be planned for from the beginning of a project.  So why is it still just an afterthought for most game development tools?  We recently had to implement an undo solution for a client in a design tool.  This is a general implementation similar to those I’ve seen at other companies.  I’m sharing it with you here so you can plan for it when you sit down to design your next tool.

For undo to work, we need an object to encapsulate the functionality of executing an action, along with the undoing of the action We also need to support redoing the action, which is a variation of the initial execution.  For those who like design patterns, this functionality fits nicely in the “command” (a.k.a. “action”) pattern.  The execute, undo, and redo are all functions that need be added to the command object to support the functionality we need, along with a specific constructor.

The constructor is responsible for storing all of the necessary data within the command class to be used later on by our execute, undo and redo functions.  We simply copy values passed in to the constructor to member variables.

The execute function does everything that would have been done had the code not been moved into an undo-able  command.  This fact makes it relatively easy (but tedious) to implement undo after much of the tool is written, or to move functionality that didn’t support undo into the undo system.

Some commands need to perform multiple actions at once.  For instance, we may need to overwrite data that existed before.  In this case, we perform two undo-able actions at once, the deletion of the old data and the creation of the new data.  So, we pass in a list of pointers to the command base class.  This list will contain this action and any other commands that need to be executed along with this one.  We’ll create and execute those actions within the execute function.  The current action is added to the list last, for consistent ordering.  The importance of this will come later.

The undo function is a simple matter of reverse engineering ourselves back to the previous state using the data passed to the constructor.  For everything the execute did, we basically do the opposite, with the exception of the multiple command functionality, which is called from code outside of this class, from the undo stack, itself.

Redo basically does everything the initial execute did, but like undo, we skip the  multiple command functionality.  We call the execute function with a null list of commands (we could use a boolean parameter) to signify we should skip the execution of the multiple command code.

In order to have more than one level of undo, we need to store these actions on a stack.  In our case, we’ll actually use two stacks (for undo and redo), encapsulated in a command stack class.  Similar to the commands themselves, there are three basic functions in our command stack — execute, undo, and redo.

A command is passed to the execute function of the command stack.  The execute function creates the list that is passed to the command’s execute function, calls that function, and pushes the resulting list (which has been populated by the command’s execute function with one or more actions) onto the undo stack.  The redo stack is then cleared, since there are no commands to redo after a brand new command has been executed.

Undo simply pops a command list from the undo stack, and executes undo on all items in the list in reverse order.  Items were added to the list in the order that they would normally be executed.  In our example above where a new item overwrote an existing one, the deletion of the existing item was first in this list. We want to restore the old item after deleting the new one.  Finally, the command list is pushed onto the redo stack.

Redo pops a command list from the redo stack, executes redo on all items in the list (beginning to end, this time), and pushes the list onto the undo stack.

Once this is ready, you simply need to create the commands where appropriate, and call execute on the command stack, with the command as parameter.  Once the commands are added to the stack, you can simply call undo and redo on the command stack from a key command or menu item.

This simple implementation will give you unlimited levels of undo functionality.  The only limitation here is that some commands can use a lot of memory.  That’s generally not a problem when talking about tools being run on PCs with virtually unlimited resources, but it can be a concern.  How the commands, themselves, are implemented will affect this, so that takes careful consideration.  A simple fix for this would be to represent the undo and redo stacks as circular buffers with fixed sizes.  Presumably, you can find a reasonable number of undo levels for your application.

Reason 3 of 6 – Leveraging the Wrong Technology

This ongoing series delves more deeply into each of the “six reasons your game development tools suck” as argued in my very first post.

At one company I worked for, we wrote our level design tool, as well as a cinematic tool on top of Maya.  The idea was that Maya already had an interface for drawing 3D objects and moving them around in the scene using well known controls.  Unfortunately, the design staff, many of which never used Maya, didn’t really get any benefit from a tool that was well understood by 3D artists. 

With the number of interface elements visible in Maya, to a designer or even a programmer, it can seem overly complex and cluttered.  Add to that the fact that we added additional interface for the design tool itself, and you’ve got something completely unwieldy for the Maya novice.

In addition, as levels became more complex, load times in the tool became longer and longer, and the responsiveness when doing the simplest operations became slower and slower.  In order for the tool to be usable, everything except what you were interacting with had to be turned off, the management of which became another task that slowed down the users.  One programmer on the game team actually refused to ever open the tool, so when testing of a feature or fixing a design bug was required, he’d get someone else to do it for him.

I’ve been in other situations where building a level design tool inside of an art package was a consideration.  In those cases, it’s often recommended as a stop-gap solution.  The argument goes that getting something up and running in an interface that is well known and already supports certain features will be quicker than writing the tool from scratch.  Saving time is usually the best policy, but thinking that time will actually be saved by this method is a fallacy, and stop-gap solutions often become permanent ones.

Time saved on initial development of a 3D viewport with picking and move controls is wasted figuring out how to cram every new feature required by the design team into a limited interface.  The designers’ time is wasted navigating an overly complex tool with buttons and menu options they will never use, nor understand. 

In this situation, we eventually learned our lesson.  The next level design tool was a stand-alone program, but that was for the next project…

Reason 2 of 6 – The System Model of Design

This ongoing series delves more deeply into each of the “six reasons your game development tools suck” as argued in my very first post.

Two of the most important concepts in software engineering are abstraction and modularity.  Abstraction allows us to categorize problems and write general code to handle all problems within a group, while modularity allows us to combine disparate abstract components to create unique solutions for a particular problem.  These two concepts give us the ability to write elegant, yet powerful systems that can solve many problems at once.

These systems often rely heavily on data, which is the glue that holds the abstract techniques together.  Data is used to configure which components plug into one another and how they behave. 

As programmers, it makes a lot of sense to us to expose the raw data in the tool to the people responsible for making something useful with it.  After all, not only is this the easiest implementation, it’s also difficult to see another implementation that would not constrict the end user’s ability to get the full benefit of the system’s power.

If the tool was in our own hands, or even in the hands of another programmer, this would all be true.  Unfortunately, this is usually not the case.  The end users have to figure our very clever system out for themselves, often with no knowledge of our intention, the underlying data structures, or even basic software engineering or programming concepts.

Instead of empowering the end users with our uber-system that can handle any problem, we’ve saddled them with a system so intricate and burdensome, that they can’t wrap their minds around it, let alone do anything useful with it.

Training can help to a degree, but that turns into one-on-one training with every user for any one person to understand.  Documentation also helps, but often ignored, in reading as well as in writing/updating.  Usually, one person ends up being the expert that everyone relies on, but when only one person can use a tool, you know that it’s doomed to failure.

The answer is simple, yet hard to swallow.  The tool interface can not be designed around the data structures used by the underlying system.  The tool must be designed around the users, and the very specific things they want to do with it. 

That will probably handle about 90% of the problems the system was designed to solve.  Most users will get along happily with that, and even find their own clever ways of getting some of the additional 10%.  They’ll be much happier with a tool that is easy to use than one that is all-powerful.

XSLT as a Development Tool

Some time ago, I decided to write a small C# “wizard” tool for enemy encounters and other level design patterns.  The idea was to create pattern types, that designers could define with a small amount of data (different for each type of pattern) that could be exported into a much more complex xml format that could describe when to spawn what enemies, what behaviors and properties to give them, etc. in order to make each instance of a pattern unique. 

The properties set by the designers were stored internally as an XML document, since XML in C# is incredibly easy to manipulate, and since the data would be different for each level design pattern.  It was easy enough to save out the raw XML data as it was stored internally, but the problem was how to transform this data into the format that would be read into the game. Enter XSLT.

C# has the functionality to transform data internally with an external XSLT file.  It’s easy enough to associate a XSLT file with a specific pattern, apply it at run time, and then simply write out the result.  At this point, it’s simply a matter of providing the designers with the data files necessary to generate their data.

The advantages here are great.  Putting the complex structure and syntax in an external file, and separating it from the designer’s view, allows them to concentrate on what’s  actually important.  The downside is that someone has to craft these XSLT files, which is a format that is a bit obtuse for someone used to functional languages.  Additionaly, XSLT has little to no debugging capability.

Now, more recently, I’ve had the challenge of writing an exporter from OpenOffice Calc, which also uses XSLT as filters for importing and exporting.  All OpenOffice documents are are stored as XML.  In fact, if you simply rename an .ODS file to a .ZIP file, you can explore the format, which is spread over several files inside the .ZIP, the most interesting of which is called content.xml.  This is the data that needs to be transformed in order to get the information out of OpenOffice into your own format.

What we wanted was a way to store properies of all enemies in a single table, so designers could tweak values easily.  The data then needed to be exported into a proprietary text format (not XML).  This is also relatively easy with XSLT, but as with anything, exporting from Calc with XSLT had its pitfalls.

It’s easy enough to access individual cells in a row in Calc.  Unfortunately, for some reason, they decided that if adjacent cells in a single row have the same value, it would only be stored in the first cell and an attribute on that cell would indicate the value repeats for n-number of cells.

With XSLT, there are no variables that can change their values, only constants within a single template (the XSLT equivalent of a function).  Consequently, there are no “for loops” in the traditional sense.  The way to get around this with XSLT is to use recursion.  In my script, I basically have every cell recursively calling the template on the next cell in the row, or on itself in the case of repeated cells, and track the cell heading (the first row of the table) separately.  Just thinking about it gives me nightmares.

At any rate, more and more data is being stored as XML, and consequently XSLT is probably here to stay.  It’s another tool that should be available in the game developer’s toolbox, but must be used with care.  To learn more, there are tons of resources on the web, but your best bet for a good introduction is the W3 schools site at http://www.w3schools.com/xsl/.

Building on the Cloud

Over the past few years, cloud computing has become the next big thing for enterprise software.  The ability to easily scale resources to meet the needs of the end users cheaply is very attractive.  Amazon, Sun, Google and now Mictrosoft (among others) are all offering cloud computing solutions.  I’ve recently been playing around with the AWS (Amazon Web Services) to see what you can do with this technology, and I can already see a few ways it could be applied to games.

Running games on the cloud is an obvious use of these resources.  Need a game server accessable from anywhere in the world?  Start one up on a virtual server.  The ability to build machine images (AMIs on Amazon), complete with your own software running on operating systems like Linux, OpenSolaris, or even Microsoft Windows Server gives you that possibility for pennies a day.

But, where cloud computing could really come in handy is in game development.  Imagine starting a build distributed across the cloud, in which thousands of virtual machines simultaneously start processing individual bits data.  You might see builds going from minutes or hours to just a few sconds.

And the cloud isn’t just for processing either.  Some companies offer services for managing data that would traditionally reside in a relational database, and as well as file storage services.  You could even use your own machine image running some flavor of SQL.  With that capability, why not store assets in the cloud?  An asset control vendor could use the software as service (SAS) model for asset control, supplying developers with web and client based views into an asset database on the cloud itself.

The big problem here is that we’re trading bandwidth for processing power and flexibility.  The build process may take a few seconds, but retrieving the results to local machines may eat up every bit of build-time savings and then some.  We may see overnight builds turn into overnight downloads, and that’s no savings at all. 

Bittorrent file serving (available on AWS) may be useful as a build distribution model, but with most users on a single network, it doesn’t seem likely to make a difference.  Limiting the download process to necessary files only is simply the flipside of building necessary files only, so may also offer little in the way of savings.  Doing a bit by bit comparrison of files built on the cloud, and downloading just the file differences, may be a way to reduce the download time, assuming there are chunks of data in a binary file that remain constant between builds.  Other optimiztions almost certainly exist.

All in all, it could be a big win, but until someone proves it, we can’t know for sure.

Reason 1 of 6 – Design As You Go

This ongoing series delves more deeply into each of the “six reasons your game development tools suck” as argued in my very first post.

Many game companies struggle with delivering tools quickly and cheaply.  Money is always an issue wherever you go.  After all, the bottom line is what keeps a company afloat and it’s employees employed.  No one wants their company to fail, to lose their jobs, or to lay off their workers.

Game companies are in an especially difficult position.  Attempting to balance a workforce spread over multiple disciplines — art, design, programming and production — is hard enough, but when you consider that those disciplines have their own specialties within each one, the task is even more difficult.

The obvious solution is to cut corners wherever possible, and that oftentimes falls squarely on the shoulders of  the tools team.  Why?  Because most game companies don’t make money selling tools.  Tools programmers serve in a support role, and therefore (in the minds of most game execs) are less valuable than those working directly on the games.

Tools teams very rarely get the full support of management, and game teams can’t be stalled waiting for tools to be completed.  The unfortunate sentiment among those in power is that there’s no time for tool design.  Get it done and get it done now.

There is no time for design, so the thinking seems to go, but what does that really mean?  Does that mean that the programmer implementing the tool charge blindly into development without thinking about how the tool needs to function?  Of course not. 

The programmer has a vague idea of what to do, and without ever writing it down or validating his thoughts with the end users in any formal way, begins to implement the design from his own mind.   He still thinks about it a great deal.  Perhaps 75% of his time is spent thinking and only 25% is spent typing.  There are probably still many  unanswered questions, but as the tool begins to take shape, some answers may start to become more obvious one by one.  The tool seems to practically design itself, but in reality, design is going on quite informally.

But wait!  What if one of those unanswered questions causes a serious problem?  What if the best answer to that question requires a rewrite of major portions of current code-base?   What if the other possible answers are so undesirable, that the rewrite actually appears to be the best option.  Because the design had been postponed until the code was in the process of being written, redesign is now very expensive.  Code that has been written will go to waste, and new effort must be exerted to replace it.

If the programmer takes this problem to a (non-technical) manager, concerned with cost and speed of developing the tool, the manager may come to the very justifiable conclusion that a rewrite is not the way to go.  Instead, just make a work-around for this one problem, in other words, a hack. 

As long as that’s the end of the story, then that’s probably okay.  Unfortunately, more issues may arise, with similar outcomes.  Also, once delivered, the end users will likely have feedback.  After all, without any formal design process, many of their needs/wants/concerns went unheard.  And now the real fun begins.

It’s already been established that the quickest solution is more desirable than better architecture and code, and so as feature requests are delivered to the programmer from the users, more and more workarounds are put into place to deliver a new tool quickly.  This leads to code that is difficult to maintain and potentially very buggy.

The end users are now saddled with a tool that does basically what they want but perhaps has stability or performance problems.  The difficulty  to fix those issues increases as time goes on as the code becomes more brittle and spaghetti-like.  Fixing one thing breaks something else, leading to a never-ending maintenance cycle that really makes no net improvement whatsoever.

Rethinking Asset Control

Many of the available source control solutions out there are great if you are a programmer.  Both Subversion and Perforce adequately handle the storing of assets, but neither is very friendly to creative types.  How often do “bad checkins” happen because some new and obscure file created on the user’s machine didn’t get added?  Or maybe the user didn’t get latest, merge the data, build the game and test it one last time before checking everything in. 

Team sizes are increasing.  So are the assets, themselves.  The more users stressing the system, the more fragile it becomes.

NxN had the right idea with Alienbrain but never really got anywhere due to serious technical issues with their back-end.   It’s been a few years since I used it last, so they may have fixed a lot of those problems.   Anyway, it also had some very nice features you don’t get in other source control solutions.  You could easily redesign the whole interface (it was mostly html and javascript as I recall), and they included a feature that was very art-centric.  Previews.

You could generate previews of assets and view them right in the Alienbrain interface.  It was a very slick feature and a selling point of the software.  Finally, a user could see a preview of a model or texture (and many other asset types) without doing a get and opening the files in Maya or Photoshop, etc.  That’s a real time-saver if you don’t remember the filename that was used for a specific asset.  You have the chance to browse all the assets of that type and find the one you want pretty easily.

Like I said, though, NxN had its share of troubles.  Still, I believe we can do better than the source control status-quo.  I imagine an asset database solution that integrates with every asset generating tool, as well as the build process, generates a preview for each asset (even if it’s a bitmap that says “Preview Not Available”), and is searchable by its meta-data, including tags, creator, last modified, and so on. 

The classic view of assets as a collection of files inside of folders, with users having to know exactly what files need to be checked in and out of source control when changes are made seems a little antiquated.  Instead of searching through folders ten layers deep, how about using a tag cloud to find assets instead?

I imagine being able to open a web-based interface, searching for an animated character from an old project and clicking a button to copy it to a new project, including all of it’s vertex, texture and animation data and using it as the starting point for a brand new character, or maybe just as a placeholder until a new character is created.  How many walk cycles does one studio need to recreate every time a new project is started, anyway?  Why not take something you have and modify it to fit a new character in a completely different game?

I really beieve that asset databases are the wave of the future for game development.  When the Xbox360 and PS3 came along, team sizes doubled, and assets got bigger and more complex.  What’ll happen next time there’s a hardware revolution?  We need to streamline the way we manage assets, or else, it’s going to bite us in the ass… even more.