refunct-tas icon indicating copy to clipboard operation
refunct-tas copied to clipboard

Multiplayer end time synchronization

Open LukeSaward opened this issue 3 years ago • 4 comments

Currently, when a multiplayer run is completed, every player's end time differs. What can be implemented is showing the same end time for all players. It can be done by getting the SecondsPartial of every player, comparing each to see which is the lowest, and then either:

  • Change the SecondsPartial of every other player to match that of the player who hit button 31 first. OR
  • Change the time display of every other player to match that of the player who hit button 31 first.

LukeSaward avatar Jun 07 '22 08:06 LukeSaward

In general, we can calculate the end time of the player hitting the button and send that time to all other players together with the last button press.

The implementation on how to set the correct time for all other players depends on when the time is displayed on the screen:

  1. Modify the end time: If the shown time is calculated and shown after endSeconds and endPartialSeconds in the LevelState have been set, we can use that time to modify the endSeconds and endPartialSeconds in relation to the start time.
  2. Modify the start time: Before spawning the pawn pressing the last button, we get the current time just like Refunct does and modify the startSeconds and startPartialSeconds to produce the correct result when Refunct gets the current time and calculates the time diff. This depends on https://github.com/oberien/refunct-tas/issues/65#issuecomment-706036181.
  3. Hook the modification function: Find out which function writes the end time into the LevelState by setting a hardware breakpoint on those addresses and inspecting the backtrace. Hook the function calculating the time and perform modifications to produce the correct end time.

oberien avatar Jun 07 '22 09:06 oberien

Find out which function writes the end time into the LevelState

UBP_MyGameInstance_C::SetTimer(int Seconds, float SecondsPartial)

Seems like this may do it, although it's a function within a Blueprint, so I don't know how you'd be able to call it. I've already looked at the functions of the last button press and it doesn't appear it's calculated with a function in that.

LukeSaward avatar Jun 26 '22 16:06 LukeSaward

With the PR #160, we can send and receive SPEEDRUN_STATE::cur_time over the server and then somehow modify UBP_Outro::Title::Text [FText], which would need to be accessed... somehow.

EDIT: I can modify start time of the other players.

LukeSaward avatar Feb 18 '23 23:02 LukeSaward

Another edit: we should be able to call BP_MyGameInstance_C::SetTimer(int Seconds, float SecondsPartial) as we can now call BP functions.

LukeSaward avatar Aug 07 '23 18:08 LukeSaward