jump to navigation

Game 1 for 1GAM: Hello Hanoi! February 27, 2013

Posted by Andor Saga in 1GAM, Game Development, Objective-C.
add a comment

hello_hanoi

My first iPhone game is available for download on the App Store. I call it Hello Hanoi!. It’s my “Hello World” for iPhone game development via Towers of Hanoi. My motivation to code and released the game came from the 1GAM challenge. A year-long event that dares developers to release 1 game every month.

When planning the game, I wanted to keep the scope very tight. At the end of it, I wanted a polished, tightly scoped game over a feature-rich, unpolished game. I think I managed to achieve that, but for my next game, I’d like to try the opposite.

The Pixels

I had a difficult time getting a hold of artists, so I decided to just learn pixel art and make all the assets myself. To begin making the art, I tried a few applications: Gimp, Aseprite, and Pixen. Gimp had issues with leaving artifacts on the canvas. Aseprite had problems with cursor position and I felt the UI was awkward. Pixen kept crashing. It was a bit frustrating so I restarted and re-installed them all. I launched Pixen first, and it seemed to work, so I stuck with it.

The result of making all the art myself shifted the release date dramatically. I should have released at the end of January and it’s almost March. At the same time, I had a lot of fun learning pixel art and learning about art in general, such as attention to color, lighting, shadows, and mood.

One particular level was very tedious to create and I soon realized I could generate the art instead! So, I launched Processing and wrote a small sketch to create a series of city buildings. It doesn’t look as good compared to what I could have done by hand, but it was a lot faster to create with this method.

The Code

The code was straightforward, but I did have to learn a few iOS specifics. How do I write a plist to storage? How do I use the new storyboards? Like the art, it was at times frustrating, but in the end it was worth it.

One mistake I did make was over-generalizing. I had the idea that it would be neat to support n number of discs. I wrote all the code to handle the rendering and positioning of the discs, but then realized it didn’t fit into the game. Players would get bored before they reached that many discs, and the necessary horizontal scaling of the disc assets would break the art style. So, I ended up taking the code out. Next time, I’ll try to catch myself over-generalizing.

I had a fun time making my first 1GAM game and I look forward to trying something new for the next one!

Advertisements

Automating my WorkFlow with TexturePacker’s Command Line Options February 17, 2013

Posted by Andor Saga in BNOTIONS, Game Development, Shell Scripting, TexturePacker.
add a comment

At work I use TexturePacker quite a bit to generate sprite sheets for UIToolkit from within Unity. Each sprite sheet ends up corresponding with a layer in UIToolkit, so the sheets we use are typically named “layer0.png”, “layer02x.png”, “layer0.txt”, “layer02x.txt”, where the .txt files are the metadata files.

During development, I’ll be interrupted every now and then with new and improved assets that need to pushed up into the Unity application. Once I have received the asset, I must take a series of steps to actually use that asset in Unity.

I open the TexturePacker .TPS file and drag the asset in. The sprites get re-arranged then I would perform the following:

  • Set the sheet filename for use with retina mobile devices, adding “2x”
  • Set the width of the sheet to 2048
  • Set the height of the sheet to 2048
  • Set scaling to 1.0
  • Click publish

I would then need to do the same thing for non-retina devices. UIToolkit will automatically select the appropriate sized sprite sheet to use based on the “2x” extension.

  • Set the data filename for use with non-retina mobile devices, removing “2X”
  • Set the width of the sheet to 1024
  • Set the height of the sheet to 1024
  • Set scaling to 0.5
  • Click publish

Once TexturePacker creates the 4 files (layer0.png, layer0.json, layer02x.png, layer02x.json ), I would rename the .json files to .txt to keep Unity happy. This process would be done over and over again, until insanity.

Automating Things

This weekend I had some time to investigate a way to automate this tedious process. I wanted a solution such that after editing the .TPS file, I could simply run a script that would take care of the rest of the work. I began by looking into TexturePacker’s command line options. After some tinkering, I came up with a short script that reduces the number of click and edits that I need to make.

I placed the script within the directory that contains all our assets. However, since the output sheets go into a folder that only contain the sheets and data files, so I need to reference these paths relative from where the shell script lives. So, this would be a script for one layer for UIToolkit:

#!/bin/bash
TexturePacker --sheet ../Resources/layer0.png    --data ../Resources/layer0.txt    --scale 0.5 --width 1024 --height 1024 --format unity layer0.tps
TexturePacker --sheet ../Resources/layer02x.png  --data ../Resources/layer02x.txt  --scale 1.0 --width 2048 --height 2048 --format unity layer0.tps

Note that I can omit changing any of the options that are already set in the .TPS file such as padding, rotation, algorithm, etc. This helps keep the script short and sweet.

The options all correspond with the changes that I mentioned previously. One interesting thing to note is the –format option which prevents needing to rename the .json data file to .txt. You might ask why I didn’t just set this option in the TexturePacker GUI. The reason is, I had just learned about this option after looking over the command line help!

I had created a script that I could run through command line, but I wanted the script to be easier to use. If I had just edited the .TPS file, I would be in Finder, and being able to double-click the script would be nicer than opening a terminal to execute it. Running the script through Finder would simply return an error since the terminal would be in my home directory.

To fix this issue, I had to modify the script a bit more:

#!/bin/bash
DIR="$( cd "$( dirname "$0" )" && pwd )"
TexturePacker --sheet "$DIR"/../Resources/layer0.png    --data "$DIR"/../Resources/layer0.txt    --scale 0.5 --width 1024 --height 1024 --format unity  "$DIR"/layer0.tps
TexturePacker --sheet "$DIR"/../Resources/layer02x.png  --data "$DIR"/../Resources/layer02x.txt  --scale 1.0 --width 2048 --height 2048 --format unity  "$DIR"/layer0.tps

When the shell script runs, we get the directory name where the script lives, cd into that directory and call pwd and assign that value into our DIR variable. This part took a bit more time as I learned spaces on either side of the equals sign will confuse bash, so I had to leave those out.

Now, if a new asset is sent to me, I open the .TPS file, add the file and save. Then I can run this script by a simple double-click. Tada!

Next steps

Using this method, I need to create a shell script for every UIToolkit layer. This isn’t nearly as bad as it sounds since we typically only have 2-3 layers. But, what I’d like to do in the future is investigate AppleScript. AppleScript can help convert a shell script into an app that allows files to be dropped on that app. If I did this, I could drop the .TPS file onto app, then the the script could extract the filename and do the rest. This would prevent needing a script for every layer.