Commit graph

6 commits

Author SHA1 Message Date
Erik
1658882439 fix(A.5 T4-T6): bootstrap guard + dead enum + test cleanups
Code review on commits 7bcabab/fb6b61e/326b698 flagged 2 Important +
4 Minor issues. Apply all fixes:

Important:
- Two-tier RecenterTo + MarkResidentFromBootstrap now throw
  InvalidOperationException on misuse — calling RecenterTo before the
  bootstrap silently emitted the entire window as fresh loads (no
  demotes/unloads since _tierResidence was empty), a correctness hazard
  that produced no exception. Calling MarkResidentFromBootstrap twice
  silently dropped accumulated tier state. Both now crash loudly via
  a _bootstrapped flag.
- Dropped TierResidence.None from the enum — never assigned, never
  checked; absence from the dictionary already encodes "not resident."

Minor:
- Renamed test: RecenterTo_FirstTick_* → ComputeFirstTickDiff_FirstTick_*
  (the test calls ComputeFirstTickDiff, not RecenterTo).
- Strengthened RecenterTo_PlayerWalks_NullToFar_* with assertions for
  ToPromote.Count==3 (the x=102 column promoting Far→Near) and
  ToUnload.Empty (everything within hysteresis).
- Replaced System.Math.Abs with Math.Abs in new code to match the
  file's existing `using System;` convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:49:35 +02:00
Erik
326b698161 test(A.5 T6): StreamingRegion transitions + hysteresis + oscillation coverage
Adds 5 tests to StreamingRegionTwoTierTests covering all tier-transition paths:
- FarToNear promote (walk 2 east from initial center)
- NullToNear teleport (loads 9 near + 40 far for a fully fresh region)
- NearToFar demote only after NearRadius+2 hysteresis threshold
- FarToNull unload only after FarRadius+2 hysteresis threshold
- oscillation no-thrash: bouncing 1 LB across a near boundary fires 0 demotes
  and at most 5 promotes total (one initial settle of the x=100 near-column)

Oscillation test fix: initialise the region at the oscillation midpoint
(103,100) rather than at a distant starting center (100,100) so the
initial move into the oscillation range doesn't itself trigger legitimate
demotes, isolating the no-thrash invariant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:39:16 +02:00
Erik
fb6b61e8ef feat(A.5 T5): StreamingRegion two-tier RecenterTo + TierResidence tracking
Adds TierResidence enum (None/Far/Near), _tierResidence dictionary seeded
by MarkResidentFromBootstrap, and the canonical two-tier RecenterTo overload
returning TwoTierDiff. Pass 1 walks the new far window and emits ToLoadFar /
ToLoadNear / ToPromote; Pass 2 walks prior residents and emits ToDemote /
ToUnload using Chebyshev hysteresis thresholds (NearRadius+2 / FarRadius+2).
EncodeLandblockIdForTest exposes the encoding rule to test assemblies.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:36:20 +02:00
Erik
7bcababf82 feat(A.5 T4): StreamingRegion ComputeFirstTickDiff
Adds the first-tick bootstrap diff: ToLoadNear for the (2*near+1)^2 inner
window, ToLoadFar for the outer annulus up to FarRadius. Uses Chebyshev
distance, matching existing Recenter convention.

Also renames the single-tier RecenterTo → RecenterToSingleTier to free
the canonical name for the upcoming two-tier overload (T5). Updates
StreamingRegionTests and StreamingController to call the renamed method.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:34:55 +02:00
Erik
378f32ac7a fix(A.5 T3): pin Radius==FarRadius invariant in two-tier ctor test
Code review on commit 7fd9c82 flagged that the test asserted NearRadius,
FarRadius, CenterX, CenterY but not the load-bearing alias
Radius == FarRadius. That alias is what makes the existing hysteresis
math (Radius+2 unload threshold) correctly target the far-tier boundary.
Future typos would silently break far-tier hysteresis.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:30:30 +02:00
Erik
7fd9c82954 test(A.5 T3): StreamingRegion two-radius constructor
Add NearRadius/FarRadius properties and a four-arg constructor
(centerX, centerY, nearRadius, farRadius). Radius is set to farRadius
so existing hysteresis math (unload threshold = Radius+2) uses the
outer ring as the bookkeeping boundary. Old three-arg constructor
becomes a thin wrapper: this(cx, cy, radius, radius) — no behaviour
change, 25 pre-existing streaming tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:27:50 +02:00