mspraggs / potentia

Southampton Game Jam 2015
0 stars 0 forks source link

Endless recursion in collision detection code when being crushed by prop #66

Closed mspraggs closed 9 years ago

mspraggs commented 9 years ago

To recreate, when you're in the level where the boxes fall randomly from underneath the dirt blocks, use the mole gauntlet to destroy one of the dirt blocks with a crate on top, whilst walking forward. When the crate falls on top of the player, the collision detection code gets recurses indefinitely. Example backtrace:

#0  0x00007ffff7b92666 in Vector::mag (this=0x7fffffd87ac0) at /home/matthew/Programming/C++/potentia/lib/Vector.hpp:37
#1  0x00007ffff7b97ed2 in Unit::applyForce (this=0x1a709b0, force=...) at /home/matthew/Programming/C++/potentia/lib/Unit.hpp:170
#2  0x00007ffff7bb67c4 in Object::collideEx (this=0x1a709b0, obj=0x1a9f310) at /home/matthew/Programming/C++/potentia/lib/Object.cpp:138
#3  0x00007ffff7ba582b in Room::tryToCollide (this=0x7fffffffb780, objOne=0x1a709b0, objTwo=0x1a9f310) at /home/matthew/Programming/C++/potentia/lib/Room.cpp:102
#4  0x00007ffff7ba5737 in Room::collisionCheck (this=0x7fffffffb780, obj=0x1a709b0, except=0x1a79790) at /home/matthew/Programming/C++/potentia/lib/Room.cpp:89
#5  0x00007ffff7ba5887 in Room::tryToCollide (this=0x7fffffffb780, objOne=0x1a709b0, objTwo=0x1a79790) at /home/matthew/Programming/C++/potentia/lib/Room.cpp:106
#6  0x00007ffff7ba5737 in Room::collisionCheck (this=0x7fffffffb780, obj=0x1a709b0, except=0x1a9f310) at /home/matthew/Programming/C++/potentia/lib/Room.cpp:89
#7  0x00007ffff7ba5887 in Room::tryToCollide (this=0x7fffffffb780, objOne=0x1a709b0, objTwo=0x1a9f310) at /home/matthew/Programming/C++/potentia/lib/Room.cpp:106
#8  0x00007ffff7ba5737 in Room::collisionCheck (this=0x7fffffffb780, obj=0x1a709b0, except=0x1a79790) at /home/matthew/Programming/C++/potentia/lib/Room.cpp:89
#9  0x00007ffff7ba5887 in Room::tryToCollide (this=0x7fffffffb780, objOne=0x1a709b0, objTwo=0x1a79790) at /home/matthew/Programming/C++/potentia/lib/Room.cpp:106
#10 0x00007ffff7ba5737 in Room::collisionCheck (this=0x7fffffffb780, obj=0x1a709b0, except=0x1a9f310) at /home/matthew/Programming/C++/potentia/lib/Room.cpp:89
#11 0x00007ffff7ba5887 in Room::tryToCollide (this=0x7fffffffb780, objOne=0x1a709b0, objTwo=0x1a9f310) at /home/matthew/Programming/C++/potentia/lib/Room.cpp:106
#12 0x00007ffff7ba5737 in Room::collisionCheck (this=0x7fffffffb780, obj=0x1a709b0, except=0x1a79790) at /home/matthew/Programming/C++/potentia/lib/Room.cpp:89
#13 0x00007ffff7ba5887 in Room::tryToCollide (this=0x7fffffffb780, objOne=0x1a709b0, objTwo=0x1a79790) at /home/matthew/Programming/C++/potentia/lib/Room.cpp:106

Example screenshot of this behaviour attached. Basically the game gets stuck at this point.

screenshot - 050315 - 22 20 30

Fyll commented 9 years ago

Hmm. I've found the problem. It's because the crates were so ridiculously heavy (100x the player's weight!), so conservation of momentum was getting silly. I've fixed it, but am also working on redoing collisions a little (you may have noticed), so will wait until that's all good before pushing.

EDIT: Oh and also because the player isn't allowed to push crates. Therefore, when the crate lands on the player's head, it pushes the player down, who pushes down on the ground (which pushes him back up), then tries to push the crate, but can't. This is the bigger problem that's prompting my attempted re-write.

mspraggs commented 9 years ago

How's all this going? Anything I can do to help?

Fyll commented 9 years ago

I've been quite busy recently, so haven't had a chance to do much on this. I imagine I won't be able to start working on this until the Easter holidays start, as I'm away until Wednesday, and then will have work to catch up on.

The big problem at the moment is how the player (and units in general) shouldn't be able to push objects by running into them, but need to be able to push an object when they get pushed from the other side.

E.g. If a crate is sat in front of you, running into it should have no effect, but if a crate lands on top of you, it'll push you down into the ground, but then it recurses and the ground pushes you back up into the crate, so the player needs to be able to push the crate in this circumstance.

This is further complicated by other units. If an enemy pushes you into a moveable object, it shouldn't move, however, it has no way to distinguish between this and if a crate pushes into the player from the side (a steel crate being pulled towards you for example).

Basically, restricting who can push what makes things really tricky to work with. If you can think of a solution, feel free to suggest it/implement it. The only solution I can think of is to have each force being a struct containing the Vector and a bool fromPlayer or something. This'd porbably make things a bit messy here and there though.

It'd be quite nice to have a list of what can't push what, e.g. Player pulling a steel crate into himself with a wooden crate on the other side. What happens? A block falling sideways (for whatever reason. Maybe it's like the up and down ones) pushes the player against a wooden crate. What happens?

DivFord commented 9 years ago

Does an object have a list of forces acting on it, or do they just get added together? That is, can we tell if something is being pushed from both sides, or to they just cancel each other out?

Fyll commented 9 years ago

They just cancel out. Units have special code that checks if they've been crushed by storing forces that act on them externally, then checking if they're big enough and counter to a force they've already felt. For everything else though, the forces just cancel, and only the net is considered. If it changed to being structs rather than Vectors, it'd keep a list of individual forces.

And with that, I'm off.

mspraggs commented 9 years ago

Have a nice trip!

As you say it sounds like we need to differentiate forces resulting directly from player input and other secondary forces. Perhaps the applyForce function needs to be split into two, one for input and another more general one?

Fyll commented 9 years ago

Okay, I've sorted this (or so I believe). It doesn't (as far as I've seen) crash when you get crushed, yet you can no longer push the crates around.

This has brought to light a slight issue with the crushing code (that it doesn't crush you if a crate is already sat on top of your head, as gravity isn't applied to things which are sat on other things), but that's its own problem for its own thread (#63).