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