CNA-BUG-265: SignedInGamer::SignedIn does not replay already signed-in gamers to a late subscriber, unlike XNA 4.0

CNA snapshot 009d40f5  ·  Known Issues › Current bugs  ·  source links pinned to 009d40f5

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

XNA 4.0 raises SignedIn during Update and its add accessor replays each already signed-in gamer to a new handler; CNA raises it inside Initialize on a plain event, so a handler added afterwards never hears about the four stub gamers.

Identifier
CNA-BUG-265
Category
Bug
Subsystem
Networking & gamer services
Status
Open
Verified against
CNA 009d40f5 (009d40f5dd085c4e674d3479675fac84b12b3e0a)
Severity
Low (a triage suggestion, not a project priority)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
Microsoft::Xna::Framework::GamerServices::SignedInGamer::SignedIn (event) and GamerServicesDispatcher::Initialize/Update

Expected behaviour

In the genuine XNA 4.0 GamerServices assembly (read from its decompiled IL), sign-in changes are raised from GamerServicesDispatcher.Update, and SignedInGamer.SignedIn has a custom add accessor: after combining the delegate it loops over Gamer.SignedInGamers and invokes the newly added handler once for every gamer already signed in. The XNA documentation likewise says the event is raised during calls to Update. A game can therefore subscribe at any time and still learn who is signed in. CNA already reproduces such a replay for NetworkSession::GamerJoined, through an EventHandler replay hook, and NET.md documents that behaviour.

Actual behaviour at TARGET

SignedInGamer::SignedIn in SignedInGamer.cpp is a plain System::EventHandler with no replay hook, and GamerServicesDispatcher::Update is empty. Initialize raises OnSignIn once for each of its four stub gamers, synchronously inside the call, and a handler added afterwards is never called for them; the game must read Gamer::getSignedInGamersProperty() instead. The CNA presence demo subscribes 'before Initialize() runs so every SignedIn firing during startup is observed', and the C route cna_signed_in_gamer_subscribe_signed_in_ext adds its handler the same way. SignedOut is never raised in production, because OnSignOut has no caller outside SignedInGamerTestAccess. SignedInGamerTest.SignedInEventFires raises the event only after subscribing, so no test pins late-subscriber behaviour.

Source locations

Evidence

XNA behaviour read from the decompiled IL of the genuine XNA 4.0 GamerServices assembly (SignedInGamer.SignedIn add accessor, GamerServicesDispatcher.Update) and from the XNA documentation of the event; CNA behaviour read from the sources named. The SignedInGamer header cites FNA's plain event declaration as its model, and CLAUDE.md says matching FNA is no defence for a behaviour XNA does not have. Nothing was built or executed.

Focused reproduction

No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.

Current tests

SignedInGamerTest.SignedInEventFires raises the event only after subscribing, so no test pins the behaviour for a handler added after the gamers signed in.

Regression test

Initialize gamer services, then subscribe to SignedInGamer::SignedIn and expect the handler to be called once for every gamer already in Gamer::getSignedInGamersProperty(), as XNA's add accessor does.

Blast radius

Games that subscribe to SignedIn after gamer services were initialised (for example in LoadContent or a later screen): they never learn who is signed in unless they also read Gamer::getSignedInGamersProperty(). Games that subscribe before Initialize, as CNA's presence demo does, are unaffected.

Workaround

Subscribe before gamer services are initialised, or read Gamer::getSignedInGamersProperty() once after subscribing.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

Known issues
Bug index