Collision Detection
25 posts
• Page 1 of 3 • 1, 2, 3
Collision Detection
Something strange is happening in the collision detection code in D2. LoNi brought it to my attention a few days ago, but it's turning into a larger problem.
It's most visible with gauss: sometimes you get a hit that deals no damage. But weirder still -- the hits you DO get deal the WRONG amount of damage. We were able to determine that a hit on the very edge of the pyro (its wings) reliably did zero damage. But it gets weirder...
I ran two tests -- one in D2 DOSBox, one in Retro 1.1.1, firing gauss at a still target. Here are the demos:
I fired some shots dead center on the pyro, some at the edge of the hit sphere. Here's what I found --
In D2 1.2 (DOSbox), I fired 7 shots. Five did 12 damage, one did 13, one did 1 (I might've missed/hit the wall on that one).
In Retro 1.1.1, 11 shots. 4 were clear hits that did 0 damage, 4 did 13, and 3 did 14.
In other words, gauss is both too weak AND too strong at the moment. On a marginal hit, you often do 0 damage; on a clear hit, you do an extra 8-17% damage.
I believe whatever's going wrong here is affecting other weapons, but it seems to be most visible with gauss. LoNi and I were able to replicate the effect -- that where you hit the ship affects how much damage you do -- significantly with mercs and slightly with concs. I suspect this may also be related to the difficulty we're having picking up powerups, and I've heard reports of marginal fusion clangs dealing 0 damage as well.
My first pass through looking at the collision code, I found some really broken additions, which I removed. That eliminated the 0 damage hits, but they turned into 4 and 6 damage hits . . . and the others jumped up to 16! So something is still broken.
I'll continue to do analysis and post any findings here.
It's most visible with gauss: sometimes you get a hit that deals no damage. But weirder still -- the hits you DO get deal the WRONG amount of damage. We were able to determine that a hit on the very edge of the pyro (its wings) reliably did zero damage. But it gets weirder...
I ran two tests -- one in D2 DOSBox, one in Retro 1.1.1, firing gauss at a still target. Here are the demos:
I fired some shots dead center on the pyro, some at the edge of the hit sphere. Here's what I found --
In D2 1.2 (DOSbox), I fired 7 shots. Five did 12 damage, one did 13, one did 1 (I might've missed/hit the wall on that one).
In Retro 1.1.1, 11 shots. 4 were clear hits that did 0 damage, 4 did 13, and 3 did 14.
In other words, gauss is both too weak AND too strong at the moment. On a marginal hit, you often do 0 damage; on a clear hit, you do an extra 8-17% damage.
I believe whatever's going wrong here is affecting other weapons, but it seems to be most visible with gauss. LoNi and I were able to replicate the effect -- that where you hit the ship affects how much damage you do -- significantly with mercs and slightly with concs. I suspect this may also be related to the difficulty we're having picking up powerups, and I've heard reports of marginal fusion clangs dealing 0 damage as well.
My first pass through looking at the collision code, I found some really broken additions, which I removed. That eliminated the 0 damage hits, but they turned into 4 and 6 damage hits . . . and the others jumped up to 16! So something is still broken.
I'll continue to do analysis and post any findings here.
-
Drakona
- Site Admin
- Posts: 1494
- Joined: Fri Aug 30, 2013 5:35 pm
Confirmed in testing with Jinx that collision detection is significantly less accurate at high FPS.
With client-side (me) running 200 FPS vs. 30 FPS in Retro 1.1.1, Jinx attempted to barely clip my pyro with gauss.
At 200 FPS, 18 shots were fired. 1 did 13 damage, 2 did 12 . . . and 15 did 0. Jinx is good at this.
At 30 FPS, 11 shots were fired. 1 did 14, 3 did 13, 4 did 12, and only 3 did 0.
This implies that running at a higher FPS makes gauss less likely to hit you.
It's possible this affects other weapons as well, but that's harder to test. With a non-blast weapon, you wouldn't even get a clang . . . you'd just get a miss where there shouldn't be one. Probably an effect dismissable as lag, though given how low the latencies are getting these days, that excuse is wearing thin.
With client-side (me) running 200 FPS vs. 30 FPS in Retro 1.1.1, Jinx attempted to barely clip my pyro with gauss.
At 200 FPS, 18 shots were fired. 1 did 13 damage, 2 did 12 . . . and 15 did 0. Jinx is good at this.
At 30 FPS, 11 shots were fired. 1 did 14, 3 did 13, 4 did 12, and only 3 did 0.
This implies that running at a higher FPS makes gauss less likely to hit you.
It's possible this affects other weapons as well, but that's harder to test. With a non-blast weapon, you wouldn't even get a clang . . . you'd just get a miss where there shouldn't be one. Probably an effect dismissable as lag, though given how low the latencies are getting these days, that excuse is wearing thin.
-
Drakona
- Site Admin
- Posts: 1494
- Joined: Fri Aug 30, 2013 5:35 pm
Found the problem. It's a math bug that has been in the code since the very beginning, and which triggers randomly. The likeliness of it happening is proportional to the framerate -- that is, you're 6.5 times more likely to see it at 200 FPS than at 30.
It affects both D1 and D2, definitely is the source of the "I wasn't close enough to suicide" problem, and MIGHT be the source of the powerup thing. That's harder to test.
I'm testing a fix now, should have an updated retro mod by the end of the night.
It affects both D1 and D2, definitely is the source of the "I wasn't close enough to suicide" problem, and MIGHT be the source of the powerup thing. That's harder to test.
I'm testing a fix now, should have an updated retro mod by the end of the night.
-
Drakona
- Site Admin
- Posts: 1494
- Joined: Fri Aug 30, 2013 5:35 pm
Fix results in a consistent 12-14 damage, which -- upon further analysis -- is correct. The dosbox test showing consistent 12s was misleading.
Out of 16 shots, Jinx wasn't able to get a single zero.
Out of 16 shots, Jinx wasn't able to get a single zero.
-
Drakona
- Site Admin
- Posts: 1494
- Joined: Fri Aug 30, 2013 5:35 pm
Updated Retro Mod --
I'll do a nice release and explanation tomorrow when I'm not so tired.
Here's a version you can use for testing:
I'll do a nice release and explanation tomorrow when I'm not so tired.
Here's a version you can use for testing:
-
Drakona
- Site Admin
- Posts: 1494
- Joined: Fri Aug 30, 2013 5:35 pm
Whoa, so it was in D1, too? I'm suddenly interested ;)! Awesome that you found the cause and made a fix so fast.
-
RiTides
- Posts: 223
- Joined: Sun Sep 01, 2013 6:13 pm
The effects on D1 were very slight -- mostly missiles detonating early and causing unexpected suicides.
Here's a fuller explanation of what was going wrong, and the effects:
There were two bugs in the code: one which had been there since D1 was released, and one added in the Rebirth era.
The original, D1 bug was a math error in the Find Vector Intersection code -- the part that found the intersection between a vector and a sphere. If the vector was heading toward the edge of the sphere and was just the right length, the code would conclude it had intersected when in fact it more than a full frame away. It triggered randomly, but was less likely at low FPS, since when the vectors are long, they are more likely to jump over the problem zone entirely. As the FPS increase, the vectors get shorter, and the chance of them being exactly long enough to cause a problem goes up.
How bad was it? Well, this being a bug in the VECTOR MATH LIBRARY, it affected a lot of things. But looking just at weapons, it got worse the faster the weapon was. I did most of my testing in D2, and recorded some gauss shots exploding almost half a shiplength away from the hull of the ship they were 'hitting'. It only affects damage on blast weapons, though, and you need a fast weapon with a small blast radius to really see it. D1 doesn't have any of those. Concs and smarts are slow, and megas will cheerfully kill you from half a shiplength away. I mean, the bug did technically affect concs, but it made them change from 27 damage to 25 or slightly less . . . big deal.
The second bug -- the one from the Rebirth era -- is a little harder to explain. Normally, Descent will look all along the flight path of a weapon in a particular frame for things to hit. If it finds one, it calculates exactly where the hit should happen, and detonates the weapon there. What they changed is, instead of looking ahead for a frame, they had weapons look ahead as if it were 30 FPS -- so 33 ms. And if it found a hit, it would determine the exact place it should happen, and then back the weapon up to almost where it started, and then detonate it. This change had no effect on the game at 30 FPS, but as you increase the framerate, detonates weapons earlier and earlier compared to where they're supposed to be. At 200 FPS, blast weapons detonate an average of 14ms and a maximum of 28ms early. (Which is ironic, because the code comments imply that the coder thought the change would make the engine more accurate at high FPS.)
This bug hit D1 harder than it hit D2, because D2 is better about remembering where a collision is supposed to happen. D2 was definitely hit, though; the sum of the two bugs was causing our zero-damage gauss shots. Anyway, this bug gets worse as framerates go up; at 30 FPS, it has no effect; at 200, it detonates weapons 28ms early.
In D2, the combined effect of these two bugs was to make gauss and mercs significantly less deadly than they were originally. You had to hit a ship with them dead on to get the full damage, and that doesn't happen very often in actual combat. Since these bugs are most noticeable with faster weapons and smaller blast radiuses, it initially was reported to me as a gauss damage bug; the other effects hadn't been observed.
In D1, the main effect was that concs/homers/smarts detonating early (both on walls and other ships) were causing suicides from what should have been safe shots.
It is possible, though it's hard to confirm, that these bugs were also causing you to miss powerups you otherwise should have picked up.
Both fixes were pretty deep in the code; one is in the physics engine, and one is in the math library(!), so the effects will probably be far-reaching. That vector intersection routine is used for everything from picking up hostages to bumping into robots to weapons hitting targets to spew flying into a ship. It is unlikely that fixing the math will break anything, since the game gets an exact and correct answer to the math problem the vast majority of the time -- it's just that it gets wrong answers sometimes, too, and more frequently as you turn the framerate up. Most likely, lots of subtle effects and bugs that have appeared since the transition to high FPS will quietly go away without us ever consciously noticing them.
For example, one harmless effect that will go away: when you hit a ship, you should see sparks on the surface of its hit sphere. But you don't -- they're slightly inside or outside -- sometimes way outside, because the code is confused about where the collision was supposed to happen. It's harmless; with a non-blast weapon, you take the full damage either way. But you should actually be able to see the sphere now.
The only change you're likely to consciously notice is that gauss has gone back to 1998 levels of overpoweredness. Which will be more or less popular depending on how you feel about gauss -- in Naphtha's words, "You'll be sorry!" But it does reflect the original game.
P.S. There was a third, small, original bug, which I also fixed: sometimes, if you were very unlucky, a blast weapon would detonate inside your ship, doing extra damage. There was code to prevent this from happening, but it didn't work; I fixed it. So you shouldn't see any 14 damage gauss shots, just 12's and 13's. Like you're watching it that closely in a firefight, right?
Here's a fuller explanation of what was going wrong, and the effects:
There were two bugs in the code: one which had been there since D1 was released, and one added in the Rebirth era.
The original, D1 bug was a math error in the Find Vector Intersection code -- the part that found the intersection between a vector and a sphere. If the vector was heading toward the edge of the sphere and was just the right length, the code would conclude it had intersected when in fact it more than a full frame away. It triggered randomly, but was less likely at low FPS, since when the vectors are long, they are more likely to jump over the problem zone entirely. As the FPS increase, the vectors get shorter, and the chance of them being exactly long enough to cause a problem goes up.
How bad was it? Well, this being a bug in the VECTOR MATH LIBRARY, it affected a lot of things. But looking just at weapons, it got worse the faster the weapon was. I did most of my testing in D2, and recorded some gauss shots exploding almost half a shiplength away from the hull of the ship they were 'hitting'. It only affects damage on blast weapons, though, and you need a fast weapon with a small blast radius to really see it. D1 doesn't have any of those. Concs and smarts are slow, and megas will cheerfully kill you from half a shiplength away. I mean, the bug did technically affect concs, but it made them change from 27 damage to 25 or slightly less . . . big deal.
The second bug -- the one from the Rebirth era -- is a little harder to explain. Normally, Descent will look all along the flight path of a weapon in a particular frame for things to hit. If it finds one, it calculates exactly where the hit should happen, and detonates the weapon there. What they changed is, instead of looking ahead for a frame, they had weapons look ahead as if it were 30 FPS -- so 33 ms. And if it found a hit, it would determine the exact place it should happen, and then back the weapon up to almost where it started, and then detonate it. This change had no effect on the game at 30 FPS, but as you increase the framerate, detonates weapons earlier and earlier compared to where they're supposed to be. At 200 FPS, blast weapons detonate an average of 14ms and a maximum of 28ms early. (Which is ironic, because the code comments imply that the coder thought the change would make the engine more accurate at high FPS.)
This bug hit D1 harder than it hit D2, because D2 is better about remembering where a collision is supposed to happen. D2 was definitely hit, though; the sum of the two bugs was causing our zero-damage gauss shots. Anyway, this bug gets worse as framerates go up; at 30 FPS, it has no effect; at 200, it detonates weapons 28ms early.
In D2, the combined effect of these two bugs was to make gauss and mercs significantly less deadly than they were originally. You had to hit a ship with them dead on to get the full damage, and that doesn't happen very often in actual combat. Since these bugs are most noticeable with faster weapons and smaller blast radiuses, it initially was reported to me as a gauss damage bug; the other effects hadn't been observed.
In D1, the main effect was that concs/homers/smarts detonating early (both on walls and other ships) were causing suicides from what should have been safe shots.
It is possible, though it's hard to confirm, that these bugs were also causing you to miss powerups you otherwise should have picked up.
Both fixes were pretty deep in the code; one is in the physics engine, and one is in the math library(!), so the effects will probably be far-reaching. That vector intersection routine is used for everything from picking up hostages to bumping into robots to weapons hitting targets to spew flying into a ship. It is unlikely that fixing the math will break anything, since the game gets an exact and correct answer to the math problem the vast majority of the time -- it's just that it gets wrong answers sometimes, too, and more frequently as you turn the framerate up. Most likely, lots of subtle effects and bugs that have appeared since the transition to high FPS will quietly go away without us ever consciously noticing them.
For example, one harmless effect that will go away: when you hit a ship, you should see sparks on the surface of its hit sphere. But you don't -- they're slightly inside or outside -- sometimes way outside, because the code is confused about where the collision was supposed to happen. It's harmless; with a non-blast weapon, you take the full damage either way. But you should actually be able to see the sphere now.
The only change you're likely to consciously notice is that gauss has gone back to 1998 levels of overpoweredness. Which will be more or less popular depending on how you feel about gauss -- in Naphtha's words, "You'll be sorry!" But it does reflect the original game.
P.S. There was a third, small, original bug, which I also fixed: sometimes, if you were very unlucky, a blast weapon would detonate inside your ship, doing extra damage. There was code to prevent this from happening, but it didn't work; I fixed it. So you shouldn't see any 14 damage gauss shots, just 12's and 13's. Like you're watching it that closely in a firefight, right?
-
Drakona
- Site Admin
- Posts: 1494
- Joined: Fri Aug 30, 2013 5:35 pm
Ooooooh, hey, I just thought of this. Those inconsistent homers you (Mark, Jedi, Merl) wanted me to investigate? That could have totally been this bug. If the collision detection is off such that they blow up early if they WOULD hit soon, that will manifest in game as them having a bigger hit sphere -- and hence being harder to dodge. In a tight dodge, that could be the difference. And as I said above, the effect would random -- doesn't happen all the time, and doesn't happen the same amount every time.
Whether or not that's the whole story, the homer behavior should be more consistent in 1.2.
Whether or not that's the whole story, the homer behavior should be more consistent in 1.2.
-
Drakona
- Site Admin
- Posts: 1494
- Joined: Fri Aug 30, 2013 5:35 pm
25 posts
• Page 1 of 3 • 1, 2, 3