Action Context
v1.0
You can safely skip this page.
You’ll never need to edit or reference ActionContext
directly — it’s used automatically by Juicy Actions and the ActionExecutor behind the scenes.
This page is for advanced developers integrating custom time systems, dependency injection, or multi-system coordination.
ActionContext
is the execution environment for every Action.
It’s automatically prepared by the ActionExecutor
when Actions run, and shared across all Actions
in a single run.
You can think of it as the “backpack” that each Action
carries — filled with references to time, randomness, shared data, and services.
🔍 Key Responsibilities
Clock Access
Provides an IClock
interface for time, deltaTime, and delays (usually ActionSystemClock.Instance
).
Blackboard Sharing
Holds a shared Blackboard
instance so restarts and RunKeys propagate to all in-flight Actions.
Deterministic Random
Supplies a seeded IRandom
for reproducible random behavior across runs.
Dependency Access
Optionally holds an IServiceLocator
so custom Actions can resolve services cleanly.
Custom Data
A small per-run dictionary (customData
) for storing and retrieving runtime variables.
Run-Key Tracking
Provides a RunKey
accessor to detect when the executor restarts (used for safe cancellation).
🧠 Lifecycle Overview

🔁 Shared Blackboard & RunKey Propagation
All Actions in a single run share the same Blackboard.
When the ActionExecutor
restarts:
It increments a RunKey in the Blackboard.
All existing Actions (which reference that Blackboard) detect the change.
They gracefully stop via their per-frame run-key check.
This prevents “zombie” Actions from continuing after a restart.
⚙️ Structure Summary
public class ActionContext
{
// Source / Game Info
public Vector2Int gridPosition;
public Component sourceComponent;
public GameObject sourceGameObject;
public int currentLevel;
public float timeScale;
public MonoBehaviour gameManager;
// Custom per-run data
public Dictionary<string, object> customData;
// Services
public IClock Clock;
public IRandom rng;
public IServiceLocator Services;
public Blackboard Blackboard;
// Shared Blackboard linking
internal void AttachBlackboard(Blackboard shared);
// Optional cloning utility
public ActionContext CloneSharingBlackboard();
}
🧩 CloneSharingBlackboard()
Used internally by the system when an Action needs a new context object (but must retain access to the same Blackboard, services, and run-state).
Example:
var subContext = context.CloneSharingBlackboard();
subContext.SetData("SpawnIndex", 4);
This ensures restart flags, run-keys, and other runtime data remain consistent.
🪄 Custom Data Utilities
You can safely use these if you need to store runtime data:
context.SetData("Target", enemy);
Enemy e = context.GetData<Enemy>("Target");
This is particularly useful for advanced Actions or sequences that coordinate temporary data between child Actions.
🧭 Relation to Other Systems
ActionExecutor
Creates and reuses the ActionContext
. Attaches shared Blackboard and sets the run-key.
ActionSystemClock
Usually injected into the context for consistent timing.
Blackboard
Shared storage for restart control, typed data, and inter-Action communication.
IServiceLocator
Optional dependency provider for advanced integrations.
🧑💻 When to use it directly
You might interact with ActionContext
directly if:
You’re building a custom Executor or specialized sequencing tool.
You need to inject your own Clock, Blackboard, or ServiceLocator.
You’re creating parallel or nested Actions that need their own data scope but the same restart propagation.
Otherwise, all of this happens automatically.
Last updated
Was this helpful?