Increase accuracy with low frame rate

This is not about the engines accuracy or anything like that. The engines fine. My calculations are not.

With higher frame rates, one can be lazy with math and do things like,

if (distance > 1f)

I know I can compensate with TPF, just not exactly sure what the formula is for calculating distance with speed when taking into account TPF so things are nearly as accurate at low frame rates as they are higher.

In my case of 1f and a low frame rate, if you calculate

speed x tpf = 0.4630469f

and your next to last calculation distance is 1.01, you overshoot by a considerable amount, almost half a meter.

What is a good formula that evens out the distance accuracy based off TPF?

Something like this prevents overshooting targets

if ((distance - (tpf * 60f / 10f)) > 1f)

but the range is still between aprox
1 to 1 + (speed * tpf)

Step 1: don’t treat visualization objects as game objects.
Step 2: don’t use the rendering loop to do game logic

2 Likes

For stationary targets like the terrain and buildings, I cast a ray to determine the impact site right away, and then I can ensure that the projectile does not fly further than the impact distance and phase through the world.

For increased accuracy with moving targets at low frame rates, you could try out a handful of ways to account for the skipped distance that the projectile moves when the TPF value is high. But in my game all the spells still move slow enough that I haven’t worked on this yet, and I guess how you do this could vary depending on how fast your spells/bullets/projectiles travel.

Ok, I think this means don’t rely on things in a control like spatial.getWorldTranslation() and instead calculate your positions independently and just move the spatial accordingly?

By this you mean do all calculations in a separate thread, independent of update loops?

1 Like

Yep. Your logic loop will update your world at a fixed rate.

The scene graph’s job is then to display what of the world the player can see.

1 Like

How do you implement your GameLogic-Thread into your games? I always thought you would run your logical app states in the JME Main Thread…

With Space Rocks I ran the physics simulation in another thread so the rendering cycle and physics sim would run side by side. The two threads synchronize when it’s time to render another frame.

Basically when the frame is done rendering and the main loop comes back around it waits for the physics sim to finish it’s step then the physics sim waits while the models and such are updated, in the main thread, to reflect the location/rotation of all the game objects in the simulation then the simulation continues on its own while the frame is rendered.

The rendering thread just takes a snapshot of the logic/physics thread at a particular point in time.

1 Like

It kind of depends on what you care about. If tpf accuracy is not a problem then it’s fine to hack things right into the visualization thread as app states.

I prefer to plan ahead and put everything in a game system, as per SiO2’s GameSystemManager:

…which on some level they are kind of like app states except without all of the rendering-related baggage and a better idea of what simulation time is.

Edit: you can see examples of its usage here: GitHub - Simsilica/Examples: Example applications for various Simsilica libraries, singly or in combination.

2 Likes

Recast detour-crowd works really well using AppState update loop and TPF (NPC navigation). Using physics and BetterCharacterControl is where this problem is happening (PC navigation).

I am going to try and remove all physics, refactor PC navigation to work like detour-crowd, and implement this GameLoop.

Ill let you know how it goes.

I should correct this because it sounds as though the physics sim runs entirely independently of the rendering cycle. The physics sim runs one step concurrently with the rendering cycle then they sync up and the visualization objects are updated, input is processed, raycasting is performed and objects are added/removed from the simulation as needed then the two threads go off on their own again.