From ec9fd52cb2de73324073e9d991b070887bdf9f7b Mon Sep 17 00:00:00 2001 From: Erik Date: Thu, 14 May 2026 17:12:48 +0200 Subject: [PATCH] fix #62: null-guard the PARTSDIAG read of ae.Animation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit B.4c sets Animation = null! for sequencer-driven door entities (sites at line 2867 + 7892), but the declared type is non-nullable. Today doors never enter _remoteDeadReckon (ACE doesn't send UpdatePosition for them), so the PARTSDIAG block's unguarded read is unreachable — but the moment something flips that, ACDREAM_REMOTE_VEL_DIAG=1 would NRE the tick. Local-var + is-not-null check keeps the guard scoped to this block; the legacy slerp branch downstream still treats ae.Animation as non-null per its declared type, so the flow analysis doesn't propagate nullable warnings to unrelated sites. --- src/AcDream.App/Rendering/GameWindow.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 55291ad..12b1c6c 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -7682,9 +7682,19 @@ public sealed class GameWindow : IDisposable { int seqCount = seqFrames?.Count ?? -1; int setupParts = ae.Setup.Parts.Count; - int animFrame0Parts = ae.Animation.PartFrames.Count > 0 - ? ae.Animation.PartFrames[0].Frames.Count - : -1; + // #62: B.4c introduced `Animation = null!` for sequencer-driven + // door entities (parallel branch sites at line 2867 + 7892). + // Doors don't currently enter _remoteDeadReckon, so this + // path isn't reachable for them today — but the read was + // unguarded and would NRE the moment something flips. + // Local-var + `is not null` keeps the guard scoped: the + // legacy slerp branch below treats ae.Animation as non- + // null (per its non-nullable declared type) unchanged. + var animMaybeNull = ae.Animation; + int animFrame0Parts = + animMaybeNull is not null && animMaybeNull.PartFrames.Count > 0 + ? animMaybeNull.PartFrames[0].Frames.Count + : -1; double seqHash = 0.0; if (seqFrames is not null) {