Jason’s babblings.

More awesome than a ten pound bag of flapjacks.

Archive for April, 2010

Day 21: Inventory screen.

Posted by Plaidman on 28th April 2010

Nothing super interesting to write about last week.

Mostly just a lot of moving around data to support adding new screens into the game. Specifically a screen for inventory management and a screen to view Red’s status. The data storage needed to be relocated because opening a new screen requires that the game drawing thread be terminated, and since the game state data is stored in the game drawing thread, that would be terminated along with it.

To prevent this, I needed to decide whether to write all game state data into the save file, like you were quitting the game, or remove the data from the game drawing thread, then fix everything that breaks as a result. Saving the data to a file takes too much time and resources when we want to seamlessly switch to a new screen, so I went for the latter option.

Some other updates include:

  • Projectile weapon charge tracking for the three types of projectile weapons mentioned in the post for Day 16.
  • Player menu is dynamic based on whether or not you’re on stairs (to ascend and descend) or if you have a projectile availabile.
  • Saved game versioning, so when I make an update the game doesn’t crash when I try to load an old version of the save file.
  • Added inventory items into the save and load game routines.

Today and this weekend I’ll be writing up a random dungeon generator. Perhaps I’ll even have a full day to work on it between now and when I finish. I think I’m going to cut out some extra-curricular activities next week so I can put some solid blocks of time into the game. Chipping away at my todo list for only an hour every day isn’t cutting it anymore.

Current demo:

Red can change gear, drink potions, and read scrolls. Gear includes weapon slots for projectile and melee weapons, an armor slot that reduces damage, and two ring slots which can give various effects.

Posted in Uncategorized | No Comments »

Day 16(?): Quick update.

Posted by Plaidman on 22nd April 2010

I haven’t had a chance to work on the game much in the past week since car shopping took up most of my free time. In fact, I’m not even sure if I’m really on day 16 or not (I don’t count days I don’t touch the game). Whatever, I’ll continue counting from there in the future.

Last weekend and yesterday I’ve been making some major tweaks to things that go on behind the scenes. First I’ve optimized the frequency of garbage collection, which has reduced random noticeable slowdown, dare I say, completely. Another fix was making the game sleep when the phone sleeps. Previously if you were to turn off the phone with the game running, it would continue to idle and drain the battery. After that was fixed, I decided to tweak the application lifecycle calls a little bit better. Basically I moved some things around so they happen in the proper order, and don’t happen when they don’t need to – like I don’t need to save the game when the phone goes to sleep, just pause the game thread.

On the visible side of things, I’ve started planning and designing an inventory system for the player. I’m concentrating on weapons and armor for now, and the idea of damage types. Like a flame sword would do fire damage, and fire armor might reduce fire damage but make you more vulnerable to ice damage. These immunities and weaknesses also apply to monsters, of course. I’ve also moved the magic (fireball) charges into the specific weapons, so you can find a wand with 7 fireball charges, but when you use them up you have to find a new wand. Unfortunately, this system is very rudimentary right now. I’d like to polish the system to distinguish between [bow/arrows which can be found in the wild] vs [magic charges which cannot be recharged] vs [throwing weapon which can be retrieved].

Current demo:

Game doesn’t suffer from noticeable random slowdown anymore. Context menu pops up when you tap on Red with Inventory, Status, and Zap. Only Zap works for now.

Posted in Android | No Comments »

Day 13: Enemies should not run into walls.

Posted by Plaidman on 11th April 2010

I’ve already been seeing a bit of slowdown in my game, and I have a hunch it’s because of the way I set up my core state machine and timer. But that’s not what I want to write about today. Today we’re going to use Dijkstra’s Algorithm to make our monsters smarter.

Dijkstra’s Algorithm takes points connected by lines with weights and tries to find the path between two points with the least combined weight of the connecting lines. This is trivial if there’s only one path from A to B, but not so much if there’s multiple routes. The algorithm goes something like this:

  1. Start with all points’ values to infinity and not-final.
  2. Set your starting point to zero and remember it as current.
  3. For each point connected to current:
  4. -If that point’s value is not-final, ignore it.
  5. -If the point’s value is less than current’s value plus the weight of the line connecting, ignore it.
  6. -Otherwise set the point’s value equal to current plus the weight of the line.
  7. Mark current as finalized.
  8. Pick a non-finalized point connected to current and repeat steps 3-8 until there are no more non-finalized points in the graph.

Now each point’s value is the shortest possible combined weight of the path to the starting point. To find exactly which lines to travel, just traverse backward through the lowest-valued points until you reach the destination. Easy!

The point-line paradigm can be easily applied our game map: the points are map tiles, with a line to each of the tiles surrounding it. If we mark the player’s location as the starting point and each line has 1 weight, we can determine the number of steps required to hit each map tile, and the optimum path for each tile to get back to the player. So now if we have a monster on any tile, we can chase the player around corners; instead of having the monster blocked by a wall while trying to go north-west, it can go north to get around the wall. The monster can also seek out higher valued tiles if he wants to run away from the player.

I tried three approaches to write this algorithm for the game. The first attempt was an elegant recursive algorithm, which threw a Stack Overflow error after traversing 250 lines. Next attempt worked successfully, but took about a full second to calculate each tile – much too long. After some tweaks, I had it down to 1/20th of a second. Much better.

Aside from that, I did end up rewriting the core state machine to make the game very noticeably faster. And a few more things since day 10:

  • Haste status effect: you make two moves for every one enemy move.
  • Slow status effect: enemies make two moves for every one of your moves.
  • New slime enemy that uses the slow effect.
  • Optimized how projectiles are handled.
  • Fixed nasty bug when when monsters and projectiles are destroyed.
  • Moved all strings into resources so they can be easily translated in the future.

Current demo: Game runs at double the previous speed, and enemies follow you without getting stuck on walls. There’s a new type of enemy that keeps slowing you until you kill it.

Posted in Uncategorized | No Comments »

Day 10: Let’s save our game.

Posted by Plaidman on 6th April 2010

Now that we have our first trappings of a proper game, we should make it save the game between gaming sessions.

Android provides us with four ways to save our data from being lost forever, but first I will go on a tangent to explain the two types of data we should be concerned with: persistent and transient. Let’s say we’re writing a race timer application that keeps track of fastest times and includes a stopwatch function. In this case, the fastest times are persistent data because we want to be able to go into the application and see them after we close it. The stopwatch timer is transient because we don’t care to keep it if we close the application after a session of races. In most cases it’d be a nice feature to keep the stopwatch timer, but for the sake of the example, we don’t care about it.

Android offers us three ways to store persistent data: simple-settings based based, flat-file based, and database based data files. It also comes with a fourth way for transient-only data, but we’ll get to that later.

The first way is the simple-settings file, which will store simple primitives – a boolean true/false, a number, some text – and offers a very clean way to load the data later. This is good for simple settings, as the name would imply, but it’s not great for more complex things like custom objects or dynamic lists of simple objects, or dynamic lists of complex objects, god forbid. For that we’ll need something more flexible.

Databases offer a wonderfully powerful way to easily organize data and link the relevant pieces together, and provide a great interface for pulling only little bits of data at a time as it’s needed. For instance, if you have a notepad application that you want to pull out the titles of each note to display in a list, then you click on one and it loads that specific note’s body text at that time – the benefit is you don’t need to pull every note’s body text to display the initial note list, you can save it until you choose which note you want to view. The drawback of using this method is there’s a lot of overhead to creating and using the database. If we’re not selectively loading our data – as is the case with the game – the benefit is lost and the overhead is not worth it.

Finally, we have the flat-file. For this, we can only read and write text to a file. It doesn’t sound very complex or helpful at first glance, but it’s lack of complexity is made up for with it’s immense flexibility. If you can create a way to translate your complex objects and lists to and from a text string, you can simply write it to a file and read from it. The hard part is formatting your complex objects into a string that can be parsed later. Fortunately there’s a few libraries out there that can help us with this (json, xml, etc).

Now, the Android has a strange quirk where if you change the orientation of the device – landscape or portrait – it’ll destroy all data, even in the middle of running an application. You can stop this from happening by locking the device into a specific orientation, but offering support for multiple orientations is more user-friendly. This is where, in addition to the persistent data being captured using one of the methods above, we’ll capture transient data – so we don’t see the timer clock (using the run timer example) reset when we tilt the screen. This transient data is stored in a special fast-access section of memory so it’s quickly stored and retrieved, but it’s not intended for the often-more-hefty persistent data, which is stored on the file system.

Game updates:

  • Added the hooks necessary to let us know when we need to save and load.
  • Created a load method to match the save method from last update.
  • Players and Monsters can now cast projectile spells.

Current demo: Monster AI changed to throw one fireball when the player is in range. Red can launch a fireball too, but he only gets one per monster he’s already killed. The number of enemies per level is increased, as is Red’s initial health to make games last a little longer.

Here’s a video of the enemies and fireballs in action.

Posted in Android | 1 Comment »

Day 8: Let’s kill some enemies.

Posted by Plaidman on 5th April 2010

Now the good stuff. Let’s make some enemies! This is actually really easy with polymorphism, or inheritance of object properties.

Monsters will extend the Character class to inherit any Character stats and routines (most importantly the movement functions), similar to the Player extending the Character class. Also similar to the Player class, the Monster class will add a few extra things that are specific to monsters (like the AI routine). Really all we need to do is to define the sprites for this Monster and give it an artificial intelligence. That is the beauty of polymorphism.

We can do some fun stuff with the AI routine. For instance, we could have the monster pursue the character, or look for other enemies of its own type and group up before attacking, or hide and ambush the player solo. For now, let’s give our simple monster a routine that if Red is within two spaces of him (using our Coord’s distance function) he’ll chase Red and attack, otherwise wander randomly. Again, since we have everything set up in Coord, we just need to hook it all together and we’re done. Other monsters will have different attack strategies, but I won’t reveal them just yet.

Now let’s update our Player object. Since we have enemies, we want this character to be able to kill them and level up. The Player is inheriting the movement routine from the Character class, but we want to override it so we can check to see if we’re close to a monster, and if so, attack it. Here we only need to define our attack routine to define how much damage we do, and we’re set.

Back to the main game handler, we’ll keep track of a list of monsters, so we can cycle through them to draw or do the AI. We should also give the game an objective: kill as many monsters as you can before they kill you, and spawn them each time the map is cleared. Sounds fun doesn’t it? Yes, it does.

Some other updates since last time:

  • Added a HUD to display Red’s level, gold, and health.
  • Optimized the game’s state handler to kill some potential memory issues down the line.
  • Added a save-game for when we exit the game. Haven’t created the load-game yet, so this is useless for now, but it will be useful later.
  • Moved the animation frame tracker to all Character classes (Monsters and Player) so they can keep track of their individual animations.
  • Updated the draw routine to make all monsters walk between tiles (instead of teleport, as Red used to do).

Current demo: Enemies have a health stat, and they fight back if they aren’t killed quickly. The game ends when Red loses all his health.

Posted in Android | No Comments »

Day 6: Let’s improve the touch control.

Posted by Plaidman on 1st April 2010

I decided to publish the game as it is and hang up my Android development hat. Back to playing WoW. There’s a little late April Fools joke for you; I hope you enjoyed it.

There’s one more game control feature we left out from yesterday that I’d like to add.

The touch screen, as we left it yesterday, requires you to tap the screen every time you want to move Red a space. The TOUCH event only fires once, even if we hold our finger on the screen. We want to make it so if you tap and hold, it keeps moving your guy in the same direction. For extra credit we’ll make it so when you move your finger, the guy will start moving in the new direction. The thing is, Android doesn’t come with a HOLD touch event, so we’ll have to get creative with the TOUCH, MOVE, and RELEASE events.

First we should update our TOUCH event to store the touched coordinates into a variable (we’ll call it touchCoordinates), and set a flag that says we’re holding our finger on the screen (touchHolding), then we’ll call the analysis routine to periodically check if we’re still touching the screen and which direction we need to move. Now we’ll make the new RELEASE event to unset the touchHolding flag, so the analysis routine knows to stop checking. Finally, we’ll define the MOVE event to update the touchCoordinates location. Our analysis routine now knows when we touch and release the screen, and when we move our finger to a new direction. Clever huh?!

Next update I’ll write about adding enemies.

Current demo: We can tap-hold to move Red now. I’ve also added enemies with very simple AI (wanders randomly) and no stats. Here’s a video if you want to see it in action: http://www.youtube.com/watch?v=VsK2LJ9BmqA

Now the good stuff. Let’s make some enemies!

We’re going to extend the Character class to make the Monsters, so the Monster will inherit everything from the Character class (our movement functions, most importantly). The Monster will add two things that the Character didn’t have: a link to the Player and an Artificial Intelligence routine. The link to the player is used so the AI routine can know where the player is, and potentially try to pursue or run away from the player depending on if he’s aggressive or wounded.

For now we’re not going to worry about super complex AI, let’s keep it simple. We’ll use a random number generator to give us a number between 0 and 15. If the number is between 0 and 7, let’s say our enemy should go in a random direction. If it’s 8-15, Red should stand still. Since we have the movement functions already inherited from the Character object, we don’t need to do anything special! The monster will automatically check to see that it’s not trying to move on a wall tile, another monster or the player character.

Now let’s update our Player object. Since we have enemies, we want this character to be able to kill them and level up. The Player is inheriting the movement routine from the Character class, but we want to override it so we can check to see if we’re close to a monster, and if so, kill it. The nice thing about inheritance is overriding the Player’s movement routine won’t affect the Monster routine or anything else that’s inheriting from the Character class.

Back to the main game handler, we’ll keep track of a list of monsters, so we can go through them and perform some action – draw them, AI routine, etc. In fact, let’s add Monsters’ AI to the movement routine so after Red moves, the monsters can move too. While we’re at it, we should add a section to the drawing routine to draw the monsters, so we can actually see them. Now there’s just one more update to give the game an official objective: let’s add one monster at the start of the game, and add more monsters each time Red clears the map. Sounds fun doesn’t it? Yes, it does.

Posted in Android | No Comments »