mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-28 13:46:53 +01:00
### Problem 1. **Unplaced first-pose phantom spawns (`render`):** In the 500 ms distance loop (`s.next_shown_rank`), `p.shown_wanted` is set to `everyone || !p.placed || nearest_distance(...) <= ...` so that before a peer's first pose arrives (`!p.placed`, `sampled == false`), their status reads `"Waiting for player poses."` rather than `"Further away than players are shown."`. However, when their first pose packet arrives in `each_active_peer` (`const bool sampled = ...`), `if (sampled) p.placed = true;` flips `p.placed` to `true` while `p.shown_wanted` is still `true` from when `!p.placed` was true. Because `nearest_distance` has not yet been checked against the newly populated `p.render_pose`, `show_remote()` is immediately called on that frame for every newly-placed player on the server — spawning a full 395-bone 3D skater, 16-bone skateboard, and cosmetics for players 300–500 m across the map, only for the next 500 ms `s.next_shown_rank` pass to evaluate `nearest_distance > s.player_distance` and immediately destroy them (`remove_remote()`). 2. **Follow-camera orbit shifting the distance boundary (`nearest_distance`):** `nearest_distance(p, local, view)` takes the nearer of `local.pose.root.position` and `view` (the camera). While `view` is needed when the camera is detached from the local skater (spectating another player across the map, replay camera, or flying a drone), during ordinary skating the follow camera orbits ~3–5 m around the local skater. Rotating the camera around the skater shifts the effective `player_distance` boundary by ~8–10 m (consuming the 15% hysteresis band at 50 m) and causes clusters of players near the boundary (such as a Spot Battle crowd) to spawn and despawn as the camera turns. ### Solution 1. When a peer's first pose transitions `p.placed` from `false` to `true` (`if (sampled && !std::exchange(p.placed, true))`), immediately update `p.shown_wanted` from `nearest_distance(p, local, view) <= s.player_distance` before evaluating `spawning` and `show_remote()`. Peers before their first pose still keep `p.shown_wanted = true` (`"Waiting for player poses."`), nearby peers still spawn on their first pose frame without waiting for the 500 ms tick, and far-away peers never phantom-spawn on arrival. 2. In `nearest_distance()`, consider `view` when `!local.ready` or when the camera is more than 12 m from `local.pose.root.position` (spectating, replay, or drone), keeping the distance radius anchored to the local skater during normal third-person follow-camera rotation. ### Verification - Tested in-game in 44–78 player online lobbies with active Spot Battle throwdowns (`ReSkate.dll` runtime verification). - Verified in `ReSkate.log` that far-away peers no longer trigger `creating a remote skater` / `Skater component factory` spawns on their first pose packet and that rotating the camera toward a Spot Battle huddle near the 50 m / 70 m boundary no longer triggers a spawn storm.