« Posts by NickDarnell

Global Game Jam 2012 Wrap-Up

The 2012 Global Game Jam is over and it was another year of awesome games in the Raleigh-Durham – North Carolina area.  This week I wanted to put the spotlight on all the games lovingly crafted by our crack squad of jammers – especially mine, Low Power! :D

The Theme

theme

The Ouroboros – but no explanation was given.  We just showed the jammers the image and it was up to them to interprete it.

LOTR Body Snatching

Rock, Paper, Scissors with body snatching!
Avoid or possess enemies to stay alive and win.

Low Power

In order to survive Low Power you must consume yourself (like the Ouroboros) to survive.  You control a robot whose battery is constantly draining but there are valuable energy cores scattered throughout the level that will sustain your life.  There are all kinds of dangerous environmental hazards that unless you enable your sensors/abilities (lights, shield, ground sensor, microphone) you’ll never survive.  However enabling the different systems will drain your battery even faster!

Parasite

You are a Parasite that leeches off battle ships. Enemies will constantly come in formations to destroy the ship you are occupying. Using the possessed ship, you must defeat your enemies! However, as you leech your ship it slowly dies, you will constantly need to take control of and leech of another ship. With out a ship for protection you are helpless!

Planes on a Snake

A rift in spacetime has resulted in a large number of World War II era planes getting stuck on the world snake.  Join the frequent fliers club of Ouroboros Airlines, racking up points while taking advantage of the torus nature of your new environment.

Roller Snake: The Quest for Chili Dogs

Control “Hardy the Hoop Snake, Jr., III, IV, and V” in his quest to eat as many chili dogs as possible while winding through ‘Catastrophe Canyon’

Snake Run

You are the snake’s guardian, you must ensure that balance is maintained.  Let enough creatures be eaten by the snake to ensure he doesn’t starve, but not enough that he frenzies and destroys everything.  All the while outrunning him!

Global Game Jam 2012: Friday!

I’ve been spending a lot of time lately rebuilding the old Triangle Game Jam website. Now that it’s done I can get back to new articles. The new site is up at http://www.trianglegamejam.com.  It’s where we’ll be archiving all Raleigh/Durham/Chapel Hill – Global and Triangle game jams.  All the past years works that I could get my hands on are up there and worth taking a look at.  It’s amazing what people with a goal can create in a weekend.

In other news – The global game jam starts this Friday (January 27th).  You should signup and find a local jam site you can attend.  It’s totally worth a weekend of your time.

Creating Kinect Controls for Angry Birds

Before I begin let me give you a little background.  About a month ago we decided to try and create NUI (Natural User Interface) or Kinect controls for Angry Birds.  Partially as a learning experience but also as proof of concept that games like Angry Birds (ex. applications that lend themselves to touchscreen devices) can work in a gestural / depth camera environment better than has been demonstrated.  In the end we tried many different input methods that would be possible with a Kinect and I wanted to catalog that experience.

I’ll start with the worst input paradigm we tried go from there.

#5 The Faux Mouse

The Idea
First we just tried mapping the hands to the screen as if they were each a mouse or finger.  Each would control a hand like cursor and move it around the screen.  Clicks could either be performed by grasping the hands or pushing towards the screen.  The game would be played normally – except you’d click on everything using your hand.

The Reality
This input method was by far the worst.  Your hands are simply not mice, they get tired much faster and are not as dexterous.  Even with heavy filtering and snap-able buttons, the interaction is just too nuanced and motor skill intensive an operation to click on a button or object on the screen using your hands as mice.  The time it took us to play a level vs. someone playing it on the iPhone was an order of magnitude or longer a task.

When pushing towards the screen a lot of care had to be taken to deal with user drift.  When a user pushes towards the screen, they may in fact be pushing towards many possible locations.  They may drift towards the TV, or the camera if that’s their focus.  They may also consciously attempt to maintain a straight hand as they push forward.  No matter the case – a user will drift even off their intended target.

When we tried grasp detection using computer vision – again we saw drift.  When a user opens and closes their hand the volume of the hand is changed from the point of view of the camera.  The result ends up displacing the center of mass of the hand causing it to shift downward when the hand is closed.  There are solutions to this problem such as eliminating the fingers from the hand volume calculation but this is a difficult problem given the quality of the data.

In the end the drift issues prevented us from playing as well as we could with the real mouse or on the iPhone and since Angry Birds is both a game of quick victory and defeat as well as a game of precision.  Having both large problems with precision and game play progression speed – we ditched this idea.

#4 Voice

The Idea
This one is exactly what you might expect – firing the bird using your voice.  Either by saying “Fire!” or maybe… “Ca Cah!”.

The Reality
We really were not sure how this method would perform.  The voice portion was layered onto the mouse control system.  Essentially you would click on the slingshot – move your hand to aim and exclaim viciously to let loose the birds of war.  The hope was that it would alleviate the drift problems, which it did.  Without having to push your hand forward to fire the drift was eliminated from firing.

However there were other problems, there was delay in the speech recognition and often outright failure if you didn’t say the words just right.  We tried several tricks, like using multiple words to identify “Fire”.  One good way to generate that list is to take the top 10 words it mistakened someone saying fire for and add those to the dictionary as triggers for firing the bird.

Moving Away From Faux Mouse

After the failures with both #4 and #5 we went back to the drawing board.  We needed to get away from the mouse or touch device centered thinking.  The worlds are simply too different to treat it the same.  So we prototyped 3 other solutions that ended up all being better than the mouse style interface.

The ideas all stem from an understanding that when you go to port an application from a touch enabled world you need to think about 2 things primarily,

  • Context
  • Automation

Context – How can you reduce and scope the options to the user so that a broad array of options can be presented to the user – but with only a few usable at any given time with a small vocabulary of motions.

An example from Angry Birds is all the options the user can perform in the game:

  • Fire Bird
  • Activate Bird Special Attack
  • Restart
  • Pan
  • Zoom
  • Return to the Menu

We needed to find a way to contextualize these options when moving away from a mouse driven style interface.

Automation – Find the items in the application that everyone does without thinking about it and automate them.  If they aren’t relevant to game play find a way to make them irrelevant in a NUI application.

An example from Angry Birds is activating the slingshot.  You probably don’t think about it when playing the game but to fire a bird you must first place your finger on the slingshot before drawing back the bird to fire it.  While this is unbelievably trivial to the point of not thinking about it on an iPhone, it’s a huge pain in an environment where you have to get a virtual hand cursor over it, even more so if you then need to push forward to activate it.

So we needed to find a way to automate clicking the slingshot.  That way instead of clicking the slingshot explicitly it would be implicitly activated by performing some gesture to begin the act of firing a bird, that would be disconnected from the onscreen location of the hand relative to the slingshot on the screen.

#3 Arclight

The Idea
You would draw back the slingshot by bringing your hands together.  Then bring your hands apart and rotate them around your center of mass to change the firing angle on the slingshot.  Then once you’ve settled on the firing angle, bring your hands together fast to trigger the fire.

The Reality
The problem with this kind of activation of the slingshot was the drift when the hands come together.  This can be partially accounted for but it’s heuristically based and can be erroneous.  Additionally activating the bird’s special power was difficult.  You would have to choose a different kind of interaction to activate the special power which would complicate the process.

#2 Stretch and Snap

The Idea
This idea grew out of the Arclight firing system.  To attempt to solve the problem of drift, have the slingshot fire as soon as the arms reach a certain distance apart.

The Reality
With this firing system you still have the problem of determining how to activate the bird special power.  You also introduce a new problem – all birds are fired at maximum drawback.  You also need to make sure to provide the user with feedback so that they know how close the user is to the *snap*, some kind of progress firing bar.

#1 Axis Separated

The Idea
For this idea I separated the functions of the hands into distinct responsibilities.  Your left hand activates the slingshot by pushing forward (doesn’t matter where).  After a threshold is crossed the slingshot is activated, from then on an angle is calculated between the shoulder location and the left hand’s location relative to it, to produce the slingshot firing angle.  To fire the bird the right hand is pushed forward and pulled back, this sends the bird flying.  To activate the bird’s special power you again push the right hand forward.

The Reality
This method ended up working perfectly.  It doesn’t result in any drift when firing is activated. It is also easy to perform because all the motions can be performed with your arms down by your sides, reducing exhaustion in long game play sessions.

Lessons Learned

You hear it all the time but it is critically important to prototype ideas when it comes to creating Kinect controls.  They simply don’t work as well as you would like in reality as they do in your head. Here’s a demonstration video of the end result,

YouTube Preview Image

Kinect, Anthropometry and You

Anthropometry (Greek anthropos (άνθρωπος – "man") and metron (μέτρον – "measure") therefore "measurement of man") refers to the measurement of the human individual.

Ask any Kinect developer what the hardest problem is developing a game or application that uses the Kinect – or any other depth camera.  The answer you’ll get most often will be creating something that works well for 95% of target users.

This is something you have to consider for all your gestures, poses, and UI interaction.

  • Is this gesture too difficult for your average user?
  • Does this pose require too much flexibility?
  • Is this UI interaction comfortable and easy to perform?

One area that can benefit from anthropometry data is UI interaction.  When you think about UI interaction with Kinect you’ve got to picture it as a real world space (box, sphere, cylinder, other) located somewhere around the body that you’re mapping the hand position in that space to the 2D or 3D UI coordinate plane.

When determining the size and location of this real world space and how it maps user hand locations onto the UI coordinate system the largest question you need to consider is:

Where will they be most comfortable?

Generally speaking you want a space that minimizes upper arm movement – as that is much more strenuous compared to forearm movements.

However, since the 3d position we’re mapping into our 2d/3d UI coordinate system varies based upon user skeleton size we can’t choose a single set of real world dimensions that will work for everyone.  We’ll have to make educated guesses about the size and location of our real world UI coordinate frame based on size and location of the users bones.

So how does anthropometry fit in?

Because the skeleton you get from Kinect – and other SDKs can be unreliable in certain poses you often find yourself heavily filtering any kind of data you’re tracking about the user.  Especially things like the user’s arm length – which can vary dramatically over a session.

So one thing I prefer to do is use anthropometry tables to ensure a more consistent size and location and doesn’t fluctuate as much as the user’s skeleton.  Using anthropometry tables we can estimate the users arm length or hand size based on other bones in their body, bones that are more stable in your skeleton SDK of choice (Kinect, OpenNI, Iisu, Omek…etc).

You can also use anthropometry tables to estimate the size of body parts that the skeleton SDK you’re using doesn’t provide – such as the size of the users hand.

But where do you find that kind of anthropometry data?

Luckily such a resource has already been painstakingly cataloged for us by the FAA – The Human Factors Design Guide.  The HFDG was put together so that planes could be constructed so that almost anyone would fit and be able to operate anything from their seat.

The anthropometry data that’s valuable to us starts in chapter 14, page 791.  For example, these lovely tables from page 818 show the functional reach and the extended functional reach of men and women broken down by population percentiles.

hfdg_reach

Making Your Files Merge Friendly

Merging is a fact of life for most of us.  Eventually two users touch the same files and a conflict must be resolved.  For programmers merging is a daily activity, but what about the content creators?

If two artists touch the same level, have your tools programmers made enough of an effort to make merging possible and if possible as painless as can be?

Here’s a handy checklist,

1 – Use XML/JSON (or some other text based file format)

It’s slower, it’s bigger but it’s going to make merging possible.  If your level files are binary blobs merging without a custom tool just isn’t going to be possible.  Using XML or JSON are the simplest text based alternatives because there are already many libraries for reading and writing them.

2 – For XML – Give Each Attribute a Line

If you’re using XML, you should make sure to write out the files such that every element and every attribute receives its own line.  If you don’t do this it will make conflicts a lot more likely if two users touch the same object.

If you’re using JSON, having each attribute on its own line is the norm unless the library is attempting to keep the text compact.

Here’s a quick example, note that after separating the attributes the merge tool handles the conflict correctly while it fails to do so when they are on the same line.

nonewline
Figure 1 – Attributes all on the same line

newline
Figure 2 – Attributes on different lines

If you’re using .Net this can be achieved very easily by changing the default XmlWriterSettings with the NewLineOnAttribute property set to true.

C#
var settings = new XmlWriterSettings()
{
    NewLineOnAttributes = true
};
 
using (XmlWriter writer = XmlWriter.Create(filestream, settings))
{
    // Write out document...
}

3 – Maintain Order

Always write out the order of the data the same.  This one is pretty easy, the only real pitfall is to make sure your data structure and undo/redo system are working correctly.  For example, if you happen to store your objects in a list and someone removes and object at the front, but when it’s undone it’s inserted at the end of the list (Even if the UI doesn’t reflect this) this could affect your output order.

4 – Don’t Add New Objects At The End

When you go to save the entities don’t write them out in the order they were created.  This will definitely result in a merge conflict.  Because it ensures that if two users edit the file and both add an entity they’ll both show up in the same location and confuse the merge tool.

One thing you could do is to sort them based on a GUID that is stored as part of the objects data.  Sorting based on GUID ensures a lower probability of collisions occurring when two users both add objects.

Alternatively a sorting based on a string containing the machine name of the original creator of the object is another idea.  It would ensure every user touching the file would be inserting to their own section of the file instead of everyone inserting to the tail.