Files
realms-in-ruin-dev/Documentation/Phase2/03-SharedGameplayContracts.md
T
tedwardsandCursor c2fa15dbe3 Document Phase 2A2a shared gameplay contract proposals.
Propose ASC resource, authority, damage/death/respawn, and related contracts for owner review without approving or implementing them.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 07:51:35 -07:00

45 KiB
Raw Blame History

Phase 2A2a — Shared Gameplay Contracts

Field Value
Status Draft
Date 2026-07-17
Phase 2A2a — Shared gameplay contract proposal
Starting Git commit 9919faab
Engine Unreal Engine 5.8
Rule All contracts are Proposed. None are Approved. No implementation in this pass.

Purpose

Translate accepted Phase 1 static archaeology and Phase 2A1 runtime evidence into proposed shared gameplay contracts. These contracts define architectural boundaries for review. They do not authorize implementation, asset changes, or Phase 2B.

Evidence vocabulary

Label Meaning
Static evidence Phase 1 archaeology observation
Runtime evidence Phase 2A1 observed runtime behavior or tool limitation
Tool limitation Cannot observe because tooling/environment blocked the path
Inference Reasonable conclusion not directly proven
Recommendation Proposed architectural choice (not observed fact)
Required approval Exact question for the project owner
Deferred validation Runtime test still required before trusting the rule

Decision states used in this pass

Proposed · Alternative · Deferred · Blocked by Runtime Evidence · Blocked by Design Decision · Rejected by Existing Evidence

Do not use Approved.

Continuity

Check Result
Phase 2A1 evidence reviewed Yes — 00, 01, 02 under Documentation/Phase2/
Starting git rev-parse HEAD 9919faab4aa667cad4b4156bfa46c2d9f2113e40
Working tree at start Clean

Cross-links: 00-Phase2A-RuntimeBaseline.md, 01-Phase2A-RuntimeEvidenceIndex.md, 02-Phase2A-OpenDecisions.md, 04-Phase2A-DecisionRegister.md.


C-001 — Canonical player resource source of truth

State: Proposed

Problem being solved

Combat, death, ability costs, potions, and HUD currently read different resource stores. ASC and DEPRECATED Blueprint values diverge immediately after spawn, so UI and combat can disagree.

Current implementation

  • Player ASC + AttributeSet live on ARIRPlayerState.
  • Overlay HUD binds ASC Health/Mana.
  • Abilities and Amazonian inbound damage use DEPRECATED floats (DEPRECATED_CurrentHealth, mana costs, etc.).
  • Consumable GEs modify ASC attributes only.
  • No sync between ASC and DEPRECATED pools.

Confirmed evidence

Kind Evidence
Static Docs 05, 06 §8, 01 P0 dual-resource risk — combat uses legacy; potions/Overlay use ASC; sync Missing
Runtime RE-2A1-001/012: ASC Health 75/100, Mana 25/50, Stamina 0/0 for Amazonian and Paladin
Runtime RE-2A1-004/005: Amazonian legacy health/mana 0; stamina 85/100
Runtime RE-2A1-013: Paladin legacy Mana 100/100 vs ASC 25/50; legacy Health 0/0
Runtime RE-2A1-002/003: no active GEs; no granted GAs at spawn
Inference Amazonian AnyDamage writing legacy health=0 is at immediate death-threshold risk if that path fires

Proposed rule

ASC attributes are the sole canonical source of truth for Health, MaxHealth, Mana, MaxMana, Stamina, and MaxStamina. DEPRECATED Blueprint resource variables are not authoritative. UI, costs, healing, damage, death, and gameplay gating ultimately read the canonical ASC attributes.

Spawn divergence is treated as a confirmed dual-store defect, not two valid truths.

Allowed behavior

  • Reading ASC attributes for gameplay and UI.
  • Writing ASC attributes through shared authoritative boundaries (C-003, C-005, C-006).
  • Temporary ASC→legacy shadow copies for unconverted read-only consumers (C-004).

Prohibited behavior

  • Treating DEPRECATED floats as authoritative for new gameplay.
  • UI or death decisions driven solely by DEPRECATED values after cutover.
  • Silent acceptance of ASC/legacy disagreement as intended design.

Transitional behavior

Until each consumer is migrated, an ASC→legacy one-way shadow may keep unconverted readers consistent (C-004). Legacy writers must be migrated or blocked before they can overwrite ASC.

Dependencies

C-002 (initialization), C-003 (access boundary), C-004 (legacy policy).

Migration impact

Ability costs, Amazonian AnyDamage/death, Cleric heal, Overlay (already ASC), any remaining Server_UpdateHUD callers, future stamina systems.

Runtime validation required

  • After init policy lands: ASC and any permitted shadow values match at spawn for each playable.
  • Potion heal changes ASC and Overlay; combat damage changes ASC Health.
  • Death fires from ASC Health ≤ 0, not legacy zero alone.

Failure modes

  • Partial migration leaves one system on ASC and another on legacy → desync returns.
  • Shadow omitted while legacy death still active → false immediate death or immortal combat.

Approval question

Do you approve ASC AttributeSet as the sole canonical source of truth for Health, MaxHealth, Mana, MaxMana, Stamina, and MaxStamina, with DEPRECATED Blueprint resource variables treated as non-authoritative?


C-002 — Character default attribute initialization

State: Proposed (recommended option A)

Problem being solved

All inspected characters spawn with identical native ASC defaults. Orphan character default GEs are unreferenced. Stamina ASC remains 0/0. Missing character defaults fail silently via native Init*, producing incorrect balance and hiding misconfiguration.

Current implementation

  • URIRAttributeSet ctor: InitHealth(75), InitMaxHealth(100), InitMana(25), InitMaxMana(50); Stamina/MaxStamina not Init'd.
  • BP_PlayerState.DefaultAttributesGameplayEffect = None.
  • Orphan GEs (GE_*_DefaultAttributes) exist per character but have 0 referencers and do not modify Max* attributes.
  • Legacy CDO defaults differ per character (Amazonian stamina 85/100; Paladin mana 100/100; both health 0).

Confirmed evidence

Kind Evidence
Static Doc 06 §§24 — orphan default GEs; native Init fallback; Max* absent on default GEs
Runtime RE-2A1-001/012 — ASC identical for Amazonian and Paladin
Runtime RE-2A1-002 — no active default GE at spawn
Runtime RE-2A1-011 — CDO explains legacy zeros / character-specific legacy stamina/mana
Tool limitation N/A for spawn values (observed)

Options compared

Option Description Fit to evidence
A. Character-specific default GE Pawn/class selects a default GE; server applies after ASC actor info valid Best fit — assets and DefaultAttributesGameplayEffect property already exist
B. Shared init GE + SetByCaller One GE; magnitudes passed per class Viable; fewer assets; more native glue
C. Native initialization service Explicit server service sets all six attrs Viable; strongest fail-visible control; bypasses existing GE assets
D. Other e.g. hybrid GE for currents + native Max* Possible but adds dual paths

Proposed rule (Recommendation: Option A)

Character defaults are applied on the authoritative server only after ASC OwnerActor/AvatarActor are valid. Every character receives explicit current and maximum Health, Mana, and Stamina. Stamina may not rely on an uninitialized native default. Initialization must be deterministic on initial spawn and respawn. A missing character default assignment must fail visibly (log/assert/fatal in development) rather than silently falling back to identical native Init* values.

Existing orphan GEs must be completed (including MaxHealth/MaxMana/MaxStamina) before they are treated as production defaults. Incomplete GEs are migration work, not a license to keep silent Init*.

Alternatives retained: B, C (Proposed alternatives, not rejected).

Allowed behavior

  • Server ApplyGameplayEffect of character default GE after InitAbilityActorInfo.
  • Explicit Max* and current values in that GE (or immediate companion apply).
  • Visible failure when class data / GE assignment is missing.

Prohibited behavior

  • Silent native-only fallback that leaves all classes at 75/100/25/50/0/0.
  • Client-authoritative default attribute application.
  • Relying on uninitialized Stamina ASC as “zero by design” without an explicit assignment.

Transitional behavior

Until GEs are completed, temporary use of Option C for Max* fill is acceptable only if documented as transitional and still fails visibly when class data is missing.

Dependencies

C-001, C-012 (ASC on PlayerState / re-init on possess).

Migration impact

ARIRPlayerState, character class data, orphan GE_*_DefaultAttributes, spawn and respawn paths, Gunslinger (no GE today).

Runtime validation required

  • Per playable: ASC currents and maxes match class policy after spawn and after respawn.
  • Missing GE assignment produces a visible error in a controlled test.
  • No active unintended GEs beyond the intended default apply.

Failure modes

  • GE overrides current without Max* → clamps/UI break.
  • Apply before actor info valid → no-op or wrong Owner.
  • Respawn skips reapply → stale or zeroed attributes.

Approval question

Do you approve Option A (character-specific default Gameplay Effect applied server-side after ASC actor info is valid), with visible failure on missing assignment and mandatory explicit current+max Health/Mana/Stamina?


C-003 — Resource-access boundary

State: Proposed

Problem being solved

Gameplay mutates resources through ad-hoc Blueprint variables, FCanUseMana, ApplyDamage, and GEs without a single authoritative interface. Incremental migration risks two authoritative stores.

Current implementation

  • Ability graphs read/write DEPRECATED mana/health/damage floats.
  • Potions apply ASC GEs via EffectActor.
  • Overlay reads ASC.
  • No shared resource API above ASC for costs/affordability.

Confirmed evidence

Kind Evidence
Static Docs 05 resource inventory; 06 legacy/GAS boundary; 07 S9
Runtime RE-2A1-001005, 012013 — dual values at spawn
Runtime Ability cost mutation path not exercised (RE-2A1-015/019/021 Tool Limitation)

Proposed rule

New gameplay may not directly read or write DEPRECATED resource variables. Resource reads, affordability checks, costs, restoration, and maximum-value queries use a shared authoritative interface that operates on ASC attributes. Cost validation and mutation occur atomically on the server.

Allowed behavior

  • Server: check affordability → commit cost → proceed, or fail without partial mutation.
  • Reads of current/max via the shared interface.
  • Migrated abilities calling the interface instead of DEPRECATED floats.

Prohibited behavior

  • New code writing DEPRECATED resource vars as authority.
  • Client-side cost commitment.
  • Dual-write of ASC and DEPRECATED as both authoritative.

Transitional behavior

Migrate each dependent path to the interface before that path is considered converted. Until conversion, that path may still touch DEPRECATED vars under C-004 constraints, but must not invent a second ASC writer. Prefer converting cost/death/heal writers first.

Dependencies

C-001, C-002, C-004, C-006.

Migration impact

FCanUseMana, all DEPRECATED_*ManaCost call sites, RecoverPlayerHealth, Amazonian AnyDamage, future GA costs.

Runtime validation required

  • Ability cost reduces ASC Mana once; Overlay updates; legacy shadow (if present) matches.
  • Failed affordability leaves attributes unchanged.

Failure modes

  • Interface bypass leaves stray DEPRECATED writers.
  • Non-atomic check-then-spend races under replication.

Approval question

Do you approve a shared server-authoritative ASC resource interface as the only allowed read/write path for new gameplay resource access, with atomic cost validation and mutation?


C-004 — Legacy compatibility policy

State: Proposed (recommended option C; bidirectional Rejected by Existing Evidence)

Problem being solved

Unconverted legacy readers still exist while ASC is becoming canonical. Bidirectional sync would create competing writers and feedback loops. Legacy writers must not silently overwrite ASC.

Current implementation

No sync code. ASC and DEPRECATED diverge at spawn. Overlay uses ASC; combat vars use legacy.

Confirmed evidence

Kind Evidence
Static Doc 06 — legacy-resource synchronization Missing
Runtime RE-2A1-004/005/013 — divergent spawn values
Inference Bidirectional sync with Amazonian health=0 and ASC=75 would create writer conflict

Options evaluated

Option Verdict
A. Bidirectional synchronization Rejected by Existing Evidence — competing writers; feedback-loop risk
B. Legacy→ASC synchronization Rejected as primary policy — would promote non-authoritative / zeroed legacy into ASC
C. ASC→legacy one-way shadow Recommended (Proposed) for temporary unconverted read-only consumers
D. No synchronization; migrate each path before use Preferred when a path can cut over in one change; compatible with C

Proposed rule

Temporary one-way ASC→legacy compatibility shadows are allowed only where an unconverted read-only consumer still requires DEPRECATED floats. Legacy direct writers must not silently overwrite canonical ASC values. Prefer Option D cutover when feasible. Bidirectional sync is prohibited.

Allowed behavior

  • After ASC mutation, optionally push values into DEPRECATED vars for legacy UI/gates not yet migrated.
  • Document each shadow consumer and remove it when migrated.

Prohibited behavior

  • Bidirectional sync.
  • Legacy AnyDamage / cost writers updating ASC without going through C-003/C-005/C-006.
  • Indefinite shadow without a migration owner.

Transitional behavior

Shadow is temporary scaffolding during reconstruction. Each shadowed consumer must be listed and retired.

Dependencies

C-001, C-003.

Migration impact

Amazonian AnyDamage, FCanUseMana readers, Server_UpdateHUD callers, any BP reading DEPRECATED health/mana.

Runtime validation required

  • With shadow on: after ASC heal/damage, shadowed legacy matches ASC.
  • Legacy writer attempt cannot change ASC without shared boundary.

Failure modes

  • Forgotten shadow → legacy death on zero.
  • Accidental reverse write → ASC corrupted.

Approval question

Do you approve ASC→legacy one-way shadow only for temporary read-only consumers, with bidirectional sync prohibited and legacy writers forbidden from silently overwriting ASC?


C-005 — Damage contract

State: Proposed (ExecutionCalculation design Deferred)

Problem being solved

Player damage uses ApplyDamage into legacy health (Amazonian) or has no enemy consumer. Potions use ASC GEs. There is no single server entry for validated damage.

Current implementation

  • Paladin/Amazonian/Cleric UseAbility* / ChargeBox: Authority ApplyDamage.
  • Amazonian ReceiveAnyDamage subtracts DEPRECATED_CurrentHealth.
  • Enemy: no ReceiveAnyDamage / health mutation (Implementation Missing).
  • No project GameplayEffectExecutionCalculation subclasses.

Confirmed evidence

Kind Evidence
Static Docs 05, 09, 06 — ApplyDamage vs missing enemy reception; ASC Health unbridged
Runtime RE-2A1-022 — player damage/death path blocked (enemy attack Missing; ability input Tool Limitation)
Runtime RE-2A1-027/030 — enemy components present; damage reception not observed

Proposed rule

One server-authoritative damage entry boundary for player and enemy targets:

Step Owner
Who may request damage Abilities, overlaps, environmental actors, future AI — as requests only
Who validates Server damage boundary
Target validity Server (alive, damageable, team/filter rules)
Magnitude calculation Server (data asset / ability / curve — implementation later)
Mitigation Server (block/armor tags — design later)
Health change Server writes ASC Health via shared resource path
Instigator / causer Recorded on the authoritative damage event
Duplicate prevention Server dedupe (e.g. ability instance / window / hit ID)
Death evaluation Trigger C-007 after Health change
Legacy ApplyDamage Transitional adapter into this boundary; not a second SoT

Not chosen now: final GameplayEffectExecutionCalculation design. Retained as Alternative for later approval if GAS execution is preferred after 2B.

Allowed behavior

  • Server-only Health reduction through the boundary.
  • Transitional ApplyDamage → adapter → ASC.
  • Presentation multicast after authoritative apply.

Prohibited behavior

  • Client-authoritative Health writes.
  • AnimNotify as sole damage authority without server validation (see C-009/C-010).
  • Damage that mutates only DEPRECATED health after cutover.

Transitional behavior

Keep Authority-gated UseAbility ApplyDamage call sites temporarily, but route Health mutation into ASC via adapter. Enemy reception remains blocked until Phase 2D implements the consumer under this contract.

Dependencies

C-001, C-003, C-007, C-009. Enemy consumers: Phase 2D.

Migration impact

All ApplyDamage call sites; Amazonian AnyDamage; future enemy inbound damage; block absorb design (Paladin 002).

Runtime validation required

  • Controlled damage reduces ASC Health once; Overlay updates; no double apply.
  • Death triggers at ASC ≤ 0.
  • Blocked today: ability-driven and enemy-driven damage (Tool Limitation / Missing Implementation).

Failure modes

  • Adapter forgotten → legacy and ASC diverge again.
  • No dedupe → double hits from multicast notifies.

Approval question

Do you approve a single server-authoritative damage entry that writes ASC Health, with legacy ApplyDamage limited to a transitional adapter, and ExecutionCalculation design deferred?


C-006 — Healing and resource restoration contract

State: Proposed

Problem being solved

Healing exists as Cleric RecoverPlayerHealth (legacy) and consumable GEs (ASC). No shared clamp/attribution policy.

Current implementation

  • Cleric UseAbility002: Authority heal via DEPRECATED recover interface.
  • Potions/food: GE Instant/Duration on ASC Health/Mana.
  • No AttributeSet PostGameplayEffectExecute clamp-to-max.

Confirmed evidence

Kind Evidence
Static Docs 05 Cleric 002; 06 GE inventory; 12 pickups
Runtime RE-2A1-018 — consumable overlap not executed (movement/input blocked)
Runtime ASC MaxHealth/MaxMana exist; Overlay binds them

Proposed rule

  • Restoration is server-authoritative.
  • Values clamp to the attributes Max* unless an approved GE explicitly documents over-resource permission.
  • Source attribution recorded (instigator, GE class, ability ID).
  • Gameplay Effects and shared restore services both enter the same resource boundary (C-003).
  • UI updates only by observing replicated ASC changes.
  • Overheal / over-mana / over-stamina not permitted by default.
  • Consumables use the same boundary (apply GE or service on server).

Allowed behavior

  • Server GE heal/mana restore; shared RestoreResource API; clamp to max.
  • Cosmetic feedback after authoritative change.

Prohibited behavior

  • Client-side Health/Mana increases.
  • Unclamped restores that leave Current > Max without explicit approval.
  • Healing only DEPRECATED health while ASC remains unchanged.

Transitional behavior

Cleric recover path adapts to ASC via C-003; potions already on ASC remain preferred pattern.

Dependencies

C-001, C-003, C-014 (pickup apply).

Migration impact

Cleric 002, EffectActor GEs, any DEPRECATED recover paths, future HoT/MoT.

Runtime validation required

  • Heal at full Health does not exceed MaxHealth.
  • Potion +25 Health updates ASC and Overlay once.
  • Blocked today: pickup overlap apply (RE-2A1-018).

Failure modes

  • Dual heal systems → Overlay shows ASC heal while combat uses legacy.
  • Missing clamp → invalid Current > Max.

Approval question

Do you approve server-authoritative restoration through the shared ASC resource boundary, clamping to Max by default, with consumables and ability heals using the same path?*


C-007 — Death contract

State: Proposed

Problem being solved

Death is evaluated from DEPRECATED health on Amazonian; ASC Health is unused for death. Animation can force enemy IsDead false. No idempotent shared death transition.

Current implementation

  • Amazonian: AnyDamage → subtract DEPRECATED_CurrentHealth → PlayerDeath if ≤ 0.
  • Base: PlayerDeath / Client_PlayerDeath / IsDead replicated bool.
  • Enemy ABP forces IsDead false every update; no damage reception.
  • State.Dead tag Present but Unreferenced.

Confirmed evidence

Kind Evidence
Static Docs 05 Amazonian death; 09 enemy death incomplete; 10 ABP death states
Runtime RE-2A1-006 — IsDead false at spawn
Runtime RE-2A1-004/013 — legacy health 0 at spawn (death-threshold risk if AnyDamage fires)
Runtime RE-2A1-022 — death/respawn not observed

Proposed rule

  • Death is evaluated from canonical ASC Health.
  • Health ≤ 0 is evaluated authoritatively on the server.
  • Death transition is idempotent — a player or enemy cannot execute the death transition twice.
  • Dead state is replicated.
  • Movement, abilities, collision, animation, and interaction respond to one shared death state.
  • Animation does not own the authoritative death decision.

Player vs enemy separation: same Health≤0 evaluation and idempotent dead state; players proceed to C-008 respawn; enemies proceed to destroy/loot/presentation policy (Phase 2D) without player respawn.

Allowed behavior

  • Server sets replicated dead state once; cancels abilities; disables input/movement as configured.
  • ABP reads replicated dead state for Death animation only.

Prohibited behavior

  • AnimBP forcing alive over authoritative dead state.
  • Death decided solely from DEPRECATED health after cutover.
  • Re-entrant PlayerDeath without guard.

Transitional behavior

Until Amazonian AnyDamage is migrated, treat legacy≤0 as transitional trigger that must also drive ASC Health to 0 / call the shared death entry — not a second SoT.

Dependencies

C-001, C-005, C-008 (players), C-011 (ability cancel on death).

Migration impact

Amazonian AnyDamage, PlayerDeath, enemy death ABP, future tags (State.Dead).

Runtime validation required

  • Damage to ASC 0 triggers death once; second damage does not re-enter.
  • ABP plays death from replicated state.
  • Blocked today: RT-006 (RE-2A1-022).

Failure modes

  • Legacy health 0 at spawn + AnyDamage → instant death while Overlay shows 75.
  • Enemy ABP clears IsDead → corpse walks.

Approval question

Do you approve authoritative, idempotent death evaluated from ASC Health ≤ 0, with animation as presentation-only and player/enemy differing only in post-death lifecycle?


C-008 — Respawn contract

State: Proposed

Problem being solved

Respawn/HUD recreation paths exist but are unverified. Risk of dying pawn owning its replacement, duplicate overlays, stale widgets, and skipped ASC re-init.

Current implementation

  • Server_RespawnPlayer / PlayerRespawn SpawnActor+Possess paths on base / PC / GM.
  • Overlay created from InitAbilityActorInfo when local HUD present.
  • Char-select PlayerFirstSpawn emits Accessed None warning but still spawns (RE-2A1-010).

Confirmed evidence

Kind Evidence
Static Docs 07 S8; 11 spawn/respawn; 03 PC_Character
Runtime RE-2A1-010 — PlayerFirstSpawn Accessed None; spawn still succeeds
Runtime RE-2A1-022 — respawn not observed (RT-006 blocked)

Proposed rule

  • GameMode and PlayerController own the server-side respawn request and timing. The destroyed/dying pawn must not be the sole authority that initiates its replacement.
  • Ordering: mark dead → cancel abilities (C-011) → schedule respawn delay → destroy or detach old pawn → spawn replacement → re-Init ASC OwnerActor/AvatarActor → reapply character defaults (C-002) → Possess → restore input → idempotent HUD bind (C-013).
  • PlayerState persists across pawn replacement.
  • Duplicate-respawn prevention: ignore respawn requests while already pending or while not dead.

Allowed behavior

  • Server GM/PC timer-driven respawn.
  • Reuse PlayerState ASC; refresh Avatar to new pawn.

Prohibited behavior

  • Client-authoritative respawn.
  • Multiple concurrent respawn schedules for one player.
  • Skipping default attribute reapplication.

Transitional behavior

Existing Server_RespawnPlayer on the pawn may forward a request to PC/GM but must not unilaterally complete the lifecycle without GM/PC ownership.

Dependencies

C-002, C-007, C-012, C-013.

Migration impact

BP_PlayerCharacterBase death/respawn, PC_Character, GM_Dungeoneer, HUD InitOverlay.

Runtime validation required

  • One death → one respawn; ASC defaults restored; Overlay instance count stable; input restored.
  • Blocked today: RE-2A1-022.

Failure modes

  • Double Overlay; stale widget bound to destroyed pawn; ASC Avatar still old pawn; spawn warning becomes hard failure.

Approval question

Do you approve GameMode + PlayerController ownership of server respawn lifecycle (pawn must not solely replace itself), including ASC re-init, default reapplication, possession, input restore, and idempotent HUD bind?


C-009 — Authority contract

State: Proposed

Problem being solved

Legacy gameplay timing depends on Multicast montage AnimNotify evaluation. Interrupt and server/client notify roles are unverified. Clients must submit intent only.

Current implementation

Input → Server_Ability_* → Multicast_PlayMontage → AnimNotify → UseAbility* (Authority gate) / SetIsAttacking

Montage OnCompleted/OnBlendOut/OnInterrupted pins unwired. Cleanup often via AN_AttackComplete.

Confirmed evidence

Kind Evidence
Static Docs 05, 10 — notify-driven gameplay; Authority Switch inside UseAbility*; Networking Risk
Runtime RE-2A1-015/019/021 — ability chain not executed (Enhanced Input Tool Limitation)
Runtime RE-2A1-023026 — two-client replication not run

Proposed rule

  • Clients submit intent.
  • Server validates state, target, resource cost, cooldown, and gameplay result.
  • Multicast events are presentation-only unless a narrowly documented exception is later approved.
  • Client or multicast animation evaluation cannot be the sole authority for damage, healing, spawning, costs, or state transitions.
  • Replicated state is written only by its authoritative owner.

Allowed behavior

  • Server RPC intent → server commit → replicate state → multicast montage/SFX/VFX.
  • Server-owned timing windows that correlate with animation (C-010) without requiring notify-as-authority.

Prohibited behavior

  • Gameplay results that only occur if a multicast notify runs.
  • Client writing Health/Mana/IsDead/CurrentlyAttacking as authority.

Transitional behavior

Legacy notify→UseAbility Authority bodies may remain temporarily but must be treated as technical debt. Migration moves hit commit to server Ability Tasks / validated windows. Document each remaining notify gameplay call site.

Dependencies

C-003, C-005, C-006, C-010, C-011.

Migration impact

All Server_Ability / Multicast_PlayMontage / AN_Ability_* paths; Phase 2B framework.

Runtime validation required

  • Listen-server + client: damage once on server; montage on both; no client-only Health change.
  • Blocked today: Enhanced Input + multi-client PIE (RE-2A1-015, 023).

Failure modes

  • Server skips montage evaluation → missed hits under legacy design.
  • Interrupt skips AN_AttackComplete → stuck CurrentlyAttacking.

Approval question

Do you approve client-intent / server-validation authority, with multicast limited to presentation, and AnimNotify forbidden as sole authority for damage, costs, or state transitions?


C-010 — Animation responsibility contract

State: Proposed

Problem being solved

Animation currently gates hit windows and attack lockout cleanup. Need a clear cosmetic vs authoritative split while preserving timing feel.

Current implementation

AN_Ability_* triggers UseAbility*; AN_AttackComplete clears CurrentlyAttacking; ABPs read IsDead/IsBlocking/etc. for presentation.

Confirmed evidence

Kind Evidence
Static Doc 10 shared animation→ability architecture
Runtime Notify chain not exercised (RE-2A1-019/021)

Proposed rule

Animation may own:

  • Visual playback
  • Sound timing
  • Cosmetic Niagara timing
  • Camera presentation
  • Cosmetic weapon-trail windows

Animation may not solely own:

  • Authoritative damage
  • Cost commitment
  • Target validation
  • Death
  • Respawn
  • Guaranteed ability cleanup

Timing correlation: Server (or server Ability Task) may open/close validated hit windows using durations/sections that match montage timing. Cosmetic notifies may fire predicted VFX. Authoritative commit remains server-side even if a notify is skipped.

Allowed behavior

  • Montage playback from server-triggered multicast.
  • Cosmetic notifies.
  • Server tasks waiting on montage events as hints with failsafe timeouts (C-011).

Prohibited behavior

  • Sole reliance on AN_AttackComplete for cleanup.
  • Damage that only applies inside a multicast notify without prior/server validation path.

Transitional behavior

Existing notify gameplay remains until Phase 2B replaces it under C-009/C-011.

Dependencies

C-009, C-011, C-007.

Migration impact

AN_Ability_001004, AN_AttackComplete, Multicast_PlayMontage pins, character ABPs.

Runtime validation required

  • Interrupt mid-montage still cleans ability state without AN_AttackComplete.
  • Blocked today: RE-2A1-020.

Failure modes

  • Cosmetic-only migration that still requires notify for damage.
  • Desynced VFX vs server hit window (acceptable if documented; damage must still be correct).

Approval question

Do you approve animation as cosmetic-only for authority purposes, with server-owned timing correlation allowed, and notify-driven authoritative gameplay prohibited as the end state?


C-011 — Ability lifecycle and cleanup contract

State: Proposed

Problem being solved

Most Server_Ability_*_End bodies are empty. Cleanup depends on AN_AttackComplete. Interrupt may leave CurrentlyAttacking stuck.

Current implementation

Gates on CurrentlyAttacking/IsDead; Ends mostly empty; AN_AttackComplete clears attacking; montage interrupt pins unwired.

Confirmed evidence

Kind Evidence
Static Docs 05, 07 S3/S12, 10
Runtime RE-2A1-020 — interrupt test blocked

Proposed rule

Shared lifecycle states:

Requested → Validated → Committed → Active → Ending → Completed | Canceled | Interrupted | Failed

Event Required behavior
Resource commitment On Validated→Committed; atomic (C-003)
Cooldown commitment On Commit (when cooldowns exist)
Montage start failure → Failed; release commit if policy requires; clear attacking
Normal completion → Completed; clear locks; EndAbility equivalent
Input release Route to Ending/Canceled per ability policy
Interruption → Interrupted; guaranteed cleanup without AN_AttackComplete
Death during ability Cancel → Interrupted/Canceled; C-007
Pawn destruction Force cleanup; no dangling timers
Target invalidation End or fail per ability; no further damage commits
Timeout / failsafe Absolute cleanup timer independent of montage

No ability may depend solely on AN_AttackComplete for guaranteed state cleanup.

Allowed behavior

  • Explicit EndAbility / cancel tags / Ability Task end states.
  • Failsafe timers.

Prohibited behavior

  • Cleanup only via montage end notify.
  • Leaving CurrentlyAttacking true after interrupt/death.

Transitional behavior

Wire montage OnInterrupted/OnBlendOut or native failsafe while notifies remain.

Dependencies

C-003, C-007, C-008, C-009, C-010.

Migration impact

All playable ability Begin/End/UseAbility paths; Phase 2B shared framework.

Runtime validation required

  • Full montage: lockout clears.
  • Interrupt: lockout clears without AN_AttackComplete.
  • Death mid-ability: cleanup + no further damage.
  • Blocked today: RE-2A1-019022.

Failure modes

  • Stuck attack lockout; orphan timers; double cost on retry.

Approval question

Do you approve the shared ability lifecycle states and the rule that cleanup must be guaranteed without sole dependence on AN_AttackComplete?


C-012 — PlayerState and pawn ownership contract

State: Proposed

Problem being solved

Need clear persistent vs transient ownership across respawn. Enemy ASC ownership differs and GetASC via PlayerState returns nullptr for enemies.

Current implementation

  • Players: ASC + AttributeSet on ARIRPlayerState; InitAbilityActorInfo Owner=PS, Avatar=Character on PossessedBy / OnRep_PlayerState.
  • Enemies: ASC on self; InitAbilityActorInfo(this,this); interface GetASC → PlayerState → nullptr.

Confirmed evidence

Kind Evidence
Static Doc 06 ownership detail; 09 enemy GetASC defect
Runtime RE-2A1-007 — PS ASC; pawn query resolves same set
Runtime RE-2A1-027/028 — enemy ASC components present; inspector rejects actor (Tool Limitation / possible init gap)

Proposed rule

PlayerState owns:

  • Persistent player ASC
  • Persistent AttributeSet
  • Cross-pawn player state intended to survive respawn

Pawn owns:

  • Avatar representation
  • Movement
  • Equipment components
  • Transient physical state
  • Animation
  • Pawn-specific targeting and presentation

On possession / pawn replacement: re-InitAbilityActorInfo; bind Overlay if local; teardown transient pawn state on old pawn. Enemies keep self-owned ASC with a separate init/accessor contract (fix GetASC for non-PlayerState owners in Phase 2D/2E).

Allowed behavior

  • Cache ASC pointer on pawn from PlayerState.
  • Persistent attributes survive pawn destroy.

Prohibited behavior

  • Moving player ASC to pawn without an approved redesign.
  • Expecting enemy GetASC-via-PlayerState to succeed.

Transitional behavior

Keep current player PS ownership. Document enemy accessor as Existing Baseline Defect until fixed under this contracts enemy clause.

Dependencies

C-002, C-008, C-013.

Migration impact

ARIRPlayerCharacter, ARIRPlayerState, enemy GetASC, EffectActor targeting.

Runtime validation required

  • After respawn: OwnerActor still PlayerState; Avatar is new pawn; attributes persist then defaults reapplied per C-002.
  • Enemy ASC readable via corrected accessor (deferred).
  • Tool inaccessibility ≠ runtime absence (RE-2A1-028).

Failure modes

  • Avatar not updated → abilities target wrong actor.
  • Enemy potions destroy without apply (nullptr ASC).

Approval question

Do you approve keeping player ASC/AttributeSet on PlayerState with pawn as Avatar only, and treating enemy self-ASC as a separate ownership/init contract?


C-013 — HUD data-flow contract

State: Proposed

Problem being solved

Dual HUD paths: Overlay (ASC) works structurally; legacy UpdatePlayerHUD unimplemented. Respawn may recreate overlays. Stamina UI missing.

Current implementation

  • ARIRHUD::InitOverlay → OverlayWidgetController → Health/Mana bars.
  • Server_UpdateHUDUpdatePlayerHUD unimplemented on PC.
  • No stamina widget.

Confirmed evidence

Kind Evidence
Static Docs 11, 06, 07 S10
Runtime RE-2A1-008/009 — Overlay bars present; WBP_PlayerHUD spawned; no stamina widget
Runtime Respawn Overlay duplication not observed (RT-006 blocked)

Proposed rule

  • Gameplay HUD reads ASC attributes through the Overlay / widget-controller path.
  • Legacy UpdatePlayerHUD route is retired (remove or leave dead; do not implement as second SoT).
  • No UI independently stores authoritative resources.
  • HUD creation is idempotent.
  • Respawn and travel must not create duplicate overlays.
  • Stamina presentation is added only after C-001/C-002 are approved.
  • UI reflects replicated authoritative state and does not drive gameplay state.

Allowed behavior

  • Rebind existing Overlay to new pawn/ASC avatar on respawn.
  • Progress bars from attribute delegates.

Prohibited behavior

  • Implementing UpdatePlayerHUD as a parallel authoritative HUD.
  • UI writing Health/Mana.
  • Unconditional InitOverlay without duplicate guard.

Transitional behavior

Leave unimplemented UpdatePlayerHUD as dead code until removal; do not repair it.

Dependencies

C-001, C-002, C-008, C-012.

Migration impact

RIRHUD, Overlay widgets, BPI_PlayerController UpdatePlayerHUD, Server_UpdateHUD callers.

Runtime validation required

  • One Overlay after spawn and after respawn.
  • Bars track ASC only.
  • Blocked: respawn path (RE-2A1-022).

Failure modes

  • Duplicate overlays; stale bar bound to destroyed pawn; stamina UI before SoT approval.

Approval question

Do you approve Overlay/widget-controller as the sole gameplay HUD data path, retirement of UpdatePlayerHUD, idempotent HUD creation, and deferred stamina UI until attribute contracts are approved?


C-014 — Pickup authority and replication contract

State: Proposed

Problem being solved

EffectActor pickups have no authority gate and bReplicates=false, risking desync and duplicate apply. Overlap apply not runtime-proven.

Current implementation

Overlap → ApplyEffectToTarget → DestroyActor; no SwitchHasAuthority; bReplicates=false; destroy even if ASC null.

Confirmed evidence

Kind Evidence
Static Doc 12 Authority Risk matrix
Runtime RE-2A1-017 — HealthPotion bReplicates=false
Runtime RE-2A1-016 — pickups present in Test01
Runtime RE-2A1-018 — overlap/GE apply not executed

Proposed rule

  • Server owns overlap validation.
  • Server applies the effect or mutation.
  • Server destroys or deactivates the pickup.
  • All clients receive a consistent pickup-existence state.
  • A pickup applies at most once per valid collection.
  • Cosmetic presentation may occur on clients after authoritative collection.
  • Non-replicated pickups must not be used for network gameplay without an explicit server-owned spawning/visibility model.

Allowed behavior

  • Replicated pickup actors; server authority gate; server GE apply; server destroy.
  • SP prototype with documented non-replicated model only if never used in MP as-is.

Prohibited behavior

  • Client-only destroy/apply for MP pickups.
  • Relying on bReplicates=false EffectActors for listen-server gameplay.

Transitional behavior

SP Test01 may keep current actors until 2E reconstruction, but they are classified Authority Risk and must not be treated as MP-correct.

Dependencies

C-003, C-006, C-012 (GetASC for enemies).

Migration impact

Four EffectActor pickups; gold path (separate AddGold defect); Phase 2E.

Runtime validation required

  • Server apply once; ASC changes; actor gone on all clients.
  • Blocked today: movement/input and 2P (RE-2A1-018, 023, 026).

Failure modes

  • Double GE apply; client destroy without server apply; enemy touch destroys without heal.

Approval question

Do you approve server-owned pickup validation/apply/destroy with replicated existence, at-most-once collection, and a ban on non-replicated pickups for network gameplay without an explicit server visibility model?


C-015 — Runtime observability contract

State: Proposed

Problem being solved

Reconstruction needs inspectable evidence. Phase 2A1 showed tool gaps (Enhanced Input, multi-client, enemy ASC inspector). Observability must be defined without requiring permanent debug UI yet.

Current implementation

Ad-hoc MCP/ObjectTools/AbilitySystemInspector during Phase 2A1; no project harness.

Confirmed evidence

Kind Evidence
Runtime Tool limitations RE-2A1-015, 023, 028, 031
Inference Without logs/harness, C-005C-011/C-014 cannot close

Proposed rule

Before reconstruction claims are trusted, the following must be inspectable via logs, debugger, Ability System inspection, or a future temporary test harness:

  • Character identity
  • ASC OwnerActor and AvatarActor
  • Current/max attributes
  • Active Gameplay Effects
  • Granted abilities
  • Ability lifecycle state
  • Authoritative damage events
  • Death transitions
  • Respawn transitions
  • Pickup application count
  • Network role

Permanent debug UI is not required yet.

Allowed behavior

  • Structured log categories; temporary console/cheats in development builds; automation hooks.

Prohibited behavior

  • Treating tool inaccessibility as proof of runtime absence.
  • Shipping permanent debug HUD as a substitute for contracts.

Transitional behavior

Use manual PIE + logging until harness exists; environment decisions for 2-client PIE and Enhanced Input remain open (see 02).

Dependencies

All contracts for validation; harness work may be Phase 2A3 planning.

Migration impact

Logging helpers; future test harness; no gameplay SoT change.

Runtime validation required

  • Each listed field obtainable in a controlled session for player pawn; enemy attributes once accessor fixed.

Failure modes

  • False “missing ASC” from inspector limits; unverifiable MP claims.

Approval question

Do you approve the minimum observability list above as a prerequisite for trusting reconstruction, without requiring permanent debug UI yet?


Architectural recommendation summary

ASC attributes on PlayerState are the sole resource SoT. Character default GEs initialize explicit current+max H/M/S on the server after actor info is valid. All gameplay resource mutation flows through a shared server interface. Damage and healing write ASC through one authoritative boundary. Death evaluates ASC Health ≤ 0 idempotently. GameMode/PC own respawn. HUD reads Overlay/ASC only. Abilities use client intent → server validate → presentation multicast, with server-owned lifecycle/cleanup. Enemies and pickups consume the same damage/resource rules under later phases.

2. Transitional architecture

  • ASC→legacy one-way shadow for unconverted read-only consumers.
  • ApplyDamage adapter into ASC damage boundary.
  • Notify-timed UseAbility retained as debt until Ability Tasks / validated windows.
  • SP non-replicated pickups tolerated only as known Authority Risk until 2E.

3. Prohibited transitional patterns

  • Bidirectional ASC↔legacy sync
  • Legacy writers silently overwriting ASC
  • Multicast AnimNotify as sole gameplay authority
  • Silent native Init* fallback hiding missing character defaults
  • Non-replicated pickups used as-is for network gameplay
  • Implementing UpdatePlayerHUD as a second resource SoT
  • Treating tool limitation as runtime absence

4. Decisions requiring owner approval

All C-001 through C-015 approval questions above. None are Approved in this pass.

5. Decisions blocked by runtime evidence

Area Blocking evidence Related contracts
Enhanced Input ability execution RE-2A1-015/019/021 C-009, C-010, C-011
AnimNotify authority roles Not observed C-009, C-010
Ability cost mutation Not observed; Ability004 cost CDO=0 C-003, C-004
Ability interruption RE-2A1-020 C-011
Player damage/death/respawn RE-2A1-022 C-005, C-007, C-008
Two-client replication RE-2A1-023026 C-009, C-014
Remote character selection Not run (needs 2P) C-008 related / 2E
Pickup authority and visibility RE-2A1-018 C-014
Enemy attribute mutation RE-2A1-028/030 C-005, C-012
Session behavior Deferred to 2E; not in 2A1 matrices Outside 2A2a contracts

6. Phase 2A3 implementation-planning prerequisites

  1. Owner review of Proposed contracts (still no Approved stamp until explicitly granted).
  2. Plan for remaining blocked runtime evidence (input harness, 2-client PIE authorization, controlled damage actor if approved).
  3. Migration sequencing: C-001/C-002/C-003/C-004 → C-005/C-006/C-007 → C-008/C-013 → C-009C-011 → C-014 with 2E.
  4. Observability harness outline per C-015.
  5. Explicit non-goals: no Phase 2B ability rewrite; no Unreal edits in 2A2a.

Dependency diagram

flowchart TD
  attrs[CanonicalAttributes_C001_C002]
  resource[SharedResourceBoundary_C003_C004]
  dmgHeal[DamageHealing_C005_C006]
  death[Death_C007]
  respawn[Respawn_C008]
  hud[HUD_C013]
  ability[AbilityLifecycle_C009_C010_C011]
  migrate[CharacterMigration]
  enemy[EnemyReconstruction]
  pickups[Pickups_C014]
  observe[Observability_C015]
  attrs --> resource
  resource --> dmgHeal
  dmgHeal --> death
  death --> respawn
  resource --> hud
  respawn --> hud
  resource --> ability
  ability --> migrate
  dmgHeal --> enemy
  death --> enemy
  resource --> pickups
  observe -.-> attrs
  observe -.-> dmgHeal
  observe -.-> ability
  observe -.-> pickups

Integrity statement

This document is Markdown-only architecture design. No Unreal assets, source, configuration, plugins, or maps were modified. No Unreal MCP or PIE was used in Phase 2A2a. No contract is Approved.