Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am developing a single-player RPG platformer in XNA 4.0. I would like to add an ability that would make the time "stop" or slow down, and have only the player character move at the original speed(similar to the Time Stop spell from the Baldur's Gate series). I am not looking for an exact implementation, rather some general ideas and design-patterns.

EDIT: Thanks all for the great input. I have come up with the following solution

    public void Update(GameTime gameTime)
        {

            GameTime newGameTime = new GameTime(gameTime.TotalGameTime,
 new TimeSpan(gameTime.ElapsedGameTime.Ticks / DESIRED_TIME_MODIFIER));
            gameTime = newGameTime;

or something along these lines. This way I can set a different time for the player component and different for the rest. It certainly is not universal enough to work for a game where warping time like this would be a central element, but I hope it should work for this case. I kinda dislike the fact that it litters the main Update loop, but it certainly is the easiest way to implement it. I guess that is essentialy the same as tesselode suggested, so I'm going to give him the green tick :)

share|improve this question

4 Answers 4

up vote 8 down vote accepted

This might be a bad solution, but not necessarily. If you're using delta time, you can change that to change the speed of certain things.

For example:

player.update(dt)
dt = dt * .5 --half speed
enemy.update(dt)

This, of course, only works if you can tell when you're updating the enemy rather than something else. You could also just give everything a speed value and do something like:

x = x + xspeed * dt * speed
share|improve this answer
    
The first part makes perfect sense, the second part isn't clear –  Zehelvion Sep 30 '12 at 16:27
2  
Just give each object that moves a speed variable which you can change, and when you have a transformation (of x, for example), multiply the magnitude by the speed variable. –  tesselode Sep 30 '12 at 17:31
    
Makes sense now. :) –  Zehelvion Sep 30 '12 at 17:43
    
The second idea sounds...off. Just scaling the movement by the "speed" factor may work for physics driven objects, but AI would be able to react at normal speed, with only their movement slowed/impaired. –  melak47 Sep 30 '12 at 23:21
    
What do you mean the AI would be able to react at normal speed? What code would the AI have that couldn't have a speed variable applied? –  tesselode Oct 1 '12 at 0:29

Using delta time(milliseconds that passed since the last frame) may not be sufficient to slow enemies down. Things like attack rate might be implemented based on the last attack time. While it will slow down movement if it is time based, it will neglect to slow attack rate, spell casting and other effects (Health regeneration, spell effects duration).. and such

If you want to slow down a large group of game elements in a single player game, you could create a second internal clock for each creature, the clock starts at the current time when the creature appears. When a slow spell is cast, each frame, the clock is incremented by x% of the time that actually passed. All monster behavior is then determined by it's internal clock. If various monsters have resistance to slow, they can use their own clock, it is basically an integer that does not require a lot of space or computation.

When the slow effect stops, the clocks are still being used and get incremented by 100% of the time that actually passed.

This could also work for hasten spells.

@Sidar : I see two choice,

  1. Internal clock per creature. In order to find out if the creature is ready to attack again: save the the last time each attack was used + recharge time and check if the internal clock is already passed that time.

  2. One timer per attack: You know how long it takes the attack to recharge and you simply set a timer and subtract the time that passed * (1-slowdown%) each turn.

I personally prefer to avoid subtracting multiple individual timers and user one internal clock to save on processing time and complexity.

It is really up to preference(It doesn't affect performance that much).

share|improve this answer
    
The need for internal clocks is not needed. It simply comes down to a multiplier that you can( in someway) link to your object that either increases or decreases the product of your dt ( delta time ) You could manage the objects by groups or whatever means. I think your way might be a bit excessive. But hey if it works...then it works. –  Sidar Sep 30 '12 at 16:50
    
@Sidar If You avoid this, you will probably need a clock per attack just to time attack recharge, Spell duration and such things. At least this way you only need to update one clock and simply keep the 'last activation' time for the reset of the properties. –  Zehelvion Sep 30 '12 at 17:00
    
His question however is regarding slowing down the environment except the player. To me that sounds like the simplest form of just multiplying the dt with a number lower than 1. While keeping it as is for the player. –  Sidar Sep 30 '12 at 17:27
    
Well, slowing the environments includes slowing their attack rate as well as their other abilities (since it is a rpg), there could be various mob abilities that rely on recharge time. Heals, buffs, debuffs, spells and etc. Not to mention activation time. –  Zehelvion Sep 30 '12 at 17:44

You just need two different clocks instead of one, one for the time relevant to the gameplay and one "true" time.

currentGameTime = 0;
gameSpeed = 1.0f;
[...]
currentApplicationTime = GetTime():
timeDelta = (currentApplicationTime - lastApplicationTime)*gameSpeed;
currentGameTime += timeDelta;
lastApplicationTime = currentApplicationTime;

Then you can simply change gameSpeed to speed up (>1) or slow down time (<1). For the player to move at different speed just check wheter the time is slowed down or not.

share|improve this answer

You can start with a simple solution as the one exposed by tesselode or Mr Beast. But if you start mixing complex things, i.e. a bullet time while a slowdown spell is cast, you'll get stuck.

I suggest you implement a clock hierarchy:

.
├── Main clock
│   └── UI clock
│   └── 3D clock
│       ├── GFX clock
│       └── Gameplay clock
│           └── Slowdown spell clock 01
│           └── Slowdown spell clock 02

Everything in your game should use delta times from one of the clock: graphics effects run on the GFX clock, AI & animation runs on the Gameplay clock, creatures affected by a slowdown spell run on a temporary Slowdown spell clock, etc. Then various things affect different parts of your hierarchy: a slowdown spell creates and affects a custom clock, while a bullet time will affect the whole 3D clock hierarchy.

share|improve this answer
    
Thanks, this an important insight. However, I think I will keep thinks simple, since it doesn't make sense in my particular case that multiple slowdown effects would occur at the same time. –  David Miler Oct 1 '12 at 9:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.