Weird Character getting stuck glitch
Weird Character getting stuck glitch
Hey Norbo, hope you're well.
I've been using this excellent physics engine of yours for a few weeks now, ever since I stripped out all of my shoddy collision detection code and rebuilt using BEPU. My game is a little bit of an unusual choice for BEPU. It's a 2D game with a perspective similar to legend of zelda: link to the past.
Right now, I'm using pretty simple features of BEPU: all walls are kinematic boxes. All characters and objects are simply dynamic boxes that slide around with their LocalInertialTensorInverse zeroed out. I'm also using spheres for things like detecting when a sword swing has hit someone, or when a player is in range of an object they can interact with. In order for these detection spheres to not collide with the solid objects in the simulation, I've made use of Collision Groups. Spheres which are meant to detect players are part of a collision group that has the rule NoBroadPhase with every other group except for Players, with whom they share a No Solver rule. I then hook up the events InitialCollisionDetected and CollisionEnded on the detection sphere in order to do stuff when a player has moved into or out of the sphere area.
The problem is, I think my player's box is actually colliding with the detection sphere, even though their collision groups are set to use NoSolver with each other. Basically, what happens is that one out of every hundred or so times I move into a detection sphere (it seems to be random), the player's character simply stops moving. The odd thing is that, while stuck, the character's box reports that its linear velocity is quite high -- the linear velocity actually freezes in place at whatever it was at when the collision between the character's box and the detection sphere took place. So the character's velocity is reported as moving at full speed, but instead the character is stuck in place, right at the edge of the sphere. Any collision with some other object in the simulation will free it. Simply moving as the player will not free the character, because right now my character movement just applies a linear velocity to the character only if its moving below a certain speed threshold. So, when the linear velocity is reported as being high, the movement controls don't do anything.
A few more points that might be significant:
I recently switched my XNA game object to IsFixedTimeStep = false. It fixes a pretty annoying screen jitter for me. Not sure, but the issue might not exist when IsFixedTimeStep = true.
I've tried passing the (float)gameTime.ElapsedGameTime.TotalSeconds into space.Update(), and I still get the problem.
Also, the detection sphere is itself connected to a solid box object by means of a BallSocketJoint. The solid box is part of a different collision group which is set on NoBroadPhase with the detection sphere. Not sure if this could cause problems.
I've tried enabling Buffered States and only adding and removing things by way of the SpaceObjectBuffer. Doesn't seem to make a difference. Tomorrow I'll try messing around with continuous collision detection and the three Position Update Modes. If that stuff doesn't work, I may just try to redo character collision with the simpleCharacterController you built, and see if that has the same issue.
If any common mistakes or problems come to mind with what I'm describing, I'd love to hear. This is the hardest to track down bug I've run into yet.
Thanks for the amazing engine -- couldn't have built anything this cool in years of work, and using it I've been able to get an action RPG practically up and running in two months. (This is actually my first real game project).
Let me know if posting a video would help. I could try recording something with fraps.
Alex
I've been using this excellent physics engine of yours for a few weeks now, ever since I stripped out all of my shoddy collision detection code and rebuilt using BEPU. My game is a little bit of an unusual choice for BEPU. It's a 2D game with a perspective similar to legend of zelda: link to the past.
Right now, I'm using pretty simple features of BEPU: all walls are kinematic boxes. All characters and objects are simply dynamic boxes that slide around with their LocalInertialTensorInverse zeroed out. I'm also using spheres for things like detecting when a sword swing has hit someone, or when a player is in range of an object they can interact with. In order for these detection spheres to not collide with the solid objects in the simulation, I've made use of Collision Groups. Spheres which are meant to detect players are part of a collision group that has the rule NoBroadPhase with every other group except for Players, with whom they share a No Solver rule. I then hook up the events InitialCollisionDetected and CollisionEnded on the detection sphere in order to do stuff when a player has moved into or out of the sphere area.
The problem is, I think my player's box is actually colliding with the detection sphere, even though their collision groups are set to use NoSolver with each other. Basically, what happens is that one out of every hundred or so times I move into a detection sphere (it seems to be random), the player's character simply stops moving. The odd thing is that, while stuck, the character's box reports that its linear velocity is quite high -- the linear velocity actually freezes in place at whatever it was at when the collision between the character's box and the detection sphere took place. So the character's velocity is reported as moving at full speed, but instead the character is stuck in place, right at the edge of the sphere. Any collision with some other object in the simulation will free it. Simply moving as the player will not free the character, because right now my character movement just applies a linear velocity to the character only if its moving below a certain speed threshold. So, when the linear velocity is reported as being high, the movement controls don't do anything.
A few more points that might be significant:
I recently switched my XNA game object to IsFixedTimeStep = false. It fixes a pretty annoying screen jitter for me. Not sure, but the issue might not exist when IsFixedTimeStep = true.
I've tried passing the (float)gameTime.ElapsedGameTime.TotalSeconds into space.Update(), and I still get the problem.
Also, the detection sphere is itself connected to a solid box object by means of a BallSocketJoint. The solid box is part of a different collision group which is set on NoBroadPhase with the detection sphere. Not sure if this could cause problems.
I've tried enabling Buffered States and only adding and removing things by way of the SpaceObjectBuffer. Doesn't seem to make a difference. Tomorrow I'll try messing around with continuous collision detection and the three Position Update Modes. If that stuff doesn't work, I may just try to redo character collision with the simpleCharacterController you built, and see if that has the same issue.
If any common mistakes or problems come to mind with what I'm describing, I'd love to hear. This is the hardest to track down bug I've run into yet.
Thanks for the amazing engine -- couldn't have built anything this cool in years of work, and using it I've been able to get an action RPG practically up and running in two months. (This is actually my first real game project).
Let me know if posting a video would help. I could try recording something with fraps.
Alex
Re: Weird Character getting stuck glitch
Is the velocity higher than anything the character could achieve normally in a single frame? Is the character position entirely frozen, without no jitter?Basically, what happens is that one out of every hundred or so times I move into a detection sphere (it seems to be random), the player's character simply stops moving. The odd thing is that, while stuck, the character's box reports that its linear velocity is quite high
If the problem was just that the character got stuck sometimes, I'd guess it was related to the character's box latching onto some other box's edge and preventing it from moving. The box-box collision case has sharp edges, so if rotation is locked, there's a possibility that motion will get stopped.If any common mistakes or problems come to mind with what I'm describing, I'd love to hear. This is the hardest to track down bug I've run into yet.
However, if the velocity is higher than a single frame's acceleration, then the above isn't the (only) problem. If continuous collision detection is enabled (entity.PositionUpdateMode = PositionUpdateMode.Continuous), it's possible the motion is being clamped, but it will never be clamped to zero. If it's not moving at all, then this too is not the (only) problem. I can't think of any other obvious possibilities off the top of my head.
Good to hearThanks for the amazing engine -- couldn't have built anything this cool in years of work, and using it I've been able to get an action RPG practically up and running in two months. (This is actually my first real game project).

A video might help, though a runnable/debuggable reproduction case showing the behavior would allow the fastest diagnosis.Let me know if posting a video would help. I could try recording something with fraps.
Re: Weird Character getting stuck glitch
The linear velocity stays completely fixed at whatever value it was at when the character's box collided with the detection sphere. The character's box stops moving, but its velocity remains set at the character's full movement speed (or whatever speed it was moving at).Norbo wrote: Is the velocity higher than anything the character could achieve normally in a single frame? Is the character position entirely frozen, without no jitter?
An interesting thing I just discovered this morning: right when the character gets frozen, its box's IsActive variable is being set to false. Is it possible the engine is for some reason turning the character's box off when it collides with the detection sphere? The IsActive variable being set to false would mean that the character's box would stop being updated by its linear velocity, right? Maybe that could explain why linear velocity is remaining at full speed, but the box isn't moving?
I've also just tried setting box.PositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Continuous, and I don't seem to be able to reproduce the issue any more. Will try again later, but that might have made it go away.
either way, I plan on switching characters to either sphere or cylinder shapes later on anyway, so obsessing over this glitch might not be the most productive thing I could do right now, anyway

I would definitely be happy to send my code over, but it's nowhere near being modular enough to pull out the issue with a smaller test case, and the issue itself sometimes takes a good 20 minutes of running into the detection sphere over and over again to reproduce. I'll definitely develop with an eye toward making a reproduction case I can pull out in the future, but it definitely won't be today, and I don't really want to make you waste time on reproducing the problem yourself. Are there any variables you're particularly curious about? I could record a video for now, with a bunch of debug values being written to the screen.A video might help, though a runnable reproduction case showing the behavior would allow the fastest diagnosis.
Re: Weird Character getting stuck glitch
Yup, that explains it.An interesting thing I just discovered this morning: right when the character gets frozen, its box's IsActive variable is being set to false. Is it possible the engine is for some reason turning the character's box off when it collides with the detection sphere? The IsActive variable being set to false would mean that the character's box would stop being updated by its linear velocity, right? Maybe that could explain why linear velocity is remaining at full speed, but the box isn't moving?
Either it's being manually deactivated by something, or the scales are such that the linear velocity is small enough for the object to be considered nearly stationary, and the deactivation manager turns it off.
The deactivation threshold can be tuned with the Space.DeactivationManager.VelocityLowerLimit. However, if a character running at full speed is running afoul of the lower limit, the scales involved might be too tiny, and could cause problems elsewhere.
Re: Weird Character getting stuck glitch
The weird thing is that the linear velocity is usually around (20, 0, 2) or so when this happens. That can't be anywhere near the default Velocity Lower Limit, can it? The scales involve dynamic objects with a mass of .3 to 5 or so, with width/height/length ranging between 1 and 10. The gravity is set at (0, -50, 0).
It just occurred to me... in order to make the detection spheres move with the objects they're attached to with a BallSocketJoint, I made them dynamic objects as well. And I gave them a mass value of .001f... could this be causing weird calculations to happen in the narrow phase, whereby the player character's box is being set to IsActive = false, even though the characters box and the detection sphere are set to CollisionRule.NoSolver?
If setting the mass to .001f on an object that's supposed to move and report collisions, but not actually affect anything with its mass IS a bad idea, what would be the best way to have the detection sphere be basically massless but still able to move? I set the mass so low because I didn't want it affecting the motion of the object it's attached to with a BallSocketJoint.
I'm still getting the issue -- I managed to reproduce it once after about half an hour of testing. IsActive goes false, even if I explicitly set IsAlwaysActive = true. That shouldn't be happening, right? I really don't think I've tried to set IsActive to false anywhere in my code.
Thanks for your responses Norbo,
Alex
It just occurred to me... in order to make the detection spheres move with the objects they're attached to with a BallSocketJoint, I made them dynamic objects as well. And I gave them a mass value of .001f... could this be causing weird calculations to happen in the narrow phase, whereby the player character's box is being set to IsActive = false, even though the characters box and the detection sphere are set to CollisionRule.NoSolver?
If setting the mass to .001f on an object that's supposed to move and report collisions, but not actually affect anything with its mass IS a bad idea, what would be the best way to have the detection sphere be basically massless but still able to move? I set the mass so low because I didn't want it affecting the motion of the object it's attached to with a BallSocketJoint.
I'm still getting the issue -- I managed to reproduce it once after about half an hour of testing. IsActive goes false, even if I explicitly set IsAlwaysActive = true. That shouldn't be happening, right? I really don't think I've tried to set IsActive to false anywhere in my code.
Thanks for your responses Norbo,
Alex
Re: Weird Character getting stuck glitch
The mass should have nothing to do with it, and those velocities/scales are far above the threshold. Something, somewhere is forcing it to deactivate, though I'm not sure what. I can't think of anything in the engine that explicitly tries to deactivate an object except for the regular deactivation loop, which should indeed be stopped by setting IsAlwaysActive = true.
Is this in v0.16.2, or the development version? If it's the development version, is it the very latest development version?
Some things changed in the deactivation system in the development version, so if it was an earlier development version, there could be a bug fixed in some of the newer development versions. It's also technically impossible to force-deactivate a single entity in the latest development version since it was an inconsistent operation to begin with, so that should help narrow things down.
Is this in v0.16.2, or the development version? If it's the development version, is it the very latest development version?
Some things changed in the deactivation system in the development version, so if it was an earlier development version, there could be a bug fixed in some of the newer development versions. It's also technically impossible to force-deactivate a single entity in the latest development version since it was an inconsistent operation to begin with, so that should help narrow things down.
Re: Weird Character getting stuck glitch
By the way, if at some point you end up wanting to make the detection sphere not physically connected to the player, an alternative is to make the sphere kinematic and set its position each frame at the appropriate offset away from the character. Kinematic objects with NoSolver collision rules are a good 'detector' since you don't have to worry about them being affected by any external forces.
It would be nice to track down the source of the current problem regardless, though.
It would be nice to track down the source of the current problem regardless, though.
Re: Weird Character getting stuck glitch
Hey Norbo, thank you so much for all your time!
Let me start off with my crack-brained theory that I'm getting from stepping through the debugger right now:
Basically, I hooked up a delegate to the event BecameDeactivationCandidate on my player character's box. Stepping through things right now, it seems to be part of a SimulationIsland with a property IsActive = false, and the SimlationIsland's Members.wrappedList.Elements contains three entries -- the character's box, but also the detection sphere and the dynamic box which the sphere is linked to. Both of these other objects have IsActive = false (which makes sense; they weren't moving).
(I wasn't clear enough before, but I'm linking the detection sphere not to the character's box, but to another dynamic box that exists as a treasure chest in my game. So, when the player moves in range of the treasure chest, the detection sphere reports a collision and enables them to open it, if they wish.)
Anyway, I guess I'm just suspicious of the SimulationIsland because it or its interface is part of the namespace BEPUphysics.DeactivationManagement. Is it possible that the simulationIsland is somehow deactivating all of the elements in its list, even though one of them is set to IsAlwaysActive = true?
And now I'll move on to less desperate theories
I've actually only been using 0.16.2 since yesterday. I've never tried building and using a version from the development fork. I'll try that now and let you know how it goes.
Thanks for the workaround you suggested involving using kinematic detection spheres. I'll definitely be trying that. The one thing I like about the BallSocketJoint method is that I don't even have to bother updating the object unless it's animating -- BEPU does everything for me! But kinematic shapes with NoSolver and automatic position updating is more in line with the methods you use in the character controllers, right?
BEPU really is a dream to work with -- this is the first stubborn issue I've run into, during the whole process of rebuilding my engine around it. I'm also not pessimistic about this problem at all -- as I said before, I'm planning on trying out different implementations for the character's physics shape anyway, including spheres and your SimpleCharacterController.
I would like to help you find this bug, though, if it is indeed a bug and not me misusing the engine, so I'll work on a stripped down debuggable reproduction case for you, where hopefully the glitch won't take too long to reproduce. Thanks again for all your help, Norbo! Stay well (and awesome),
Alex
Let me start off with my crack-brained theory that I'm getting from stepping through the debugger right now:
Basically, I hooked up a delegate to the event BecameDeactivationCandidate on my player character's box. Stepping through things right now, it seems to be part of a SimulationIsland with a property IsActive = false, and the SimlationIsland's Members.wrappedList.Elements contains three entries -- the character's box, but also the detection sphere and the dynamic box which the sphere is linked to. Both of these other objects have IsActive = false (which makes sense; they weren't moving).
(I wasn't clear enough before, but I'm linking the detection sphere not to the character's box, but to another dynamic box that exists as a treasure chest in my game. So, when the player moves in range of the treasure chest, the detection sphere reports a collision and enables them to open it, if they wish.)
Anyway, I guess I'm just suspicious of the SimulationIsland because it or its interface is part of the namespace BEPUphysics.DeactivationManagement. Is it possible that the simulationIsland is somehow deactivating all of the elements in its list, even though one of them is set to IsAlwaysActive = true?
And now I'll move on to less desperate theories

I've actually only been using 0.16.2 since yesterday. I've never tried building and using a version from the development fork. I'll try that now and let you know how it goes.
Thanks for the workaround you suggested involving using kinematic detection spheres. I'll definitely be trying that. The one thing I like about the BallSocketJoint method is that I don't even have to bother updating the object unless it's animating -- BEPU does everything for me! But kinematic shapes with NoSolver and automatic position updating is more in line with the methods you use in the character controllers, right?
BEPU really is a dream to work with -- this is the first stubborn issue I've run into, during the whole process of rebuilding my engine around it. I'm also not pessimistic about this problem at all -- as I said before, I'm planning on trying out different implementations for the character's physics shape anyway, including spheres and your SimpleCharacterController.
I would like to help you find this bug, though, if it is indeed a bug and not me misusing the engine, so I'll work on a stripped down debuggable reproduction case for you, where hopefully the glitch won't take too long to reproduce. Thanks again for all your help, Norbo! Stay well (and awesome),
Alex
Re: Weird Character getting stuck glitch
Forgot to mention, removing the offending detection sphere from the space seems to wake the character's box back up. It's also really strange that the issue often won't happen for about 20 minutes, and then will suddenly start happening all over the place for a few minutes, and then will go back to not happening.
I tried the newest development version, and I have yet to see the issue, but it also completely breaks my "attack" class, which uses a kinematic sphere as a hit area, which is added to the space during the attack animation and then removed toward the end of the attack animation. There seems to be some sort of issue with setting the "hit area" sphere's position based on the attacker's position? I'll try the second most recent development version and see what happens.
I tried the newest development version, and I have yet to see the issue, but it also completely breaks my "attack" class, which uses a kinematic sphere as a hit area, which is added to the space during the attack animation and then removed toward the end of the attack animation. There seems to be some sort of issue with setting the "hit area" sphere's position based on the attacker's position? I'll try the second most recent development version and see what happens.
Re: Weird Character getting stuck glitch
I can't say it's impossible, but I don't know how it would happen at this pointAnyway, I guess I'm just suspicious of the SimulationIsland because it or its interface is part of the namespace BEPUphysics.DeactivationManagement. Is it possible that the simulationIsland is somehow deactivating all of the elements in its list, even though one of them is set to IsAlwaysActive = true?

Here's some general background on how the deactivation system works to make things a little less mysterious:
1 ) Dynamic entities have a SimulationIsland which is a group of objects which interact and respond to each other, like a pile of blocks. In other words, they are a connected component in the constraint connection graph.
2 ) Kinematic entities do not have a simulation island because they are a 'dead end' for interaction graphs. They have infinite mass and inertia, so no collision response affects them.
3 ) Moving kinematic entities will, however, wake up adjacent sleeping dynamic objects.
4 ) When dynamic objects go from having no contacts to having one or more contacts, a contact constraint and its associated simulation island connection is added to the space. If the involved entities have different simulation islands, the islands are 'merged.' Merging can also occur when any other connection, like a BallSocketJoint, is added. The merging process makes the two previously separated connected components into a single connected component. The resulting island is forced into an active state.
5 ) When a connection is removed, a 'split' operation occurs. A search algorithm runs which tries to find a path between the nodes involved in the removed connection. If no path can be found, then the simulation island is split into two simulation islands. Technically, as of the recent development versions, split attempts are enqueued for later use and only a few are dequeued each frame for performance reasons.
6 ) The deactivation manager itself has three phases. The first flushes out a limited number of the split attempts. The second goes through all entities and updates their deactivation candidacy. The third phase goes through a portion of the simulation islands and attempts to deactivate them if all entities within are known to be ready to deactivated.
7 ) Deactivation candidacy is based on an object having low velocity for some period of time. An object can go in and out of deactivation candidacy while still being active. If a simulation island is not active, then all its members should be deactivation candidates. If a member has IsAlwaysActive = true, the object should never become a deactivation candidate and the island should never go to sleep.
8 ) The same conditions used for deactivation candidacy are also used to stabilize slow moving objects. That is what the entity's AllowStabilization property and the DeactivationManager's UseStabilization property refer to. Stabilization damps energy out of the system.
9 ) Adding and removing entities to the Space will trigger similar removes/adds for any existing connections at the time of addition/removal.
I should really get around to putting stuff like this on the codeplex documentation section.
In the SimpleCharacterController, yes, a kinematic object sits at the bottom of the character and collects pairs. Its position is set each frame based on the current character body position.But kinematic shapes with NoSolver and automatic position updating is more in line with the methods you use in the character controllers, right?
There are other ways to do it, though. The full-featured CharacterController does not use any secondary detection kinematics. Instead, it uses an expanded bounding box and performs queries on objects detected within that bounding box.
The kinematic detector approach probably fits better with attack-area queries than it does with the SimpleCharacterController usage.
How many frames is the attack object in the space? At least one whole frame must pass before the broad phase is able to update its hierarchy to match the new state and generate new collision data. Another possibility is that something with the collision rules is different.I tried the newest development version, and I have yet to see the issue, but it also completely breaks my "attack" class, which uses a kinematic sphere as a hit area, which is added to the space during the attack animation and then removed toward the end of the attack animation. There seems to be some sort of issue with setting the "hit area" sphere's position based on the attacker's position?
However, neither of the above should have changed between v0.16.2 and the development version, so I'm not sure.
Re: Weird Character getting stuck glitch
The attack object is in the space for probably a bit less than a half-second... so 30 physics frames? A sword swing animation plays, and at the end of the animation the hit area sphere is removed from the space. So, it must be enough frames for the sword swing to animate.
Whats weird is, I'm writing the hit sphere's position to the screen, and it does change every time I move and then attack. So it seems like it's working. But even though HitArea.Position is being written to the screen and looks right, the actual thing that triggers the InitialCollisionDetected event (I guess it's the collidible, and not the shape? Not sure if that makes sense...) is staying in the same place every time it's added to the space. So I every time I attack, a collision is reported if there's an enemy in the same place I first attacked when the level was loaded, and not if there's an enemy at my current position. I can post the code to the attack class if you want, it's pretty concise.
Alex
Just figured out that the only reason the position of the hitArea is changing at all is because the first time I set its position
I do it before it gets added to the space for the first time. If I add it to the space first, then call PositionAttackArea, the position of the collidible, or whatever it is that triggers the InitialCollisionDetected event, never moves from (0, 0, 0) (which is what I initialize it at in the constructor.)
This is the code for PositionAttackArea, which seems to be moving the HitArea.Position but not affecting whatever part of the physics object it is that triggers InitialCollisionDetected:
There's also code for taking the offset into account, but I've commented that part out for testing, right now.
Whats weird is, I'm writing the hit sphere's position to the screen, and it does change every time I move and then attack. So it seems like it's working. But even though HitArea.Position is being written to the screen and looks right, the actual thing that triggers the InitialCollisionDetected event (I guess it's the collidible, and not the shape? Not sure if that makes sense...) is staying in the same place every time it's added to the space. So I every time I attack, a collision is reported if there's an enemy in the same place I first attacked when the level was loaded, and not if there's an enemy at my current position. I can post the code to the attack class if you want, it's pretty concise.
Alex
Just figured out that the only reason the position of the hitArea is changing at all is because the first time I set its position
Code: Select all
PositionAttackArea();
Space.Add(HitArea);
This is the code for PositionAttackArea, which seems to be moving the HitArea.Position but not affecting whatever part of the physics object it is that triggers InitialCollisionDetected:
Code: Select all
HitArea.Position = Attacker.box.Position;
Re: Weird Character getting stuck glitch
I fixed a bug left over from the deactivation system rewrite: http://bepuphysics.codeplex.com/SourceC ... evelopment
I believe that should solve the detector problems.
I believe that should solve the detector problems.
Re: Weird Character getting stuck glitch
Yep, works like a charm. I'll let you know if I see the character box getting stuck again in this version. No issues so far. Thanks Norbo!
Alex
Alex