Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Topic Gosu / Gosu Exchange / Problem with Delta-Time Physics in a windowed Gosu (Ruby)
- - By bardolos Date 2015-10-14 20:32
While developing a simple physics engine to integrate with a Gosu game I'm hammering together, I noticed an issue that might compromise Delta-Time systems.

The current implementation of my simple system is very efficient and can run particle collisions and so on.
The problem is that when I click and drag the window, the Gosu engine pauses, but the Gosu::milliseconds() counter keeps going up. This makes sense since it should "return the number of milliseconds elapsed" since the Gosu started running.

However, for time-sensitive applications - especially a physics engine handling collisions - this means that certain features may be skipped.

An an example, imagine a free-falling object at position (0,0), that follows this equation(source):

position += speed*dt

And it is supposed to hit the ground at, say position (0,100). With very small dt's, as a result of being called in a healthy update loop, this object's animation is very smooth and can easily find the floor at (0,100) by successional approaching and correcting its trajectory.

However, when I hold and drag the window the updates stop, meaning "position += speed*dt" is not computed until I let go of the window.
When I do let go though, I will have a very large dt, as a result of using Gosu::milliseconds() to get that time delta between that update cycle and the previous one.
Eventually, for sensitive trajectories such as the one mentioned above, this new king-sized dt can blast the object's position to (0,9456) for example, which would take it way below the floor without ever having the opportunity to check for a collision.

I tried looking for a solution but it yielded no results.
I was wondering if anyone had looked into this before and was willing to provide some insight. I thought there may be a way of monkey-patching the window class to forbid dragging (which is a solid option in my case), or some kind of lower-level approach that keeps the game loop running even during the window dragging operation.

Any help is appreciated.
Thanks a lot.
Parent - - By RunnerPack Date 2015-10-15 00:31
I've done some research on physics engines, and most of them treat fast moving objects as lines, rather than points, for collision purposes. I.e., you take the imaginary line segment from the object's last position to its current position, test for the first collision between that line and the rest of your geometry (the floor, in this case), clip the object to that point, and calculate the appropriate collision response.

BTW, I ported some geometry intersection code to Ruby a while back. If it's useful, feel free to use it: https://github.com/runnerpack/intersect (be sure to click the link to the project from which I ported it!)

Another idea would be to simply detect extremely long dt's, and reject them (maybe save the last dt and reuse it for one cycle).

Finally... what about just using full-screen mode? Do you have to use a draggable window?
Parent - - By bardolos Date 2015-10-15 16:37
Hi, thanks for replying. The idea of using lines was more or less the direction I was headed. My implementation is based on a "two-step discrete simulation" of sorts, where the current position (which is safe) is used for drawing and the "next position" is used for computations and hypothetical collision checking. These two points make the imaginary line segment, except I don't consider the line itself. For most cases this is fine, but for small particles and fast moving objects, like you said, using the full line should yield much better results.

I will implement this soon and will take a look at your code and the project you ported it from. I don't have the time to do this at this exact moment so I'll probably come back with an opinion some time from now.

And sadly, I do have to use a window :(
The current project is meant to be a sort of companion app to assist in level development, and the user is expected to work with multiple other windows. The ideal case would be for the loop to keep running and drawing even during the dragging operation, but if that's not possible, the window should at least have a "lock" or something that can enable or disable dragging at will (so I can condition the user's control flow).

Thanks.
Parent - By lol_o2 Date 2015-10-15 18:12
You can also measure time in frames. Each frame is like 16-17 milliseconds, so make a global frame counter and multiply it by milliseconds for your calculations. The advantage is that this time is more accurate on lags and hangs. When using real-time milliseconds you risk that your in-game time will differ from your calculations. However I don't know how does this apply to physics.
Parent - By jlnr (dev) Date 2015-10-18 09:51
This also happens when the user closes their laptop and opens it up on the next day. I think limiting dt is the way to go, but to be honest I haven't ever built a dt based game.
Up Topic Gosu / Gosu Exchange / Problem with Delta-Time Physics in a windowed Gosu (Ruby)

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill