Entries in how to (2)

Wednesday
Oct132010

How to use Illustrator, SVG, TouchXML and XPath for simple level design, meshes and other game data

In the run up to implementing some relatively complicated mesh management (including collision detection, triggers and game mechnics) for our main title in development (Dead West) we wanted to try out a few methods in our component architecture-based framework. There'll be posts on this later - suffice to say component-based development is kicking the ass of the bloated-and-object-oriented alternatives.

Our entry in the Ludum Dare October Challenge, Ludum Racer (soon to likely be called Dwarf Derby) was the perfect platform for this - it's a simple top-down racer with relatively basic physics and flat collision data. Most importantly, it's based on the same component architecture that Dead West is based on.

So, that's something of a round-about away of getting to the point of this post -- we wanted to try using Illustrator as a level/track design tool. Whilst we could've easily used Vertex Helper or similar for the Dwarf Derby project, Dead West has a complicated, layered set of co-ordinate-based game data (that Illustrator is well suited to managing).

The plan (and thus far successful execution) was this:

  1. Create nav mesh (just triangles for the purpose of this) in Adobe Illustrator
  2. Export from Illustrator to SVG
  3. Load that SVG in-game using TouchXML
  4. Build whatever data structures we need in memory by querying the XML/SVG document with XPath statements

This required some specific methods and tweaks, so I've brought those together below in a deliberately basic how-to. You'll need to embelish this with your own data and outputs, but it should provide a reasonably solid process to build upon.

Illustrator - setting up layers and creating shapes

Setup a couple of layers - you'll likely want a background reference layer upon which you'll draw the require geometery.

In the example above, we've got a "reference art" layer, that contains a flattened version (from a Photoshop original) version of the level art and a "triangles" layer, that contains all the geometry we want to use.

It's important that you place the shapes that generate your in-game data on dedicated layers. When we get to the SVG stage you'll see why.

Create your polygons (we're using triangles here, but any polygon would work in effectively the same way) using the line tool. With the tool selected:

  • Click and drag to make the first edge (then release the mouse)
  • Hover the mouse of the end point of that edge so you see "anchor" appear
  • Click and drag the second edge (then release)
  • Connect the triangle by clicking from the end anchor of the second edge to the start anchor of the first edge

So far we just have a collection of edges, and as you draw out more polygons a direct export to SVG will result in a confusing mess of unconnected co-ordinates.

In order to distinguish the polygons, we must group their edges - select the 3 (or however many if you're not using triangles) edges and then hit CMD+G (or right click, Group).

Exporting to SVG

In Illustrator, use save-as and select "SVG (svg)" - not "SVG Compressed".

In the save options dialog for SVG, check you're using v1.1 and switch image location to "Link" - unfortunately you have to do this every time.

If you take a look at the SVG document, you'll see why we grouped the edges of our polygons, and why we collected all relevant shapes on a single layer -- most everything useful in SVG is a "g" element. Later using TouchXML and some XPath queries, we can use this structure to get at exactly what we need.

Loading the SVG in your iOS project

You need to get TouchXML running in your project first - I'd recommend this excellent TouchXML installation guide at foobarpig.com. Note that you'll need to download TouchXML itself from github, not the old Google code location.

Test you can compile once TouchXML's included in your project, then add an #import "TouchXML.h" to the relevant class and load up your XML -- in the example below we've a simple method that loads an SVG file, sets up the SVG namespace and executes a test query (specifically populates an NSArray with all of the triangles from our "triangles" layer).

At this point it's over to you - we'll be stepping over that array and building an in-memory array of our geometry for some simple collision detection. 

A couple of important points to note:

  • Illustrator's origin is top-left, so you need to transpose any coordinates accordingly.
  • If you are just wanting the polygon nodes, then you only need to pay attention to the x1 and y1 attributes (see SVG sample above) as the x2 and y2 coordinates of the first edge will be the same as the x1 and y1 of the second edge.

A couple of less important but otherwise useful points:

  • There's nothing stopping you from pre processing the SVG (XSLT would be a great way to do this), or to transpose it to another data format (for Box2d for example).
  • You can easily add additional data (particularly for debugging) to you data by simply adding Illustrator text elements to the polygon groups. They will get output into the SVG in "text" elements, which would be ignored when querying for "g" elements with the XPath above.
  • XSLT and XPath are wonderful tools if you're working with XML a lot - I can thoroughly recommend Doug Tidwell's XSLT book if you want to learn more - I've had a copy beside my desk for longer than I care to remember. 

Update: TouchXML is now at https://github.com/TouchCode/TouchXML

Wednesday
Oct062010

Just add the Secret Sauce: a tried and tested recipe for a finished game

There is a very significant difference between a game mechanic (or collection thereof) and a finished game. It's not the quality of the game mechanic, or the way it plays, or the polish you apply to it. It's all the other stuff you just don't care about when you're prototyping or concentrating on The Next Great Idea.

As dull as it may feel in comparison, finishing a game makes a world of difference to the "game" play itself. Take, use and implement just one of the items on this list and then tell me your game isn't better off because of it. Seriously, the first time time I added a pause feature to a prototype I actually thought to myself, "Wow, it's like I made a real game!"

So - checklist, design input, verification or otherwise - if you want to make sure your game is finished, you need this list. I'm assuming the production of the Secret Sauce is under control.

Method

 

Prepare each of the ingredients below, as soon as you possibly can. This recipe's all mise.

 

Ingredients

1. Pause

Simple - a button that when pressed pauses the game, wth a corresponding "resume" button. Ideally:

  • It should pause immediately.
  • The resume should resume gameplay immediately (expect for situations where it's awkward for the player to reconfigure their posture between the press of the resume button and normal gameplay - e.g. a console racer that uses the start button for pause/resume and a face button for gas).
  • It should be located as per the norms of the platform (iPhone - in a corner; Xbox 360 - start button).
  • Resume should be triggered by the same interaction (press start to resume, tap same corner etc).
  • Audio and sound effects should pause immediately (no ambient noise or background music in pause screens please).
  • Unless it provides an unwanted advantage, let the player see the frozen game screen in the background of the pause screen

2. Menus

Do this early. Avoid hacks and workarounds for accessing normally menu-driven features. It's easy to sketch out a layout of your menus and implement the navigation between them early on. Ideally:

  • Menus should be immediately responsive to user interaction and load quickly (see almost any DVD or Blu-ray for an example of how not to do this).
  • Menus should be easy and intuitive to use (that obscure setting might be quirky the first time, but it just gets irritating).

3. Save and load

Yes, this is hard. But liklihood is that you're going to need it. Get it in there early. Ideally:

  • Saves should happen when you expect them to (Bungie's insistence on making the Halo player actually select "Save" despite having passed "checkpoints" since the last save is illogical and gets me every time -- it's still doing it in Reach).
  • Saving should be quick - please don't make save game "names" mandatory on a console device, for example.
  • It should be easy for the player to understand what the consequences of loading and saving are (i.e. do I lose current progress, can I resume from an earlier save etc). If Quantic Dream can do it for Heavy Rain, you can.
  • There should be support for multiple save profiles. Some platforms provide for this briliantly (360). Some do not (I'm looking at you Steve). Worst case, Nintendo's model for most Mario games works pretty well.

4. Reset / restart

Unless you're specifically wanting to prevent it as part of the game's design, make it easy for the player to reset/restart since the last significant juncture (level, checkpoint, whatever). Ideally:

  • Resets should be independent of the save/load feature - some players will want to reset a level regardless of where they loaded it from.

5. Platform-expected norms -- i.e. iOS resume / multitasking

This does apply to other platforms - but the iOS 4.0-introduced multi tasking has reinforced players' expectations around app switching and resume. If you've done (3.) this shouldn't be a problem.

6. Sound effects

I deliberated including music and art on this list -- but to be honest it's difficult to argue that they are really required to make a game a "game" as such. SFX are a different matter however: they provide one of the two primary/common sensory feedback mechanisms (visual being the other). Ideally:

  • SFX should be optional - in most cases it should be possible to play the game without any SFX.
  • SFX should enhance the experience, not distract from it.
  • SFX should provide feedback to the player -- on a touch-screen device, for example, they help you compensate for the lack of tactile feedback on button/screen presses.

7. A title

This is all I'll say about marketing here -- and I'm not really including it for that reason, it just it normally gets lumped in "marketing". Your game needs a title. It doesn't matter what you call it -- you can change it later. You'll be amazed by how much easier it is to talk about your game when it has a name.

8. An indication of progress

The player has to understand what they have accomplished by playing the game. This is better explained by a list of what progress might look like:

  • High sores
  • Accessing a new level
  • Unlocking an item
  • Being rewarded with an achievement

9. Instructions and help

Think about a player picking this up for the first time - what do they need to know? Ideally:

  • Controls should leverage the expectations of platform (left stick move; right stick look etc).
  • Objectives should be clear when they need to be (it's okay if you want the player to figure this out -- but that has to be a core part of your game's design)
  • There should be an easy fallback for players -- if they don't know what do where is the first place they're going to start looking? That's where you should put the help and instructions.
  • Dynamic help is useful but it can get tiresome -- detect abnormal use (like the player hasn't jumped yet) and gracefully display non-intrusive instructions ("press A to jump")
  • If you provide a structured training environment (whether this is a couple of dialogs or a training mode) make sure you clearly indicate length and relative progress.

10. The Secret Sauce

You did this already, right?