You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This change fixes inconsistent mine collision detection by replacing the partition manager's circle fill algorithm with a more precise algorithm. The new logic is placed behind a new RETAIL_COMPATIBLE_CIRCLE_FILL_ALGORITHM preprocessor directive to help isolate the change as it is potentially slightly less performant.
The retail circle fill logic - an implementation of the midpoint circle algorithm - does not accurately cover the cells occupied by spherical or cylindrical geometry. This leads to various collision inaccuracies throughout the game, one of which is the infamous mine behaviour described in #24. Various collision logic is only processed within partition cells that are considered occupied - the partition cells act as a 'broad phase' to determine which geometry then needs to be checked for overlaps.
It's particularly important to note that objects with a geometry radius >= 20 and < 40 (the most common range) only cover a single partition cell, for example Tunnel Networks (radius: 25) and Stinger Sites (radius: 30). This can be seen in the video below. A blue/green square indicates an occupied cell.
SINGLE_CELL.mp4
Mines happen to fit right within this range with a radius of 30, and therefore only end up covering a single cell. This is a problem as most units happen to be smaller than a single partition cell, and can end up bypassing adjacent occupied cells altogether. Below is an example of this happening.
DODGER.mp4
Below is a demonstration of the difference in cell coverage in retail (left, blue) vs this change (right, yellow) at different radii. It should be apparent that retail cell coverage becomes more inaccurate as geometry radii increases towards each multiple of the partition cell size (40, 80, 120, etc.), whereas the new algorithm is always perfectly accurate. Note that radii < 20 uses a separate dedicated 'small geometry' algorithm which is 100% accurate.
GRID_COMP.mp4
And below is a direct comparison between retail mine cell coverage and the new mine cell coverage.
Before
Mine cell coverage using the retail algorithm
After
Mine cell coverage using the new algorithm
And some real gameplay demonstrations for good measure.
Before
The Technical skips over several mines, allowing the terrorists to destroy the War Factory
BAD_MINES.mp4
After
The Technical and terrorists explode on the mines as expected
Stubbjax
added
Bug
Something is not working right, typically is user facing
Major
Severity: Minor < Major < Critical < Blocker
Performance
Is a performance concern
Gen
Relates to Generals
ZH
Relates to Zero Hour
NoRetail
This fix or change is not applicable with Retail game compatibility
labels
Jan 28, 2026
This PR replaces the partition manager's midpoint circle algorithm with a precise circle-to-AABB collision test to fix inconsistent mine collision behavior. The change addresses a critical gameplay issue where objects with geometry radii between 20 and 40 (including mines with radius 30) only occupied a single partition cell, allowing units to bypass them entirely.
Key Changes:
Added RETAIL_COMPATIBLE_CIRCLE_FILL_ALGORITHM preprocessor define to control algorithm selection
Implemented doCircleFillPrecise() method using accurate circle-to-cell overlap detection
Applied changes identically to both Generals and GeneralsMD codebases
Preserved retail behavior via conditional compilation guards
Algorithm Details:
The new doesCircleOverlapCell() function finds the closest point on the cell's bounding box to the circle center and checks if that distance is within the radius. This guarantees 100% accurate cell coverage for all geometry radii, particularly fixing the critical 20-40 range where the midpoint circle algorithm was most inaccurate.
Validation:
The PR includes extensive visual demonstrations showing improved cell coverage and gameplay videos confirming mines now properly detect passing units.
Confidence Score: 5/5
This PR is safe to merge with very high confidence
The implementation is mathematically sound, uses a well-established collision detection algorithm, preserves retail compatibility through conditional compilation, has been thoroughly demonstrated with visual evidence and gameplay testing, and applies changes consistently across both codebases
No files require special attention
Important Files Changed
Filename
Overview
Core/GameEngine/Include/Common/GameDefines.h
Added RETAIL_COMPATIBLE_CIRCLE_FILL_ALGORITHM preprocessor define to control circle fill algorithm selection
Implemented precise circle fill algorithm using circle-to-AABB collision test and added conditional compilation to preserve retail behavior (Zero Hour version)
Sequence Diagram
sequenceDiagram
participant PD as PartitionData
participant PM as PartitionManager
participant Cell as PartitionCell
Note over PD: updateCellsTouched() called
alt Geometry is SPHERE or CYLINDER
alt RETAIL_COMPATIBLE_CIRCLE_FILL_ALGORITHM = 1
PD->>PD: doCircleFill(x, y, radius)
Note over PD: Uses midpoint circle algorithm<br/>(less accurate)
else RETAIL_COMPATIBLE_CIRCLE_FILL_ALGORITHM = 0
PD->>PD: doCircleFillPrecise(x, y, radius)
Note over PD: Calculate bounding cells
PD->>PM: worldToCell(centerX ± radius, centerY ± radius)
PM-->>PD: minCellX, minCellY, maxCellX, maxCellY
PD->>PM: getCellSize()
PM-->>PD: cellSize
loop For each cell (x, y) in bounding box
PD->>PD: doesCircleOverlapCell(centerX, centerY, radius, cellX, cellY, cellSize)
Note over PD: Find closest point on cell to circle<br/>Check if distance < radius
alt Circle overlaps cell
PD->>PM: getCellAt(x, y)
PM-->>PD: cell
alt cell exists
PD->>Cell: addSubPixToCoverage(cell)
end
end
end
end
end
Note over PD: Partition cells now accurately<br/>reflect object's collision bounds
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
BuffMakes a thing more powerfulBugSomething is not working right, typically is user facingChinaAffects China factionGenRelates to GeneralsMajorSeverity: Minor < Major < Critical < BlockerNoRetailThis fix or change is not applicable with Retail game compatibilityPerformanceIs a performance concernZHRelates to Zero Hour
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #24 from the patch repository
This change fixes inconsistent mine collision detection by replacing the partition manager's circle fill algorithm with a more precise algorithm. The new logic is placed behind a new
RETAIL_COMPATIBLE_CIRCLE_FILL_ALGORITHMpreprocessor directive to help isolate the change as it is potentially slightly less performant.The retail circle fill logic - an implementation of the midpoint circle algorithm - does not accurately cover the cells occupied by spherical or cylindrical geometry. This leads to various collision inaccuracies throughout the game, one of which is the infamous mine behaviour described in #24. Various collision logic is only processed within partition cells that are considered occupied - the partition cells act as a 'broad phase' to determine which geometry then needs to be checked for overlaps.
It's particularly important to note that objects with a geometry radius >= 20 and < 40 (the most common range) only cover a single partition cell, for example Tunnel Networks (radius: 25) and Stinger Sites (radius: 30). This can be seen in the video below. A blue/green square indicates an occupied cell.
SINGLE_CELL.mp4
Mines happen to fit right within this range with a radius of 30, and therefore only end up covering a single cell. This is a problem as most units happen to be smaller than a single partition cell, and can end up bypassing adjacent occupied cells altogether. Below is an example of this happening.
DODGER.mp4
Below is a demonstration of the difference in cell coverage in retail (left, blue) vs this change (right, yellow) at different radii. It should be apparent that retail cell coverage becomes more inaccurate as geometry radii increases towards each multiple of the partition cell size (40, 80, 120, etc.), whereas the new algorithm is always perfectly accurate. Note that radii < 20 uses a separate dedicated 'small geometry' algorithm which is 100% accurate.
GRID_COMP.mp4
And below is a direct comparison between retail mine cell coverage and the new mine cell coverage.
Before
Mine cell coverage using the retail algorithm
After
Mine cell coverage using the new algorithm
And some real gameplay demonstrations for good measure.
Before
The Technical skips over several mines, allowing the terrorists to destroy the War Factory
BAD_MINES.mp4
After
The Technical and terrorists explode on the mines as expected
GOOD_MINES.mp4