feat(runtime): FA2 -- RuntimeFellowshipState + RuntimeAllegianceState sibling J-owners
Two new sibling Runtime owners under GameRuntime per the Slice-J pattern (D2): RuntimeFellowshipState is session-scoped (a new RuntimeGenerationResetStage.Fellowship clears it at every generation reset, matching the ExternalContainer precedent); RuntimeAllegianceState survives reconnect behind a HasServerSeed-style one-way latch and participates in NO reset stage (its data persists like a real disconnect does not sever allegiance membership). Fellowship: full-update REPLACE, incremental-fellow UPSERT, self-vs- other quit/dismiss removal (self clears the whole snapshot), disband clear, and retail's leader hand-off rule for the Quit button (RequiresLeaderHandoffBeforeQuit -- the current leader quitting WITHOUT disbanding must send 0x0290 AssignNewLeader before 0x00A3, lane B §2.5/§3.6). Allegiance: seeded by AllegianceUpdate (0x0020, always self) and, self-gated on TargetGuid == playerGuid(), by AllegianceInfoResponse (0x027C); wraps the FA1-assembled flat AllegianceMemberRecord list directly (AllegianceTree was deleted at FA1 -- nothing left to wrap). Both apply the full 8-edit J-owner template: construction + fault points + Owner/View properties + CaptureOwnership + a new GameRuntimeTeardownStage pair (FellowshipDisposed/AllegianceDisposed, stage count 11->13) + RuntimeGameplayOwnershipSnapshot inclusion + RuntimeStateCheckpoint/trace fields. IRuntimeFellowshipCommands/ IRuntimeAllegianceCommands added to IGameRuntimeCommands and implemented on DirectGameRuntimeCommandAdapter. No IRuntimeEventObserver member added (D2) -- consumers poll Snapshot.Revision. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
1c40104896
commit
369729f06a
19 changed files with 1949 additions and 35 deletions
|
|
@ -19,6 +19,8 @@ public sealed class GameRuntimeTests
|
|||
Assert.Same(runtime.CharacterOwner.View, runtime.Character);
|
||||
Assert.Same(runtime.CommunicationOwner.View, runtime.Chat);
|
||||
Assert.Same(runtime.CommunicationOwner.SocialView, runtime.Social);
|
||||
Assert.Same(runtime.FellowshipOwner.View, runtime.Fellowship);
|
||||
Assert.Same(runtime.AllegianceOwner.View, runtime.Allegiance);
|
||||
Assert.Same(runtime.ActionOwner.View, runtime.Actions);
|
||||
Assert.Same(runtime.MovementOwner.View, runtime.Movement);
|
||||
Assert.Same(runtime.EnvironmentOwner, runtime.Environment);
|
||||
|
|
@ -110,6 +112,8 @@ public sealed class GameRuntimeTests
|
|||
[InlineData((int)GameRuntimeConstructionPoint.InventoryCreated)]
|
||||
[InlineData((int)GameRuntimeConstructionPoint.CharacterCreated)]
|
||||
[InlineData((int)GameRuntimeConstructionPoint.CommunicationCreated)]
|
||||
[InlineData((int)GameRuntimeConstructionPoint.FellowshipCreated)]
|
||||
[InlineData((int)GameRuntimeConstructionPoint.AllegianceCreated)]
|
||||
[InlineData((int)GameRuntimeConstructionPoint.MovementCreated)]
|
||||
[InlineData((int)GameRuntimeConstructionPoint.ActionsCreated)]
|
||||
[InlineData((int)GameRuntimeConstructionPoint.EnvironmentCreated)]
|
||||
|
|
@ -147,6 +151,10 @@ public sealed class GameRuntimeTests
|
|||
Assert.True(captured.Inventory.CaptureOwnership().IsConverged);
|
||||
if (captured.Communication is not null)
|
||||
Assert.True(captured.Communication.CaptureOwnership().IsConverged);
|
||||
if (captured.Fellowship is not null)
|
||||
Assert.True(captured.Fellowship.CaptureOwnership().IsConverged);
|
||||
if (captured.Allegiance is not null)
|
||||
Assert.True(captured.Allegiance.CaptureOwnership().IsConverged);
|
||||
if (captured.EntityObjects is not null)
|
||||
{
|
||||
Assert.True(captured.EntityObjects.CaptureOwnership().IsConverged);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue