Skip to content

perf(Spatial Hash IM): Refresh Grid on Interval - #4015

Merged
miwarnec merged 2 commits into
masterfrom
ImproveSpatialHash2
Aug 4, 2026
Merged

perf(Spatial Hash IM): Refresh Grid on Interval#4015
miwarnec merged 2 commits into
masterfrom
ImproveSpatialHash2

Conversation

@MrGadget1024

Copy link
Copy Markdown
Collaborator
  • Substantial performance increase at scale
  • Notes added to explain why this is acceptable
  • Default visRange set to more likely real world value
  • Tests updated

- Substantial performance increase at scale
- Notes added to explain why this is acceptable
- Default visRange set to more likely real world value
- Tests updated
@miwarnec

miwarnec commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

@copilot what does this change, is this a good idea?

Copilot AI commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

@copilot what does this change, is this a good idea?

This change throttles how often the Spatial Hash grid is fully rebuilt. Before, every OnCheckObserver call could trigger a refresh path under load; now we refresh on a fixed interval and reuse the existing grid between refreshes.

Why it’s generally a good idea:

  • It removes a lot of repeated work in large scenes.
  • It keeps interest checks cheaper and more stable frame-to-frame.
  • Visibility correctness is still preserved because rebuilds still happen regularly, just not redundantly.

Tradeoff: there can be up to one refresh-interval of staleness for moved objects, so this is best when that small delay is acceptable for the project. The interval/default can be tuned per game.

@miwarnec

miwarnec commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

@copilot why was this done in OnCheckObserver before, and say mor eabout the one refresh-interval of staleness

Copilot AI commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

@copilot why was this done in OnCheckObserver before, and say mor eabout the one refresh-interval of staleness

It was previously done in OnCheckObserver because that path is guaranteed to run right before visibility decisions, so rebuilding there ensured the grid was always fresh at decision time. The downside is that at scale it can cause repeated rebuild work within short windows.

With interval refresh, “one refresh-interval of staleness” means a moved/spawned/despawned object might still be indexed in its previous cell until the next scheduled rebuild. Practically: observers can briefly over-see or under-see that object for up to that interval, then it self-corrects on the next refresh. So the interval is a performance-vs-immediacy knob: shorter interval = less staleness, higher CPU; longer interval = more staleness, lower CPU.

@miwarnec

miwarnec commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

@copilot whats the call stack for OnCheckObserver? is this called whenvever someone spawns or when?

Copilot AI commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

@copilot whats the call stack for OnCheckObserver? is this called whenvever someone spawns or when?

OnCheckObserver is called during server-side observer rebuilding, not only on spawn.

Typical path is:
NetworkServer visibility rebuild loop -> NetworkIdentity.RebuildObservers(...) -> each observed NetworkIdentity invokes the active interest management’s OnCheckObserver(identity, newObserver).

So it runs whenever Mirror recomputes who should observe an object (periodic rebuilds and events that trigger observer rebuild), including after spawns, but also for ongoing visibility updates while objects/connections move/change.

@miwarnec

miwarnec commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

@copilot when does it currently rebuild observers? wouldnt this pr make the previous observer rebuilt interval obsolete? wouldnt it be cleaner to keep as is?

Copilot AI commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

@copilot when does it currently rebuild observers? wouldnt this pr make the previous observer rebuilt interval obsolete? wouldnt it be cleaner to keep as is?

Observer rebuilds are currently driven by Mirror’s existing rebuild cadence/triggers (server-side RebuildObservers flow). This PR does not replace that cadence.

What it changes is narrower: inside each observer check, spatial hash grid refresh is now throttled by its own interval instead of potentially rebuilding on every check call. So:

  • existing observer rebuild interval/triggers still decide when checks happen
  • new spatial refresh interval decides how often we rebuild the spatial index used by those checks

So it’s not making the existing observer rebuild interval obsolete; it decouples two costs. Keeping as-is is simpler, but ties grid rebuild cost directly to check frequency, which is the perf issue this PR is targeting at scale.

@miwarnec

miwarnec commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

@copilot if there already is a built in check frequency, shouldnt users just increase the built in check frequency instead of introducing another one right here?

Copilot AI commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

@copilot if there already is a built in check frequency, shouldnt users just increase the built in check frequency instead of introducing another one right here?

That can help, but it changes the wrong knob in many cases.

Increasing built-in observer check interval reduces all visibility updates (coarser global behavior), which can hurt responsiveness for every IM strategy. This PR keeps the existing observer check cadence intact, but reduces only the expensive part for Spatial Hash (grid rebuild frequency).

So users can still tune global check frequency if they want, but this adds a more targeted control: keep observer responsiveness, while independently capping spatial rebuild cost.

@miwarnec
miwarnec merged commit 025a763 into master Aug 4, 2026
5 of 6 checks passed
@miwarnec
miwarnec deleted the ImproveSpatialHash2 branch August 4, 2026 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Awaiting Review enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants