d3xMachina / FFPR-Fix

Tweaks for Final Fantasy Pixel Remaster games
MIT License
2 stars 0 forks source link

Stutter fix #4

Closed jmroon closed 1 month ago

jmroon commented 1 month ago

Preface:

Hi there! I'm the original author of ffpr-tool where I tried my best to alter the walk speed to reduce stutter. I didn't really know what I was doing and just did some hex edits to try to align the walk speed to better match the camera. This, of course, was a very imperfect approach.

Having not looked at the issue for a very long time, I stumbled across your incredible collection of mods here. I don't know much about writing BepinEx plugins, and even less about Unity development, but I deep dove into it a bit tonight.

The issue:

So the issue for the scroll stutter in this game I think seems reasonable. I believe they only ever move the camera, or the world, in integer steps. This was the assumption I took when trying to fix the issue initially by modifying the move speed and I think it checks out. Due to the movement only happening in integer steps, it results in a judder as we get an uneven amount of pixels being scrolled every frame.

So I just poked around with a decompiler to see what I could find. I'm honestly not sure if I found it, but this seems potentially promising:

Last.Camera.FrontRenderTarget seems like the most likely place for this behavior. ConvertMainGamePosToScreenPos ConvertScreenPosToMainGamePos

The problem is I'm not sure if we can effectively patch these to achieve the desired result. If game/screen are just slightly different, and screen is just a pixel clamped version of main, then maybe these can be overriden to not convert between game/screen and that would do the trick? Not super optimistic though since its taking a vector and camera type as input...it might be a bit more involved.

Maybe you might have some better ideas. Addressing this is a bit beyond my skill set at this point, but I'd love to contribute if I can somehow get up to speed.

d3xMachina commented 1 month ago

Hi!

It seems the functions ConvertMainGamePosToScreenPos and ConvertScreenPosToMainGamePos are only used for the touch input (a remnant of the code for the Android version which it is based on) and is not related to the scroll stuttering.

The rest of the functions in Last.Camera.FrontRenderTarget won't help either looking at the disassembled code.

When I saw the GetPPU function I had a bit of hope (PPU = pixel per unit) but it doesn't affect the field, just the bird view. Here is what it looks with a value of 1 for the fun (with a bigger value it's just zoomed in) : FINAL FANTASY VI 2024-08-24 13-38-29

I've tried finding a proper way to fix the stutter in the past but didn't find it. I looked for references to Unity.Engine.Mathf.RoundToInt : it's used in Last.Entity.FieldSpriteEntity.MoveTo and Last.Entity.FieldEntity.MoveTo or for some int casting in related functions (I don't remember which) to avoid moving in integer steps. But removing the rounding here (by editing the assembly) didn't help and even created some softlocks. Since setting the FPS to 100+ or adjusting the player speed gets rid of most of the perceptual stutter, I ended up calling it a day.

If someone finds a solution, I would be glad to implement it as long as it's doable with BepInEx.

jmroon commented 1 month ago

Thanks for looking into it! My hopes are dashed for now haha.

Your findings does seem to point to the MoveTo functions likely having the rounding baked in, but it sounds like some other code is probably reliant on positions being integers at all times. I really was hoping they were handling this at the rendering or camera layer.