Development is Complete for Lemonade Stand

The game has been released, and all of the subsequent bug fixes and patches have been rolled out. Lemonade Stand has actually been finished. There is tons of advice to be found online for what to do to make your first game. Most of it talks about the scope of your project, and most of it says to keep it small. I have talked about this before, but my original goals for Lemonade Stand were something of a paradox, in direct opposition to each other. I had wanted a project that was small enough in scale that I could actually finish it, but at the same time I wanted to test myself, to push the boundaries of what I was capable doing as a single developer.

The idea of lemonade stand seemingly fulfilled both of those goals. A business simulator would be the most complex thing I had programmed up to that point, involving lots of AI acting independently in a system, and yet the classic Lemonade Stand games seemed simple and manageable. I had started development with the intention of finishing in 6 months. From the day I started it ended up taking roughly 18 months. Lots of that is due to having a somewhat busy school schedule and other projects eating up lots of time. Lots of that is also due to lack of time management and scheduling, something I have learned a lot about over the course of this project. There were instances of time stretches up to 3 months long with no progress being made. Ultimately the reason Lemonade Stand was only ever released was because in the month preceding its initial launch date, I decided I was going to finish the game.

I made a conscious decision that this was it, this was the last stretch of development. For maybe a little more than 2 weeks I worked on the game almost constantly, and in that time I made as much progress as I had in maybe the previous year. All the things I did leading up to release included:

  • Design and implement the entire UI
  • Implement and create achievements
  • Create the tutorial
  • Add sound effects
  • Add music
  • Balancing and bug fixes
  • Implement donations through In App Purchases
  • Create the Google Play store page

For those 2 weeks of actually working on the game I realized, I really could have done this at almost any time in the last year. And the game would have been finished that much sooner. For all my future projects, I will remember this experience and hopefully use it to be more motivated to do things with purpose and focus.

I think something that would help immensely is establishing goals. For the 2 weeks leading up to release I had a very clear goal of actually finishing the game, it was very tangible and felt very possible.  However, I didn’t just keep this idea of finally completing the game hovering in my mind for motivation. I have a whiteboard hanging above my desk. On the whiteboard, I wrote a list of everything I had to do in the game for it to be done. It contained all the above bullet points almost word for word, but it also further broke down the tasks. Under designing the UI I wrote every single menu screen I would have to design and code. Under sound effects I wrote for what actions I wanted a sound for, under achievements I included implementing detection and rewards and adding the menu screen separately. Once I completed a task, I didn’t erase it, I crossed it out. Over the course of the two weeks every task I completed was on the whiteboard, and some new ones were added. On release day, with everything crossed out, I finally erased it.

In the future I will be doing pretty much exactly this for all of my projects. At most I’ll take it month by month, and establish not only tasks that I am going to complete today or better yet, right now, but also the longer term goals and checkpoints. I think doing this helps you get a sense of real progress while simultaneously ensuring you will never be at a loss for what to work on next. The sense of achievement and progress by physically crossing out each task, and seeing everything you have crossed out helps motivation too, and you can imagine the immense satisfaction from erasing the whiteboard.

While development of Lemonade Stand is currently complete, I will be putting blog post updates on hiatus, though there are a few areas of Lemonade Stand development I may return here to expand upon later. Until then, see you in the next update!

The Graphics of Lemonade Stand: Asset Creation Workflow

We’re back with a long overdue update on Lemonade Stand. A while ago I had completed the first phase of development, the game was feature complete, and all I had left to do was create the levels and tidy up the user interface and I was practically done! Well as it turns out actually creating the content on top of the game systems was also going to be a lengthy task. Who would have guessed. Now, however, that phase of development is also finished and I’m here to tell you how it went and also maybe give you a couple of tips and relate some things I learned throughout the process, things primarily about productivity and the asset creation pipeline.

Workflow Development

My art creation workflow came out of the combination of 3 things: the software and techniques that I was comfortable working with or wanted to expand upon, the art style I had in mind for the game, and the limitations that my platform and code imposed upon me. I have lots of prior experience working with Photoshop and as much as I love open source and free alternatives in my mind it is an irreplaceable tool, so I knew I would be making good use of that. Also I had some previous experience working with Blender, which is probably my favorite software ever, and I wanted to expand on my 3d modelling skills. Also, I knew I wanted to write all the code of this game myself and I was working in native android, so there was no way I was going to be making a full scale 3d game engine as that was way beyond the scope of my project. That’s where I decided to use 3d renders to give the game a faux style of low poly voxel art that has been incredibly common among mobile apps lately. That’s also where the art style informed my workflow, to capture the 3d style I wanted I would have to emulate it in 2d so that affected the way I rendered and processed each image in Photoshop.

Level Creation Workflow

Rather than rendering every tile onscreen individually I would create a “background” for the level that had as much detail as I could put in with the knowledge that anything I placed that might appear in front of one of the walkers would have to be later processed by the rendering code I wrote. This allowed the game to be more efficient and gave me more creative freedom in creating the environments, and I think it helped me work faster. Instead of having to visualize the level as a combination of tiles I could create the entire level at once. I created a few tiles consisting of things like trees or lamps that would regularly appear in places that walkers could walk around so I could easily add them in through the tilemap, but initially I created the level as I wanted it to appear in Blender. Later I would split the scene into 3 layers, the “background” was layer one and the first rendered image that would be behind everything else in the level. This was the image with the most detail to increase efficiency. Then I would have layer 2 be all the trees or lamps that would need to actually be rendered in the game engine so walkers could appear in front or behind them. And finally I separated the layer of “scenery” the things that would always be in front of the walkers and obscure your vision of them. MY workflow ultimately evolved to look like this:

  • Create the entire level in blender from an isometric perspective
  • Split the level into 3 layers, the background, obstacles, and scenery
  • Render the background and scenery layers and export them into Photoshop for editing
  • Create the tileset defining walker’s paths, spawn points, and obstacles
  • Mix all the ingredients in their corresponding layers and now you have a level!

This slideshow requires JavaScript.

I would create images for all the obstacles to be reused in each level so I only used the second layer in blender to tell me where to put the obstacles in the tilemap, it never actually got rendered. In Photoshop I would usually only edit the shadows to make sure there weren’t any sharp cutoffs and to resize the images so they had the correct scale. I was able to make my 5 levels I’m shipping with very quickly once I got this workflow down. I think that’s the most important lesson, is once you have defined a clear workflow you should stick to it for the remainder of the project to actually be able to finish. And the 3 things which usually define your workflow are your abilities and experiences (or goals), the art style and direction of the project, and the technological limitations you face.

Animations Workflow

For making animated assets the workflow was a little different, but it still followed the general idea of creating everything in blender then using Photoshop to convert the assets into a 2d form. I decided to use spritesheets, while a somewhat antiquated animation format I have lots of experience with them and decided to use it. When I say I used spritesheets, I mean that was the format I saved the animations to, I actually animated the walkers using bones in blender and then exported each frame as an image. I then used Photoshop’s awesome animation and scripting features to convert the frames into a spritesheet with a set amount of rows and size. I made use of this handy script to convert layers into a spritesheet, and used the “load files into stack” option to load each file into a layer of a single image.

Also I used the “actions” feature to crop or resize or even edit the shadows of each frame automatically in Photoshop. This handy tool lets you record any action or combination of actions in photoshop, from applying the eraser, a brightness or contrast layer, or cropping and resizing the image, and apply those actions automatically to a batch of files. After that the spritesheet was ready for production.

actions
This is my new favorite tool

Lastly I want to make one thing clear: I am by no means a professional artist or even a professional game developer by any stretch of the imagination, so my specific workflow probably isn’t the best and you probably shouldn’t try to copy it exactly. Despite this, I feel the broader points I made, about what your workflow should be defined by and sticking to it throughout the project, are very important for your productivity. If your game ever wants to see release then adhering to structured progress will be the best way to get there. With that said, now Lemonade Stand enters the next stage of development: making the UI not suck. Until then, see you next update!

The AI of Lemonade Stand: Walker Collision Detection and Avoidance

The very last, and perhaps the trickiest feature I implemented in the game was a system that made it so the walkers wouldn’t walk into each other. This of course builds directly off of the system that allows walkers to follow a path, so you can refamiliarize yourself with that here and here. Now onto how this system actually works, essentially it boils down into 2 main steps, the first of which is an if statement that checks if the walker collides with another.

Step 1: See if the Walkers will Walk into Each Other

Obviously the entire goal of our system is to avoid this exact thing from happening, so we need to first somehow check if it is about to happen, then take a precautionary measure to avoid it. This might sound difficult to anticipate the action of two walkers, but its something real people do all the time, otherwise we would all walk into each other. Lucky for us, it turns out predicting the future in a controlled system is pretty easy. First we return to the code that handles all of the collisions with other walkers, where we check if their images are intersecting. This is done with a nested for loop, the outer one iterating through the array of walkers and the inner array checking to see if we are colliding with any of the other walkers in the array. That would be set up like this:

// First For loop, updating all the walkers
for (int i = 0; i <walkers.size(); i++)
{
    if (walkers.get(i).status == 1) // If the person is going somewhere
    {
        // The second for loop, to check if they collide with somebody
        for (int j = 0; j < walkers.size(); j++)
        {
            // If it is the same walker then move on
            if (j == i)
            {
                continue;
            }

            // If they collide with another walker
            if (collision(walkers.get(i), walkers.get(j)))
            {
                // Do stuff

The key realization here is at this stage we don’t know if they are going to walk into one another, essentially all we know is they are pretty close to each other. The next part of this process is making sure they actually are about to walk into one another, because even if their sprites are technically touching, they could be going in opposite directions or walking side by side. Luckily for us we know that all the walkers are following a path calculated by our pathfinding algorithm, we can use that to our advantage by seeing if the next step of the walker’s paths are the same.

// Make sure they have not just spawned
if (walkers.get(i).stepNum > 0 && walkers.get(j).stepNum > 0)
{
    // If they are walking into them
    if (walkers.get(i).path.getX(walkers.get(i).stepNum) == walkers.get(j).path.getX(walkers.get(j).stepNum) && walkers.get(i).path.getY(walkers.get(i).stepNum) == walkers.get(j).path.getY(walkers.get(j).stepNum))
    {

So that second if statement is very long. Essentially all it does is check if the x and y coordinates of the walker’s next steps are equal to each other, if so that means they are about to collide! The first if statement is a precautionary measure to make sure there will be a step in the walker’s path before this one because will be retracing their steps in part 3. Also all of the walker spawning happens off screen so any collisions won’t actually do anything! This entire system is mostly to make sure the walkers don’t look weird after all, so it doesn’t matter if we can’t see them! Though it also prevents odd bugs from multiple walkers buying lemonade at the time, but that’s beside the point. Now we know for sure there is going to be a collision, its time to stop it.

Step 2: Editing the Walker TileMap and Recalculating the Path

While I talked extensively about using and rendering tilemaps in this article, I didn’t mention that I also use another tilemap to save whether or not a walker can walk on any given tile. Essential it is a grid of numbers, which denote the spawn and despawn locations, as well as the passable and impassable tiles. This step is somewhat trivial but the most important part of the process of making the walkers avoid collisions. Essentailly we set the tile that the collision would happen on to an impassable tile, then recalculate the route to the walker’s destination. This is all done in only a few lines of code so I’ll go through it piece by piece.

// go around them by recalculating the path
startCoords = tileMap.coordsToTile(walkers.get(i).path.getX(walkers.get(i).stepNum - 1), walkers.get(i).path.getY(walkers.get(i).stepNum - 1));
badCoords = tileMap.coordsToTile(walkers.get(i).path.getX(walkers.get(i).stepNum), walkers.get(i).path.getY(walkers.get(i).stepNum));
targetCoords = tileMap.coordsToTile(walkerDeath.get(0).getX(), walkerDeath.get(0).getY());
tileMap.setTile(badCoords.getX(), badCoords.getY(), 0);
walkers.get(i).setPath(finder.findPath(walkers.get(i), startCoords.getX(), startCoords.getY(), targetCoords.getX(), targetCoords.getY()));
tileMap.setTile(badCoords.getX(), badCoords.getY(), 1);

We start out by creating 3 coordinate pairs. The first one is the previous step along our walker’s path which we will use as the starting place for our new path. The second pair is the tile that we would have had a collision on. The last coordinate pair is the walker’s destination, in this case the despawn point. Now we set the tile located at badCoords to 0 because that value makes the tile impassable. We then immediately recalculate the walker’s path with these new values, before immediately resetting the tile to its initial value of 1. Changing the value of this tile doesn’t cause any problems for other walkers because the tilemap is only considered when generating paths, and here we only create the path we need before resetting the tile. Because this article has been a little heavy on the reading side lets enjoy a nice long gif showing the fruits of our efforts.

Repathing.gif
Oh baby a triple… path recalculation

Here you can actually see I implemented all 4 directions of animation and added all the different colors of walkers, so they’re not just red anymore. You can also see how the walkers recalculate their paths so they walk side by side not once, not twice, but three times in one gif. Good stuff right there. Maybe next time they will actually buy lemonade at the stand instead of off to the left of it. I’ll see you in the next update!

Lemonade Stand: Feature Complete

Today I can officially say, after months of development and bug fixing that Lemonade Stand is finally feature complete. After today there are no more major features to be added, and no significant code to be written. I have not updated the site with articles covering every major feature yet, those are still on their way, but I thought I should at least write something to commemorate this milestone. I started this project this spring, with no previous experience in android development, and limited experience working with java in general. Above all this was a great learning experience, one that is by no means over and I look forward to continuing it. Before I delve into the future though, I’d like to at least take a look at all the features that are in the game. Without further ado:

  • Isometric graphics
  • Persistent inventory management
  • In game time and day system
  • Weather system
  • Mechanic of changing the lemonade recipe in game
  • Walker pathfinding
  • Walker line forming
  • Walker collision avoidance system (Article coming soon!)
  • Walker personality and AI system for buying/rating lemonade (Multiple Articles coming soon!)

So there you have it, a complete feature list. Some of these are kind of a given for this type of game like the inventory and weather systems, and because both are rather simple I don’t think they quite deserve entire articles to themselves. However I have already started drafting some articles for the personality generation of the walkers, the algorithm that determines if they are going to buy lemonade, and the collision avoidance system, so definitely expect at least 3 about those topics. It was actually the collision avoidance system that was giving me the most trouble in these recent weeks so I expect a write up on that will come soon. One very important topic not yet addressed is what I am planning to be the main game mechanic, changing the recipe of the lemonade as the game is running. This ties into the Walkers having random personalities so these topics will end up building on each other quite a bit. With the feature list covered, lets take a look at what lies ahead for the development of lemonade stand.

Now all the easy stuff is out of the way we can focus on the real interesting part of game development. In the spirit of making lists why don’t we make a list of things to do now to go along with the things we’ve done.

  • Add actual levels
  • Learn and implement good UI design
  • Fine tune difficulty and AI settings
  • Polish and Juice

In terms of creating content, I’m planning on making a few different levels and locales that will have different feels to them by editing the weather and walker AI. Implementing this in the code will be fairly trivial, in fact I already have the menu system prepared, so on that front the biggest time sink will be creating the graphics. I didn’t allow myself to work on any graphics until the codebase was complete, so now here we are.

For UI design up to this point everything has been default minimal effort, following the similar philosophy as working on graphics, I wanted to focus on learning and coding the java platform. I’ve also had little to no experience in designing UI and for a business simulator that’s kind of the most important part.

Fine tuning AI and difficulty is something that can only be done through rigorous testing. Once I have some levels implemented you can switch between I’ll have to make sure players don’t end up rolling in the cash after the first Monday, and that not every single person wants to buy lemonade etc.

Finally we get to the good stuff, my personal favorite part of game design. This is the part where you actually make the game good. If I implemented all the content, made the AI and difficulty reasonable, maybe I could say the game was done. However, the game would probably be pretty boring. There’s a saying in software development that goes:

The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time.

This is true for any software project, and especially so in games. Even if its not code I’m working on, the last 10% of the project will end up being likely not only as time consuming, but just as important as the other 90% of the project that’s already finished. This last 10% for my is going to be the polish and fine tuning that elevates the game from passable to actually good. In the AAA industry, you hear about games “going gold” all the time, meaning somewhat confusingly not that they’re surpassed an arbitrary amount of sales like in the music biz, but instead that the game is ready to ship, and they have started printing copies for retail. However nearly every single game also has a huge day one patch, containing what you hope is the remaining 10% and polish that will actually make the game you just preordered worth it. Or maybe its a last ditch effort to fix all the game breaking bugs that were rushed out the door, who knows. For Lemonade Stand, and all my future games, I hope to actually finish the game, including the polish before release. I hope you found this post somewhat interesting, I’ll see you in the next update!

The AI of Lemonade Stand: Waiting (and Cutting) in Line

Previously I Implemented the A* path finding algorithm so the people in Pineapple Town or wherever this game takes place can actually walk to wherever it is that they’re going. I was pretty excited about that, it was probably one of the more complex things to tackle in the making of this game and now I had finally finished it time for celebration! Well not quite. Actually all I had done was write the code to return a path for the Walker, as I dubbed the people trapped in my simulation, and now I needed to write the code for them to actually follow the path.

Following the Path

This wasn’t really that big of a deal, as you may remember from last time the final path returned is a series of locations for the walker to follow, and we can just generate a vector for the walker to travel along for each step of their path. That code ended up looking like this:

public void followPath()
{
    if (path == null)
    {
        System.out.println("path is null");
    }
    else // if a path exists then go to it step by step
    {
        dx = (path.getX(stepNum) - x);
        dy = ((path.getY(stepNum) - 72) - y);

        double factor = speed / Math.sqrt(dx * dx + dy * dy);

        dx *= factor;
        dy *= factor;

        // if they are at the next step check if its the end of the path and move up
        if (Math.abs(path.getX(stepNum) - x) < speed && Math.abs(path.getY(stepNum) - 72 - y) < speed)
        {
            setX(path.getX(stepNum));
            setY(path.getY(stepNum) - 72);
            dx = 0;
            dy = 0;

            stepNum++;
            if (stepNum == path.getLength())
            {
                status = 2;
            }
        }
    }
}

Here we set a static value for the walking speed of the walker, which is essentially how long it should take the walker to move from one step to the next. We divide that speed by the Pythagorean length of our travel vector to get a scalar value we can use to modify our total x and y distance that we move each frame. The checking if the path is null is really just a last resort to warn me something terrible has happened because there are other systems in place here to stop the null path from getting this far. The last if statement tells us the walker has reached the end of the path, and changing the walker’s status to 2 essentially just tells the walker to execute whatever they are supposed to be doing at the location they arrived at.

So that is how the walkers follow their paths. I went so far into detail about this because it is instrumental to understanding how they wait in line, as its a fairly simple modification to this.

Waiting in Line

For waiting in line I initially considered making the walkers recalculate their route to a predetermined “end of the line” tile which would change whenever it was occupied. But to me this sounded too complicated to implement, instead I decided to go for a more organic approach. Instead of artificially defining a line I would let how the walkers spawn and make their way to the lemonade stand dictate how the line forms. Lets look at the code and some game footage to get a better idea of what I mean.

if (stepNum == path.getLength() - 1)
{
    status = 2;
}

isWaitingLine = true;

The journey of our line starts here, if the walker’s destination is the lemonade stand then we check to see when he arrives at the step of the path before he starts buying lemonade. Once he is we then execute this code:

if (status == 3) // is waiting in line
{
placeInLine = path.getLength() - stepNum - 1;

if (isWaitingLine)
{
 dx = 0;
 dy = 0;
 if (walkForwards.getCurrentFrame() != 6)
 {
 walkForwards.update();
 }
}

We set this walker’s place in line relative to how many steps he has taken to get to the lemonade stand,  giving priority to whoever is closest to the lemonade stand and then also whoever walked the furthest to get there. However, since this walker doesn’t have anyone else to deal with, he just keeps walking to the lemonade stand. So he enters status = 2 which will execute this code:

if (status == 2) // Arrived at end of path, is first in line
{
    dx = 0;
    dy = 0;

    if (wantsLemon)
    {
        inLine = true;
        placeInLine = 0;
    }

Now to see how our line develops we need to look at the collision code for when walkers walk into each other. Lets introduce a second walker to the situation.

if (collision(walkers.get(i), walkers.get(j), false))
{
    hasCollided = true;

    // if they are going to the lemonade stand
    if (walkers.get(i).wantsLemon)
    {
        // if they collide with somebody in line and we are not in line then get in line
        if (walkers.get(j).inLine)
        {
            // our walker is now in line, one place behind the person they collided with
            walkers.get(i).inLine = true;
            walkers.get(i).setStatus(3);
        }

Here we will say i is the new walker and j is the one who just arrived at the lemonade stand. We are checking if they collide with someone who is waiting in line, in this example our original walker who was just about to buy their lemonade. We tell our current walker that they are now in line and their place is defined by the code executed in status 3, the waiting in line status. So now we have two walkers who are next to eachother, they both want lemonade, and they are both technically “in line” and have placement to say who gets priority. Next we just tell the walker with the lowest priority to wait until all other walkers with higher priority leave, and that’s it! We’ve got a line going on.

else if (walkers.get(i).status == 3) // if the walker is in line
{
    // if they do not collide with somebody who is ahead of them in line then go forwards otherwise just hang out
    boolean hasCollidedNextPerson = false;

    for (int j = 0; j < walkers.size(); j++)
    {
        // If it is the same walker then move on
        if (j == i)
        {
            continue;
        }

        // if they collide with somebody ahead of them in line
        if (collision(walkers.get(i), walkers.get(j), false) && walkers.get(j).placeInLine < walkers.get(i).placeInLine)
        {
            hasCollidedNextPerson = true;
        }
    }

    // if they don't collide with anybody ahead of them in line and they are waiting then move up
    if (!hasCollidedNextPerson && walkers.get(i).isWaitingLine)
    {
        if (walkers.get(i).placeInLine != 0)
        {
            walkers.get(i).stepNum++;
        }
        walkers.get(i).isWaitingLine = false;
    }

Here we are manually advancing the step of the path that the walker follows when they meet no opposition from someone who is also in line and has a higher priority than them. This code may seem to jump around a lot but that’s because it takes advantage of 3 systems I already had in place for controlling AI, the collision system, path following system, and their “status” system. I think it was a good design decision to make use of those tools instead of creating an entirely new system to handle waiting in line. Now lets take a look at the code in action to confirm it does indeed work.

path1
These walkers have realized that vehicles haven’t been implemented yet, and thus the street is safe to stand in.

I just spawned a few walkers and disabled buying anything to display the line forming. We can see that there is actually 2 lines forming here but that actually doesn’t provide any conflict as their place in line is not based on how many people are physically ahead of them but rather how close they are to the lemonade stand. Now lets wrap this up by finally looking at how I “implemented” the walkers cutting each other in line.

Emergent AI Behavior: Its a Feature not a Bug!

So something I quickly noticed when testing this code is that the walker’s don’t always let the person who has waited the longest go first, because their place in line is based only on their distance to the lemonade stand and how long it took them to get there. Instead of fixing this bug I decided to encourage this behavior ,cause you know what, in real life people don’t always let the person who waited the longest go first so why should my game do that! Call it a metaphor for the capitalist themes that Lemonade Stand is pushing, its survival of the fittest when you’re thirsty and the lemonade stand can only serve one person at a time. I accomplished this by addressing the edge case for when the walker encounters someone who has the same place in line as them:

else if (collision(walkers.get(i), walkers.get(j), false) && walkers.get(j).placeInLine == walkers.get(i).placeInLine)
{
    // if someone is in the same place in line as them let them cut you cause they're so mean
    walkers.get(i).placeInLine++;
}

So whoever we check first will end up letting the other person have the right of way. Technically in the code this means that its just this one guy being excessively nice but I like to think of it as him being taken advantaged of. Here’s some actual footage of this occurring:

cut
What do you think those other two people are thinking as they watch this guy just stride in front of them?

I also made it so there is a delay when they buy lemonade, to make lines more likely to form. So really here I decided to change the code to favor a stylistic outcome that is probably not the “ideal” outcome you would initially expect. I think that this will add a lot to the game though, if the walkers only formed one line and always let the person first in line go that would perhaps look better, but I think this more organic system will help add character to the walkers. That is actually one of my primary goals for this game, and I think this was a good step to achieving it. Thanks for reading all the way through this marathon of an article, see you in the next update!

The AI of Lemonade Stand: Isometric A* Pathfinding

In a previous article I mentioned how I had some issues with the way I decided to render isometric tiles, and implementing pathfinding. So lets talk about how it is I overcame those problems and why implementing A* was way more difficult then it should have been. First, so we are all on the same page, lets go over the A* algorithm itself.

The A* Algorithm

What A* is meant to do is find the shortest and most efficient path to get from point A to point B. Its important to make the distinction that not only is it the shortest as in the most direct path, but also the most efficient. The reason that this algorithm is so widespread is that it can adjust for both distance and efficiency.

This algorithm creates the best path by testing every node that is accessible to the object it is moving. In our case, a node can be a tile on a tile map. It tests every object for two values. First, its g cost which is usually the physical (or digital) distance that the mover would have to go to reach that node or tile. The second value it tests, is the node’s heuristic a value that estimates how cheap it is to go to that node. As an example, say you are racing in a dirt bike trying to escape from a bipedal amphibious radioactive monster. You come across a turn in a road that goes around a pit of quicksand. The shortest distance from point A to point B, that is, your current location to a nuclear bunker stocked with bipedal monster repellent, would be to cut across the muddy path. So your g cost tells you to keep going straight. However, the heuristic of the dirt road is way less than the heuristic of quicksand so the best path is to stay just on the edge of quicksand.

That’s what makes A* so convenient, it can be applied to myriad of situations and is (usually) not to hard to implement. Lets look at how we would go about implementing in java.

Implementation

A* works by keeping two sets or lists of nodes to check and compare their heuristic and g costs against each other. The first set is called the Open Set which contains all the nodes to be checked. Nodes are added to the open set based on if they are adjacent to either the starting position, or adjacent to a node in the closed set. Nodes are added to the closed set when their g cost and heuristic are calculated. The algorithm decides which nodes from the open set to check by defaulting to the one with the lowest combined g cost and heuristic. You can see how easy this would be to achieve in Java by using a SortedList for the open set and an ArrayList for the closed set. The open list is sorted by the combined g cost and heuristic of every node, the f value. However in order to populate the lists with nodes we need to define what exactly a node is.

private class Node implements Comparable<Node>
{
    private int x;
    private int y;
    private int cost;
    private float f;
    private float heuristic;
    private Node parent;
    private int depth;

    public Node(int x, int y)
    {
        this.x = x;
        this.y = y;
        f = cost + heuristic;
    }

    public int setParent(Node parent)
    {
        depth = parent.depth + 1;
        this.parent = parent;

        return depth;
    }

    public int compareTo(Node other)
    {
        if (f < other.f)
        {
            return -1;
        }
        else if (f > other.f)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}

So this is the creation of our node class, basically it is defined by its x and y values, which are taken from our level data array. Its other attributes are its ability to have a parent node, basically it saves the node that it is connected to so we can later recreate the pathway once the algorithm is done. Also it has a depth value, telling us  how many levels we are within the algorithm and also the number of nodes that make up the path. Finally it can be compared to other nodes based on what its f value is, a prerequisite for being included in a SortedList.

Before going into how g cost and heuristics are calculated lets look at a visual representation of the algorithm using what we already know.

astar_progress_animation
Image courtesy of Wikimedia Commons

Here we can see the open circles represent nodes in the open set while colored nodes are in the closed set. The more green the color is the closer to the goal the nodes are. Right away you can see how the algorithm investigates all the nodes in a straight line towards the goal until it hits a barrier, because those nodes all have much lower f values than the nodes way back by the starting position. Once it hits the barrier then it doubles back and investigates those nodes around the start.

Understanding nodes and the open and closed sets is all well and good, but how do we go about calculating the g cost and heuristic?  Here is where it gets a little tricky. Lets start with the g cost.

// Get movement cost of node
public int getMovementCost(GameObject mover, int sx, int sy, int tx, int ty)
{
    CoordinatePair start = map.tileToCoords(sy, sx);
    CoordinatePair target = map.tileToCoords(ty, tx);
    int dx = Math.abs(target.getX() - start.getX());
    int dy = Math.abs(target.getY() - start.getY());

    if (dx != 0 && dy != 0)
    {
        return 108;
    }
    else
    {
        return 208;
    }
}

This function accepts the type of object that is being moved (in case you want a person and a car to behave differently), the starting x and y coordinates, and the target x and y coordinates. I convert the values from level data coordinates to actual x and y coordinates using my function I detailed in a previous article and then get the distance between the two point on the x and y axis. I then check if the mover is moving on more than one axis i.e. diagonally, and give it a lower movement cost than if the mover were to go directly up, down, left or right.

move
A crude illustration of the concept

This is to avoid people from walking in crazy zigzag patterns that don’t make any sense, which did happen a lot prior to fine tuning the movement cost of the two different types of moves.

We then calculate the heuristic by finding calculating the Euclidean distance between the node we are investigating and the goal.

// Get Heuristic of node
public int getHeuristicCost(GameObject mover, int x, int y, int tx, int ty)
{
    CoordinatePair start = map.tileToCoords(y, x);
    CoordinatePair target = map.tileToCoords(ty, tx);
    int dx = Math.abs(target.getX() - start.getX());
    int dy = Math.abs(target.getY() - start.getY());
    return (int) Math.sqrt((dx*dx)+(dy*dy));
}

An alternative to this is calculating Manhattan distance, essentially just adding the difference between the x and y positions of the two nodes without square rooting or squaring them. This would obviously be much faster, but does not work with the “zigzag” style system we are using to store our level data. This leads well into the next topic, the problems introduced by using zig zag style isometric rendering, which are not introduced when using “normal” style isometric data. More info can be found in the aforementioned previous article.

Problems with Isometric Data

As mentioned in the previous article, I am storing all my level data as an offset grid to better approximate how the level data will actually look in the game. An array of tiles might look like this:

While Manhattan distance works just fine with a standard grid, this offset data will not work at all with that distance calculation. This is because the tiles directly above the starting tile are actually either to the left or right of the starting tile, and not just above it. This is also why we needed to convert the coordinates of the nodes to actual pixel coordinates, because the cell coordinates of where the node is located in the array are inaccurate to where it is located on the screen. Essentially the need to convert the data slows down the algorithm with extra calculations.

Now to the issue that gave me the most trouble with implementing the A* algorithm into the zigzag data: selecting adjacent nodes to enter the open set. Lets start by looking at what we want to do, select the 8 nodes around the starting position.

move1
Pretty colors

The green color denotes our starting position, while the red show the tiles with the smallest movement cost and the blue are the larger movement cost. You can immediately see a problem when looking at the coordinates shown on the image. If the algorithm simply added and subtracted 1 to the x and y location of the node, it would not get the right nodes at all. Instead the algorithm needs to take into account 5 different rows of data, with a different number of  columns for each row. My solution to this is certainly not the cleanest but I couldn’t think of some kind of miracle equation that would give me all the correct adjacent tiles mathematically, so I had to iterate through each row individually. Here’s what the code looks like:

// Look at each tile neighboring our current one in a diamond pattern
for (int y = -2; y < 3; y++)
{
    // Check if y is odd to offset accordingly on the diagonal neighbors
    int offsetX;
    if ((current.y & 1) != 0)
    {
        // cellY is odd and y is odd
        offsetX = 1;
    }
    else
    {
        // cellY is even
        offsetX = 0;
    }

    // Make sure the diamond is wide enough in each row
    int numXNodes = 3 - Math.abs(y) + offsetX;

    // Add enough new x nodes per row to make a diamond
    for (int countX = 0; countX < numXNodes; countX++)
    {
        // Define each x starting place, sure wish I had some kind of formula for this.
        int x;
        if (y == 0)
        {
            x = -1 + countX;
        }
        else if (Math.abs(y) == 1)
        {
            x = -1 + countX + offsetX;
        }
        else
        {
            x = 0;
        }

        // if this is the node we are on then skip it
        if ((x == 0) && (y == 0))
        {
            continue;
        }

        int xp = x + current.x;
        int yp = y + current.y;

So that’s how I added eligible tiles to the open set. After I got that out of the way it was pretty much standard implementation from there, you would check all the surrounding nodes for the one with the lowest heuristic and g cost then move onto the next one. That code looks like this:

if (isValidLocation(mover, sx, sy, xp, yp))
{
    int nextStepCost = current.cost + getMovementCost(mover, current.x, current.y, xp, yp);
    Node neighbour = nodes[xp][yp];

    if (nextStepCost < neighbour.cost)
    {
        if (open.contains(neighbour))
        {
            open.remove(neighbour);
        }
        if (closed.contains(neighbour))
        {
            closed.remove(neighbour);
        }
    }

    if (!open.contains(neighbour) && !(closed.contains(neighbour)))
    {
        neighbour.cost = nextStepCost;
        neighbour.heuristic = getHeuristicCost(mover, xp, yp, tx, ty);
        maxDepth = Math.max(maxDepth, neighbour.setParent(current));
        open.add(neighbour);
    }

This code essentially removes a node from the open list and into the closed list if it has a lower f value than its neighbors and then uses that node as the next starting point. The maxDepth is the predetermined limit to how long the algorithm will search before it gives up.

All of the previous code is executed in a loop until either maxDepth is reached or the goal is found by the algorithm. The while loop saves the closed set and exits where a Path is constructed. This part is made much easier by having the nodes save their parents!

// If finding a path was unsuccessful return null
if (nodes[tx][ty].parent == null)
{
    return null;
}


// We have now definitely found one, build the path starting from the target and work our way backwards using the parent identities
Path path = new Path();
Node target = nodes[tx][ty];
while (target != nodes[sx][sy])
{
    CoordinatePair targetCoords = map.tileToCoords(target.y, target.x);
    path.prependStep(targetCoords.getX(), targetCoords.getY());
    target = target.parent;
}

return path;

Finally we return Path and the algorithm is complete. The path is essentially a collection of the x and y values for the mover to follow, in the next update I’ll go into how this path is followed by a walking person and how it was adapted to also serve as the code for waiting in line too. I hope you enjoyed the article, I’ll see you in the next update!

 

The Graphics of Lemonade Stand: Rendering Isometric Tiles

In a previous article I talked about why a business simulation even needs graphics. Moving beyond the psychological ideas of why a graphical based interface is much more exciting than simply watching numbers go up, the main concern was introducing other levels of user interaction beyond setting some initial variables like price and then watching the game play itself for a few minutes. Having a robust graphical interface is necessary for these other levels of interaction occur in a meaningful way. In this article I’ll go into detail about this supposedly “robust” graphical system, or in other words, lets talk about the graphics.

When I first started making this game I wanted to try a new graphical style; previously I had made Flash based side scrolling platformers and shooters Though a side scrolling platformer business simulator would certainly be interesting, I was thinking more along the lines of a top down or isometric style game. I quickly decided on pursuing the latter, mainly because I wanted to push my boundaries more, and I thought that the coding implementation between a side scrolling view and a top down view was too similar. Also I noticed a trend among simulation games I had played, namely RollerCoaster Tycoon and SimCity: they also were all isometric. Also, to make AI pathfinding and rendering more simple, a tiled system was an easy approach to take.

When I started researching ways to implement an isometric rendering system I found that there were basically two main ways to go about drawing isometric tiles. The first and perhaps most common is where the world is viewed as a diamond.

The Diamond Approach

The information describing the map is arranged in a standard grid like so:

A simple two dimensional array, that looks and functions exactly the same way as one for a top down or side scrolling grid would. The difference here is that the rendering code interprets the grid as:

..  ..  1  ..  ..
  ..  1   1  ..
..  1   0   1  ..
  1  0     0  1
1  0    0    0  1
  1  0     0  1
..  1   0   1  ..
  ..  1   1  ..
..  ..  1  ..  ..

There are two ways to achieve this. First, you could create a new area holding level data, and populate all the cells where the dots are above with null data, but this removes the advantage that this diamond rendering approach has, that the data does not need to be changed at all. Instead we can edit the code used to render the tiles to rotate them 45 degrees to one side. Some sample code might look something like this:

level_data[][];

for (cellY = 0; cellY < level_data.size; cellY++)
{
    for (cellX = 0; cellX < level_data[cellY].size; cellX++)
    {
        draw(
        level_data[cellY][cellX], 
        screenX = (screen_width / 2) + (cellX * tile_width / 2) - (cellY * tile_width / 2) 
        screenY = (cellY * tile_height / 2) + (cellX * tile_height / 2));
    }
}

This is a pretty simple nested for loop, iterating through each dimension of our level data. For simplicity’s sake lets say that level data is the array shown above. This function iterates through every “row” of tiles and draws them diagonally. It does this by changing both the x and y coordinates of every subsequent tile drawn by one half of the tile’s size. Its only half a tile size because the tiles are stacked diagonally on each other, so there is overlap of the tile’s dimensions but graphically looks correct.

This method will render the tiles in this order:

iso-gif1
Pretty snazzy animation right?

Each new color is a new column or cellY value, so you can see how it is rotated 45 degrees to the right. This approach of rendering from the back to the front also makes sure that tiles of varying height like buildings appear correctly.

This diamond approach has one major failure however, and that is if you want your level to fill the entire screen you need to have a lot of empty data to fill out the corners of the screen. Enter, the other “zig zag” method, the method I decided to use for my game Lemonade Stand.

The Zig Zag Approach

Lets start by taking the same level data array I had before:

The zig zag approach would render it like this:

..  ..  ..  ..  ..
   1   1   1   1
..   1   0   0   1  ..
   1   0   0   1
..   1   0   0   1  ..
   1   0   0   1
..   1   0   0   1  ..
   1   1   1   1
..  ..  ..  ..  ..

That’s a little hard to visualize so lets look at another informative gif made by yours truly:

iso-gif2
Notice how the 1 tiles are no longer in a straight line

This looks more complicated than the diamond approach at first, and that’s because it is a little more complicated. The major benefit that the zig zag method has is you need far less dummy data to fill an entire screen, and the level data in a two dimensional array gives a better approximation of how the level will actually end up looking compared to the diamond approach. For these benefits, the code used to implement it is a little more tricky and a simple nested for loop isn’t going to cut it.

Luckily it only really requires an extra if statement that checks which row we are currently rendering and then shifting all the tiles over the appropriate amount. Here’s some code that I use in my game to convert cell coordinates to actual screen coordinates:

// Convert Cell data from tile map to x and y coordinates
public CoordinatePair tileToCoords(int cellY, int cellX)
{
    int x;
    int y;
    int offsetX;

    if ((cellY & 1) == 0)
    {
        // cellY is even
        offsetX = 0;
    }
    else
    {
        // cellY is odd
        offsetX = TILE_WIDTH / 2;
    }

    x = ((cellX * TILE_WIDTH) + offsetX) - TILE_WIDTH;
    y = ((cellY * (TILE_HEIGHT / 2)) - ((TILE_HEIGHT / 2) + TILE_HEIGHT));

    return new CoordinatePair(x, y);
}

This is really the only part that’s different from the rendering code, you would still need to use a nested for loop but here there’s an extra step of checking if you are on an even or odd row. I do this by checking the last bit of the integer to see if its a 0 or 1; if the bit is 1 then the number is odd, otherwise its a 0 and the number is even. If you don’t understand this application of binary I encourage you to experiment with this handy learning tool courtesy of Harvard’s into to computer science course, CS50. Mostly by entering a number and toggling the first bit or “bulb” from one to zero (or on and off) to see how the number changes from even to odd.

So anyways as I mentioned before, ultimately I chose the zig zag method over the diamond one. This was mostly because at first glance I thought the code would be easier to implement, though that turned out to be not really correct. Also I didn’t want to have to fill my array with so much empty data that wouldn’t be shown on screen. In hindsight, and for any future isometric games, I’ll probably use the diamond method. This is because later on in development I found that the zig zag data is much harder to work with when implementing pathfinding, while the diamond data is essentially the same as a regular grid system and requires no extra code to work with.

I hope you enjoyed this article/tutorial thing, in the next update I’ll go into detail about overcoming these pathfinding issues and talk about the A* algorithm. See you then!

Creating a Stable and Persistent Game Loop in Android

When you’re writing the software framework for your game, one of the first things you need to do is establish the game loop. Naturally, when I started learning about Android development this was also one of the first things I looked into. For a few months I used the basic design outlined in the Lunar Lander Example that came with the Android SDK, and on the surface it appeared to work fine. It turns out that implementation of the game loop has a bug where anytime the game screen’s activity is exited and restarted, the game crashes as it fails to compensate for the activity life cycle. Essentially this means anytime you get a phone call, navigate to a different app, pause the game, or open up a menu within the game, restarting the game’s activity would result in a crash.

If you are unfamiliar with the android activity life cycle, or activities in general, these resources will give you a deeper understanding onto whats going on here, but if all you need is a refresher, lets take a look at a handy infographic on what happens during the life cycle:

 

android-activity-lifecycle
The important part is actually knowing when these methods are called

We can see from the flowchart that in the majority of instances where onStop is called, the activity actually is is killed and is wiped from memory. This happens whenever you get a phone call, or if you exit the app with the back button, all things that you can expect to happen a lot when someone is playing your game. The problem with the game loop outlined in the Lunar Lander example is that it creates a game loop separate from the Activity, and thus is not killed when the activity is. This causes issues when the user navigates back to the activity that initiated the game loop, because it tries to start a thread that is already running.

A very common solution is to encapsulate the entire thread in a while loop that is dependent on a boolean variable. When onStop and onStart are called you can simply set the variable to true and allow the thread to “start” and “stop” without accidentally re initializing it. This code would essentially look like this:

while(running)
{
    startTime = System.nanoTime();
    canvas = null;

    //try locking the canvas for pixel editing
    try
    {
        canvas = this.surfaceHolder.lockCanvas();
        synchronized (surfaceHolder)
        {
            this.level.update();
            this.level.doDraw(canvas);
        }
    } catch(Exception e) {}
    finally
    {
        if(canvas != null)
        {
            try
            {
                surfaceHolder.unlockCanvasAndPost(canvas);
            } catch(Exception e) {e.printStackTrace();}
        }
    }

    timeMillis = (System.nanoTime() - startTime) / 1000000;
    waitTime = targetTime-timeMillis;

    try
    {
        this.sleep(waitTime);
    } catch(Exception e) {}

    totalTime += System.nanoTime()-startTime;
    frameCount++;
    if(frameCount == FPS)
    {
        averageFPS = 1000 / ((totalTime/frameCount) / 1000000);
        frameCount = 0;
        totalTime = 0;
    }
}

That critical running variable would be set to false in the onStop method of the parent activity, and to true in the onStart method. However because the game thread we create is running separate from the UI thread that activities run on, it might take a few tries to stop it so that code would look like:

public void stop()
{
    boolean retry = true;
    while(retry)
    {
        try
        {
            thread.setRunning(false);
            thread.join();
        } catch(InterruptedException e) {e.printStackTrace();}
        retry = false;
    }
}

This solution is pretty easy and quick to implement, but it suffers from one flaw depending on the implementation. That is persistence. When I used this method I found that every time I exited and restarted the activity, the game loop was wiped clean. This meant every time I exited and reentered the game all progress in that specific level would be lost, sending the player back to square one. Obviously that’s not ideal. This issue centered around the above solution stopping the game loop from running at all, so when it would be restarted it would not have saved any of the variables it was previously manipulating.

An alternative solution that I implemented in tandem with the one above is using Synchronized Pause Locks to halt the thread from running within the update of a single frame.  This is where a generic Java Object is created and halts a loop mid update  while it awaits a resume command. Very similar to the above example, with the main difference being the usage of an object instead of just a boolean, and the ability for the loop to save its state while being paused. This code would be added to the bottom of you while(running) loop from the above block of code.

synchronized (mPauseLock)
{
    while (mPaused)
    {
        try
        {
            mPauseLock.wait();
        } catch(InterruptedException e) {}
    }
}

mPauseLock is just a regular object and mPaused is a regular boolean declared like:

mPauseLock = new Object();
mPaused = false;

The only tricky part here is that synchronized tag. It essentially allows the object to be interacted with in 2 different threads, in this case the Activity’s UI thread and the Game Loop thread. This also circumvents the issue described earlier about how we had to try multiple times to stop the game loop thread using just a boolean from the UI thread. The way we lock and unlock this object is using synchronized functions and the notifyAll method. They would look like this:

public synchronized void onPause()
{
    synchronized (mPauseLock)
    {
        mPaused = true;
    }
}

public synchronized void onResume()
{
    synchronized (mPauseLock)
    {
        mPaused = false;
        mPauseLock.notifyAll();
    }
}

This allows us to communicate with the game thread from outside of it. The notifyAll method wakes up the game loop thread now that mPauseLock is no longer telling it to wait.

In my current game loop implementation I use this synchronized code block to put the thread to sleep and wake it up whenever the user navigates away from the thread, and I use the first implementation of setting runnable to false and clearing the game loop data when the user quits the application, when onDestroy is called.

I hope you found this more technical article useful, I’ll see you in the next update!

Lemonade Stand: Why does a Business Simulation Need Graphics?

I started this Lemonade Stand Project with very little prior experience developing specifically for Android. I had previous experience in Java and game development as a whole, but there were a few months in the beginning of the project where I was not necessarily working on the actual game but more familiarizing myself with the Android workflow. Because of that it might not be fair to say I started this project in March of 2016, and in stead a more accurate starting point would probably be May. At least, at that point in time I had solidified my goal of creating a lemonade stand game for android, and I now had the knowledge to do so.

For the start of this project, I decided to take a completely different work ethic than compared to my previous efforts with flash games. Instead of working on the graphics, code, game design, and sounds at the same time, I limited myself to only using placeholder art until I had completely solidified the code and game design. Essentially, I told myself I would only work on the graphics until the game was feature complete. Normally this plan would fail terribly, because usually the art style will be very closely tied to implementation of certain features, as well as some features being completely tied to the graphics like fancy particle effects or attacking animations etc. However, this provided another good reason for making a Lemonade Stand business simulator, as nearly all of the major game play elements are separate from the actual graphics. In fact the graphics for Lemonade Stand are completely unnecessary and serve only as a sort of abstraction for the underlying algorithms and math that makes the simulation work.

That realization got me thinking, why did the original game for the Apple II even have graphics? If it was supposed to be an educational tool wouldn’t seeing the numbers be enough? The obvious answer is no, it needs graphics to be fun and engaging. If the game consisted only of entering numbers and nothing else then it wouldn’t really be viewed as a game by everyone who played it but instead as work. So basically the graphics in Lemonade Stand are the entirety of what makes the game fun to play. Without an interesting enough feedback loop for the buttons that the player presses, it doesn’t matter how much thought you put into the algorithms behind those graphics, the game will be boring.

So with those things in mind, I got to coding a basic interface and implementing standard deviation into all of my random generation. Eventually I had a complete simulation running where the only graphical interaction was watching numbers go up and down. This essentially confirmed my original thoughts. The game was boring.

Shop1
So boring. You know, I still haven’t changed the shop interface…

During that time I was thinking of alternative ways to present essentially the same information, but this time actually make it fun. I fell back on my favorite business simulation game of all time, RollerCoaster Tycoon, for inspiration. While RCT has a whole lot more going on that Lemonade Stand, if you took away the roller coaster building the game mostly boils down to just watching numbers go up and down. The thing that makes RCT so approachable and fun is its personality. Every Peep is unique and has their own amount of money to spend, their own likes and dislikes, preference for roller coasters, etc. I also realized a big part of that was allowing the player to directly interact with every single peep and see their details and make informed decisions about gameplay based on that. Following this idea, the walking guy was born.

Anim_Forward
Look at him walk. Where’s he going?

I know I said before, no graphics until the game was feature complete, but here is finally a case where the graphics are integral to the game play and the implementation of the game design choices. Also I wanted to figure out my workflow for creating the art. So I essentially scrapped all the old simulation code I had written, because it was all based around parameters players set before the simulation started, it would run, you would watch the numbers change, then it was over. Now I completely changed how it worked, instead of arbitrarily deciding how many people purchased lemonade based on whatever factors, I could arbitrarily generate the people and let them decide for themselves.

This obviously required way more work. Now I needed to write path finding, some sort of AI for the people, and implement a way for them to each have their own personality. So much more work! But the product would be so much better. Truth be told, anything would be better than watching numbers change. That work took, a long time, but I got the bulk of it done. Pathfinding, walker guy generation, and an interface to look at the walker’s personality, even though its pretty ugly.

Proto2
Yes, I am using that comic sans ironically.

This is a screenshot of the latest build, I’ll have to compile a progress slideshow or video sometime in the future (probably when I’m actually done with the game) but this should give you some sort of idea about how moving from a development stance focused solely on the simulation and coding aspect of the game pigeonholed me into making a product not that fun. Now by taking graphics into account I also gave myself way more options for game play as well. Instead of having to rely only on user interaction in the beginning of the simulation, I can also have user interaction while the simulation is running, which opens up way more possibilities for a more enjoyable feedback loop. I’ll definitely be going into detail on what I came up with for that in a future post.

I hope you found this part development update, part game design analysis helpful or interesting, see you in the next update!

Introductions and the First Project

First of all, Welcome!

This website is going to be my internet home base, so to speak, across all these social media accounts that I’ve been trying to get setup and running for the past week or so. Never again will I think less of the public relations manager of an indie developer or other small business. There’s a lot of social media.

Anyway, what I’m thinking for the general flow of content for this website and Pineapple Labs is to have a few different projects going on at the same time that will be updated separately, cause variety is the spice of life right? Hopefully I’ll have one “software” project and one “hardware” project going on at the same time so I can have game development articles and 3d printing or robotics articles coming out at the same time.

With a general idea of how content updates are going to work, the first project that I’m going to introduce is an android mobile phone game that I’ve been working on for a couple months now, Lemonade Stand. “What?!” you cry out indignantly, “I thought you said before that there was going to be interesting game development articles, what is this mobile game clone?” Well, before you quickly close the window and go ridicule me on the tigsource forums or something (please don’t… I’m a nice guy! Promise!) at least hear me out first.

My previous game dev experience has pretty much been 3 years of unfinished Flash games, and an obsessive amount of reading and learning about game design along the way. However, I  have not actually finished a project. I want to, and need to, actually put something out there, even if the end product isn’t the most inspired groundbreaking game ever.

What will hopefully be inspiring and groundbreaking part of the game, and the part that is giving me the motivation to finally finish a project, is this devlog. I mentioned before, I spend an obsessive amount of time researching about game development, and there is an incredibly interesting science behind that sort of intangible aspect that really makes a game good. All game development is, at least, a large part of it, is trying to instill that sense of polish and execution that directly translates into the entire reason for the existence of games, fun.

So because my focus is not necessarily entirely on the end product of Lemonade Stand, but more on the creation of an experience that can be used as a case study for some important tenets of game design. That shift in focus naturally will make this less of a devlog, and something more like a series of articles detailing game dev concepts and how to implement them, how they interact with each other, etc.

That’s why I’m making Lemonade Stand as my first game, I wanted to use a simpler concept that everyone understands the basic premise of, in order to fully expose the meaning behind game mechanics or design decisions that could be otherwise overlooked. I’m not doing this to get rich, or even to make a profit,  I actually don’t even have a budget. I’m doing this because I want to learn more about game development, and I want to create resources for other people to learn more about it too.

So that’s our first software project, Lemonade Stand. Hopefully this weekend I can introduce the first hardware project, which is the official Pineapple Labs 3d printer. As for a timeline of updates on these projects, I really, really want to make the Wednesday/Weekend pattern a schedule, but I’m not sure yet how feasible that’s going to be.

I hope you found this introductory post at least a little interesting, see you in the next update!

Design a site like this with WordPress.com
Get started