Paused clock dt?

edited October 2013 in General discussions
Hi guys, I am at that point of my game that you have to stop and refactor things that are hardcoded/bad designed to avoid that they will come back later as huge bugs.

One of the problems I am facing is the game pause, I was always using the main clock and it can't be paused.
So I created a clock myself with:
mainWorld.clock = orxClock_Create(0,  orxCLOCK_TYPE_USER);

When the game is paused by pressing an UI button, I use:
    orxClock_Pause(mainWorld.clock);

Then I get the clock info, when I check the ftime, it is not changing, but the fDT is always a float number (it seems to me that is the last fDT). My question is, shouldn't it be 0?
I can save the last fTime and subtract from the new one, which will give me 0, but this is exactly what fDT should be for.

Comments

  • jimjim
    edited October 2013
    I don't know whats the value of fDT but I guess its pretty small which is close to 0 but not zero, I think I know why is this. If you are using fDT in some computation, then fDt = 0 might produce unexpected result. For example, you are dividing some value by fDT. Then, it would throw unexpected error and your program would stop executing.

    Do you still get tiny movement of your objects, even if you use pause or its just that fDT is not zero as you expected ?
  • edited October 2013
    Here is the fDT/fTime log of my clock object:
    [16:56:03] [LOG] 0.009121 3.936312
    [16:56:03] [LOG] 0.017414 3.953726
    [16:56:03] [LOG] 0.009119 3.962845
    [16:56:03] [LOG] 0.017395 3.980240
    [16:56:03] [LOG] 0.009146 3.989386
    [16:56:03] [LOG] 0.017405 4.006792
    [16:56:03] [LOG] 0.009143 4.015934
    [16:56:03] [LOG] 0.017411 4.033345
    [16:56:03] [LOG] 0.009176 4.042521
    [16:56:03] [LOG] 0.017348 4.059868
    [16:56:03] [LOG] 0.009138 4.069006
    [16:56:03] [LOG] 0.017404 4.086411
    [16:56:03] [LOG] 0.009232 4.095642
    [16:56:03] [LOG] 0.017315 4.112957
    [16:56:03] [LOG] 0.009142 4.122099
    [16:56:03] [LOG] 0.016778 4.138877 <- Paused here
    [16:56:03] [LOG] 0.016778 4.138877
    [16:56:03] [LOG] 0.016778 4.138877
    [16:56:03] [LOG] 0.016778 4.138877
    [16:56:03] [LOG] 0.016778 4.138877
    [16:56:03] [LOG] 0.016778 4.138877
    [16:56:03] [LOG] 0.016778 4.138877
    
    


    For instance, my game has a monster factory struct that creates the monsters.
    It creates a monster every given interval (say 0.3 seconds), that is set by the time of the factory creation (there may be more than one active factory).

    Here was my code to take care of the interval (recoverd from the git repository):
    -    orxCLOCK* clock = orxClock_FindFirst(orx2F(-1.0f), orxCLOCK_TYPE_CORE);
         const orxCLOCK_INFO* clockInfo = orxClock_GetInfo(clock);
    
    (...)
    
    -        testFactory.timer += clockInfo->fDT;
    -        if (testFactory.timer >= testFactory.interval){
    

    My though was that with the clock paused, the fDT would be 0 and this would stop the timer to increase.
    I changed the code to use the time difference instead, but I believe it would be more intuitive that the time between ticks when a clock is not ticking should be zero, not the last difference before the pause.
  • jimjim
    edited October 2013
    Hmm, but if you pause your clock, your clock should not update. I just checked the clock tutorial, and if I pause a clock, that clock is not updated. So, the update function or the function you bind with your clock callback, is not called when you pause a clock.
  • edited October 2013
    I didn't bound it to a clock, it is called every frame in the Update function.
  • jimjim
    edited October 2013
    Hmm, I get it what your are doing. Its logical that clock info should only be updated if the clock is active, when it is paused, its not updated anymore. Hence, they retain their last value. And their values are not set to a default values.

    What you can do is check if a clock is active or not, then execute your clock related code only if its active.
    if (!orxClock_IsPaused(pstClock)) 
    {
        // your clock related code
    }
    
  • edited October 2013
    Yeah, I know, just wanted to bring into discussion if the dt shouldn't be 0.
  • edited October 2013
    Well, I think both approaches are correct depending on one's point of view.
    The idea was that clock info would always be used from "inside" a callback or timer triggered by the clock itself. Which means that when a clock is paused, it remains invariant.
    Setting the DT to 0 is only relevant when seen from outside but in which case which DT would that be?
    It's supposed to represent the amount of time between two consecutive ticks, not compared with an outside referential.

    Now imagine that you have two clocks, one [A] that ticks at 60Hz, and the other one varies between 15 and 60Hz.
    If you look at the DT of from within an update of [A], DT won't really mean anything as sometimes there will be a single tick of between two of your observations, and sometimes you'll see multiple time the same DT (and time) as [A] will tick 2, 3 or 4 times before ticks again, which would result in wrong maths as time hasn't actually passed by for but is flowing for [A].
    Does it make sense?

    As a side note, what is it you're trying to do? There might be an easier way of achieving it rather than using a user clock. For example objects can be paused separately (it's also nicely wrapped up in Scroll if you're using it, including a IsPausable config property).
  • edited October 2013
    Ah, now I understand the reason.

    Basically i am coding a game that can be paused.
    My Run function runs all the game logic. To calculate things such as movement and animation adjustments I use one clock and the UI uses another clock.
    So when I click the pause button I just pause the clock that process the logic and I stop the physics simulation. It is working already, just my life would have been a lot easier if the paused clock returned 0 as dt.
  • jimjim
    edited October 2013
    So, fDT only makes sense inside the callback function for that clock. In this case, you can maintain the dt for yourself as you said
    I can save the last fTime and subtract from the new one, which will give me 0
    It would take just few lines of code.
  • edited October 2013
    I have to admit that in my own projects, I simply go over the pausable objects and call orxObject_Pause() on them, leaving all the menus and buttons unpaused.

    Now if I were to be using dedicated clocks, I'd probably do something like this.
    Config:
    [GameClock]
    Frequency = 60
    

    Code:
    void orxFASTCALL UpdateUI(const orxCLOCK_INFO *_pstInfo)
    {
      // ...
    }
    
    void orxFASTCALL UpdateGame(const orxCLOCK_INFO *_pstInfo)
    {
      // ...
    }
    
    orxSTATUS orxFASTCALL Init()
    {
      // Registers UI update to core clock
      orxClock_Register(orxClock_FindFirst(orx2F(-1.0f), orxCLOCK_TYPE_CORE), UpdateUI, orxNULL, orxMODULE_ID_MAIN, orxCLOCK_PRIORITY_NORMAL);
    
      // Registers game update to custom game clock
      orxClock_Register(orxClock_CreateFromConfig("GameClock"), UpdateGame, orxNULL, orxMODULE_ID_MAIN, orxCLOCK_PRIORITY_NORMAL);
    
      // Done!
      return orxSTATUS_SUCCESS;
    }
    

    When I'd go to pause I'd simply pause "GameClock" and all the logic in UpdateGame() would not be called anymore till it's unpaused.

    One could even make sure all the game objects are linked to that clock so that they'll get paused as well (including all internal stuff such as spawners, FXs, ...):
    [MyGameObject]
    Clock = GameClock
    
Sign In or Register to comment.