From 39533642477a2a246cafd40ccde6b55efd72ba65 Mon Sep 17 00:00:00 2001 From: JohnM <234386938+treuenten@users.noreply.github.com> Date: Sat, 10 Oct 2026 00:08:48 +0800 Subject: [PATCH] Free the last match's body animations before the next map loads Every PersistentRemoteTree holds an Arc (since 25c008b), which owns the match's player XAnimCatalog and BodyMeshCatalog. reset_anim_for_match clears the other per-match animation state on MatchInstalled and MatchTornDown, but not RemoteBodyTrees, and the trees' only pruning (retain_live in pose_remote_bodies) runs once the next match poses remote bodies. When a different map loads, load_prepared_match drops the resident copy of the last match before walking the new one, and from then until the first remote pose the trees alone keep the old match's catalogs alive, through the peak of the next load. Reset RemoteBodyTrees with the rest of the per-match state. The trees are rebuilt when remote bodies are posed in the new match. Co-Authored-By: Claude Opus 5.5 --- crates/render_anim/src/occupancy/match_reset.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/render_anim/src/occupancy/match_reset.rs b/crates/render_anim/src/occupancy/match_reset.rs index feb2c78..a40133f 100644 --- a/crates/render_anim/src/occupancy/match_reset.rs +++ b/crates/render_anim/src/occupancy/match_reset.rs @@ -3,6 +3,7 @@ use frame::{MatchInstalled, MatchTornDown, SessionSwapApplied}; use net::ClientSet; use crate::anim::fpv_prepared::PreparedFpv; +use crate::anim::remote_body::RemoteBodyTrees; use crate::anim::scene_submission::AnimDObjSceneSkels; use crate::occupancy::dyn_ent::{DynEntPhysClip, DynEntPhysWorld}; use crate::occupancy::fpv_present::{ @@ -24,6 +25,7 @@ pub(crate) fn reset_anim_for_match( mut settled: ResMut, mut held_life: ResMut, mut scene_skels: ResMut, + mut remote_trees: ResMut, existing: Query>, ) { let installs = installed.read().count(); @@ -42,6 +44,7 @@ pub(crate) fn reset_anim_for_match( settled.0 = None; held_life.0 = None; *scene_skels = AnimDObjSceneSkels::default(); + *remote_trees = RemoteBodyTrees::default(); for entity in &existing { commands.entity(entity).try_despawn();