Skip to content

Entity lifecycle safety

Mass Forge treats entity identity, Mass representation, and gameplay presentation as separate concerns. This contract defines what happens when entities are destroyed or recycled, Actors enter or leave representation, LOD changes, and a world shuts down.

Identity and generation rule

Mass Forge Entity Handle stores both the Mass entity index and serial number. The pair is the identity. An index alone is never sufficient.

  • Every public operation revalidates the full index/serial pair against the operation's world.
  • Destroying an entity invalidates every copy of its old handle.
  • If Mass later reuses the same index, the serial number changes. An old request, ability target, persistent-effect handle, or Blueprint variable cannot address the replacement generation.
  • Handles are world-local runtime references. Do not save, replicate, compare, or reconstruct them as durable IDs across world travel.

Project code must reacquire a handle after spawn, pooling/reactivation that creates a new Mass entity, representation reassignment, seamless travel, or load.

Queued requests

Queue acceptance transfers a generation-checked source/target handle and the authored definition identity into a bounded world queue. Acceptance does not reserve the entity or guarantee later success.

At execution, complete Entity State Restores, focused Attribute Snapshot Restores, Attribute Changes, counted Gameplay Tag changes, Instant Effects, Persistent Effect requests, Damage, Death Handling, and Abilities revalidate the identities they use. A destroyed or recycled entity produces the operation's explicit invalid-entity or invalid-target completion. It is never redirected to an entity that later occupies the same index. Queued restores own their copied payload; definition assets are revalidated against the stable ID captured when queued.

Separate requests remain independent transactions. If one request destroys or invalidates an entity, later requests for the old generation fail normally and keep their own request IDs.

Active ability lifecycles

Active casts and channels are keyed by the source's complete entity handle.

  • If the source is destroyed, the next safe lifecycle pass removes the stored lifecycle and publishes one end event with Source Invalid and Invalid Entity.
  • If a required target is destroyed before cast commit, commit fails atomically with Invalid Target: costs, cooldowns, charges, effects, and persistent effects do not commit.
  • If a target becomes invalid during a channel, that pulse reports its normal target failure. The Ability Data Asset's Channel Failure Policy then continues, cancels, or interrupts the channel.
  • A replacement generation never inherits the old source's lifecycle, cooldown state, grants, or target identity.
  • Queued Ability Grant/Revoke retains the complete entity generation. Queued Cancel/Interrupt also captures the exact active lifecycle ID, so a delayed request cannot affect either a recycled entity generation or a replacement lifecycle on the same source.

Lifecycle observers should clear presentation on every end reason, including Source Invalid and Commit Failed. UI should not wait for an invalid source to become queryable again.

Persistent-effect handles

A persistent-effect handle combines a world-local effect instance ID with the owning generation-checked entity handle.

  • Query or manual removal through a stale owner returns Invalid Entity and never searches a replacement generation.
  • The persistent-effect subsystem performs invalid-owner retirement on every valid tick, including a zero-delta cleanup pass. Retirement removes all subsystem metadata and publishes one removal event with Entity Invalidated.
  • Authoritative per-entity slots disappear with the Mass entity. Replacement entities begin with empty effect slots and cannot inherit grants or modifier handles.
  • World teardown clears all remaining persistent metadata without gameplay callbacks.

Project-side maps keyed by persistent handles must remove entries when they receive any removal event or when a query reports an invalid owner.

Actor representation and LOD

Mass Forge attributes, tags, effects, abilities, cooldowns, charges, and lifecycles live on Mass fragments. Actor representation is an optional lookup and presentation route; it is not simulation authority.

  • Removing an Actor-to-Mass mapping makes Actor resolution return Not Represented and clears its output handle. The existing Mass entity and its handle remain valid.
  • Assigning the Actor to a different Mass entity makes the next resolve return the new complete handle. Previously resolved handles are not rewritten.
  • Representation LOD changes that preserve the Mass entity do not change gameplay identity or state because core systems do not key state by Actor, mesh, visual LOD, or representation fragment.
  • If a project implements an LOD or pooling transition by destroying one Mass entity and creating another, that is an identity change. Reacquire the new handle and deliberately initialize or restore state.

The base plugin does not destroy, hide, pool, or respawn represented Actors. Damage Definitions can request project deactivation or generation-safe Mass destruction, but presentation ownership stays with the host project. The published skeletal and VAT horde twins demonstrate that gameplay identity survives a presentation-backend change: the skeletal map uses one rigged player and a bounded near tier, while the VAT map uses one batched HISM presentation for represented enemies. The older procedural-WPO crowd harness remains an internal regression fixture and is never reported as VAT.

World teardown

Each world owns independent schemas, queues, request counters, lifecycles, AI tickets, persistent-effect metadata, tag-event buffers, and inspection providers. During subsystem deinitialization Mass Forge:

  • drains pending Entity State Restore, Attribute Snapshot Restore, Attribute Change, Gameplay Tag, Instant Effect, Persistent Effect, Damage, Death Handling, and unified Ability-operation queues;
  • clears active ability lifecycles, tracked AI requests, persistent-effect metadata, deferred events, providers, and transaction scratch state;
  • resets world-local request and handle counters; and
  • does not emit gameplay completion, lifecycle-end, or persistent-removal callbacks for discarded teardown state.

This no-callback rule prevents shutdown code from mutating a world that is being destroyed. A loading screen, pending-action UI, or save system must clear its own project state from world/level lifecycle events rather than waiting for Mass Forge completions.

The gameplay clock and the exact state that does or does not cross save/load and seamless-travel boundaries are defined in the time, travel, and save contract.

Safe project recipes

Pool presentation while preserving simulation

  1. Keep the Mass entity alive.
  2. Remove or change only its representation.
  3. Retain the complete entity handle.
  4. Re-resolve the Actor whenever presentation returns.

Attributes, effects, abilities, and identity remain intact.

Retire and later create a fresh entity

  1. Stop submitting work for the old handle.
  2. Destroy or deactivate the old Mass entity through the chosen death policy.
  3. Clear UI, targeting, AI, and project maps for the old generation.
  4. Create a new entity and acquire its full handle.
  5. Initialize from traits or restore a validated stable-ID snapshot when continuity is intended.

Never copy only the old index and never assume recycled memory implies gameplay continuity.

Automated proof

The isolated-world suite cross-checks the contract at several boundaries:

  • a queued damage request cannot touch the replacement created after its target is destroyed, including when Mass recycles the index;
  • Actor representation can be removed and reassigned while authoritative entity-handle operations continue correctly;
  • destroyed cast sources end once with Source Invalid, and destroyed cast targets fail commit without costs or effects reaching a replacement;
  • persistent owner destruction retires metadata and emits Entity Invalidated on a zero-delta pass; and
  • a request deliberately left pending at world teardown produces no gameplay completion callback.

All other world tests also destroy their isolated worlds after exercising real subsystem state, providing repeated teardown coverage across the supported engine matrix.

Mass Forge documentation — generated from the shipping Markdown source.