-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Velocity at high ranges causes the game to crash #4225
Comments
Do you mean range or velocity? They aren't the same thing, plus range is a product of velocity and lifetime so is unlikely to cause a crash (although it might still be correlated). |
I meant velocity, sorry. |
Are you sure this is what is causing the crash? Could you paste the data of the weapon you think is causing this crash? I just set the beam laser to fire at a velocity of 3200 and I didn't get a crash. |
Doubled the velocity to 6400 and my game crashed. If you are using a plugin weapon with a sprite that spans that 3200 range, perhaps this has something to do with drawing the projectile at such a distance, not the velocity itself. (Edit: Changed my beam laser sprite. No effect as far as I can tell by using a 3200 range laser projectile.) By changing the velocity of the Beam Laser:
|
So it seems like we have some sort of edge case at 2^12 velocity. @Variance-Moment Can you replicate my results, with 3200 specifically not crashing the game, but anything seemingly higher than 2^12 giving a clear crash? |
The physical size of the screen won't matter. You could try telling windows (or whatever OS you use) that you have a 720p screen and see if that effects it, if it is an effect then I would expect to see it crash at around 2730 (~4096*2/3). The 2^12 hypothesis seems more likely. |
I seem to get similar results:
Sprite size also doesn't seem to matter. |
This is related to integer overflows in the endless-sky/source/CollisionSet.cpp Line 199 in b73d640
and other parameters that involve multiplication, like It's possible the allowable maximum velocity can be shifted to larger bounds by using Also note that there is a difference between "the application crashed" and "the application stopped responding". The "stopped responding" is a great hint that a loop is not exiting somewhere (in this case, the So until this is fixed, be cognizant when designing your outfits that the higher the velocity of the weapon, the more taxing it is to the game to calculate its collisions. This means that large battles involving many of these weapons will be even more taxing on players' systems. |
Looking into the CollisionSet a bit further, the deal with 4095 / 4096 is that 4096 results in a signed integer overflow if the projectile is fired at an exact diagonal angle. While unsigned integer overflow is a defined behavior (it loops around), signed overflow is undefined behavior, and observed behavior then depends on the particular compiler and system used to make the executable. The overflow happens when computing the endless-sky/source/CollisionSet.cpp Lines 199 to 200 in b73d640
We see that 2^31-1 (max value of If we take the simplest fix route and ensure that But, can we raise the limit even further? Yes:First though, we need to know the calculation step that induces the overflow, so we can work around it. endless-sky/source/CollisionSet.cpp Lines 250 to 251 in b73d640
This diff calculation is the limiting step in the CollisionSet algorithm, as in the worst case, rx or ry have the same value as full (which in the worst case is the max representable value of the integral type int64_t , 2^63-1). It's interesting to note that the maximum value of this product doesn't occur at mx =my , but rather when cos(a)*sin(a)~0.47 (about ±10° off 45°). This is due to the mixed products of x and y components and the angular relationship.We can allow larger values by introducing two divisions in (nearly) every grid cell, replacing two multiplications (which are generally faster than divisions, hence their use in this computation-intensive loop). If we perform the divisions instead of the multiplication, this section could look like: if(!mx)
{
// Stepping only along y grid cells
gy += stepY;
if(gy == endGY)
break;
}
else if(!my)
{
// Stepping only along x grid cells
gx += stepX;
if(gx == endGX)
break;
}
else
{
// Determine whether to advance the x or y grid cell. Because of the scale used, these are always even divisions.
int64_t xRatio = rx / mx;
int64_t yRatio = ry / my;
int64_t diff = xRatio - yRatio;
/* resume current code */ This will then have shift possible overflows to computing the new values of endless-sky/source/CollisionSet.cpp Line 270 in b73d640
endless-sky/source/CollisionSet.cpp Line 278 in b73d640
With this approach, the overflowing angles are near 0 / 90°, with a maximal projectile velocity in the range of 189'812'818: However, using insane values of projectile velocity is not "free": the number of grid cells that must be checked also increases. Given that up to 3 different CollisionSets are checked (depending on asteroids and minables in the given system), this results in framerate loss (although yes, there are still frames). Equipping just 4 outfits with a 4-frame lifetime and a velocity of 189'812'800 results in an in-game CPU time of ~5600-10000x, depending how many of the guns are firing (my system had both minables and asteroids). With a more "reasonable" (yet-still-insane) projectile velocity of 400'000, I didn't notice any stuttering when activating the same four weapons. While we can increase the projectile velocity limit further with some extra calculations, given that 454'046 is already a 100x improvement with no algorithmic changes, making algorithmic changes to allow an already-absurd projectile velocity to be increased even further is not going to happen. Framerate in large battles with reasonable weapon velocities is already enough of a concern that we don't want to also require considering "is some mod being extra, extra ridiculous, and that's why there is this player issue?" I'll put together the fix this week, and include a guard against CollisionSet receiving a velocity that could cause UB. |
Describe the bug
When firing a weapon with a velocity above 3200 or so the game crashes.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The weapon to fire without consequence.
System (please complete the following information):
The text was updated successfully, but these errors were encountered: