Deterministic State Machine

Formal State Transitions, Timing Deadlines & Reentrancy Guards


At the heart of every PerchAgent is a formal, deterministic finite state machine (FSM). Rather than loosely polling boolean flags across multiple components, all creature transitions are governed by strict lifecycle invariants.


The 10 States of PerchState

  +--------------+
  |   Disabled   |
  +-------+------+
          | (OnEnable)
          v
  +--------------+
  |  FreeFlight  | <======================================================+
  +-------+------+                                                        |
          | (Decision / Request)                                          |
          v                                                               |
  +--------------+                                                        |
  |  Selecting   | ──(No Candidates)──> [Return to FreeFlight on Cooldown]|
  +-------+------+                                                        |
          | (Candidate Selected)                                          |
          v                                                               |
  +--------------+                                                        |
  |   Planning   | ──(Obstacle / Failure)──> [Release Lease & Cooldown]   |
  +-------+------+                                                        |
          | (Lease Claimed & Corridor Clear)                              |
          v                                                               |
  +--------------+                                                        |
  | Approaching  | ──(Obstacle / Lease Lost)──> +---------------+         |
  +-------+------+                             | AbortRecovery | ─────────+
          | (Contact Threshold)                +-------+-------+          |
          v                                            | (Trapped)        |
  +--------------+                                     v                  |
  |  Touchdown   |                             +----------------------+   |
  +-------+------+                             | InterventionRequired |   |
          | (Stance Locked & Occupied)         +----------------------+   |
          v                                                               |
  +--------------+                                                        |
  |   Perched    |                                                        |
  +-------+------+                                                        |
          | (Dwell Expired / Depart Command / Panic Wave)                 |
          v                                                               |
  +--------------+                                                        |
  |  TakingOff   | ──(Body Clears Footprint & Releases Slot)──────────────+
  +--------------+

Detailed State Invariants

State Motion Owner Primary Invariant & Behavior
Disabled None Agent is unregistered from PerchWorld. All leases released, motors detached.
FreeFlight ExternalProvider Driven by external flight AI. Enforces minimum flight roaming time before auto-landing triggers.
Selecting ExternalProvider Filters slots by tags, size, and distance. Evaluates candidate suitability scores.
Planning ExternalProvider Atomically claims lease token. Computes Hermite spline and performs swept collision checks.
Approaching PerchMotor PERCH motor assumes exclusive control. Decelerates along arc-length LUT spline. Sends 0.25s heartbeats.
Touchdown PerchMotor Final contact alignment. Solves two-bone IK leg placement. Transitions slot to Occupied.
Perched PerchMotor Creature rests on perch. Evaluates wing fold, breathing sway, dwell timers, and moving platform deltas.
TakingOff PerchMotor Pre-flight departure sweeps verify exit path. Launches into air. Holds exclusion footprint until clear.
AbortRecovery PerchMotor Safely steers away from unexpected obstacles before returning control to ExternalProvider.
InterventionRequired PerchMotor Triggered if an agent is completely entrapped without any escape route. Holds safe pose without crashing.

Reentrancy Safety (DEC-010)

A classic vulnerability in game architecture is event callback reentrancy: a user attaches an event listener to OnStateChanged, and inside that listener immediately calls agent.CancelLanding() or agent.RequestLanding(). In poorly architected systems, this mutates internal collections while the state machine is iterating, causing collection modified exceptions or infinite recursive loops.

PERCH solves this using Preallocated Struct Circular Buffers:

  • Commands are queued into a fixed-size PendingCommand[16] ring buffer.
  • Events are buffered into a QueuedAgentEvent[32] ring buffer.
  • The state machine drains events using a frozen snapshot count.
  • Any reentrant commands issued during an event callback are safely enqueued and processed on the subsequent tick, ensuring complete reentrancy safety and zero heap allocations.

Copyright © 2026 Decnet Games. All rights reserved. PERCH is a commercial Unity Asset.

This site uses Just the Docs, a documentation theme for Jekyll.