Skip to content

GridFixtureSystem Optimizations#6415

Open
Aidenkrz wants to merge 5 commits intospace-wizards:masterfrom
Aidenkrz:GridStuff
Open

GridFixtureSystem Optimizations#6415
Aidenkrz wants to merge 5 commits intospace-wizards:masterfrom
Aidenkrz:GridStuff

Conversation

@Aidenkrz
Copy link
Contributor

@Aidenkrz Aidenkrz commented Feb 8, 2026

About the PR

Optimizes GridFixtureSystem in a few hot paths that were doing more work (and allocating more garbage) than they really needed to.

Ended up doing a bunch more fuckery to SharedGridFixtureSystem as well after looking through it as well, refer to technical details for info on that.

Why / Balance

One of my maintainers pointed out that there was some evil LINQ garbage in this system that called .Sum() a bajillion times whenever CheckSplits ran. Not the end of the world, but also easily avoidable. This cleans that up and makes the whole thing scale way better without changing behavior. Also noticed system was allocating new collections constantly, so i changed that as well.

Technical details

  • The BFS scratch structures (_splitFrontier queue and _splitGrids list) are now reused as class fields instead of being allocated every CheckSplits call.

  • The sort comparator was doing repeated LINQ .Sum() calls, resulting in something like
    $O(N \times M \times \log N)$ work.
    This is now replaced with a precomputed gridSizes dictionary, bringing it down to
    $O(N \times M + N \times \log N)$.

    As a rough example:

    • For N = 50 grids with M = 100 tiles each, this cuts the comparator work by ~90%.
    • For N = 200 grids with M = 250 tiles each, it’s closer to a ~97% reduction.

    I didn't do any real benchmarking as I don't have dottrace, but I mean, the math checks out.

  • In CreateNodes, the tile HashSet now only tracks non-empty tiles (capacity set to chunk.FilledTiles) instead of blindly allocating for all 256 chunk positions.

  • Cross-chunk neighbor detection now bails early for interior tiles, since only edge tiles can possibly have neighbors in adjacent chunks.

  • MapGridComponent is now passed through the full call chain as a nullable parameter with TryComp/Comp fallback.

  • Grid fixture diffing in UpdateFixture now cross-references old and new fixtures by ID instead of using a full Fixture.Equals comparison. The old approach always failed because content (e.g. ShuttleSystem.OnGridFixtureChange) modifies fixture density after creation, causing every fixture to be destroyed and recreated on every tile change. The new approach compares shapes only via EqualsApprox, preserving content-set properties like density. This also eliminated a redundant shape check that existed solely as a workaround for the broken equality comparison, and fixed a latent bug where chunk.Fixtures (a HashSet<string>) was being modified during foreach enumeration.

  • During grid splits, entity reparenting now does a single broadphase query per node using the union bounding box of all its tiles, instead of one query per tile. Entities are filtered by converting their position to a tile index and checking membership in a HashSet<Vector2i>. This reduces broadphase queries from O(tiles) to O(1) per node.

@Aidenkrz
Copy link
Contributor Author

Aidenkrz commented Feb 8, 2026

accidentally left the PR title as the commit name and cant change it now 👎

@ArtisticRoomba
Copy link
Member

github stays winning

@Tayrtahn
Copy link
Member

Tayrtahn commented Feb 8, 2026

Apparently you can still change it from the mobile app. You can also just tell me what title you'd like and I'll change it for you.

@Aidenkrz Aidenkrz changed the title Optimization pass Server GridFixtureSystem Optimizations Feb 8, 2026
@Aidenkrz
Copy link
Contributor Author

Aidenkrz commented Feb 8, 2026

Apparently you can still change it from the mobile app. You can also just tell me what title you'd like and I'll change it for you.

Thanks I used GitHub mobile

Copy link
Contributor

@moonheart08 moonheart08 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking for footage of this being tested, ideally, just as a "this obviously works". The changes lgtm though.

Copy link
Member

@DrSmugleaf DrSmugleaf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outside of DungeonJob it seems like the only other caller to CheckSplits is SharedMapSystem.RegenerateCollision, which seem fine at a glance

@Aidenkrz Aidenkrz changed the title Server GridFixtureSystem Optimizations GridFixtureSystem Optimizations Mar 26, 2026
@Aidenkrz Aidenkrz marked this pull request as draft March 26, 2026 20:02
@Aidenkrz Aidenkrz marked this pull request as ready for review March 26, 2026 20:08
@Aidenkrz Aidenkrz requested a review from DrSmugleaf March 26, 2026 20:08
@Aidenkrz
Copy link
Contributor Author

grid.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants