From 85fa2ea1c2b093f2b73d8134daf237374a6ccb8e Mon Sep 17 00:00:00 2001 From: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Date: Sat, 13 Sep 2025 08:05:12 -0700 Subject: [PATCH] Locks Diagonal Movement to the Tick (#92956) ## About The Pull Request When we move diagonally, we multiply our movement rate by sqrt(2) (cause A\*A + B\*B = C\*C right). The problem with this is most of the time our movement rate is cleanly divisible by 0.5 (our tick rate), and sqrt(2) is like 1.47 something. This means anytime you move diagonally, you become desynced from the tick, and get movement jitter (about 80% off window for standard diagonals, tho that gets better as it compounds). I saw this in my smooth movement pr (#92935), it's been a problem for 4 years now (#63058) we just like, never noticed cause why would you the rest of the game is horrible too. This behavior also possible with normal movement, but that is not CONSTANT like this is. What I'm doing here is flooring the resulting delay to the tick rate, because that's basically close enough, and I prefer moving slightly faster to moving slightly slower. ## Why It's Good For The Game Best case displays (with all other problems resolved) Old: https://github.com/user-attachments/assets/0151af94-9204-4ba9-ad0c-7e4958faa254 New: https://github.com/user-attachments/assets/2eb4df09-abff-4e10-b32f-3765755336e1 ## Changelog :cl: fix: Moving diagonally will no longer lead to stutter stepping (it's tickbound) /:cl: --- code/modules/mob/mob_movement.dm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index f833ad9028a..16a77411e4c 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -101,8 +101,10 @@ //We are now going to move var/add_delay = mob.cached_multiplicative_slowdown - var/new_glide_size = DELAY_TO_GLIDE_SIZE(add_delay * ( (NSCOMPONENT(direct) && EWCOMPONENT(direct)) ? sqrt(2) : 1 ) ) - mob.set_glide_size(new_glide_size) // set it now in case of pulled objects + var/glide_delay = add_delay + if(NSCOMPONENT(direct) && EWCOMPONENT(direct)) + glide_delay = FLOOR(glide_delay * sqrt(2), world.tick_lag) + mob.set_glide_size(DELAY_TO_GLIDE_SIZE(glide_delay)) // set it now in case of pulled objects //If the move was recent, count using old_move_delay //We want fractional behavior and all if(old_move_delay + world.tick_lag > world.time) @@ -120,7 +122,7 @@ . = ..() if((direct & (direct - 1)) && mob.loc == new_loc) //moved diagonally successfully - add_delay *= sqrt(2) + add_delay = FLOOR(add_delay * sqrt(2), world.tick_lag) var/after_glide = 0 if(visual_delay)