0
votes

I'm working on a little game with libGDX, that uses Box2D for collision detection. This was working fine, till I added an arrow to the game, so the player can shoot. Since I added this feature I'm facing the problem that the game gets stuck from time to time, and doesn't react anymore.

I think the reason for this behaviour is an endless loop somewhere in the Box2D world step. When I stop the execution using the debugger the stopping point is always in the World.step(float, int, int) method. Unfortunately this is a native method so I can't find where the problem is exactly:

// from com.badlogic.gdx.physics.box2d.World

public void step (float timeStep, int velocityIterations, int positionIterations) {
    jniStep(addr, timeStep, velocityIterations, positionIterations);
}

private native void jniStep (long addr, float timeStep, int velocityIterations, int positionIterations);

The problem:

Sometimes when using the new "shoot arrow" feature the execution seems to stop and the game just freezes. It is realy hard to reproduce, therefore I can't realy tell what the real root cause is. It only appears when adding a new arrow to the Box2D world, but the problem does not appear all the time.


What I've tried so far:

  • To validate that the problem is within the Box2D code, I've tried to change the mask of the arrow's fixture to 0x0000, so it doesn't collide with any other object. This actually fixed the problem (or at least I couldn't reproduce it anymore). But this doesn't help very much, because an arrow that doesn't hit anything isn't very usefull in the game...
  • Changing the mask of the fixture, so it doesn't collide with a specific category (called CATEGORY_OBSTACLE) also seemed to fix the problem, but I have no idea why, and still this isn't realy a solution...

The code:

Since I couldn't seem to even reliably reproduce the problem, I also wasn't able to create a minimal reproducable example. I can only point to the GitHub repo of the game. Sorry for this :( The current code is placed in the branch projectile_bug.

To explain the code a bit:

  • The class GameScreen has a render method, from which the World.step method is called (the one that causes the endless loop).
  • The class Dwarf has an executeSpecialAction method, which starts the creation of the arrow through some factory methods.
  • In the end, the class ProjectileFactory has a createProjectile method, that creates the arrow and adds it to the world.
  • The categories and masks that are used by the Box2D fixtures are placed in the PhysicsBodyCategories class. The arrow's fixture uses the mask MASK_PLAYER_ATTACK

Steps to reproduce:

Since I don't realy know the root cause of the problem, the bug can only be reproduced by shooting some arrows over the map:

  • Start the game using the main method in the class DesktopLauncher in the desktop-subproject.
  • Move over the world and fire some arrows using the space key
  • Hope for the bug to appear... It usually takes quite some arrows on the world for the bug to appear (I increased the fire rate in the projectile_bug branch to speed things up a bit)

The Question:

I'm not sure what causes this bug and I'm still quite new to Box2D. If anyone has an idea on how to fix this or knows a workarround for this problem, it would realy help me a lot. Also if you know about some related, reported bugs or anything like this, it could also help.

Thanks in advance.

1

1 Answers

1
votes

Okay, I bite for it. In my experience box2d crashes or hangs most of the time when bodies or fixtures are not correctly destroyed, or when there are some dangling references to destroyed bodies. So I just tried to remove this statement form your code PhysicsWorld.getInstance().removeBodiesAndFixtures(); right after the step function, and voila, it works. Nice game btw. This is of course not the solution, but it might give you a hint where to search for the root cause.