Skip to content

Commit

Permalink
Clean up infodisplay; Attempt to appease linter
Browse files Browse the repository at this point in the history
  • Loading branch information
kierio04 committed Feb 26, 2024
1 parent b51e1f2 commit 4af5ffc
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 207 deletions.
122 changes: 64 additions & 58 deletions scripts/Modules/TimeDifference information.txt
Original file line number Diff line number Diff line change
@@ -1,58 +1,64 @@
This file contain some information about the TimeDifference scripts in infodisplay.

In infodisplay.ini, you can chose to display or not each time difference calculation.

In infodisplay.ini, "timediff setting" is a setting with 4 possible value :
"player" which will use the TimeDifference (Player -> Ghost)
"ghost" which will use the TimeDifference (Ghost -> Player)
"ahead" which will use the TimeDifference (the one ahead -> the one behind)
"behind" which will use the TimeDifference (the one behind -> the one ahead)
any other value will default to "player".

In infodisplay.ini "history size" is a setting used for the TimeDifference RaceComp.
history size = 200 means the TimeDiff RaceComp can at best detect a timedifference of 200 frames or less.
It uses memory, so don't use an unecessary large number.

Some TimeDifference calculations are not symmetrical. It means this calculation gives different result
for the time difference between the ghost and the player, and between the player and the ghost.
Here's an example : For the TimeDifference Absolute (Player1 -> Player2) :
We take Player1's speed, we take the distance between both players.
And we simply define the TimeDiff as the distance divided by the speed.
Player1 and Player2 have asymmetrical roles in the calculation.
Therefore : we talk about the timedifference from Player1 to Player2 (and not the timedifference between Player1 and Player2)

This is how each one is calculated :

-TimeDifference Absolute (P1 -> P2) (Not very relevant imo)
Take S1 the speed of P1
Take D the distance between P1 and P2
Return D / S1

-TimeDifference Relative (P1 -> P2) (A bit more relevant maybe)
Take S1 the speed of P1 directed "toward" P2. (mathematically, it's a dot product)
Take D the distance between P1 and P2
Return D / S1

-TimeDifference Projected (P1 -> P2) (A good one for short distances)
Take S1 the speed of P1
Take D the distance represented here : https://blounard.s-ul.eu/iMDYhZDI.png
Return D / S1

-TimeDifference CrossPath (P1 -> P2) (Another good one for short distances)
this one is symmetrical
With the notation here : https://blounard.s-ul.eu/WYbotlks.png
Calculate t1 = TimeDifference (P1 -> C) (in this case, all 3 above timedifference formula will give the same result)
Calculate t2 = TimeDifference (P2 -> C) (--------------------------------------------------------------------------)
Return t1-t2

-TimeDifference ToFinish (P1 -> P2) (Perfectly precise when both player are going straight to the finish line at constant speed. Useless otherwise)
this one is symmetrical
Calculate t1, the time needed for P1 to cross the finish line if P1 keep going at a constant speed.
Calculate t2, the time needed for P2 to cross the finish line if P2 keep going at a constant speed.
Return t1-t2

-TimeDifference RaceComp (P1 -> P2) (Useful even for long distances. Based on RaceCompletion data. Has several flaws)
this one is symmetrical
Store in memory the racecompletion data for both players for the last few frames.
Make the player ahead go "back in time" until it's behind the other player.
How much frame you had to go "back in time" is how much frame the player was ahead.
This file contains information about the Time Difference functions in infodisplay,
as well as the different settings you will find within infodisplay.ini

By default, "Time Difference" is set to "False". When set to "True", Projected and ToFinish will be displayed.
If you wish to display all other calculations, use the "(Extra)" option. These are not recommended for TASing.

By default, "Comparison Type" is set to "Player" - it has 4 possible values:
"Player": Which compares the Player against the Ghost (generally the most useful)
"Ghost": Which compares the Ghost against the Player
"Ahead": Which compares who is ahead against who is behind
"Behind": Which compares who is behind against who is ahead
NOTE: Any other value will default to "Player" too.

By default, "History Size" is set to 200. It determines how many frames of history are stored for certain parts
of infodisplay (in Time Difference, it's used for the RaceComp calculation to store previous race completions).
WARNING: If you use a number too large, it will take up a large amount of your computer's memory.

NOTE: Not all Time Difference calculations are symmetrical, since for most of them, the speeds and angles of
only one of the player and the ghost are considered. This doesn't make the calculations any less accurate, as
it's perfectly normal to have the time taken for the player to reach the ghost to be different to the time taken
for the ghost to reach the player. As such, we say "Time Difference FROM player TO ghost" or vice versa.

Descriptions for each calculation:

[DEFAULT]

- Projected (P1 -> P2)
- Returns D / S1 (Speed of P1) where D is the distance represented here: https://blounard.s-ul.eu/iMDYhZDI.png
- Best general-purpose calculation for non-race-end time difference
- Forward movement is taken to be the direction P1 is moving
- As with all but RaceComp, becomes more inaccurate mid-turn

- ToFinish (P1 -> P2)
- Returns T1-T2 where T is Time taken for a player to cross the finish line if they continue at a constant speed
- Perfectly accurate approaching the finish line
- Useless for all non-race-end calculations
- Symmetrical, as both players are fully considered

[EXTRA]

- Absolute (P1 -> P2)
- Returns D / S1 (Speed of P1) where D is the distance between P1 and P2
- Incorrectly assumes "forward" is wherever the other player is
- Also incorrectly assumes speed is directed towards the other player
- Will probably be removed in the future; mostly misleading calculation

- Relative (P1 -> P2)
- Same as Absolute but S1 is the speed of P1 directed "toward" P2, using a dot product
- Still incorrectly assumes "forward" is wherever the other player is
- However correctly calculates speed with this "forward" direction in mind
- So, rarely useful, but at least accurate for some niche scenario

- CrossPath (P1 -> P2) (Another good one for short distances, lacks evolving gain/loss from skewed angles)
- Returns T1-T2 where T is Time taken for a player to cross the other player's path, as so: https://blounard.s-ul.eu/WYbotlks.png
- Technically accurate long-term, but lacks the evolving time difference from skewed angles
- Symmetrical, as both players are fully considered

- RaceComp (P1 -> P2)
- Returns how long ago P1 was at the race completion of P2 by storing Race Completion history in memory
- Accurate only if P1 and P2 take near-identical paths, due to the nature of Race Completion
- Has a delay of however far ahead P1 is to return an accurate result
- Takes up a lot of memory very quickly (60 frames of Race Completion history per second of gameplay)
- Allows for long distance time difference calculations (irrelevant as this is a micro-optimisation tool)
- Symmetrical, as no calculations involving physical values from either player are used
4 changes: 2 additions & 2 deletions scripts/Modules/mkw_classes/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ def length(self) -> float:
def length_xz(self) -> float:
return math.sqrt(self.x**2 + self.z**2)

def forward(self, facing_yaw) -> float:
def forwards(self, facing_yaw) -> float:
speed_yaw = -180/math.pi * math.atan2(self.x, self.z)
diff_angle_rad = (facing_yaw - speed_yaw)*math.pi/180
return math.sqrt(self.x**2 + self.z**2)*math.cos(diff_angle_rad)

def sideway(self, facing_yaw) -> float:
def sideways(self, facing_yaw) -> float:
speed_yaw = -180/math.pi * math.atan2(self.x, self.z)
diff_angle_rad = (facing_yaw - speed_yaw)*math.pi/180
return math.sqrt(self.x**2 + self.z**2)*math.sin(diff_angle_rad)
Expand Down
22 changes: 11 additions & 11 deletions scripts/Modules/mkw_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ def time_difference_absolute(P1, P2, S1, S2):
return float('inf')


def get_time_difference_absolute(player1, player2):
def get_time_diff_absolute(player1, player2):
"""Time difference "Absolute" (simple and bad)
Simply takes the distance player-ghost, and divide it by raw speed (always positive)"""
P1, S1, P2, S2 = get_physics(player1, player2)
Expand All @@ -226,7 +226,7 @@ def time_difference_relative(P1, P2, S1, S2):
return (P2-P1).length() / s


def get_time_difference_relative(player1, player2):
def get_time_diff_relative(player1, player2):
"""Time difference "Relative"
Take distance player-ghost. Divide it by the player's speed "toward" the ghost (dot product)"""
P1, S1, P2, S2 = get_physics(player1, player2)
Expand All @@ -240,7 +240,7 @@ def time_difference_projected(P1, P2, S1, S2):
return (P2-P1)*S1/(s**2)


def get_time_difference_projected(player1, player2):
def get_time_diff_projected(player1, player2):
""" Time difference "Projected"
Take the distance between the player and the plane oriented by the player speed, covering the ghost.
Then divide it by the player raw speed
Expand All @@ -267,7 +267,7 @@ def time_difference_crosspath(P1, P2, S1, S2):
return t1-t2


def get_time_difference_crosspath(player1, player2):
def get_time_diff_crosspath(player1, player2):
"""Time difference "CrossPath"
Take both XZ trajectories of the player and the ghost
Calculate how much time it takes them to reach the crosspoint. (2D only)
Expand Down Expand Up @@ -299,7 +299,7 @@ def time_difference_tofinish(P1, P2, S1, S2):
return t1-t2


def get_time_difference_tofinish(player1, player2):
def get_time_diff_tofinish(player1, player2):
"""Assume player and ghost are not accelerated.
Calculate the time to the finish line for both, and takes the difference."""
P1, S1, P2, S2 = get_physics(player1, player2)
Expand All @@ -319,7 +319,7 @@ def find_index(value, value_list):
return find_index(value, value_list[:h])


def get_time_difference_racecompletion(history):
def get_time_diff_racecompletion(history):
"""Use RaceCompletionData History to calculate the frame difference
The function assume that RaceCompletion is increasing every frames"""
curframe = history.get_older_frame(0)
Expand All @@ -344,16 +344,16 @@ def get_time_difference_racecompletion(history):


def get_timediff_settings(string):
if string == 'player':
if string == 'Player':
return 0, 1
if string == 'ghost':
if string == 'Ghost':
return 1, 0
pp, sp, pg, sg = get_physics(0, 1)
player_is_ahead = int(sp*(pg-pp) > 0)
if string == 'ahead':
if string == 'Ahead':
return 1-player_is_ahead, player_is_ahead
if string == 'behind':
if string == 'Behind':
return player_is_ahead, 1-player_is_ahead
else:
print('TimeDiff setting value not recognized. Default to "player"')
print('TimeDiff setting value not recognized. Default to "Player"')
return 0, 1
Loading

0 comments on commit 4af5ffc

Please sign in to comment.