SuperAPI AI Directory

ue5-gameplay-state-ownership

General & other

View repository

Updated 10-16 00:00

About this skill

Gameplay State Ownership

Almost every "where should this live?" question in UE5 has one correct answer, and it is determined by a single property: how long the state must survive.

The classes exist at different lifetimes. State placed in a class that dies sooner than the state needs is lost; state placed in a class that outlives it leaks into the next round and appears as a bug that only shows up on the second playthrough. Both are decided at the moment the variable is declared, and both are cheap then and expensive later — moving state is not a refactor of one field, it is a refactor of everything that reads it.

The default failure is putting things on the Pawn, because the Pawn is what you have a pointer to. A Pawn is one of the shortest-lived things in the project.

Assign by lifetime, before declaring the variable

  1. Ask how long the state must live, in these terms: shorter than one possession, one possession, the whole match, across level transitions, or across sessions. That answer selects the owner almost by itself. See references/lifetime-table.md.
  2. Ask who needs to read it. State that many unrelated systems read from a deep object graph is a sign the owner is too low in the hierarchy.
  3. Never place state on a Pawn that must survive the Pawn. Destruction, respawn, and possession changes all end a Pawn's life while the game continues.
  4. Distinguish "match rules" from "match state". The rules object and the shared state object are different, and putting observable state in the rules object is a common error with a delayed cost.
  5. Prefer a subsystem over a singleton or static. Subsystems have defined lifetimes and deterministic teardown; a static has neither, and gives you state that survives things it should not. See references/subsystems.md.
  6. Record the assignment in the project context file, with the lifetime that justified it. The lifetime is the reason; without it the table is unmaintainable.

Load only what applies:

Required answer format

When this skill fires, return:

  1. State table — state | required lifetime | owner class | who reads it.
  2. Justification — for each entry, the lifetime event that rules out the next-shorter owner.
  3. Reset behavior — what happens to each entry at respawn, round end, and level transition, stated explicitly rather than inherited.
  4. Access paths — how each reader reaches the state, and any that traverse more than two hops.
  5. Subsystem choices — for any subsystem, which scope and why.
  6. Not verified — anything whose required lifetime is genuinely unknown, marked rather than guessed.

Hard rules

  • Never store state on a Pawn that must survive destruction, respawn, or a possession change.
  • Never store persistent player-associated state on a Controller if it must survive a level transition; check what your project's transitions actually preserve rather than assuming.
  • Match rules and match state are separate concerns. Anything that must be observed by other systems belongs in the shared state object, not the rules object.
  • No statics or ad-hoc singletons for gameplay state. Use a subsystem with the narrowest scope that covers the required lifetime.
  • Every piece of state has a defined reset behavior at every boundary it survives. Undefined reset behavior is the mechanism behind "only wrong on the second round".
  • Choose the narrowest scope that satisfies the lifetime. Wider scopes are not safer; they are a different bug — state that persists past its meaning.

Verification

The destruction test. Destroy and respawn the Pawn mid-session. Every value that should persist must persist; every value that should reset must reset. This single test catches the most common misplacement in UE5 projects, and it takes one console command.

The second-round test. Play two rounds without restarting the process. State that leaks between rounds appears here and nowhere else — a first round is always clean, which is why this class of bug reaches release.

The transition test. Cross a level transition and audit the table. Which owners survive a transition is project-configuration dependent; verify it rather than reasoning about it.

Reachability audit. For each entry, count the hops from a typical reader to the state. Long chains are a design signal: the state is owned too low, and every reader is paying for it.

Scope

This skill decides where state lives. It does not cover serialization and save games, which add a persistence question on top of a lifetime question, nor the content or design of the state itself.

It does not cover network replication or authority. Those questions layer onto this one, and getting ownership right first makes them tractable — but nothing here is sufficient for a networked project, and replication may be banned in your phase anyway (ue5-phase-bans).