I have a nasty problem with my physics engine. Objects sometimes just jump in place, or roll left and right.

Main game loop works in that manner:

  • Every living object is updated (it changes velocity, the logic is different for each object)
  • Engine computes collisions using objects' positions and velocities and resolves them.

Imagine that we have a grenade positioned at one pixel above ground, with zero speed, and the gravity is 1 px/tick^2. Normal bounce coefficient is 0.5, so an object will bounce with half speed.

According to the algorithm:

  • Object's controller adds gravity to its velocity, so now v = -1.
    Engine moves object to y = 0, no collisions happen.
  • Velocity is changed to -2 by the controller.
    Engine tries to move the object, the collision happens immediately, v is set to 1, and object moves to y = 1.
  • Velocity is changed to 0 by the controller.
    The object remains in place.

Initial conditions has reproduced. The object will bounce forever with a period of 3 ticks. These situations vary, but they all are caused by discrete nature of the engine described above.

This bug was in every version of my game. Objects may vary in shape and size, and the terrain is destructible Worms-like. I use my own engine that uses swept collision detection customized to work with small and fast objects, never letting them go through impassable object unless they were spawned inside, and the only acceptable option for me is to modify it.

One thing that I have in mind that I can detect if object had very low speed for some time, make it "immobile" and call different controller functions depending on "immobile" flag. It's an ugly solution though, because the complexity of my logic will increase. Also, when a round object stands on two points and we remove one, it will not fall. So this approach is wrong at all I guess.

What is the right approach to fix that?

  • \$\begingroup\$ Are your physics positions and velocities constrained to integers? \$\endgroup\$ – DMGregory May 30 '19 at 11:56
  • \$\begingroup\$ @DMGregory They are floats. \$\endgroup\$ – trollingchar May 30 '19 at 12:01
  • \$\begingroup\$ Regarding your proposed solution, some physics engines allow for an object to be disabled once they reach a very low speed. \$\endgroup\$ – Vaillancourt May 30 '19 at 12:08
  • \$\begingroup\$ I remember my attempt to implement idle flag, when two objects were waking each other up by contact. Is there a common solution to avoid this? \$\endgroup\$ – trollingchar May 30 '19 at 12:46
  • \$\begingroup\$ How can objects wake each other by contact if both are disabled? \$\endgroup\$ – Vaillancourt Jun 6 '19 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.