Skip to content

perf: scope same-chunk entity tracker refreshes with a chunk index - #552

Draft
carabistouflette wants to merge 2 commits into
Steel-Foundation:masterfrom
carabistouflette:pr8-tracker-refresh-scoping
Draft

perf: scope same-chunk entity tracker refreshes with a chunk index#552
carabistouflette wants to merge 2 commits into
Steel-Foundation:masterfrom
carabistouflette:pr8-tracker-refresh-scoping

Conversation

@carabistouflette

@carabistouflette carabistouflette commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Type of change

  • Block implementation
  • Item implementation
  • Command implementation
  • Entity implementation
  • Bug fix
  • New feature
  • Breaking change
  • Refactor / code cleanup
  • Performance improvement

Description

Scopes same-chunk entity tracker refreshes:

  • EntityTracker keeps entities_by_chunk, a secondary index of entity IDs by registered chunk, maintained on add, remove, dead-entity removal, and section moves.
  • New update_player_nearby(player, view, center, radius_chunks, is_chunk_sent) evaluates only entities registered within the view radius of the player chunk. ChunkMap::update_player_status uses it when the view is unchanged (pure same-chunk movement) — previously every accepted movement scanned every tracked entity in the world (entities.iter_sync).
  • Full update_player scans remain for cross-chunk view changes, initial joins, and chunk batch commits.
  • The shared vanilla visibility predicate is extracted to entity_visible_to_player so both paths stay in lockstep with vanilla's updatePlayer rules.

How this was tested

  • New regression test update_player_nearby_uses_chunk_registry_without_full_scan: scoping (far entity outside the radius is neither evaluated nor despawned), idempotence (no duplicate spawn packets for already-paired entities), and despawn-on-removal (removed entities inside the radius are despawned with CRemoveEntities).
  • cargo test -p steel-core --lib (2422 tests) pass; cargo clippy -r --all-targets clean.

Screenshots / logs

N/A.

Checklist

  • Code builds w/o errors or warnings
  • Self-reviewed the diff
  • Docs updated (if applicable) — N/A
  • No leftover debug code / comments

Additional notes

  • The regression test caught a real bug during development (missing CRemoveEntities in the nearby despawn path) — kept as the guard against reintroducing it.
  • Stacked on pr7-chunk-light-efficiency (base of this PR).
  • Env: Linux, Rust nightly, Minecraft protocol 776 (0.15.2+mc26.2).

Note: stacked on #551 (pr7-chunk-light-efficiency). Until it merges, this PR's diff includes its commits; the tracker changes themselves are the final commit. Incremental diff: carabistouflette/SteelMC@pr7-chunk-light-efficiency...pr8-tracker-refresh-scoping

…s light locks

- ChunkSender::collect_candidates selects the closest pending positions with a
  bounded max-heap (vanilla Comparators.least) instead of fully sorting the
  pending set; kernel A/B measured 2.2x faster at 512 pending chunks and 5.5x
  at 4096 (criterion, quota 64)
- commit_batch resolves prepared chunks through an FxHashMap built once per
  batch instead of a linear find per encoded chunk (O(B^2) -> O(B))
- the light publication pass defers sends to a per-player phase: each
  player's tracking view and chunk sender are locked once per pass instead of
  once per candidate chunk (up to 18 candidates); World::
  send_deferred_light_updates owns the per-player resolution and
  get_light_packet_tracking_players is removed
- chunk light section matching switches to an FxHashSet when a section delta
  list holds more than 4 entries
- EntityTracker keeps entities_by_chunk, a secondary index updated on add,
  remove, removal of dead entities, and section moves
- update_player_nearby evaluates only entities registered within the view
  radius of the player chunk; ChunkMap::update_player_status uses it when the
  view is unchanged (pure same-chunk movement), which previously scanned every
  tracked entity in the world
- full update_player scans remain for view changes, initial joins, and batch
  commits
- the shared visibility predicate is extracted to entity_visible_to_player so
  both paths stay in lockstep with vanilla's updatePlayer rules
- regression test covers scoping, idempotence, and despawn on removal
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

This pull request has conflicts with the base branch "master". Please resolve those so we can test out your changes.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants