2021-09-22 12:43 CEST

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0006421Spring engineGeneralpublic2020-08-29 04:33
Assigned To 
Product Version104.0 +git 
Target VersionFixed in Version 
Summary0006421: Stale QuadField information causes very strange behaviour
DescriptionSee https://zero-k.info/Battles/Detail/946942 at frame 8959 - I've made an illustration of the situation at https://curio.antihype.space/reaver-quads-f-8959.png

In this frame, while the Reaver appears to unambiguously be in quad 871, and possibly 870 as well, the engine consider the Reaver to exclusively be in quad 870. The next frame, quad membership is updated, and the Reaver is considered to be exclusively in quad 871.

Quad membership updates only happen at 2Hz, or when sudden changes happen such as through lua's SetUnitPosition. This means that even very slow units such as the Reaver can be missed when the QuadField is searched for units in an area. 67 frames later, a nearly identical situation occurs, but with much more visible consequences: https://curio.antihype.space/widow-quads.png

The frame after this, the widow fires its LightningCannon after correctly checking, among other things, that the position of its target and the position it is aiming from are in range. This check passes because it knows the unit it is targeting, and does not need to search for units in an area. When the LightningCannon actually fires, it performs a RayTrace to find units along the ray. The RayTrace correctly determines that the ray only overlaps quad 832 and 872, and searches through units in the area to detect hits. Because the Reaver is considered to be exclusively in quad 871, it is not checked for hits, and so the Reaver is not stunned by the Widow (!), much to the surprise of both players.

While this is most obvious with weapons that only check collision for a single frame, like the LightningCannon, this affects anything that relies on QuadField information for hit detection. For example, cheating in an LLT, and having it fire in this situation, has the laser not interact with the Reaver until its quad membership is updated a few frames later: https://curio.antihype.space/beamlaser-yuv-420p.mp4
Additional InformationExtending the range used for CQuadField::GetQuadsOnRay is not sufficient, because it's possible for a ray to arrive from a normal to where the unit was moving. For example, consider the situation in https://curio.antihype.space/widow-quads.png but if the Widow was directly above the Reaver, such that an extended ray would go on to quad 912 rather than quad 871.

A dirty and cheap workaround on the mod side could be to use lua to invoke SetUnitPosition on the target with its current position, whenever a LightningCannon fires. This would ensure that a unit has correct and up to date information on its quad membership for the imminent hit test. This would only fix the most visibly egregious part of the problem, and cause a visible (though not affecting the underlying sim) stutter for deltatime rendering, since the old position would be set to its current position.

The checks currently performed in CQuadField::MovedUnit could be made much more efficient if Spring could assume a fixed unit radius most of the time, and only perform a full recalculation when this changes. This might allow quad membership updates to happen every frame, rather than on slow update.

Alternatively, MovedUnit could increase the radius used to determine quad membership, becoming the model radius plus the distance a unit could move in a slow update by its MoveType. This would ensure that every quad which could potentially come to contain a unit before the next slow update, does contain said unit. There would still need to be an additional check for if a unit's velocity exceeds what could be expected from its MoveType, such as through high impulse weaponry.
TagsNo tags attached.
Checked infolog.txt for ErrorsYes
Attached Files




esainane (reporter)

Possibly related to https://springrts.com/mantis/view.php?id=6280

-Issue History
Date Modified Username Field Change
2020-08-29 04:32 esainane New Issue
2020-08-29 04:33 esainane Note Added: 0020527
+Issue History