Here is a quick rundown of the month in which I built Air Luggage, and how I went from concept to release.
New Year’s Resolution
Seeing a post the game dev sub-reddit advertising the One game a month challenge (#1GAM) with the title ‘Make games not excuses’ got me thinking about all the projects in 2012 I had eagerly started, but a few weeks later abandoned as the enthusiasm dropped. As a new year’s resolution I decided to put an end to this, and set myself to completing a game within a month as part of the challenge rules. This meant, no feature creep, no bloat, no ‘it would be awesome if it did this….’.
I wanted the game to be as simple as possible for not only players, but for me to be able finish during the tiny timescale (I only had evenings and 4 weekends to complete it in).
Whilst coding my previous game, in which the player had to keep traffic flowing in a city, I created a way point system for cars to follow, the way points had junctions in which the cars would randomly choose which direction to go in.
This was when I had the idea for a game where the player controlled which direction the traffic would flow by setting the direction of each junction. This idea was more arcade based than the puzzle game you see today, the bags would appear in random colors constantly and the player had 10 lives to direct the bags into each gate, the rate at which the bags entered would slowly increase until the player ultimately lost. Using this I wrote up the game description as below:
Using nodes from Traffic, create a new junction switching mechanism to control Y Junctions
Idea is for the player to solve fast paced puzzles of getting colored luggage to the correct gate
Luggage can be directed onto different treadmills using the switch gates, there is a central feeder system that keeps unsolved luggage in a loop.
Player has to complete each level by surviving the day with minimum of x losses.
At this point of development the games focus involved in changing the junction gates as the bags were moving rather than setting up the gates beforehand. and involved filling up a ‘progress meter’ to complete the level.
The trouble with the arcade style was making it fun and varied, once you’ve completed a level, the next would just look a little different, I wanted and needed puzzle solving.
However, I could not find a reasonable way to mesh both ideas together, if the player could change the orientation of the gates at any point, it would mitigate any puzzle as they could just wait until the correct bag came around and flip it accordingly to win. I needed a way to prevent this, and unfortunately this meant letter the player setting up the gates beforehand, and then watching the outcome. I hated this Idea, there was no live interaction or feedback and thus there wasn’t any room for fun game play. After a few days of sleeping on the prospect of removing the arcade element entirely it started to grow on me, and I decided to focus on making a puzzle game.
I started designing the levels and at that point it was clear I made the right decision.
This was surprisingly fun and at the same time a chore, I opted to use a spreadsheet to design the level due to the 2D grid matching the game’s 2D grid. There was no real process involved, except trial and error, and iterating on the previous level adding new elements, Initially I had 2 ideas for junction gates, the ‘accurator’ (count gate) and the flip flop, I designed 5 levels for each thinking later levels will combine both elements to make another 5 levels.
The hard part was making sure the puzzle was solvable without being too easy or obvious, often I’d relook at a level and realize how to solve it without even using half the gates (this was especially true of the accurator tiles when I decided the players could set the starting direction as well as the number of bags it’ll let though. I also made the mistake of not taking into account the timings of each conveyor, which proved to cause a lot of headaches in development when bags would try and occupy the same tile if the player did not take the ‘happy path’.
I enjoy being able to see behind the scenes so here is the development copy of the Level doc for your viewing pleasure:
You’ll also notice some symbols near tiles (this was to help me remember how to solve my own puzzles)
The conveyors were the main focus of the game, so the prototype had a way to place conveyor tiles in 4 directions and have a bag follow the conveyor path, there were no physics or animations at this point, the bag would jump to the next tile every second
If you used the editor in the game, you’ll notice it has not changed much from this screenshot.
I continued developing this prototype adding the flip flop gate and count gate, and tested each of my levels in the level doc, to which I noticed quite a few were unsolvable, or had overlapping bags.
(Sadly I don’t have any screen shots from this point)
One thing that was sitting at the back of my mind was how to make the bags move along the conveyor, I could moved them linearly across tiles, however I was stuck on what happened when 2 bags tried to occupy the same tile, which bag had priority, did they overlap, did they collide?
I knew a way to solve all my problems with 1 stone, but having never properly implementing a 3rd party physics engine before I was very hesitant given my timescale, if it wouldn’t play nice. I opted for farseer, due to it being the de facto for XNA.
Many hours of setting the collision boxes, masses and friction were needed to try and get more than 1 bag around 90′ corners without getting stuck, but boy did it look good.
There’s actually a lot more going on than first appearances to get the effect the bag is traveling on the conveyor, and there is little to no information on the web about how to achieve such movement.
Each bag has 4 points at the edges that are separately checked to see which conveyor they are on, and which direction the conveyor is moving, this allows the subtle rotation of the bag as it changes direction, the direction each point should be moving is stored as a unit vector, and the following code is used to work out how much impulse to add to the angle (all the further rotations and movement is handled by farseer)
float forceLength = Force.Length(); //Force = Direction the corner should be moving in
Vector2 curVel = AttachedBody.LinearVelocity;
Force /= BagCollisonBoxes.Count; // Divide the direction force scale by the number of points we re checking (this case it’s 4) so its 25 % influence over the bags direction
float power = Vector2.Dot(curVel, Force) / (forceLength); // Work out how much impulse is needed to make the bag move in this direction (this is already scaled by 25%)
if (power < forceLength)//apply if we’re not at 100% speed
Force *= (forceLength – Math.Max(power, 0)); //Difference between our desired vel and current vel
Force *= AttachedBody.Mass;
AttachedBody.ApplyLinearImpulse(ref Force, ref worldPos); //apply force directly at the point
The force values and max speed were fine tuned to match roughly the conveyor animation speed, the world has no gravity which completes the top-down look.
Another problem I encountered was that farseer objects tend to bump off of joins in the solid tiles, so if a bag was sliding along the conveyor wall, between each tile it’ll bounce and rotate off the wall as if it had a dent in the wall. I had to write a collision hull generator that looked across tiles to create a single large solid plane for the bags to collide, each time a level is played this is created on the fly:
As you can see here, the green collision boxes have been simplified if 2 tiles are adjacent to each other. The white arrow shows where the simplification process hasn’t been applied (I didn’t take into account vertical joins as they’d always be a block to the left of this tile to join to in a real level). The hull generation process also has the added benefit of reducing the number of collision meshes the physics engine has to process making it a lot faster. Each tile has it’s own meta-data on what collision edges it has and a simple formula marches though the tiles drawing connected boxes.
The game play code was pretty much complete once the physics engine was in, was just a case of telling each bag a different direction to travel in for the flipflop and other special tiles.
I am not an artist, in fact I’m hopeless at art, which is a big problem when making games by yourself. Lucky I get around this by using vector art, which works in a very different way to pixel art (Photoshop etc), every texture in the game is made using lines. Vectors means you can zoom in indefinitely and never get pixel blur, which gives the game a crisp look, vectors are also adjustable, allowing the assets to be tweaked over and over until it looks decent. I also rigorously used color theory, keeping the backgrounds dark and low contrast, and making game objects colorful with dark pin lines to separate them away.
The Menu color pallets where created using http://colorschemedesigner.com/ which use color theory to pick complementing colors.
The tiles were just made with a big tile sheet to keep things simple, I started exploring overlays later in development to do the walls for each tile etc (this is the only tile with fixed collision edges)
I’m so close to finishing, yet I could not release the game in time for the January deadline, I was still missing the last 5 levels, and knew I needed another tile type to keep things interesting. I had a huge holiday booked in February and in the week I was home I did not have time to do the finishing touches.
The project looked to sit on the shelf for all eternity, I still had not come up with a new tile type (How many directions can the bags move) nor had any new level ideas. Eventually I forced myself to sit down and code something, this was the Teleport tile, which allowed matching bags to appear in another location in the level. With another week of work and 2 weekends the game was finally ready to be released.
I submitted the game to the #1GAM march game list and GameJolt.
At the time of writing it’s got 200 views and 55 plays on Game Jolt and a 5/5 rating, which is about average given the time on game jolt. For me it’s a personal success being able to finally release a full game, nothing quite beats the feeling of shipping something.