Rapid adding/removing from simulation

Topics: User Forum
Jan 6, 2010 at 4:10 PM

Hi all,

So, I've been working on a game project using Farseer physics and I've run into an issue while I was optimizing. My game uses fairly large levels that are based on 200px tile segments (each wall tile is a static physics rectangle). I found that I was getting a significant performance increase when I would take my PhysicsSimulation and manually .Add() and .Remove() physics objects that were outside of a specific range (static tiles went the furthest out, then enemies would be deactivated further in so that an enemy would never move into space that may or may not have a static tile). Although this gave the needed performance boost, I also found an issue with using the engine like this. When I would move between areas where tiles would be activated/deactivated, physics objects that have not been added or removed seem to be effected sometimes. Often when I'm pushing against 2 tile walls while moving between them, if there is an enemy on the other side of the tile wall (also still in range to be activated and pushing the static wall from the other side) I can see some weird behaviors occurring. Sometimes enemies pass through walls, sometimes my character passes through walls, and sometimes we just seem to get pushed away from walls at a rate higher than our bounciness should allow.

At first I thought that this method would be equivalent to changing body.Enabled attributes, but the adding and removing seems to give me even more of a boost in performance. Is there any good way of dealing with this, and is this common behavior when you are rapidly adding and removing? Or is this just not the right way to deal with these kinds of objects in the physics library?

If you're a more visual person and need to see how the game is laid out (tiles and enemies and all that) I run a set of video development diaries and you can check out the latest one at http://www.youtube.com/watch?v=RMekHxtFOoc

Thanks for any help y'all can provide.

Jan 6, 2010 at 6:04 PM

I recommend that you enable/disable bodies instead of removing and adding them. There should be very little overhead in having disabled bodies in your level since they are excluded in the broadphase.

If you are using the default narrow phase collider, then you are recreating the distance grid once you add the bodies again, that can slow down your game and uses a lot of memory. You might also want to experiment with different broadphase colliders to see which one gives the best performance in your case. Some of them are better at static bodies than others. We even have some that are better with disabled bodies - said in another way; they have the least overhead.

You can use a debug view like the one included in our samples. It is a great way of resolving issues like your. You can extend it with drawing disabled bodies with another color (Not sure if I included it already).

Jan 12, 2010 at 3:16 PM
genbox wrote:

I recommend that you enable/disable bodies instead of removing and adding them. There should be very little overhead in having disabled bodies in your level since they are excluded in the broadphase.

I don't think they are, they are treated the same as static bodies from what I can see, with all of the broad phrase colliders.

There might be a way to only delete / readd to the broad phrase collider and not the narrow phrase, so there wouldn't be as much of a slowdown recreating the distance grid when readding, but I haven't tried this yet.

Jan 12, 2010 at 5:24 PM

But they are excluded, and no, static bodies are indeed included in the broadphase.
I can understand why you would think otherwise. Let me explain:

All the broadphase algorithms needs to check ALL objects against each other. How they do that is up to the algorithm. Some use trees, others uses lists; but all of them need to check each and every object against the other. The great thing about the algorithms, is that they are clever. They remember the previous state and only update from the previous state to the current (only some of them do that). This behavior is great for objects that does not move fast, teleport (or gets readded all the time).

Inside the loop that does all the checks, there also is a check to see if they are disabled. If they are, they will not generate an arbiter, and thus it will not go to the very expensive narrow phase. Static bodies, they go to the narrow phase all the time (unless they are disabled too). There is a special scenario where both the objects are static, that scenario will not generate an arbiter.

The bottom line is, deleting and then adding the body from the broadphase can actually be harmful performancewise. It really depends on the algorithm being used. In the case of the bruteforce broadphase algorithm, it is always better to delete and then readd the geometries (it is an O(n^2) algorithm, keeping n low is a good thing in that case). But in algorithms like sweep and prune (it is stateful) it can hurt the performance. Besides that, the Add and Remove operations on the PhysicsSimulator are O(n) operations in themselves.