Kinematic physics losing contact point responses every 33rd frame

Using the method for collision handling described in the platformer tutorial (or any other method I have tried) I get stable results with one problematic exception:

When a kinematic body is standing still against a floor-surface (I have a constant gravity applied to the velocity of the body in my script) every 33rd frame or so the body gets no contact point responses from the floor. I do not get this hitch with dynamic bodies.

It looks alright in the rendering of the sprite, but since I have a bool property on the kinematic script that tells other scripts whether or not the body is touching ground I get unreliable results, and since my idle state is checking that bool, I start falling for one frame before it realizes I’m on the ground again.

I have worked around it for now with this ugly piece of code delaying the setting of my bool property:

if self.ground_contact then     -- This is set in the callback for each contact point response
	self.touching_ground = true    -- This is my property
	self.framecounter = 0

else
	self.framecounter = self.framecounter + 1
	if self.framecounter == 2 then
		self.touching_ground = false
		self.framecounter = 0
	end
end

If I print my velocity.y in my script every frame, it looks like this for 32 frames:
DEBUG:SCRIPT: -6.6666669845581

and then the 33rd still looks like this
DEBUG:SCRIPT: -13.333333969116

My question is: Is this expected behaviour when making custom collision handling or is there something else I can do to prevent the hitches other than delaying the setting of my property?

This sure sounds odd but I’m no expert on Box2D. I’ll ask someone else from the team to answer this.

Hey! Some ideas to trace it further…

I guess you are using some way to separate the kinematic body from the ground. Is this active while the body is touching ground? One reason could be that the separation value decreases to a barely visible amount, which after a number of frames (33?) manages to completely separate the body from the ground, in which case the contact point would not be reported. This should be quick to detect by printing the separation value every frame, or probably even better to print the y-position of the body every frame. Kill the application immediately after the non-contact-thing occurs and check if the y-position was increased by any amount before it happened. If the y-position did not change, do the same with whatever separation-value you apply to the position.

If you don’t affect the position of the body while it has ground-contact, I can not think of anything that would cause this to happen. Start with trying out the stuff above and repost if it fails to work.

1 Like

I disable gravity on the object when I am touching ground so my velocity is a zero-vector. The contact point response pushes my body out even when I am standing still, but the values don’t seem to change from frame to frame. Printing position.y of the body looks like this:

DEBUG:SCRIPT: 239.88888549805
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: 239.99998474121
DEBUG:SCRIPT: LOST GROUND CONTACT
DEBUG:SCRIPT: 239.88887023926
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: 240
DEBUG:SCRIPT: LOST GROUND CONTACT

…and so on.

Printing my compensation value (which is the same as the separation value in this case) that I use to adjust the position looks like this:

DEBUG:SCRIPT: LOST GROUND CONTACT
DEBUG:SCRIPT: vmath.vector3(0, 0.11112969368696, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: vmath.vector3(0, 2.7939677238464e-006, 0)
DEBUG:SCRIPT: LOST GROUND CONTACT

I assume that the compensation-value is too small to show up in my position print and that it invisibly pushes it further out every frame? Do you have any suggestion as to how I can avoid this?