jak1: fix balance-plats at high-fps #4069
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Looking at the balance-plats, they showed an immediate visual clue, which was the stuttering of Jak's feet on their surface.
This is precisely what happens when you don't include sticky on a collision; it doesn't "pull" Jak along with it, and he repetitively "falls" onto it's surface over and over as it moves downwards.
This is a mystery, since this actor does have sticky, in fact, it's not even possible to detect riders without sticky, which these certainly do. This same appears on PS2, so I knew fixing it was not an option.
I had an immediate theory of what was happening: since Jak is continuously falling onto it as it moves downwards, he's only riding some frames, and skipping others. A higher frame rate = more moments he's touching.
This means that basically, the balance-plat's entire speed is determined by when his feet happen to micro-stutter. This is the hardcoded scalar for it's entire speed.
This means I needed to emulate the 60 FPS "falling" at different framerates. I tried adding an fps counter to the actor so that the rider check only ran once every 60th of a second, but I knew adding a variable to the actor just for fps wasn't a good idea.
However, I was able to confirm that would work. Luckily, this comment gave me an idea, which meant I could use a variable of process drawable, avoiding adding a variable.
This unique problem needs a unique solution, I gate rider checks so they only pass if one sixtieth of a second
(seconds 0.01666666)has passed since the last ride. This makes it act like his feet are stuttering like they do at 60 FPS, avoiding the extra frames where his feet are touching at high framerates that add more speed.I also added the same for the send-to messages, since at high frame rates the passive return to center that runs every frame was stomping the send-to-next velocities which run less often.
Then, I managed to refactor it down to a tiny edit, a guard in one place that gates on 1/60th of a second, framerate already 60, or, self grow (since you don't want to double-gate these).
It's just: this guard,
(set-state-time)on ride, and(set-state-time)on grow (limits increased-rate return to center stomping grow).Lastly, there was an issue with the existing multiplies by FPS RATIO, which was a clear double scale of the acceleration (once when setting accelerate, then again when adding the accelerate). I'm guessing since the extra riding frames added so much speed, this double scalar helped slow it down, however when corrected the double scalar made it too slow since it was slowing down for framerate twice.