Skip to content

fix: zone-transition latch + FCS 7.51 + Lumina 7.5 + ILRepack 2.0.45#112

Merged
logicallysynced merged 4 commits into
mainfrom
sharlayan-9-rebuild
Jun 3, 2026
Merged

fix: zone-transition latch + FCS 7.51 + Lumina 7.5 + ILRepack 2.0.45#112
logicallysynced merged 4 commits into
mainfrom
sharlayan-9-rebuild

Conversation

@logicallysynced

@logicallysynced logicallysynced commented May 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Four commits ahead of main:

This PR also clears the open Dependabot PRs (#113 Lumina, #114 ILRepack); Dependabot will auto-close both once this merges. No open Dependabot security alerts.

ILRepack 2.0.45 bump (1b6e29f)

Routine upstream patch ("Update to ILRepack 2.0.45" — no breaking changes called out). Merged DLL size unchanged at 10980 KB; all 189 tests still pass.

FCS 7.51 bump (f646a1c)

Upstream FCS landed Patch 7.51 across two commits (560ab6a07 "7.51 partial" and 2c914a526 "7.51"), bringing struct layouts in line with the new minor patch. Other notable changes pulled in:

  • 84d71d03e removed every obsolete-marker that was previously a build warning (now a compile error). Sharlayan didn't reference any of them — build clean.
  • 2e02334c7 renamed AtkValueType.String8ConstString. Not used here.
  • e391da512 fixed ExcelSheet (downstream Lumina.Excel wrapper); unrelated to Sharlayan's reflection-driven offset lookups.
  • 0e3388cae / 4535876ce / 57511682e WKS mission + module naming churn.

Other deps on NuGet are already at latest stable: Lumina 7.5.0, Lumina.Excel 7.4.3, NLog 6.1.3, Newtonsoft.Json 13.0.4.

Login-state latch fix (bd3f4e4)

FFXIV briefly zeroes the local-player slot in GameObjectManager for 1-3 reads during any zone transition (teleport, instance entry, Gold Saucer mini-game entry, etc.) while the actor table rebuilds. Reader.GetCurrentPlayer() returns Entity = null over that window, and GameStateResult.IsLoggedIn — computed inline as cp != null && cp.ID != 0u — flips false with it. Downstream consumers polling at 5 Hz (Chromatics' default) see a spurious "user on title screen" event mid-zone followed by a "user logging in" event on the next tick.

The fix is a small internal LoggedInStateLatch that caches the most recent present ActorItem and hands it back through up to N consecutive null reads, where N is configurable via SharlayanConfiguration.LoggedInLatchTicks (default 10 ≈ 1 s at 10 Hz / ≈ 2 s at 5 Hz; set to 0 to disable). A genuine logout still surfaces once the underlying read has stayed null past the threshold.

Why a tick-debounce instead of using the existing zoning signals

GameStateResult already exposes IsTeleporting and TerritoryLoadState, and at first glance gating the latch on those looks cleaner. In practice the territory-load state and the actor-table-rebuild window don't perfectly overlap — territory can be Loaded (state 2) while GameObjectManager is still half-built — and the conditions/gamemain keys aren't guaranteed to have scanned in degraded scan modes. A pure tick-based debounce is robust to scan-key availability and to whatever the actual transient window shape turns out to be on a given patch.

Public API impact

None. CurrentPlayerResult.Entity is still a (nullable) ActorItem. GameStateResult.IsLoggedIn is still a bool. IsLoggedIn inherits the fix transparently because it reads through GetCurrentPlayer(). The only new surface is SharlayanConfiguration.LoggedInLatchTicks — additive, defaulted.

Thread safety

LoggedInStateLatch uses Interlocked.Increment for the absence counter and Volatile.Read / Volatile.Write for visibility. No locks on the hot path.

Tests

10 new unit tests in LoggedInStateLatchTests cover:

  • live entity passes through unchanged
  • null before any live read surfaces as null
  • transient null window (3 ticks) returns cached entity
  • sustained absence past threshold lets null surface
  • partial absence resets the counter when live returns
  • zero-ID entity is treated as absent
  • a new live ID replaces the cache
  • threshold = 0 / negative disables the latch entirely
  • repeated zone transitions each get the full latch window

FCS / Lumina bump (58c7542)

  • FFXIVClientStructs submodule e8908dbe5 → 7fc8e99ed (20+ commits, mostly struct updates).
  • Lumina 7.4.0 → 7.5.0 (Lumina.Excel stays at 7.4.3, no new release at the time).

Version

9.0.34 → 9.0.38.

Test plan

  • dotnet build clean — 0 warnings, 0 errors.
  • dotnet test — 189 / 189 pass.
  • Debug DLLs deployed to Chromatics Build Dependencies/Sharlayan/.
  • Eye-check in-game on 7.51: zone into Gold Saucer (or any teleport) on a Chromatics-instrumented session; confirm Entity and IsLoggedIn do not flutter over the transition window.
  • Eye-check the negative case: log out via the system menu; confirm Entity and IsLoggedIn flip to absent within ~2 s at 5 Hz polling (within ~1 s at 10 Hz).
  • Harness [7] scanner diff against a 7.51 client to confirm no [StaticAddress] patterns silently drifted.

🤖 Generated with Claude Code

logicallysynced and others added 2 commits May 17, 2026 21:52
FCS pulls ~20 commits — "Update structs" ×4, AgentTryon / CharaView /
CharaViewItem updates, ShellCommandModule.EvaluateTextCommand, new
LayoutWorld.SetInteriorFixture API + supporting types
(IndoorAreaLayoutData, fixture/stains array rename), Update Format pass,
ffxiv_structimporter.py refresh.

Lumina core 7.4.0 → 7.5.0 (Lumina.Excel stays at 7.4.3, latest published).

All 179 tests pass; no integrity-test pin drift.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
FFXIV briefly zeroes the local-player slot in GameObjectManager for 1-3
reads during any zone transition (teleport, instance entry, Gold Saucer
mini-game entry, etc.) while the actor table rebuilds. Reader.GetCurrentPlayer
returns Entity=null over that window, and GameStateResult.IsLoggedIn -
computed inline as cp != null && cp.ID != 0u - flips false with it. Downstream
consumers polling at 5 Hz see a spurious "user on title screen" event mid-zone
followed by a "user logging in" event on the next tick.

Add an internal LoggedInStateLatch that caches the most recent present
ActorItem and hands it back through up to N consecutive null reads, where N
is configurable via SharlayanConfiguration.LoggedInLatchTicks (default 10,
~1s at 10 Hz / ~2s at 5 Hz; set to 0 to disable). A genuine logout still
surfaces once the underlying read has stayed null past the threshold.

Public API is unchanged - Entity stays a (nullable) ActorItem and IsLoggedIn
stays a bool. IsLoggedIn inherits the fix transparently since it reads through
GetCurrentPlayer(). Counter uses Interlocked.Increment + Volatile reads; no
locks on the hot path.

10 new unit tests in LoggedInStateLatchTests cover the transient zone-transition,
sustained-absence-then-give-up, partial-absence-resets-counter,
zero-ID-treated-as-absent, replacement-after-character-change,
threshold-disabled, and repeated-zone-transitions cases. 189 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@logicallysynced logicallysynced self-assigned this May 17, 2026
Upstream FCS landed Patch 7.51 across two commits (560ab6a07 "7.51 partial"
and 2c914a526 "7.51"), bringing struct layouts in line with the new minor
patch. Other notable changes pulled in:

- 84d71d03e removed every obsolete-marker that was previously a build warning
  (now a compile error). Sharlayan didn't reference any of them; build clean.
- 2e02334c7 renamed AtkValueType.String8 → ConstString. Not used here.
- e391da512 fixed ExcelSheet (downstream Lumina.Excel wrapper); unrelated to
  Sharlayan's reflection-driven offset lookups.
- 0e3388cae / 4535876ce / 57511682e WKS mission + module naming churn.

Other dependencies (Lumina 7.5.0, Lumina.Excel 7.4.3, NLog 6.1.3,
Newtonsoft.Json 13.0.4) are already at latest stable on NuGet — no updates
available.

Build clean, all 189 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@logicallysynced logicallysynced changed the title fix: latch CurrentPlayer.Entity across zone-transition null window + FCS/Lumina bump fix: latch CurrentPlayer.Entity across zone-transition + FCS 7.51 + Lumina 7.5 Jun 3, 2026
)

Upstream rolls up to ILRepack 2.0.45 — release notes are bare ("Update to
ILRepack 2.0.45"), no breaking changes called out. The merge target in
Sharlayan.csproj (FFXIVClientStructs + InteropGenerator.Runtime → Sharlayan.dll)
produces a byte-identical merged DLL size (10980 KB) against the prior build
and all 189 tests still pass. Closes Dependabot PR #114.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@logicallysynced logicallysynced changed the title fix: latch CurrentPlayer.Entity across zone-transition + FCS 7.51 + Lumina 7.5 fix: zone-transition latch + FCS 7.51 + Lumina 7.5 + ILRepack 2.0.45 Jun 3, 2026
@logicallysynced logicallysynced merged commit 6162361 into main Jun 3, 2026
3 checks passed
@logicallysynced logicallysynced deleted the sharlayan-9-rebuild branch June 3, 2026 23:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant