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>
45 KiB
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
URIRAttributeSetctor: 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 §§2–4 — 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-001–005, 012–013 — 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
ReceiveAnyDamagesubtracts 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 attribute’s 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.Deadtag 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/PlayerRespawnSpawnActor+Possess paths on base / PC / GM.- Overlay created from
InitAbilityActorInfowhen local HUD present. - Char-select
PlayerFirstSpawnemits 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-023–026 — 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_001–004, 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-019–022.
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 contract’s 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_UpdateHUD→UpdatePlayerHUDunimplemented 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
UpdatePlayerHUDroute 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=falseEffectActors 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-005–C-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
1. Recommended canonical architecture
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-023–026 | 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
- Owner review of Proposed contracts (still no Approved stamp until explicitly granted).
- Plan for remaining blocked runtime evidence (input harness, 2-client PIE authorization, controlled damage actor if approved).
- Migration sequencing: C-001/C-002/C-003/C-004 → C-005/C-006/C-007 → C-008/C-013 → C-009–C-011 → C-014 with 2E.
- Observability harness outline per C-015.
- 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.