Skip to content

Pickups β€” Authority

Folder: Runtime/Systems/Pickups/Authority

This folder provides the authority seam used by pickups to decide whether an actor is allowed to consume a pickup.

It is intentionally minimal, optional, and netcode-agnostic.


Purpose

The Authority system provides a pluggable rule for pickup consumption.

It determines whether an actor is allowed to consume a pickup locally.

It does not handle:

  • replication
  • ownership syncing
  • prediction or rollback
  • server validation

These concerns belong to your networking solution.


Folder Overview

This folder contains:

  • a single authority interface (IPickupAuthority)
  • a resolver and cache (PickupAuthority)
  • a default binder implementation (PickupAuthorityBinder)

It is a lightweight integration seam, not a full system.


What Lives Here

  • IPickupAuthority β†’ authority contract
  • PickupAuthority β†’ resolver and cache
  • PickupAuthorityBinder β†’ default implementation

Usage Guidance

Implementing Authority

public interface IPickupAuthority
{
    bool HasAuthority(GameObject actor);
}

Implement this interface to define your own authority rules.

You can attach implementations to:

  • scene roots
  • player objects
  • server or host objects
  • custom gameplay systems

Resolution Model

PickupAuthority resolves from the pickup, not the actor. Every shipped gate passes the pickup component as the context; the actor is only ever the argument to HasAuthority.

Resolution order:

  1. GetComponentInParent<IPickupAuthority>(true) on the pickup β€” checked first and never cached, because it is a per-hierarchy answer and the cache is per scene
  2. Cached scene-wide authority, if the cached instance is still usable
  3. Scene roots (GetComponentInChildren), first hit β€” cached
  4. Global scan of active MonoBehaviours, first hit β€” cached

A scene in which nothing resolves is remembered for the rest of that frame (play mode only), so the global scan runs at most once per scene per frame. A miss is never cached as a permanent null.

Cache is cleared when:

  • scenes load
  • scenes unload
  • active scene changes
  • domain reload occurs

Manual invalidation is available if binders change at runtime:

PickupAuthority.Invalidate();

What step 1 does and does not buy

A binder above a pickup β€” on its prefab, or on a parent it sits under β€” gates those pickups only, and is not shadowed by a scene-wide answer. That is what "never cached" is for.

It does not scope the answer to an actor. A world pickup's ancestors do not include any player, so a binder placed on a player is reached by step 3 like any other scene-wide authority and answers about every actor, in root order. Express per-actor rules inside the implementation, from the actor it is handed.

This section previously published the pre-1.2.0 model β€” cache first, hierarchy second, and a null cached when nothing was found β€” which described the resolver as it was before the per-hierarchy step was moved in front of the cache, and would have a reader design against a shadowing that no longer happens.


Default Binder

PickupAuthorityBinder provides a simple default implementation.

public bool alwaysTrue = true;
  • true allows all non-null actors
  • false denies all actors

This is intended for:

  • single-player setups
  • prototypes
  • testing scenes

Multiplayer setups should provide their own implementation.


Diagnostics

TriggerPickup Flow

  1. Resolve authority via PickupAuthority.Resolve(this)
  2. If no authority exists β†’ allow consumption
  3. If authority exists β†’ call HasAuthority(actor)
  4. If false β†’ block consumption
  5. If true β†’ apply effect

InteractablePickupBase

This base class does not enforce authority automatically.

Authority can be enforced manually:

var auth = PickupAuthority.Resolve(this);
if (auth != null && !auth.HasAuthority(actor))
    return false;

Important Notes

  • Authority is optional
  • If no binder exists, consumption is allowed
  • One binder per scene is recommended β€” plus, optionally, one above any pickup that needs its own answer. A binder per player is not a thing this resolver can honour
  • Authority decisions are local and not network-synchronised

Not for Production Use

It defines a decision seam only

This folder does not provide:

  • networking or replication
  • ownership synchronisation
  • server validation systems

  • UnityIntegration/TriggerPickup.cs
  • UnityIntegration/InteractablePickupBase.cs
  • Core/PickupEffectRunner.cs