That is some ugly UI code you got there…

My last post I talked about different UI designs that I could do for the tower defense game. I solicited feedback from a bunch of people and implemented what I think is a good touch system. Here are some screen shots of my efforts.

If the user selects a tile with no tower.
User selects a tile with a tower
User doesn’t have enough money to build all the towers.
User doesn’t have enough money to upgrade the tower

What I find interesting is how I started off refactoring code and feeling good about what I was doing. Then as time went on, my code got ugly really fast. I feel part of this is due to my misunderstanding of how to work with UIKit and SpriteKit, but maybe I am just trying to make excuses.

To appease my code design guilt, I kept telling myself that this is semi prototype code. That I can go back and change it, and that it is better to get something working then it being prefect. I once heard a game developer say, “if you code something quickly and ugly, and you never change it, then you coded it the right way”. I don’t know if I completely agree with that, but it rings true enough.

At this point I want to get feedback from play tester and let their feedback drive any improvements. My thinking is that when people only talk about the game play and not the touch system, that is when I know it is good enough. Or to put in a different way, if they don’t notice it, I did it right.

 

Does this sidebar make me look fat?

The main actions for my game is building, selling, and upgrading towers. I have been wondering how the user should do these actions?  Right now I am going to focus on just the building aspect. I might do another post that talks about selling and upgrading.

When I first implement this part of the game I chose to code it the quickest and easiest way that I could. Now that I want to get this ready for play testers, I think that I should create the UI/UX  the “correct way”. Basically draw everything out using pen and paper and get people feedback before coding. I already did some pen and paper work and decided to converted them to images (using Keynote), for your viewing pleasure.

UI 1:

This first design is basically what I currently have.  You tap on a tile and it display the towers that you can build. This is the simplest to code and is fairly easy to understand. The main thing I don’t like about this is how much finger movement is required to build a tower.

 

UI 2:

For this one when you tap on a tile it display the towers that you can build around the selected tile.  This one is very appealing to me, but I fear it is also the hardest one to code and get right.

 

UI 3:

The towers will always appear on the screen and it gives the user two ways to build towers. First they can tap on the tower to build and then tap the tile to build on. Second they can drag from the tower and it create a ghost version that they drag it to the tile they want it build at. I like the idea of the ghost version because I could also show the firing range of the tower.

 

UI 4:

For this one I am thinking more like an RTS game, where you have the list of towers in a scrollable area. It would have the same input methods as UI 3. The main difference is, it is reducing the visibility of the most importance part of the game, the map. I am currently displaying it on the right side of the screen, but it could be anywhere.

 

Those are currently the designs that I am fixating on, maybe after this post, more idea will come to me. Even with these designs I still have some things that I am not sure about:

  1. Finger travel: This is the main thing I want to avoid. On an iPhone it is not a big deal, but on an iPad (or Pro) this gets annoying.
  2. Blocking the screen: On the iPhone the screen is so small that I worry about having to many things on the screen. On the iPad I have lot of screen space.
  3. To many taps: I worry about requiring the user to tap a lot.
  4. Number of towers: I am not sure how many towers I want to have in this game.
  5. Needless coding: I don’t want to spend too much time coding when the input system may change.

I would love to get some feedback about these designs. Maybe you can think of something simpler. Maybe you have things that just bug you in Tower Defense games. I would love to hear it.

Slow down a little there…

My last post I mused over how I could handle the connect yet unconnected nature of using SpriteKit and how I was doing spawning and timing in my game. I am please the say that the solution was far more simpler then I was dreaming of.

To recap, my game run off the time it gets from the SKScene.update method. I would then calculate how much time has past between the frames and then pass the “delta” to all my other objects that needed updating.

After some searching I decided to treat my game logic more like how I would a physic engine. Instead of passing in the delta time between each frame. I now process a fixed amount of time, multiple times during each frame. Keep reading if that doesn’t make sense, hopefully I can explain this more clearly.

Currently SpriteKit calls the frame update method about every 0.016 seconds. I decided that I would set my step time to 0.014 seconds. Or in other words my game logic would calculate how much has changed in 0.014 seconds. It would does this calculation at least once every 0.016 seconds.

One problem with this is that if my game logic updates every 0.014 seconds and SpriteKit updates about every 0.016 seconds, after 7 frames update my game logic would be one frame behind (0.016 * 7 = 0.112;  0.014 * 7 = 0.098;  0.112 – 0.098 = 0.014). It doesn’t seem like a lot, but after a few seconds everything in the game would be wrong and no one would want to play it.

To fix this problem of missing steps, I keep a sum of the delta time between each frame in a variable called “simulationTime”.  Then if simulationTime is greater then 0.014 I take a step. After each step I subtract 0.014 from simulationTime. I continue doing this until simulationTime is less then 0.014.  Using the numbers above, every 7 frame updates I would take an extra step.

Now to have the game logic move faster or slower, it is just a matter of multiplying the delta time between frames by the speed the user selected. If the player wants the game to run 2x faster, I just times the frame delta by 2 and my game will take the correct number of steps each frame. If I want it to move half the normal speed then I just times it by 0.5 and it just works.

I am really happy to see is that even if the game is running 2x times faster (it is taking 3 to 4 steps each frame) the game is still running around 60 FPS without any problems. If I start having issues with a drop in FPS I can always raise or lower the step interval, but I wont worry about that unless I need too.

Overall I am pleased with this. I can now continue using SpriteKit and enjoy the animation, and still have the rest of my game run smoothly with no issues.  I am hoping that I can convert a more of my code to SpriteKit and reduce the number of lines that I have written.

 


One thing that I did notice during this time, is that I can no longer use the simulator; I have to use my device.  When testing in the simulator the game is running at about 12 to 20 FPS. While on my device I get about 60 FPS. I also notice strange slow downs on the simulator, but not on the device.

If you want to learn more about variable time stepping a great resource is this blog post.

 

Did you forget speed?

When I started working on this game, I took some old path movement code and adjusted it to work with the game. I considered it a quick(ish) implementation and hoped it would be fine. The code took a path and and every update it would pass in the time that had past and it would calculate where the object needed to be. This created a consistent linear movement which is what I wanted.

Unfortunately the code had two main problems. The enemies are only single file and the movement didn’t feel as smooth as I wanted; especially when it was running at 4x speed. Now that I am in a polishing mind set, for the past few days I started reworking this code.

My first though was to see what options SpriteKit and SKActions had for me, and to my surprised it has a follow path action.  This action work much better then what I had created.  The main difficulty that I have, is it has no dynamic speed control.  Well, that is not completely true, there are methods for controlling speed and duration of an action, but getting this to work for just one action yet alone for the many that I will have in the future made controlling and calculating the speed for actions far to difficult for me.

I felt like I was doing thing that hardest way possible, so I started to review documentation and blog posts to see if there was better way. I discover that there is a speed property on SKNode. This property will affect the speed on itself and all its children node and their corresponding SKActions. Meaning I could just set the scene (SKScene is a child of SKNode) speed to 2.0 and all animation and actions will move at that speed.  I wished I had notice this properties earlier, but I guess I just need to learn to read the manual more closely.

I wish that, that was the end of this tale, but there is still a problem.  If I slow down the game, the enemies will spawn really close together, if I speed up the game they will be further apart. The enemies still all move at the same speed it is just a problem when they spawn. I think I know what the problem is though.

When I spawn an enemy I am using the time I get from SKScene.update method which is in system time. In my code I calculate the different in system time from the last update and I pass that delta down to the update method of my game objects. My thinking is that I need to create what I am calling simulation time.  Simulation time is the time that the game thinks has past, not the what the wall clock says.

My thinking with simulated time is it will add a fix duration for each frame. This duration will be modified by the current select game speed. Then when I need to do a time base calculation I can know that simulation time will match what the user is seeing on the screen and everything will be nice and smooth.

I have a bit more research to do, because I don’t think this idea of simulated time is anything new. Hopefully I am not to far off on a workable solution.