From 6222ae44febe365a6dc83ef77baf6d646f6f9cf2 Mon Sep 17 00:00:00 2001 From: "Jean-Baptiste L." Date: Fri, 1 May 2026 02:19:21 +0200 Subject: [PATCH] AdventurerPlateStep: tolerate not-yet-ready portrait texture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Run()` is called every frame while the Adventurer Plate window is open (NeedsUpdateEveryFrame returns true), but the very first frames after the window opens (and apparently on some 7.5 sessions in general) have either AgentCharaCard.Instance()->Data or its PortraitTexture pointer still null. The current code dereferences these unconditionally inside GetCurrentCharaViewImage and throws a NullReferenceException, swallowed by Dalamud's per-event error handler — the result is a flood of [ERR] log entries each frame and the step potentially completing on a frame where the plate is only partially populated. [ERR] [Auracite] Exception in event handler IFramework::Update System.NullReferenceException: Object reference not set to an instance of an object. at Auracite.AdventurerPlateStep.GetCurrentCharaViewImage() in …/AdventurerPlateStep.cs:line 106 at Auracite.AdventurerPlateStep.Run() in …/AdventurerPlateStep.cs:line 36 Walk the AgentCharaCard.Instance()->Data->PortraitTexture->D3D11Texture2D pointer chain step by step inside GetCurrentCharaViewImage, returning Image? and bailing out at the first null link. In Run(), also check storage and bail out when GetCurrentCharaViewImage returns null. The next frame retries cleanly. Once the texture is ready the existing happy-path runs unchanged and Completed fires exactly once. --- Auracite/Steps/AdventurerPlateStep.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Auracite/Steps/AdventurerPlateStep.cs b/Auracite/Steps/AdventurerPlateStep.cs index 4e24e14..67cdf14 100644 --- a/Auracite/Steps/AdventurerPlateStep.cs +++ b/Auracite/Steps/AdventurerPlateStep.cs @@ -33,7 +33,9 @@ public void Run() unsafe { var storage = AgentCharaCard.Instance()->Data; - var image = GetCurrentCharaViewImage();; + if (storage == null) return; + var image = GetCurrentCharaViewImage(); + if (image == null) return; // texture not ready yet, retry next frame var plateDesign = storage->PlateDesign; @@ -101,9 +103,16 @@ public void Run() } } - public unsafe Image GetCurrentCharaViewImage() + public unsafe Image? GetCurrentCharaViewImage() { - var texture = CppObject.FromPointer((nint)AgentCharaCard.Instance()->Data->PortraitTexture->D3D11Texture2D); + var data = AgentCharaCard.Instance()->Data; + if (data == null) return null; + var portraitTexture = data->PortraitTexture; + if (portraitTexture == null) return null; + var d3d11Texture = portraitTexture->D3D11Texture2D; + if (d3d11Texture == null) return null; + + var texture = CppObject.FromPointer((nint)d3d11Texture); var device = (Device5)(IntPtr)FFXIVClientStructs.FFXIV.Client.Graphics.Kernel.Device.Instance()->D3D11Forwarder; // Copy to a CPU-mapped staging texture