Enabling our artist to work faster

We are creating out first game using Unity 3D (Pro) and as I previously posted, tile based graphics.  The problem is that our artist does not have Unity 3D AND he is working just over 2000 miles away.  This means that each time he needs to see how a new tile looks in the game, he needs to upload the file to our shared folder, email us that there are new tiles, wait for us while we add it to the game, take a screenshot, and email it back.  Seems like it wouldn’t take that long, but since we left our previous jobs we have been trying to check our email less frequently because it can be a huge distraction.  Also, since he is 2 time zones away our work schedules don’t match up that well.

Our artist’s major hurdle is that the tiles he is creating look good at the size and resolution he is creating them at, but look completely different after importing it into the game.  Due to the distance and poor testing setup, it became obvious that the iterative process that game-art requires did not have the fast feedback that is a core part of the process.

As we slowly came to this realization, one of us came up with the idea to create a build that used replaceable art…. meaning that the build of the game would load specifically named textures into the scene at runtime.  This only took a few hours out of an afternoon (mainly because I hit a couple bugs), but it should help speed up how our artist can iterate on his work.

While putting the scripts together, I came across a few things that may help anyone that reads this.  The first, is that the www class in Unity makes it super simple to load textures from other locations.  Check out this bit of code:

IEnumerator LoadTexture(string i) { 
    m_location = m_baseDir + i + ".png"; 
    WWW someWww = new WWW(m_baseDir + i + ".png"); 
    yield return someWww; 
    loadedTextures.Add(someWww.texture);
    loadedTextures[loadedTextures.Count - 1].wrapMode=TextureWrapMode.Clamp;
    loadedTextures[loadedTextures.Count - 1].Apply(); 
}

That’s all the import part of the script ended up being… it was simple and relatively painless.  A problem that I ran into was that I attempted to change the wrapMode on the someWww.texture prior to saving it to my loadedTexture list.  WWW.Texture is read only so that didn’t work and I don’t recommend trying it and adding other code-bandaids to try to cover it up, my attempt at unknowingly doing that wasted at least an hour.

Mesh Creator

I came across the Mesh Creator project for Unity a while back while I was trying to create a game that my niece designed (Rainbow Unicorn…. no ponycorn’s here).  Scanning in marker drawings, inserting a transparent background, and then creating custom meshed objects was super simple.  To create the meshes in Unity, you drag in the assets (downloadable from the link) into your project, add a script to an empty game object, give it a texture, specify what type of mesh you want, and hit go.

I liked it so much that I used it again when making a second game that my niece designed, a Christmas-based game that currently resides in the same iOS app as Rainbow Unicorn.  I made a few improvements along the way to the Mesh Creator script, but didn’t really keep track of what I had changed.  I eventually contacted the creator of the Mesh Creator, Jonathan Cecil, and offered to share my improvements with the project…. weeks later I still need to learn how to use Git so I can actually share.   :P

A random Mu Studios game appears

We are using 2D tiles to create the environment and characters, think Planet Cute pixel dimensions but different art, for our first major development project.  Kevin was able to get a basic framework together quickly based on work he had done in earlier prototyping.  Once we saw things moving across the screen it was great, then we noticed the frame rates were…not good, especially if we hoped to submit to the AppStore at some point in the future.  We suspected that the problem was each 101×171 texture in the scene had at least some amount of transparency.

After my worlds collided and I told Kevin about the Mesh Creator script I had been working with, I started to plan and make some changes so it could speed up the development process.  I saw the following problems and potential solutions as ways to keep it simple for us and our artist:

  1. The Mesh Creator script requires that you have specific folders already created and saves the resulting meshes and materials in those locations.  We already have a folder structure that we use and are used to, so I wanted to be able to pass the script a few strings on where to place things.
  2. The script only handles one texture at a time.  This would have been a huge bottleneck as well unless I did something about it.  Working on previous games and prototypes had shown us that the art, just like the code, is not ‘done’ once the initial version has been created.
  3. The script would create game objects in the currently open scene.  I didn’t feel like creating new prefabs for every gameObject that was created…. so I knew that the scripts should create prefabs in a user specified location as well.

Luckily I had worked through some of Jonathan’s code previously while working on the Rainbow Unicorn games, but there was still quite a bit of catch up.  I was unfamiliar with some of the techniques used but was able to code through them without ruining anything.

After working through quite a few Unity crashes (it’s really picky when you are working with saving things via the Editor classes), I had completed the aforementioned tasks and was able to convert folders full of textures into separate folders with meshes and materials.  It was great, but I quickly discovered that we were still seeing poor performance due to transparencies AND the Planet Cute characters were missing large chunks of their torso.  After some further investigation I found two more problems:

  1. The Mesh Creator script will create any parts of the converted mesh that you want, but if you want just the front face of a mesh it bypasses the conversion portion and creates a simple 2-triangle rectangular mesh.  I hadn’t noticed this with the Rainbow Unicorn games because those games required extruded meshes to simplify how I was handling collisions.  The current Mu game only needs the front mesh to work correctly.
  2. The Mesh Creator script only checks to see if each pixel has an alpha value equal to 1.  The Planet Cute images had alpha values that varied slightly and this was why part of the characters’ bodies were being lopped off.  The initial images we had from our artist also had varying alpha values and resulted in completely unusable meshes.

I decided to tackle the 2-tri mesh issue first.  After attempting to modify his routines for each case, I scrapped it all and started over by copying his main routine and cutting out everything I didn’t need.  Doing so meant that I left the redundancy in the code, but it is structured similarly to the other mesh cases and it works well. The only thing that I found annoying in this modification was that it uses ArrayLists instead of the much friendlier List.

Then came the alpha values in the SimpleSurfaceEdge script.  This was my second attempt at it… I had previously attempted to convert over to a user specified alphaCutoff value, but it did not go well.   I swapped out the many == and != comparisons that were in the code for >= and <.  Not too difficult.  It would run perfectly for images that were alpha binary (1 or 0), but it would still cause Unity to either crash or stop responding completely for other values.

After quite some time (largely due to restarting Unity every time that it failed….. ya, lots of Unity-fail in this process), I tracked the problem down to the script’s MakeOutsideEdge function.  What this function did is collapse collinear lines into a single line and make a complete edge around each ‘island’ of alpha’d-in values.  These edges would then be sent to the triangulation routine which would mesh each ‘island’.  As it always seems to be, a ‘while’ loop was causing the repeated hangs and crashes.  I looked into the issue further and found that the routine wasn’t adding subsequent lines to islands of alpha’d values because it had an incomplete, and disconnected, set of lines.  After a few hours of frustrating debugging, I described the problem to Kevin and asked him to take a look.

Kevin’s first question: Are you sure there isn’t a break or continue statement somewhere?

Me: There isn’t one, I can check again but I’ve been staring at it and I haven’t seen one.

Kevin: Looks like there is a continue statement right up top.

Me:  :|

It took about 3 seconds to fix the problem.  The fix was to add similar logic that I had applied to the == and != checks to the ‘continue’ statement.  It works great now and hopefully adds value to the Mesh Creator project.  Once I get the chance to clean up the code a little more I will figure out Git and add it to the project.

Prototyping New Game Ideas

As we’ve hosted weekly game jams and helped organize the Global Game Jam in Madison, we’re often asked how people can start prototyping games. And we tell them:

Just do it.

Easy, right? Anyone can prototype a game. Don’t know how to program? Great! Make the prototype using physical materials or work with someone who can program. To be clear, we’re talking about prototyping gameplay––the rules that make up the game and some way to represent that state. Adding art, music, and sound effects frame the game and suggest an interpretation of the rules, but the point of a gameplay prototype is to test out the rule system.

Physical prototypes are a fast, inexpensive, and easy way to try game ideas. You really only need two things other than the idea: Something to write on and something to write with.

That’s it. Paper and pencil. 3×5 cards and a pen. Sticky notes and crayons.

These tools let you record the rules to the game and sketch the current state ranging from tick marks to a game board to content cards. If you’re planning on prototyping lots of games, then you might want to obtain more tools for convenience. In our physical game jams, most of the games use some of the following:

  • Dice. Six-sided dice are common and work great; polyhedral dice offer more control over the results.
  • Playing cards. Standard 52-card decks are most popular, with Uno cards coming in second.
  • Figurines. Buckets of plastic animals and insects are fun and complement the tokens found in other games lying around such as chess.
  • Tokens. Poker chips, aquarium stones, or Go stones all work perfectly.

The above combined with standard office supplies have supported most games made in our jams, but if you’re looking for even more suggestions check out Raph Koster’s suggested equipment.

Digital prototypes are also an option if you or a partner are comfortable programming. Simple shapes like cubes or squares are a fast way to try interactions; textures and audio can further enhance the framing and emotional impact of the game if they can be added quickly.

Luckily, there are some high-quality tools that can help. Dan Cook’s Planet Cute and Small World tiles are two collections of graphics that can work with many game styles. For audio, sfxr and its variants for OS X and ActionScript are the fastest, most flexible tool to generate sound effects that we’ve used. And the Netlabels collection has genre-ranging music, many with a permissive license.

Actually making the prototype is the fun, and hard, part. The goal for an initial prototype should be to showcase the gameplay; this can be done by describing the rules in sufficient detail so that someone else could play the game. But what if another player doesn’t understand something? Easy––just make something up and change the rules.

One other tip is to have a fixed time limit for developing the prototype. In both short 1-hour prototypes and longer 1-week prototypes, most of the work seems to happen in the last part of the alloted time; without a deadline, it’s easy to get caught up in abstract generalities instead of bringing the gameplay down into something concrete and playable.

Happy prototyping!

Other great sources of prototyping tips: