Implementing a Fast Forward feature for Tower Defense


(PLC Gremlin) #1

Hey All,

I am trying to get a Tower Defense game finished and am struggling with one of the key features. I am using Fixed Time step and am working on a way to implement a fast forward feature. I’m currently running at 40fps and can’t simply increase the framerate to fast forward the simulation. I would like to double the speed of the simulation and I don’t think that any acceptable fps at standard speed could be doubled reliably on slower hardware.

I have tried to simply call the World/Engine Update Twice in a row, for instance, Calling Super.update() twice in the update function of Main.as. This works for the most part (Simulation Speed Wise) but messes with some of my code that handles mouse clicks/etc. It seems to call the functions that are based on mouse input twice in a row. In some cases, I use a mouse click to delete an entity so calling it twice in a row throws a null object error… So I know there is weird things going on just by trying to call the Engine update twice.

I’m sure there is a simple way to do this that is eluding me. I really just need to update all my game logic (Entity Updates) twice before starting the delay/waiting on the next Frame.


(JP Mortiboys) #2

Have you tried FP.rate = 2; ?

Edit: that might only work with variable timesteps; not sure.


(Ultima2876) #3

FP.rate works with both fixed and variable timestep as long as all your motion-related code uses FP.elapsed. In a fixed-framerate game people don’t tend to bother with this, unfortunately, so it’s probably not going to be as simple as that. You could go through all your entities modifying them to use FP.elapsed in the correct places, then use FP.rate to adjust the simulation speed.


(PLC Gremlin) #4

Ha. Funny. My game has been variable timestep from the very beginning and just a couple days ago I decided that it wasn’t deterministic enough. The outcome of the game would(could) change when I changed FPS or speed. It was only then that I decided to change to Fixed Timestep,… at which point I overlooked the fact that I could still change FP.Rate to change speed. The good news is that all my FP.elapsed is still scattered all throughout my code and I just commented it out. Looks like I will uncomment it back in and try changing the FP.rate for the win. Thanks for the help. One other thought, how hard do you all think it would be to separate the rendering from the game logic update. It would be nice to have a fixed timestep update for all the game logic but allow the rendering to operate using variable timesteps to keep it rendering smoother. I guess the question really is would it be worth the effort.


(PLC Gremlin) #5

I may have to scratch my last post… I started looking at my code and it hit me again why I was originally just trying to get the Engine to Update Twice in a row. I’m pretty sure just changing the rate will not work for a Tower Defense Game. Here is the reason.

At normal speed, A Creep may be moving past a tower and due to the range of the tower and the # of game loop updates it takes for the Creep to make it past tower,… It could be hit twice and die. At Double speed, the same Creep may get hit once but then on the next update it may travel twice as far in one update and it could be out of range of the turret and wouldn’t get hit a second time.

I think now though looking at the Engine class, I can modify the engine to force multiple updates in a row and it should work. The Engine already does this if it has to skip frames. There is a while loop that runs the update multiple times until it catches up.

From Engine.AS

              while (_delta >= _rate)
		{
			FP.elapsed = _rate * FP.rate * 0.001;
			
			// update timer
			_updateTime = _time;
			_delta -= _rate;
			_prev = _time;
			
			// update loop
			if (!paused) update();
			
			// update input
			Input.update();
			
			// update timer
			_time = getTimer();
			FP._updateTime = _time - _updateTime;
		}

I think I will just add a for loop around this code and have it execute twice if I’m in Fast Forward Mode… Will let yall know how it goes.


(Ultima2876) #6

I wonder if it might be better to patch this functionality into FlashPunk itself. Seems like something a lot of people might want to do, and having a fixed-timestep equivalent for rate that is deterministic in the way you describe seems like something the engine should have support for anyway (plus would be easily added).

With regards to the render thing, the render loop is already separate (particularly noticeable in fixed timestep mode)! If the game is lagging, it will do multiple updates before it renders (as you see above). There isn’t much of an advantage to doing multiple renders per update… because without an update to move sprites etc, you’ll essentially just be rendering the exact same thing twice in a row. On mobile that means wasting battery to draw twice as much as you need to (and on desktop/web it means wasting extra CPU for no reason) :wink:


(PLC Gremlin) #7

Here is what I ended up with to make the Engine.AS update twice in a row to double my speed when needed and stay Deterministic.

                _deltaTemp = _delta; //Added on 2/25/14
		
		for (var i:int = 0; i < FP.updateSpeed; i++) //Added on 2/25/14
		{
		_delta = _deltaTemp; //Added on 2/25/14
		
		while (_delta >= _rate)
		{
			FP.elapsed = _rate * FP.rate * 0.001;
			
			// update timer
			_updateTime = _time;
			_delta -= _rate;
			_prev = _time;
			
			// update loop
			if (!paused) update();
			
			// update input
			Input.update();
			
			// update timer
			_time = getTimer();
			FP._updateTime = _time - _updateTime;
		}
		
		}

I added in FP.updateSpeed as a uint. I can now change it from 1 to 2 when I want the engine to double its speed and it works good for my purposes. This is dissimiliar to FP.rate in that we can’t use anything other than whole numbers for obvious reasons. So we can only Double, Triple Speed, etc…

I have to disagree somewhat that the Rendering is separated from the update in Fixed frame mode. It is a separate function but it is only called at the interval that the FPS is set at (at most) whereas in Variable timestep it gets called about as fast as possible which is why things tend to appear to move smoother instead of jerking around.

In the onTimer function of Engine, you have the line that Returns the function early if enough time hasnt elapsed for one full frame.

if (_delta < _rate) return;

The Render function is called down below that. If one were to let it render , lets say at double the speed of the fixed update or faster, we would have to keep up with a separate Elapsed time property for the render and our gamelogic would have to base sprite movements,etc… on that for rendering until the actual “deterministic” update happened. I think…

Also, the FP.elapsed variable is somewhat Faked in Fixed timestep mode so that it always evaluates to the exact same time period on every update.Not that its a problem(it has to be that way), just something Ive been thinking about since I looked at the way it works.

I’m going to try and not worry with that right now and keep chugging along on the game since I have the Fast Forward working. Thanks for the help.


(Ultima2876) #8

In variable timestep it gets called once per frame at most as well - that’s just the way Flash handles frames (no timer callback ever happens more than once per frame). So whether you use fixed or variable timestep, it will only ever render a maximum of FPS frames per second.

The actual reason for things moving smoother in variable timestep mode is because you’re multiplying their movement by an exact elapsed timestep instead of compensating by sometimes updating multiple times. This is called temporal aliasing; consider being able to move at 1.5x each update (variable, looks more fluid because of the constant motion) versus having to move 1x, 2x, 1x, 2x, 1x, 2x (fixed and jerky because we perceive the change in motion speed as ‘jagginess’ - temporal aliasing). This actually isn’t related to how fast the game is rendering (but will certainly be more noticeable if you’re running at a lower framerate thanks to each frame being visible for longer).

Having a separate render that is called as much as possible is much more useful in games that have heavy use of physics. There are some good articles on the internet about this, but it’s fiercely difficult to get right and probably outside the scope and needs of a flash game.


(Per_K) #9

I don’t know if I’m being overly simple here, but the solution that comes to my mind is;

Add var speedfactor:Number=1;

Everything that change during update, that should speed up in fast forward, you take x speedfactor. In normal mode speedfactor is set as 1. In fast forward it is set as 2 (or any other number you might like).


(Ultima2876) #10

That’s what the FP.rate variable does, but it caused some problems with determinism as the OP described here:

At normal speed, A Creep may be moving past a tower and due to the range of the tower and the # of game loop updates it takes for the Creep to make it past tower,… It could be hit twice and die. At Double speed, the same Creep may get hit once but then on the next update it may travel twice as far in one update and it could be out of range of the turret and wouldn’t get hit a second time.


(PLC Gremlin) #11

Ultima, Good Discussion. When I initially mentioned separating the rendering from the Main Gamelogic update (in Fixed timestep), I was referring to doing something like is described in this article. http://www.koonsolo.com/news/dewitters-gameloop/

I am just not describing it well. By the time you get to the bottom of the article, he is explaining what I was trying to. Basically a hybrid approach where you use a fixed timestep like we are using in Flashpunk but Rendering with a variable timestep using interpolation/prediction. Flashpunk’s fixed timestep does have time left over where you could do multiple renders to smooth movement based on the “real” eleapsed time. The actual simulation would still be based on the fixed tick so that it can maintain its determinism.

I agree that this is outside my needs for my flash Tower Defense game. I have the determinism I need now and can also speed up the simulation without affecting the results so I’m set. Now the hybrid timestep approach is just something to think about improving in order to distract me from actually completing my game…I could use my time more wisely finding someone who could help in the art department for my games…:wink:


(Ultima2876) #12

Ah, yes, I remember that article. It’s great; I’ve not done a game myself yet where I’ve tried it, but if you have the time it could definitely look nice :wink:

My primary concern tends to be mobile where having time to do extra rendering is very rare (rendering is almost always the bottleneck on mobile).

I imagine if it’s done in a bit of a different way this could be a very useful technique though. Running the update loop at 30fps and keeping the render at 60 using interpolation could be an interesting thing to try. If all our motion is interpolated in the render cycle, who’s to say that we need to bother running a ‘full’ update at 60 fps? In theory it’ll look just as smooth as if we were truly updating at 60fps, and input delay shouldn’t be a concern because a lot of games run at 30fps already (including a lot of commercial ones) and are fine.

It could be a nice outside-the-box way to save a lot of processing time… (and on mobile, battery power ;D)