How to make a game run at the same speed on any PC?

Hello everyone!
I asked this a while ago here, but I lost the code, and you can’t search
messages… (Can you?)
I remember it was something about calculating distance (SDL_GetTicks()
and SDL_Delay) or something like that, but how was it? Thanks!

P.S: I’m sorry if I provided insufficient data, I can’t remember…

L-28C wrote:

I asked this a while ago here, but I lost the code, and you can’t search
messages… (Can you?)
I remember it was something about calculating distance (SDL_GetTicks()
and SDL_Delay) or something like that, but how was it? Thanks!

The idea is to decouple display updates with game-world data updates;
for example, in a 3D engine, you generally want to update the screen as
fast as possible, while having the objects in the game updating at some
natural rate (maybe 24x/second?.. it probably varies by game).

There are basically two ways of doing this:

  1. a single game loop:

    init_game()
    last_update = get_time()
    while( game_is_playing ):
    draw_screen()

     delta = get_time() - last_update
     if( delta >= update_interval ):
          update_game_world()
          last_update = get_time()
    
  2. a game loop and a thread:

    // Main thread game loop:
    init_game()
    launch_world_thread()
    while( game_is_playing ):
    draw_screen()

    // Game world update thread:
    while( game_is_playing ):
    sleep_until_update()
    update_game_world()

Using a thread to handle updates can be a cleaner implementation, but it
introduces the normal threading issues, plus the fact that at least two
platforms (Windows and Mac OS X) require you to handle input and UI
events from the main loop. (Well, you can only receive them there, you
can handle them any way you want.)

Hope that helps!–
Chris Herborth (@Chris_Herborth) http://www.pobox.com/~chrish/
Never send a monster to do the work of an evil scientist.

Hey! I’ve seen that code before! It’s the one I was talking about! :smiley:
Just… What is update_interval supposed to be? And shouldn’t
draw_screen() be inside the if statement? Thanks!

Chris Herborth wrote:> L-28C wrote:

I asked this a while ago here, but I lost the code, and you can’t search
messages… (Can you?)
I remember it was something about calculating distance (SDL_GetTicks()
and SDL_Delay) or something like that, but how was it? Thanks!

The idea is to decouple display updates with game-world data updates;
for example, in a 3D engine, you generally want to update the screen as
fast as possible, while having the objects in the game updating at some
natural rate (maybe 24x/second?.. it probably varies by game).

There are basically two ways of doing this:

  1. a single game loop:

    init_game()
    last_update = get_time()
    while( game_is_playing ):
    draw_screen()

     delta = get_time() - last_update
     if( delta >= update_interval ):
          update_game_world()
          last_update = get_time()
    
  2. a game loop and a thread:

    // Main thread game loop:
    init_game()
    launch_world_thread()
    while( game_is_playing ):
    draw_screen()

    // Game world update thread:
    while( game_is_playing ):
    sleep_until_update()
    update_game_world()

Using a thread to handle updates can be a cleaner implementation, but it
introduces the normal threading issues, plus the fact that at least two
platforms (Windows and Mac OS X) require you to handle input and UI
events from the main loop. (Well, you can only receive them there, you
can handle them any way you want.)

Hope that helps!

Hmm? I thought I had answered to this topic… >:(
Anyways, I asked what update_interval was supposed to be… Thanks!

Chris Herborth wrote:> L-28C wrote:

I asked this a while ago here, but I lost the code, and you can’t search
messages… (Can you?)
I remember it was something about calculating distance (SDL_GetTicks()
and SDL_Delay) or something like that, but how was it? Thanks!

The idea is to decouple display updates with game-world data updates;
for example, in a 3D engine, you generally want to update the screen as
fast as possible, while having the objects in the game updating at some
natural rate (maybe 24x/second?.. it probably varies by game).

There are basically two ways of doing this:

  1. a single game loop:

    init_game()
    last_update = get_time()
    while( game_is_playing ):
    draw_screen()

     delta = get_time() - last_update
     if( delta >= update_interval ):
          update_game_world()
          last_update = get_time()
    
  2. a game loop and a thread:

    // Main thread game loop:
    init_game()
    launch_world_thread()
    while( game_is_playing ):
    draw_screen()

    // Game world update thread:
    while( game_is_playing ):
    sleep_until_update()
    update_game_world()

Using a thread to handle updates can be a cleaner implementation, but it
introduces the normal threading issues, plus the fact that at least two
platforms (Windows and Mac OS X) require you to handle input and UI
events from the main loop. (Well, you can only receive them there, you
can handle them any way you want.)

Hope that helps!

Hi,

Anyways, I asked what update_interval was supposed to be… Thanks!

Just a constant - it’s the interval between game world updates (in ms I think).
Like update_interval = 500 would make it call the update function every 1/2 sec.

The point is to make the updating function to be called on a fixed
interval independent of the machine the program is run on. The screen
OTOH is updated as often as possible.

  • Janne Junnila

There’s a great article on fixing your logic timestep here:
http://www.gaffer.org/articles/

His other articles are also very good. Hope this helps,

Peter

“Janne Junnila” <janne.junnila at gmail.com> wrote in message
news:770a6dc40607230033x6df09271xbca8208b6872a5a6 at mail.gmail.com…> Hi,

Anyways, I asked what update_interval was supposed to be… Thanks!

Just a constant - it’s the interval between game world updates (in ms I
think).
Like update_interval = 500 would make it call the update function every
1/2 sec.

The point is to make the updating function to be called on a fixed
interval independent of the machine the program is run on. The screen
OTOH is updated as often as possible.

  • Janne Junnila

Hmm… Now it all screwed up… :frowning:
I think my movement mechanism is wrong… I’m doing it like, at
SDL_KEYUP event, the movement key for that direction goes to 0… But
at SDL_KEYDOWN, it the variable goes to 1, so the dude’s moving…
But since this function is called only every half a second, the movement
is updated every half a second too! So, it starts and stops moving half
a second after my key presses and releases… :frowning:

Note that I add PLR_SPEED to the player’s X/Y positions in the
update_screen function… I tried putting it in the same function as
the event handling, but it didn’t work either, it moved only every half
a second…

Do you know how to fix this? Thanks very much! :wink:

Janne Junnila wrote:
Peter Mackay wrote:> There’s a great article on fixing your logic timestep here:

http://www.gaffer.org/articles/

His other articles are also very good. Hope this helps,

Peter

“Janne Junnila” <janne.junnila at gmail.com> wrote in message
news:770a6dc40607230033x6df09271xbca8208b6872a5a6 at mail.gmail.com

Hi,

Anyways, I asked what update_interval was supposed to be… Thanks!
Just a constant - it’s the interval between game world updates (in ms I
think).
Like update_interval = 500 would make it call the update function every
1/2 sec.

The point is to make the updating function to be called on a fixed
interval independent of the machine the program is run on. The screen
OTOH is updated as often as possible.

  • Janne Junnila

Hi,

Anyways, I asked what update_interval was supposed to be… Thanks!

Just a constant - it’s the interval between game world updates (in ms I think).
Like update_interval = 500 would make it call the update function every 1/2 sec.

The point is to make the updating function to be called on a fixed
interval independent of the machine the program is run on. The screen
OTOH is updated as often as possible.

  • Janne Junnila

You don’t have to use 500. That was just a throwaway value. Most demo
code I’ve seen uses a value of 30, which ostensibly gives you a frame
rate of about 30 frames a second, probably a little closer to 33. That
means the sampling rate of your events would be about fifteen times
faster than a half second interval. I haven’t tried this, and probably
won’t get around to it any time soon, but if you want to make your
sampling even faster than that you could probably create a shorter delay
loop inside a larger loop to do your sampling and update what’s
necessary before updating the screen.

In a project I’ve had to put off I was thinking of looking at the
keyboard state at the moment that the decision needs to be made. I have
an object that moves towards intersections and can only move forward,
without speed change, until then . So the only thing that matters is
whether one of four possible keys is pressed at that specific time.
Maybe something like that is what you need.

Lilith

Hmm… Now it all screwed up… :frowning:
I think my movement mechanism is wrong… I’m doing it like, at
SDL_KEYUP event, the movement key for that direction goes to 0…
But
at SDL_KEYDOWN, it the variable goes to 1, so the dude’s moving…
But since this function is called only every half a second, the
movement
is updated every half a second too! So, it starts and stops moving
half
a second after my key presses and releases… :frowning:

Note that I add PLR_SPEED to the player’s X/Y positions in the
update_screen function… I tried putting it in the same function as

the event handling, but it didn’t work either, it moved only every
half
a second…

Do you know how to fix this? Thanks very much! :wink:

Janne Junnila wrote:
Peter Mackay wrote:

There’s a great article on fixing your logic timestep here:
http://www.gaffer.org/articles/

His other articles are also very good. Hope this helps,

Peter

“Janne Junnila” <janne.junnila at gmail.com> wrote in message
news:770a6dc40607230033x6df09271xbca8208b6872a5a6 at mail.gmail.com

Hi,

Anyways, I asked what update_interval was supposed to be…
Thanks!

Just a constant - it’s the interval between game world updates (in
ms I

think).
Like update_interval = 500 would make it call the update function
every

1/2 sec.

The point is to make the updating function to be called on a fixed
interval independent of the machine the program is run on. The
screen

OTOH is updated as often as possible.

  • Janne Junnila

Hi,

Anyways, I asked what update_interval was supposed to be…
Thanks!

Just a constant - it’s the interval between game world updates (in
ms I
think).

Like update_interval = 500 would make it call the update function
every 1/2
sec.

The point is to make the updating function to be called on a fixed
interval independent of the machine the program is run on. The
screen>>> On 7/23/2006 at 7:53 PM, in message <ea15lh$uag$1 at sea.gmane.org>, leo28c at gmail.com wrote:

OTOH is updated as often as possible.

  • Janne Junnila

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Hmm… Still not working :frowning:
I’m testing the game with 2 comps, one of 2.8GHz and one with half of
that (1.4GHz)… The 1.4GHz PC takes like one second to load the
screen, and the 2.8GHz one is instant. Then, if I press the Left arrow
on both comps at the same time and leave them pressed, the 1.4GHz one
takes just a bit longer to get to the end of the screen. Why is this?
Some misdesign? I only have a guy walking around sand tiles with a car
that he can get on by walking into it, no rotating or anything weird
either… How can I fix it? Thanks!

PD: It doesn’t take

Lilith Calbridge wrote:> You don’t have to use 500. That was just a throwaway value. Most demo

code I’ve seen uses a value of 30, which ostensibly gives you a frame
rate of about 30 frames a second, probably a little closer to 33. That
means the sampling rate of your events would be about fifteen times
faster than a half second interval. I haven’t tried this, and probably
won’t get around to it any time soon, but if you want to make your
sampling even faster than that you could probably create a shorter delay
loop inside a larger loop to do your sampling and update what’s
necessary before updating the screen.

In a project I’ve had to put off I was thinking of looking at the
keyboard state at the moment that the decision needs to be made. I have
an object that moves towards intersections and can only move forward,
without speed change, until then . So the only thing that matters is
whether one of four possible keys is pressed at that specific time.
Maybe something like that is what you need.

Lilith

On 7/23/2006 at 7:53 PM, in message <ea15lh$uag$1 at sea.gmane.org>, @Leo_Cabrera wrote:
Hmm… Now it all screwed up… :frowning:
I think my movement mechanism is wrong… I’m doing it like, at
SDL_KEYUP event, the movement key for that direction goes to 0…
But
at SDL_KEYDOWN, it the variable goes to 1, so the dude’s moving…
But since this function is called only every half a second, the
movement
is updated every half a second too! So, it starts and stops moving
half
a second after my key presses and releases… :frowning:

Note that I add PLR_SPEED to the player’s X/Y positions in the
update_screen function… I tried putting it in the same function as

the event handling, but it didn’t work either, it moved only every
half
a second…

Do you know how to fix this? Thanks very much! :wink:

Janne Junnila wrote:
Peter Mackay wrote:

There’s a great article on fixing your logic timestep here:
http://www.gaffer.org/articles/

His other articles are also very good. Hope this helps,

Peter

“Janne Junnila” <janne.junnila at gmail.com> wrote in message
news:770a6dc40607230033x6df09271xbca8208b6872a5a6 at mail.gmail.com

Hi,

Anyways, I asked what update_interval was supposed to be…
Thanks!

Just a constant - it’s the interval between game world updates (in
ms I

think).
Like update_interval = 500 would make it call the update function
every

1/2 sec.

The point is to make the updating function to be called on a fixed
interval independent of the machine the program is run on. The
screen

OTOH is updated as often as possible.

  • Janne Junnila
    Hi,

Anyways, I asked what update_interval was supposed to be…
Thanks!

Just a constant - it’s the interval between game world updates (in
ms I
think).

Like update_interval = 500 would make it call the update function
every 1/2
sec.

The point is to make the updating function to be called on a fixed
interval independent of the machine the program is run on. The
screen

OTOH is updated as often as possible.

  • Janne Junnila

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

I can’t claim to be an expert on this kind of programming so I can only
offer a guess. I’m still kind of new to the process and have had to put
off getting into the game aspect of it in order to develop the graphics
for a presentation (using SDL) I’ll be giving in January.

My feeling about the difference in speed is this…

Using the tick count is still very inaccurate. Despite the speed of
the process, there’s so much going on with processes that support the OS
that can’t be interrupted that time resolution to 1 ms is really
impossible. You can really expect something more on the order of 10 ms.
The slower processor means that the OS is taking longer to deal with
its overhead so you may be coming in closer to the 10 ms resolution or
beyond. Maybe not on every iteration of your loop but often enough to
cause some sort of timing difference.

That’s the downside of having to use the OS for support. Then again,
who wants to write a program that you have to boot the system to play.
This kind of thing was perhaps a bit easier to do on DOS based systems
because DOS could be cut from interfering with the program until it
finished unless you needed DOS to do some output for you. But you’d
also have to deal with different processor speeds in a different manner
too.

Lilith

Hmm… Still not working :frowning:
I’m testing the game with 2 comps, one of 2.8GHz and one with half of

that (1.4GHz)… The 1.4GHz PC takes like one second to load the
screen, and the 2.8GHz one is instant. Then, if I press the Left
arrow
on both comps at the same time and leave them pressed, the 1.4GHz one

takes just a bit longer to get to the end of the screen. Why is
this?
Some misdesign? I only have a guy walking around sand tiles with a
car
that he can get on by walking into it, no rotating or anything weird

either… How can I fix it? Thanks!

PD: It doesn’t take

Lilith Calbridge wrote:

You don’t have to use 500. That was just a throwaway value. Most
demo

code I’ve seen uses a value of 30, which ostensibly gives you a
frame

rate of about 30 frames a second, probably a little closer to 33.
That

means the sampling rate of your events would be about fifteen times
faster than a half second interval. I haven’t tried this, and
probably

won’t get around to it any time soon, but if you want to make your
sampling even faster than that you could probably create a shorter
delay

loop inside a larger loop to do your sampling and update what’s
necessary before updating the screen.

In a project I’ve had to put off I was thinking of looking at the
keyboard state at the moment that the decision needs to be made. I
have

an object that moves towards intersections and can only move
forward,

without speed change, until then . So the only thing that matters
is

whether one of four possible keys is pressed at that specific time.

Maybe something like that is what you need.

Lilith

Hmm… Now it all screwed up… :frowning:
I think my movement mechanism is wrong… I’m doing it like, at
SDL_KEYUP event, the movement key for that direction goes to 0…
But
at SDL_KEYDOWN, it the variable goes to 1, so the dude’s moving…
But since this function is called only every half a second, the
movement
is updated every half a second too! So, it starts and stops
moving

half

a second after my key presses and releases… :frowning:

Note that I add PLR_SPEED to the player’s X/Y positions in the
update_screen function… I tried putting it in the same function
as

the event handling, but it didn’t work either, it moved only every
half
a second…

Do you know how to fix this? Thanks very much! :wink:

Janne Junnila wrote:
Peter Mackay wrote:

There’s a great article on fixing your logic timestep here:
http://www.gaffer.org/articles/

His other articles are also very good. Hope this helps,

Peter

“Janne Junnila” <janne.junnila at gmail.com> wrote in message

news:770a6dc40607230033x6df09271xbca8208b6872a5a6 at mail.gmail.com

Hi,

Anyways, I asked what update_interval was supposed to be…
Thanks!

Just a constant - it’s the interval between game world updates
(in

ms I

think).
Like update_interval = 500 would make it call the update
function

every

1/2 sec.

The point is to make the updating function to be called on a
fixed

interval independent of the machine the program is run on. The
screen

OTOH is updated as often as possible.

  • Janne Junnila
    Hi,

Anyways, I asked what update_interval was supposed to be…
Thanks!

Just a constant - it’s the interval between game world updates
(in

ms I

think).

Like update_interval = 500 would make it call the update function
every 1/2
sec.

The point is to make the updating function to be called on a
fixed>>> On 7/23/2006 at 10:40 PM, in message <ea1fem$gga$1 at sea.gmane.org>, leo28c at gmail.com wrote:

On 7/23/2006 at 7:53 PM, in message <ea15lh$uag$1 at sea.gmane.org>, leo28c at gmail.com wrote:
interval independent of the machine the program is run on. The
screen

OTOH is updated as often as possible.

  • Janne Junnila

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Oohh… So it’s OK to leave it like that? Will the users notice it?
This is a multiplayer game, so there can’t be someone that has an
advantage… :stuck_out_tongue:

Anyone else know? Thanks!

Lilith Calbridge wrote:> I can’t claim to be an expert on this kind of programming so I can only

offer a guess. I’m still kind of new to the process and have had to put
off getting into the game aspect of it in order to develop the graphics
for a presentation (using SDL) I’ll be giving in January.

My feeling about the difference in speed is this…

Using the tick count is still very inaccurate. Despite the speed of
the process, there’s so much going on with processes that support the OS
that can’t be interrupted that time resolution to 1 ms is really
impossible. You can really expect something more on the order of 10 ms.
The slower processor means that the OS is taking longer to deal with
its overhead so you may be coming in closer to the 10 ms resolution or
beyond. Maybe not on every iteration of your loop but often enough to
cause some sort of timing difference.

That’s the downside of having to use the OS for support. Then again,
who wants to write a program that you have to boot the system to play.
This kind of thing was perhaps a bit easier to do on DOS based systems
because DOS could be cut from interfering with the program until it
finished unless you needed DOS to do some output for you. But you’d
also have to deal with different processor speeds in a different manner
too.

Lilith

On 7/23/2006 at 10:40 PM, in message <ea1fem$gga$1 at sea.gmane.org>, @Leo_Cabrera wrote:
Hmm… Still not working :frowning:
I’m testing the game with 2 comps, one of 2.8GHz and one with half of

that (1.4GHz)… The 1.4GHz PC takes like one second to load the
screen, and the 2.8GHz one is instant. Then, if I press the Left
arrow
on both comps at the same time and leave them pressed, the 1.4GHz one

takes just a bit longer to get to the end of the screen. Why is
this?
Some misdesign? I only have a guy walking around sand tiles with a
car
that he can get on by walking into it, no rotating or anything weird

either… How can I fix it? Thanks!

PD: It doesn’t take

Lilith Calbridge wrote:

You don’t have to use 500. That was just a throwaway value. Most
demo

code I’ve seen uses a value of 30, which ostensibly gives you a
frame

rate of about 30 frames a second, probably a little closer to 33.
That

means the sampling rate of your events would be about fifteen times
faster than a half second interval. I haven’t tried this, and
probably

won’t get around to it any time soon, but if you want to make your
sampling even faster than that you could probably create a shorter
delay

loop inside a larger loop to do your sampling and update what’s
necessary before updating the screen.

In a project I’ve had to put off I was thinking of looking at the
keyboard state at the moment that the decision needs to be made. I
have

an object that moves towards intersections and can only move
forward,

without speed change, until then . So the only thing that matters
is

whether one of four possible keys is pressed at that specific time.

Maybe something like that is what you need.

Lilith

On 7/23/2006 at 7:53 PM, in message <ea15lh$uag$1 at sea.gmane.org>, @Leo_Cabrera wrote:
Hmm… Now it all screwed up… :frowning:
I think my movement mechanism is wrong… I’m doing it like, at
SDL_KEYUP event, the movement key for that direction goes to 0…
But
at SDL_KEYDOWN, it the variable goes to 1, so the dude’s moving…
But since this function is called only every half a second, the
movement
is updated every half a second too! So, it starts and stops
moving

half

a second after my key presses and releases… :frowning:

Note that I add PLR_SPEED to the player’s X/Y positions in the
update_screen function… I tried putting it in the same function
as

the event handling, but it didn’t work either, it moved only every
half
a second…

Do you know how to fix this? Thanks very much! :wink:

Janne Junnila wrote:
Peter Mackay wrote:

There’s a great article on fixing your logic timestep here:
http://www.gaffer.org/articles/

His other articles are also very good. Hope this helps,

Peter

“Janne Junnila” <janne.junnila at gmail.com> wrote in message

news:770a6dc40607230033x6df09271xbca8208b6872a5a6 at mail.gmail.com

Hi,

Anyways, I asked what update_interval was supposed to be…
Thanks!

Just a constant - it’s the interval between game world updates
(in

ms I

think).
Like update_interval = 500 would make it call the update
function

every

1/2 sec.

The point is to make the updating function to be called on a
fixed

interval independent of the machine the program is run on. The
screen

OTOH is updated as often as possible.

  • Janne Junnila
    Hi,

Anyways, I asked what update_interval was supposed to be…
Thanks!

Just a constant - it’s the interval between game world updates
(in

ms I

think).

Like update_interval = 500 would make it call the update function
every 1/2
sec.

The point is to make the updating function to be called on a
fixed

interval independent of the machine the program is run on. The
screen

OTOH is updated as often as possible.

  • Janne Junnila

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Now you HAVE read the article pointed to by Peter Mackay? [1]
If you do it that way, there should really not be any difference
between an 1.4-GHz and a 2.8-GHz PC. First don’t bother with the state
interpolation, just do it like described in the section labelled “Free
the physics”.
Another thing to be aware of is where to put your delay in relation to
where you check the input. Don’t check your input, then wait for X
milliseconds, and THEN updated the game state; it will cause an
average delay from user input to action which is larger. It may sound
simple, but it’s easy to get wrong :slight_smile:

[1] http://www.gaffer.org/articles/Timestep.htmlOn 7/24/06, L-28C wrote:

Oohh… So it’s OK to leave it like that? Will the users notice it?
This is a multiplayer game, so there can’t be someone that has an
advantage… :stuck_out_tongue:

Anyone else know? Thanks!


Regards, Rasmus Neckelmann
http://royal.flof.dk/rasmus

Holy crap it works! Thanks to you and everyone who helped me out!! :wink:

Rasmus Neckelmann wrote:> On 7/24/06, L-28C <@Leo_Cabrera> wrote:

Oohh… So it’s OK to leave it like that? Will the users notice it?
This is a multiplayer game, so there can’t be someone that has an
advantage… :stuck_out_tongue:

Anyone else know? Thanks!

Now you HAVE read the article pointed to by Peter Mackay? [1]
If you do it that way, there should really not be any difference
between an 1.4-GHz and a 2.8-GHz PC. First don’t bother with the state
interpolation, just do it like described in the section labelled “Free
the physics”.
Another thing to be aware of is where to put your delay in relation to
where you check the input. Don’t check your input, then wait for X
milliseconds, and THEN updated the game state; it will cause an
average delay from user input to action which is larger. It may sound
simple, but it’s easy to get wrong :slight_smile:

[1] http://www.gaffer.org/articles/Timestep.html