Box2D has an isBullet property that can be set on dynamite dynamic bodies to perform continuous collision detection. We do not expose this property.
Can you share an example project where this problem is very obvious and I’ll play around with the property? If it solves your problem we’ll look into adding it in the API.
I was curious that I hadn’t seen this behaviour in other engines I’ve used (Flash and Gideros), so I created a minimal example in Gideros with just a ball bouncing. It doesn’t display any tunneling, even with very high gravity (100000). In Gideros, a gravity of 100 feels earth-like.
A dynamic collision object with restitution 1 that bounces on a static body with restitution 0 increases each bounce a little. A value of 1 should only retain the bounce height, not increase it.
When setting frame cap to 20 the issue becomes much more pronounced, to the point at which the ball tunnels through the other side and disappears.
It seems to me this must be related to how Defold updates the physics?
After a delightful GUI only project I’m thinking of driving back into the world of physics again. Has there been any progress on the physics front, especially to do with tunneling?
Relevant threads:
Updating the version of Box2D Defold uses:
Chain shape feature request:
An interesting recent development is the native Box2D extension by @sergey.lerg:
This extension also seems to suffer from tunneling, which may or may not be related (screenshot from the video in the post above):
To me it’s preferable to use the built in physics in Defold, so that collision shapes can be added easily right in the editor without third party tools. That said, maybe Sergey’s native extension is the way forward when it comes to a more accurate physics simulation?
To prevent tunneling Box2D has bullet mode for dynamic objects, which is easy to set in my extension.
Bullets
Game simulation usually generates a sequence of images that are played at some frame rate. This is
called discrete simulation. In discrete simulation, rigid bodies can move by a large amount in one time
step. If a physics engine doesn’t account for the large motion, you may see some objects incorrectly pass
through each other. This effect is called tunneling.
By default, Box2D uses continuous collision detection (CCD) to prevent dynamic bodies from tunneling
through static bodies. This is done by sweeping shapes from their old position to their new positions.
The engine looks for new collisions during the sweep and computes the time of impact (TOI) for these
collisions. Bodies are moved to their first TOI and then the solver performs a sub-step to complete the
full time step. There may be additional TOI events within a sub-step.
Normally CCD is not used between dynamic bodies. This is done to keep performance reasonable. In
some game scenarios you need dynamic bodies to use CCD. For example, you may want to shoot a high
speed bullet at a stack of dynamic bricks. Without CCD, the bullet might tunnel through the bricks.
Fast moving objects in Box2D can be labeled as bullets. Bullets will perform CCD with both static and
dynamic bodies. You should decide what bodies should be bullets based on your game design. If you
decide a body should be treated as a bullet, use the following setting.
bodyDef.bullet = true;
The bullet flag only affects dynamic bodies.
Does bullet solve the problem with your extension? The tunneling in Defold’s built in physics is likely to do with the way Defold works, rather than Box2D itself. See example video above I made in Gideros, which uses a more “pure” version of Box2D.
I don’t know what Box2d settings gideros uses, but if known, it’s possible to recreate in Defold with my extension. There are several values in Box2D for fine tuning.
It would be interesting to see if the overlap in the extension is because of Defold, or if it’s expected Box2D behaviour. Does a dynamic bouncing ball tunnel through a static box using the extension? I wasn’t able to get any tunneling in Gideros with that setup.
New game, same issue! This time I’m using joints, so the body has to be dynamic.
My new theory is that the game object is moved before all collisions have been resolved, so it appears stuck in the terrain for one frame.
I have been trying to move the body back when overlapping using the hack of firing a blind raycast and picking up its “ray_cast_missed” message mentioned in these threads: