From 64d17a290da1c16fd8d4ae56491f379992c8f9f5 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Fri, 25 Sep 2026 18:33:09 +0200 Subject: [PATCH] Cut 12.3 fix batch (F4): one writer for lane completion, delete dead reachability offset ApplyPooled.Resolve no longer calls FinishLane directly -- AdvanceLane is now the single place that checks pointer >= walked and finishes a lane, so lane completion has one writer instead of two. StillReachableByAnotherLane's own `blocked ? pointer+1 : pointer` collapses to plain `pointer[li2]`: the alreadyContributed check just above it already excludes a lane that is blocked on the very item being asked about, so `pointer[li2]` is never that item's own cell by the time the +1 would have mattered. Soul's findings (docs/fire-control-cut.md, Cut 12.3): F4. Co-Authored-By: Claude Opus 5.5 --- Assets/Scripts/ServerShared/FireControl.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Assets/Scripts/ServerShared/FireControl.cs b/Assets/Scripts/ServerShared/FireControl.cs index b81a7a2d3..eebbda665 100644 --- a/Assets/Scripts/ServerShared/FireControl.cs +++ b/Assets/Scripts/ServerShared/FireControl.cs @@ -758,8 +758,10 @@ public static class FireControl if (contributors[k].lane == li2) { alreadyContributed = true; break; } if (alreadyContributed) continue; - var start = blocked[li2] ? pointer[li2] + 1 : pointer[li2]; - for (var i = start; i < walked[li2]; i++) + // No +1 needed when li2 is blocked at this same item's cell: `alreadyContributed` above already + // caught that case (a blocked lane is always a contributor to the item it is blocked on), so + // `pointer[li2]` itself is never this item's own cell by the time this line runs. + for (var i = pointer[li2]; i < walked[li2]; i++) if (target.GearOccupancy[buffers[li2][i].Cell.x, buffers[li2][i].Cell.y] == item) return true; } return false; @@ -780,7 +782,9 @@ public static class FireControl rem[lane] = amounts[k]; blocked[lane] = false; pointer[lane]++; - if (pointer[lane] >= walked[lane]) FinishLane(lane); + // One writer for lane completion: AdvanceLane, not here. Unblocking and advancing the + // pointer is enough -- the next call to AdvanceLane(lane), later this pass or the next while + // iteration, is the one place that checks `pointer >= walked` and calls FinishLane. } } finally