Skip to content

Reduce physics meshing allocations and make chunk streaming safe - #170

Merged
fredboy merged 5 commits into
developfrom
fix/physics-streaming
Oct 21, 2026
Merged

fredboy merged 5 commits into
developfrom
fix/physics-streaming

Conversation

@fredboy

@fredboy fredboy commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

Walking across chunk boundaries caused heavy collision-meshing allocations and exposed races between terrain loading, physics preparation, entity persistence, and eviction. This PR reduces preparation cost and makes those lifecycle transitions consistent.

  • Collision meshing: Replace repeated set merging and temporary coordinate objects with flood-fill over reusable primitive arrays and packed fixture vertices. Build geometry from a terrain snapshot, preserving material boundaries, enclosed cave contours, collision margins, fixture order, and finite-world mirrors.
  • Async collision preparation: Track each column's load lifetime and each section's revision. Cancel unloaded jobs, reject stale results after edits or reloads, and notify readiness once per residence. Keep existing bodies until their replacements are installed.
  • Terrain streaming and saves: Publish terrain, evict chunks, and notify listeners on the main thread. Workers load/generate detached chunks. Persist immutable terrain snapshots with write ordering so older eviction saves cannot overwrite newer data; retain pending snapshots for immediate reloads.
  • Entity persistence: Restore saved entities before replacing their snapshot, even if collision preparation is unfinished. Include queued mobs and drops in save/eviction, and prevent duplicate restoration from repeated readiness callbacks.
  • Fire lifecycle: Compute and apply each fire tick in the same main-thread turn, removing deferred mutations that could affect an edited or reloaded chunk.
  • Physics readiness: Check every active moving body's swept bounds before each fixed step, including offscreen entities and entities restored by readiness callbacks. Finish pending collision geometry synchronously where needed; temporarily suspend affected bodies when terrain is absent.

Measured collision preparation for a generated 16×256 column, including outlines:

Metric Before After
Median time 5.843 ms 0.168 ms
JVM allocation 23.248 MiB 0.317 MiB

These are local microbenchmark results, not measured gameplay frame-time gains. Geometry comparisons matched 1,040 generated sections and 174,186 ordered vertices; native checks matched 8,685 fixtures, including both mirror offsets, and verified body replacement accounting.

Validation: 41 new regression tests cover meshing, stale async results, eviction/reload, entity persistence, fire scheduling, and native Box2D stepping. ./gradlew testCore desktop:classes html:buildJs passed: 136 core tests passed, with one existing test skipped. Affected modules also passed ktlintCheck.

Interactive walking/teleport playtesting and an in-game frame-time profile remain unverified. Synchronous collision completion can still add work to a frame when an actor reaches unfinished terrain.

@fredboy
fredboy merged commit 95ed85d into develop Oct 21, 2026
9 checks passed
@fredboy
fredboy deleted the fix/physics-streaming branch October 21, 2026 19:37
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.

1 participant