Tick/Update method

What is the best way to implement tick() method, so i dont have to multiply every movement in game by *tpf ?

You can ignore tpf if you don’t mind your game running at different speeds as frame rate speeds up or slows down… else just use tpf. There’s really no way around it.

Even if you implement a completely separate thread that attempts to always run at a fixed frequency, there will be times where it will lag for one reason or another. Though if you want a fixed time step, that’s the ā€˜easiest’ way. You have to manage a whole bunch of threading stuff, though.

What’s wrong with just using tpf?

Well the most primitive way is to just set the framerate in the settings of the application by code. So you limit the max speed, but it might slowdown based on load, (depending on the gametype this might be the reqired behaviour tho)

In fact my whole server behaves similar, as I prefer a slowed down game to a choppy one.

a very complete article on the subject if you want to understand it all.

I personnaly prefer to use a logic thread that run at fixed rate. This way I only have a constant ā€œtime per frameā€ and all calculations are based on it. No need to hike the tpf to all layers.

The variable elapsed time between frame (called ā€œtpfā€ in jMonkey, I never understood why ^^) requires to mutiply things to it and it may become confuse what need to be scaled and what doesn’t need, especially with physic.

Yeah, I do my physics/logic/etc. loops this way on the server also. I still pass a version of tpf… it’s just fixed. That way I can change the step size without having to rewrite ā€œliterally everythingā€.

But when dealing with networking, you are already messing the threading on the client and dealing with the multithreading issues.

To me, in a single player game where the logic is ā€˜right there’… for someone at the skill level where they need to ask this question, it’s probably 100x easier just to multiply by tpf.

TPF = time per frame

TSLF = time since last frame :chimpanzee_closedlaugh:
TTHPSLF = time that has passed since last frame :chimpanzee_closedlaugh:

Just joking. :chimpanzee_winktongue:

I admire you folks … I wish I knew how to implement a server for a multiplayer game in a clever way (so that I could save the 100 hours (or 200 hours) (or more) to get there)…
Do you know any good tutorials / papers on that topic?? :chimpanzee_smile:

How about this approach?

float timePassed = 0;
public void update(float tpf){
    timePassed += tpf;
    while(tpf >= 0.05){
        tick();
        timePassed -= 0.05; 
    }
}

I know it’s not perfect, but in theory it should give you ticks of 0.05 seconds each.

At least 0.05 seconds :smile: It seems dangerous to me cause you can’t count on it.

Well many things are not important : the game sjust slows down. But some times, it may lead to very strange behavior. Think about velocity calculations : if the time is slowed, you get a slower speed, but also slower acceleration and deceleration, which may lead to bugs or unexpected results.

What about a damge over time ? should it tick 9 times? of 3 times per seconds? are you sure that the tick count will be the same at every framerate?

A surely fixed frame rate for the game logic is, IMO, a much safer way to code.

Though note: it implies interpolation or prediction to make the visual frame rate sync with your different game thread… else you get strange jittering(*). This is not trivial stuff for someone at the level of experience of asking this question in the first place.

(*) could be ugly stuttering doesn’t matter… some people want smooth movement, though.

absolutly

No you don’t get any slow down or speedups with his method, I was actually going to suggest exactly the same because it doesn’t involve threads. If the frame rate is slower than 0.05s you get multiple updates in one frame, if its faster you get one every few frames. The only issue is the actual updates of the visual output but you have virtually the same issue when you use a separate thread as Paul hinted.

Thanks for the backup :smiley: Yeah it just updates multiple times per drawing if the framerate is too small. That can lead to stuttering, but you get that anyway. Also, if you want multiple tick-rates for different parts of your game (I think minecraft does something like that), you can add additional float fields and loops.
And I do see the reason for fixed framerates, especially in games where acceleration is a gameplay factor (I saw a 2D-Game with orbital ā€œphysicsā€ once where this method was used)

There is one problem in Din’s algorithm though:
If the tick() takes very long, then you will get an eternal slow down.

So you would not just calculate ā€˜time per frame’ but need to also cap that to a maximum value.
So if the tick() takes 0.10 seconds then you don’t add the 0.10 seconds but a significantly lower value.
Or you do that cap once the ā€œaccumulated timeā€ has reached, say, 1 second.

:chimpanzee_smile:

Otherwise a good solution, except for the stuttering that Paul mentioned…


Still waiting for…

Game Programming Patterns by Nystrom is good. It’s even freely available:
http://gameprogrammingpatterns.com/

1 Like

Hm… his book is more about basic stuff.
Seems not to be specifically about:

That’s* what I meant by ā€œthat topicā€.
Well, anyways, thanks for providing a link to a free book about game coding. :+1: :chimpanzee_smile:

*That and what the others said about their fancy multiplayer servers…

@pspeed always has valve’s posts at hand :stuck_out_tongue:
Though I guess you need to be more clear on what you want to achieve since an MMORPG is more complex than a card game though an FPS might be more complex and focus on other things than an MMORPG.

For Example: An MMORPG has to be efficient (because of the MMO part), whereas an FPS has to make heavy use of interpolation and for example every input is captured and delayed (so everything happens in the past).

Well, not yet sure whether it’s only for a group of people with FPS-style precision. Or (what I think) an MMO precision with a FPS size group of people (and thus multiple instances on one server).

When I’m at that point (which will take some weeks), I will first look at Monkey Zone, but that’s only a start.

We use that ā€œincrementalā€ approach in Skylimit Tycoon, and it works well for us.

We have also implemented a game speed enum that indicate what speed the game should run at, with constants to use when multiply for animations, etc. It’s usefull for us since we want to fast forward now and then.

One tick is one minute in our game.

public enum GameSpeed {

    PAUSE(0.0f, 0),
    NORMAL(1.0f, 1), // 1 minute per second
    FAST(1.0f / 8.0f, 2), // 8 minutes per second
    VERY_FAST(1.0f / 60.0f, 3); // 60 minutes per second

    GameSpeed(final float timePerMinute, final int index) {
        this.timePerMinute = timePerMinute;
        this.timeModifier = 1.0f / timePerMinute;
        this.index = index;
    }

    private final float timePerMinute;
    private final float timeModifier;
    private final int index;

    /**
     * @return the amount of tpf that's required for incrementing a minute
     */
    public float getTimePerMinute() {
        return this.timePerMinute;
    }

    /**
     * @return the constant to multiply with when skipping time
     */
    public float getTimeModifier() {
        return this.timeModifier;
    }

    public int getIndex() {
        return index;
    }

}

Enum has an ā€˜ordinal’ (0-based index). :chimpanzee_smile:

1 Like

If you use that value for anything other than looking up the enum value later then it’s best to hard-code some index into the enum… else you will break a lot of your code if you ever add an enum in the middle or reorder them. Best not to have these magic side-effects cascade through your code.

…perhaps better still not to use the ordinal() for anything real. (Though it can be very tempting for database storage… it’s a bad idea.)

3 Likes