docs(overhaul): correct S5 c1 review comments

Remove the deleted outdoor-fallback claim, describe the visible-cell union as diagnostics rather than a shared admission answer, and distinguish the landscape particle, resident-light, and future shadow consumers.

Correct ParticleSystem complexity prose: only the SortedSet indexes have logarithmic lifecycle edges; the view list uses binary-search insertion with linear shift and linear removal.

Focused verification: Core ParticleSystemTests 47/47; App visibility/terrain/frame/renderer 38/38; AP-116 settings/live-object 3/3; git diff --check clean. No behavior, tests, register, or architecture change.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-09-04 16:38:03 +02:00
parent 282fe87fb3
commit 4d1110812c
4 changed files with 33 additions and 16 deletions

View file

@ -41,10 +41,11 @@ public sealed class ParticleVisibilityController : IWorldSceneParticleVisibility
}
/// <summary>
/// Declares that this frame has an authoritative world-visibility product.
/// That product can come from the unified retail PView or from the outdoor
/// landscape fallback. Login and portal-space frames deliberately omit it;
/// dedicated pass and examination emitters carry explicit bypass policies.
/// Declares that this frame has the completed retail PView product: one
/// viewer position plus its exact walk-owned landscape-cell set. Frames
/// without that PView product, including login, portal space, and the
/// null-root terrain safety draw, deliberately omit it; dedicated-pass and
/// examination emitters carry explicit bypass policies.
/// </summary>
public void UseWorldView()
{

View file

@ -868,11 +868,14 @@ internal sealed class WalkFrameDriver : IWalkEventSink, IWalkLookInViewSource
}
/// <summary>
/// Copies the walk's complete retail <c>CObjCell::IsInView</c> answer:
/// EnvCells reached by interior floods/look-ins plus outdoor land cells
/// visited by the landscape walk. The two families stay separately
/// retained because only the first is valid EnvCell batch input, but
/// particles, lights, and shadows consume their union.
/// Copies the walk's diagnostic union: EnvCells reached by interior
/// floods/look-ins plus outdoor land cells visited by the landscape walk.
/// The two families remain separately retained because EnvCells are shell
/// preparation input while only the landscape half feeds land-cell particle
/// eligibility; EnvCell particle eligibility is the constant-true virtual.
/// Point lights use the resident registry, and directional-shadow use of the
/// landscape product remains owned by S5-c2. No admission path consumes this
/// union as a complete <c>CObjCell::IsInView</c> answer.
/// </summary>
internal void CopyVisibleCellsTo(HashSet<uint> destination)
{

View file

@ -14,16 +14,17 @@ public sealed class ParticleSystem : IParticleSystem
private readonly EmitterDescRegistry _registry;
private readonly Random _rng;
private readonly Dictionary<int, ParticleEmitter> _byHandle = new();
// Handles are monotonic, so sorted indexes preserve retail emitter-spawn
// order while making every lifecycle edge O(log E). The old List.Remove
// hard-stop path was O(E) and became visible when portal routes retained
// thousands of finite/fading emitters.
// Handles are monotonic, so the SortedSet indexes preserve retail
// emitter-spawn order while making their lifecycle edges O(log E). Their
// predecessor List.Remove hard-stop path was O(E) and became visible when
// portal routes retained thousands of finite/fading emitters.
private readonly SortedSet<int> _allHandles = [];
private readonly SortedSet<int> _simulationHandles = [];
// ApplyRetailView is a per-frame production path. SortedSet's enumerator
// allocates its traversal stack, so retain this subset as a sorted list;
// lifecycle mutations pay the binary insertion/removal cost and the
// warmed view walk stays allocation-free in emitter-spawn order.
// allocates its traversal stack, so retain this subset as a sorted list.
// Insertion uses a binary search followed by a linear list shift; removal
// searches and compacts linearly. Lifecycle mutations pay those costs so
// the warmed view walk stays allocation-free in emitter-spawn order.
private readonly List<int> _worldSimulationHandles = [];
private readonly SortedSet<int>[] _renderableHandlesByPass =
[[], [], []];