timkurvers / redota

Revisit past Dota 2 matches in the browser
https://timkurvers.github.io/redota
MIT License
48 stars 7 forks source link

Inconsistency on the Game Time #113

Open Orion-Zheng opened 3 months ago

Orion-Zheng commented 3 months ago

I've noticed that the game time displayed on ReDota differs from the time displayed on OpenDota for the same replay. Let’s take match ID: 7730647719 as an example. Initially, I located this replay by its ID, and the official game duration was recorded as 30:33.

image

However, after uploading the replay to ReDota, the displayed game time changed to 48:14. Here’s the image from ReDota:

image

If I play this replay in the player, the game start from 12:13 to 48:14, which is 36:01.

image

Upon playing this replay in the player, it starts from 12:13 and ends at 48:14, amounting to a total duration of 36:01. This variation in the reported game times across different platforms is perplexing. Can you help me understand why this discrepancy exists?

Beside, there is a similar bug report in 2021 about the game time. Does this bug still exist?🤔https://github.com/timkurvers/redota/issues/21#issue-856956721 Any help will be really appreciated, thank you!

timkurvers commented 3 months ago

Hi there! Yes, that is still an open improvement.

The replay time in the bottom of the player is effectively replay time (e.g. server time), is linear / not interrupted, and includes all of the following:

What you're likely interested in (and what OpenDota likely reports) is the actual game play-time bit above (perhaps excluding pauses?).

The main reason this is not yet implemented is that ReDota currently uses Parser.summary to quickly fetch the summary of the game, without having to do a full parse of the replay file.

Orion-Zheng commented 3 months ago

Thank you for you helpful reply! I think I get it😃I notice you mentioned several game phases, which correspond to GAME_PHASE in the src/lib/constants.js.

export const GAME_PHASE = {
  INIT: 0,
  WAIT_FOR_PLAYERS_TO_LOAD: 1,
  HERO_SELECTION: 2,
  STRATEGY_TIME: 3,
  PRE_GAME: 4,
  GAME_IN_PROGRESS: 5,
  POST_GAME: 6,
  DISCONNECT: 7,
  ...
}

I extract the ticks and clocktime in phase GAME_IN_PROCESS referring to https://github.com/timkurvers/redota/issues/56. And in my output file, I find the maximum clocktime extend to 1834. If the unit of clocktime is in seconds, the actual game play time should be 30.56666667 minutes, which is approximately 30:33 in the summary. Now everything makes sense, thank you!😃

image

I take a closer look to the code and find the clocktime is from game.time which is obtained from:

if ('m_pGameRules.m_fGameTime' in delta) {
      game.time = delta['m_pGameRules.m_fGameTime'] | 0;
} else {
      // Since patch 7.32e game time is no longer continously updated as part of
      // the game rules entity. A delta still triggers approximately once a second
      // for other fields. For these matches: infer the current game time based
      // on server tick combined with the total amount of ticks the game was passed.
      const ticksElapsed = (game.pauseStartTick || this.serverTick) - game.totalPausedTicks;
      game.time = (ticksElapsed * this.tickInterval) | 0;
}

I am a bit confused about the computation of ticksElapsed. I think ticksElapsed = this.serverTick - game.totalPausedTicks makes sense to me, because you said When the game is paused: replay / server keeps ticking, in-game clock time is paused. But why we also subtract totalPausedTicks from pauseStartTick🤔

timkurvers commented 3 months ago

Cannot go deep into the details right now, but I seem to recall that pauseStartTick contained the last server tick when the game was paused. However, that would not take into account any previous pauses the game may have had, so we need to deduct those, too.

It is not entirely impossible there's a logical glitch here somewhere though 😊