Collision callback returns error: "Box2D assertion failed""

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Sammm
Prole
Posts: 37
Joined: Fri Sep 09, 2022 4:39 pm

Collision callback returns error: "Box2D assertion failed""

Post by Sammm »

Hello!

I'm trying to handle collisions between the player and spikes, and when the player collides with the spikes, reset the player position. Here's my code for handling the collision, using callbacks:

Code: Select all

function beginContact(a, b, coll)
	if a:getUserData() == "Player" and b:getUserData() == "Spikes" then
		player.body:setPosition(player.x, player.y)
	end
end
However, when I run it, it works fine, but when the player collides with the spikes, I get an error, stating:
Error

main.lua:225: Box2D assertion failed: m_world->IsLocked() == false


Traceback

[C]: in function 'setPosition'
main.lua:225: in function <main.lua:223>
[C]: in function 'update'
main.lua:161: in function 'update'
[C]: in function 'xpcall'
I know the collision works fine normally, before I tried to reset the player's position, I printed a line to the console and everything worked fine. It's the "setPosition()" function that's somehow giving me an error. Here's the zip file with the code (I'm still trying to figure out how to make a .love file, sorry).
game.zip
(1.24 MiB) Downloaded 46 times
Thanks for any help! :)
Lua is LÖVE, lua is life
Ross
Citizen
Posts: 97
Joined: Tue Mar 13, 2018 12:12 pm
Contact:

Re: Collision callback returns error: "Box2D assertion failed""

Post by Ross »

Check the warning on the World:setCallbacks() page:
Making changes to a World is not allowed inside of the beginContact, endContact, preSolve, and postSolve callback functions, as Box2D locks the world during these callbacks.
It's a bit of a nuisance, but that's just how it works, which is understandable, since modifying things while the physics engine is in the middle of resolving collisions would really throw a wrench in the works.

I deal with it with a simple delayed callback setup. Inside the callbacks, if I want to do something that may modify the physics world, I instead just add the function and its arguments to a table, then after world:update() is done, I go through the list of delayed callbacks (if any) and call them.

Also of note from the docs:
The Contacts may be destroyed immediately after the callback is called, so if you want to store their data for use later in love.update, you must cache it.
In other words: you can't save the Contact itself for later, if you need the contact normal or something, you need to get it from the Contact during the physics callback and save that data for use later.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 35 guests