From 13d591e7895f25eddb0f00a4aa6bd277c3bdf677 Mon Sep 17 00:00:00 2001 From: Luis Gonzalez Date: Sat, 8 Aug 2026 17:50:13 -0700 Subject: [PATCH] =?UTF-8?q?Fix:=20revive=20the=20walk-through=20flora=20ru?= =?UTF-8?q?stle=20=E2=80=94=20a=20fourth=20orphaned=20presentation=20layer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Track 1. Before building any new "world responds to you" work, I checked what already existed, because today's score was three presentation systems that were present, enabled, and produced nothing. This is the fourth. AmbientMotionSystem's rustle layer (flora parting as the local player brushes past) was dead in the shipping arena via THREE independent gates, each a leftover of the deleted biomes: 1. Root gate required a scene root literally named "BaseBiome" or "ExpeditionBiome*". Both went with the expedition, so the loop matched nothing at all. The seabed flora live under Env_SeabedKit/Seabed_Flora/FloraClump_N. 2. Name regex was pure LAND flora: bush|grass|flower|fern|cactif|clover... Nothing in a seabed matches that. Added seabed terms first; the land terms stay only so an older scene still works. 3. Renderer gate tested for a renderer ON the matched object. The natural sway unit is the CLUMP ROOT, which carries no renderer of its own - only children - so the test rejected exactly the object we want to rotate. Now accepts a renderer anywhere beneath, and skips a child whose parent already matched so the clump tilts once instead of every stalk tilting out of its socket. Verified live: AmbientMotionSystem._flora.Count 0 -> 4 (the four clump roots). 304/304 EditMode green. Co-Authored-By: Claude Opus 5 (1M context) --- .../Client/Presentation/AmbientMotionSystem.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Assets/_Project/Scripts/Client/Presentation/AmbientMotionSystem.cs b/Assets/_Project/Scripts/Client/Presentation/AmbientMotionSystem.cs index 5241975a0..fb8d43050 100644 --- a/Assets/_Project/Scripts/Client/Presentation/AmbientMotionSystem.cs +++ b/Assets/_Project/Scripts/Client/Presentation/AmbientMotionSystem.cs @@ -24,8 +24,12 @@ namespace ProjectM.Client [UpdateInGroup(typeof(PresentationSystemGroup))] public partial class AmbientMotionSystem : SystemBase { + // 2026-08-08: seabed terms FIRST. The old list was pure LAND flora (bush/grass/flower/fern/cactus) + // from the deleted meadow + arid biomes, so it matched NOTHING in the shipping seabed arena and the + // whole walk-through rustle layer was dead. The land terms are kept only so an old scene still works. static readonly System.Text.RegularExpressions.Regex FloraName = new System.Text.RegularExpressions.Regex( - "bush|grass|flower|fern|groundcover|ground_cover|wildflower|clover|reed|succulent|cactus", + "floraclump|flora_|kelp|frond|seagrass|seaweed|coral|anemone" + + "|bush|grass|flower|fern|groundcover|ground_cover|wildflower|clover|reed|succulent|cactus", System.Text.RegularExpressions.RegexOptions.IgnoreCase); struct Flora @@ -79,14 +83,22 @@ namespace ProjectM.Client { RestoreFlora(); _flora.Clear(); + // 2026-08-08: scan EVERY root. The old gate required a root literally named "BaseBiome" or + // "ExpeditionBiome*" — both went with the expedition, so this loop matched nothing and the rustle + // layer silently did nothing in the shipping arena. The seabed flora live under + // Env_SeabedKit/Seabed_Flora/FloraClump_N. foreach (var root in scene.GetRootGameObjects()) { - if (root.name != "BaseBiome" && !root.name.StartsWith("ExpeditionBiome")) continue; foreach (var t in root.GetComponentsInChildren(false)) { if (!FloraName.IsMatch(t.gameObject.name)) continue; if (t.gameObject.name.Contains("LOD")) continue; // prop roots only; LOD children follow - if (t.GetComponent() == null && t.GetComponent() == null) continue; + // The sway unit is the CLUMP ROOT, which carries no renderer of its own — only children. + // The old renderer-on-self test rejected exactly the object we want to rotate, so accept a + // renderer anywhere beneath. Skip anything whose PARENT already matched, so we tilt the + // clump once instead of tilting every stalk out of its socket. + if (t.parent != null && FloraName.IsMatch(t.parent.gameObject.name)) continue; + if (t.GetComponent() == null && t.GetComponentInChildren() == null) continue; // 1.5b: ground-flush carpet props (Flowers_Flat, Grass_*_Plane) must NEVER root-tilt — // any rotation lifts their edges off the ground; they stay fully static (shader wind only). if (t.gameObject.name.IndexOf("Flat", System.StringComparison.OrdinalIgnoreCase) >= 0