Page MenuHome

Better clock management
ClosedPublic

Authored by Arnaud Degroote (adegroot) on Aug 9 2014, 5:46 PM.

Details

Summary

I would like to improve clock management in BGE, to be able to accelerate / slow the time, and also to finely synchronize clock with external engines. Rationale are described more precisely in the thread http://lists.blender.org/pipermail/bf-gamedev/2013-November/000165.html.

See also T37640

Diff Detail

Repository
rB Blender
Branch
clock_management2

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

PS: please consider using Arcanist to submit patches. By using that, we'll be able to see the context of your patch (i.e. where it now says "Context not available", you'll be able to click & see more code). It helps us reviewing.

Arnaud Degroote (adegroot) updated this revision to Diff 5032.EditedSep 8 2015, 12:27 PM
Arnaud Degroote (adegroot) edited edge metadata.

Try to handle sybren remarks

Please remove D1512, it was a mistake in arc use.

The patch is getting there, just a few more tidbits to clean up.

source/gameengine/Ketsji/KX_KetsjiEngine.cpp
603

Still no need to add this line.

1760

Please don't prefix variables with their type (so no 'b')

source/gameengine/Ketsji/KX_KetsjiEngine.h
303

"user clock" is a vague term.

source/gameengine/Ketsji/KX_PythonInit.cpp
973

"user" is a vague term here, and inconsistent with the concept "external clock".

975

There is no such thing as "the" BGE clock when there is "real time", "frame time" and an "external clock". When introducing multiple concepts of time, they really should be well-defined and described.

980

You can remove the word "parameter", "multiplier" is enough.

  • A few more cleanup based on sybren notes
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
582

You can remove this comment, it's obsolete now.

1791

No need to declare void here. I know it's to be consistent with GetUseFixedTime, but that's not necessary. The BGE has such a mix of code styles, that we aim for clarity/brevity for new/modified code, rather than consistency with other BGE code.

source/gameengine/Ketsji/KX_PythonInit.cpp
975

It's improving, but you should document *which* time you're referring to. The external clock? Internal clock that can be sped up/down? Wall clock that's always running at constant speed?

What is "render time"? The time it took to render the frame? Please be clear. There is no shame in using more than a single sentence to describe something.

977

What is "frametime"? It could also be the time it took to render the frame, which means it *could* be the same as "render time".

  • Be more clear about what time represents explicitly
Sybren A. Stüvel (sybren) requested changes to this revision.Sep 17 2015, 8:44 AM
Sybren A. Stüvel (sybren) edited edge metadata.

I think we can still clarify some things.

  • "clock time" is vague, as all time is measured by some clock. I suggest changing it to "game time".
  • "render time" usually does not refer to a point in time, but rather refers to a duration: the time it takes Blender to render a frame. Let's not use that term here, and just use "the current game time" instead.
  • I still don't understand what "frame time" is, and in what way it is different from "clock time". The docstring refers to the time of the last physics/logic tick, but since there can be multiple physics ticks per logic tick, this is also ambiguous, and conflicting with the comment "Returns current logic frame clock time" in KX_KetsjiEngine.h. Apaart from this, both the comments in the CPP code as well as the docstrings for the Python wrapper should explain whether it's game time or wall clock time that is referred to here.
  • The set/getTimeScale functions don't document *which* time is multiplied. This should mention "game time".
This revision now requires changes to proceed.Sep 17 2015, 8:44 AM

I think we can still clarify some things.

  • "clock time" is vague, as all time is measured by some clock. I suggest changing it to "game time".

I'm not responsible for the API name and the current documentation.

  • "render time" usually does not refer to a point in time, but rather refers to a duration: the time it takes Blender to render a frame. Let's not use that term here, and just use "the current game time" instead.

It is not the current game time. It is really the game time corresponding to the next frame rendered. The current game time, from the logic point of view is "frame time".

  • I still don't understand what "frame time" is, and in what way it is different from "clock time". The docstring refers to the time of the last physics/logic tick, but since there can be multiple physics ticks per logic tick, this is also ambiguous, and conflicting with the comment "Returns current logic frame clock time" in KX_KetsjiEngine.h. Apaart from this, both the comments in the CPP code as well as the docstrings for the Python wrapper should explain whether it's game time or wall clock time that is referred to here.

The "documentation" said you can have multiple physics ticks per logic tick, but it is not what I understand from the code. In next frame, I see sequential call to logic than physics call, without any conditional. But I may miss something. I can keep only "logic tick".

  • The set/getTimeScale functions don't document *which* time is multiplied. This should mention "game time".

It modifies game time in general (i.e. clocktime and frametime). And I don't see what it can modifies otherwise, as the only other time is "real" time, which won't be real if we can modify it.

source/gameengine/Ketsji/KX_PythonInit.cpp
975

I tried to be consistent with terms used in comment of source/gameengine/Ketsji/KX_KetsjiEngine.h. I just extend a bit the python API to expose existing interface. What I can try to do is to extend ./doc/python_api/rst/bge.logic.rst with a "time management" section which will explain the different time used in the interface (and it may help BGE developpers also). What do you think about it ?

I'm not responsible for the API name and the current documentation.

My idea was that, since you are actively working on this, and wrapped your mind around which thing means what, you're the perfect person to clarify things. And I feel (but this is a personal thing) that the person making things more complex is also responsible for making things easier to understand.

It is not the current game time. It is really the game time corresponding to the next frame rendered.

I don't understand. How is this possible, when the time the next time will render at is depending on the logic code that's currently running?

The "documentation" said you can have multiple physics ticks per logic tick, but it is not what I understand from the code. In next frame, I see sequential call to logic than physics call, without any conditional. But I may miss something. I can keep only "logic tick".

Bullet can actually perform multiple physics steps per call, I think it's hidden in there.

It modifies game time in general (i.e. clocktime and frametime). And I don't see what it can modifies otherwise, as the only other time is "real" time, which won't be real if we can modify it.

That's pleasantly consistent. So now you and I know this, but I feel that this still should be documented; the BGE doesn't always make sense, so even when it does it's nice if it's explicitly documented. The docstrings have my preference, but you could also just update the RST files.

@Arnaud Degroote (adegroot) I've opened up a discussion on time handling in general in the BGE; the more I look at it, the more I see a need to clarify things. Maybe you want to join in the discussion as well? Please see the comments at D1509.

Arnaud Degroote (adegroot) edited edge metadata.
  • More comments about game time
Sybren A. Stüvel (sybren) edited edge metadata.

Those are some nice additions to the comments. It clarifies a lot, and also clarifies where things are unclear :)
Thanks!

Those are some nice additions to the comments. It clarifies a lot, and also clarifies where things are unclear :)
Thanks!

What is the next step for this patch so ?

As far as I'm concerned, we should just accept this patch and merge it with the master branch. Bigger time management overhauls for the BGE will come later. The next step is for @Jorge Bernal (lordloki) and/or @Porteries Tristan (panzergame) to either accept this patch, or explain why they don't.

@Arnaud Degroote (adegroot): Can you add these functions in the python rst doc file for bge.logic module ?

See :

Press up arrow to accel, down arrow to slow and 0 to reset time scale.

I found a bug when you accel at start, slow and accel again, the second accel is bigger than the first, i checked with logic.getTimeScale : it's the same value.

Arnaud Degroote (adegroot) edited edge metadata.
  • Fix logic of frames computation in presence of timescale change
  • [doc] Document the new API about time in bge.logic.rst

See :

Press up arrow to accel, down arrow to slow and 0 to reset time scale.

I found a bug when you accel at start, slow and accel again, the second accel is bigger than the first, i checked with logic.getTimeScale : it's the same value.

It should be fixed now. Thanks for the report.

  • [doc] Document the new API about time in bge.logic.rst

Done in f96b898e32ce

source/gameengine/Ketsji/KX_KetsjiEngine.cpp
596

A tiny little thing: now that you're changing this line anyway, please add a space after the = sign.

I made some code style remarks.

doc/python_api/rst/bge.logic.rst
105 ↗(On Diff #5465)

This typo fix is not related to this patch.
I think it is better to do this in an separate patch.

source/gameengine/Ketsji/KX_KetsjiEngine.cpp
137

1.0f

138

0.0f

source/gameengine/Ketsji/KX_KetsjiEngine.h
115–118

Make on space between semicolon and the double slash (; //);

117

; //

source/gameengine/Ketsji/KX_PythonInit.cpp
560

static PyObject *gPySetUseExternalClock(PyObject *, PyObject *args)

576

static PyObject *gPySetClockTime(PyObject *, PyObject *args)

587

static PyObject *gPyGetFrameTime(PyObject *)

592

static PyObject *gPyGetRealTime(PyObject *)

597

static PyObject *gPyGetTimeScale(PyObject *)

602

static PyObject *gPySetTimeScale(PyObject *, PyObject *args)

973
{"getUseExternalClock", (PyCFunction) gPyGetUseExternalClock, METH_NOARGS, (const char *)"Get if we use the time provided by an external clock"},
974
{"getUseExternalClock", (PyCFunction) gPyGetUseExternalClock, METH_NOARGS, (const char *)"Get if we use the time provided by an external clock"},
Mitchell Stokes (moguri) requested changes to this revision.Nov 24 2015, 6:39 PM

I'd like a chance to look over the new API and make sure it provides a good user experience. I'll try to get to a review soon.

This revision now requires changes to proceed.Nov 24 2015, 6:39 PM

Added some notes. The logic seems sound, so now it's just a matter of making a good, clean API.

doc/python_api/rst/bge.logic.rst
387 ↗(On Diff #5465)

"in second" -> "in seconds"

If this is the render time, why not make the method name clearer and make it getRenderTime()? We'd probably want to add a note that this is a target and not actual FPS.

393 ↗(On Diff #5465)

"in second" -> "in seconds"

Could we simplify the wording to just simply say it's the time between logic steps? The note that is is what the user is usually interested in is a good addition.

399 ↗(On Diff #5465)

Do we need this? I believe we could get the same thing with time.time() in Python.

Porteries Tristan (panzergame) edited edge metadata.

@Arnaud Degroote (adegroot) : All works, the documentation is great, nice patch :)

doc/python_api/rst/bge.logic.rst
399 ↗(On Diff #5465)

It's the time for the game beginning.

doc/python_api/rst/bge.logic.rst
399 ↗(On Diff #5465)

That's not 'real' time then. Let's just make sure that 'real' refers to 'reality', which has nothing to do with the game.

Arnaud Degroote (adegroot) edited edge metadata.
  • Revert part of f96b898e32ce09b0ad0e2190599db2c91f89e234
  • Improve a bit the documentation
  • More WS policy
doc/python_api/rst/bge.logic.rst
387 ↗(On Diff #5472)

I try to be consistent with the existing naming. It is why I use ClockTime everywhere. Do you suggest I modify the exposed API (i.e. just the python method), or more generally move everything from clockTime to RenderTargetTime (or something like that ?

Arnaud Degroote (adegroot) marked 2 inline comments as done.Nov 25 2015, 9:06 AM
source/gameengine/Ketsji/KX_PythonInit.cpp
576

You have overlooked *args

Any hope to see it merged before 2016 ?

I know that it is a volunteer project, and that everyone has a lot of other stuff to do. But, on other side, my initial mail on the mailing-list (with the associated patch) was in November 2013 (more than 2 years ago), and the logic change is about 5 lines of code (and it is pretty clear that, in the default setting, it does change nothing). It is hard to keep motivated to contribute to BGE in these conditions.

Anyway, best regards,

Jorge Bernal (lordloki) edited edge metadata.

Yes, you're right. We would have to be a lot quicker reviewing the differentials. We will try to improve this.
Anyway, you did a very good work here. LGTM.

If Moguri is Ok, I will commit this weekend.

Mitchell Stokes (moguri) edited edge metadata.

Looks good to me.

This revision is now accepted and ready to land.Dec 10 2015, 6:15 PM
Closed by commit rBaae93ae4c6c1: BGE: Improve clock management (authored by Arnaud Degroote <arnaud.degroote@isae-supaero.fr>, committed by Jorge Bernal (lordloki)). · Explain WhyDec 12 2015, 2:49 AM
This revision was automatically updated to reflect the committed changes.