How dynamic context works

Understand the states and events model, canonical context format, and how updates queue and flush before and during conversations.

Dynamic Context gives characters a live, structured view of what is happening in the scene. Instead of relying only on the static system prompt configured on the Convai dashboard, a character can reference a trainee's current location, the equipment they have collected, or an alarm that just triggered — because that information was injected directly into the session as it occurred. This page explains the underlying model: what the primitives are, how the SDK assembles them into a canonical context string, and why updates queue safely before a conversation starts.

States and events

Dynamic Context is built on two primitive types.

States are persistent, named key-value pairs. Each state has a name and a value. When you set a state, any previous value for that name is replaced. States are suitable for facts that change over time but have exactly one current value: the operator's current station, the hazard level in a zone, or whether a checklist item has been completed.

Events are chronological, one-time occurrences. Unlike states, events accumulate in sequence and are never replaced or deduplicated. Each call to AddEvent appends a new line to the character's context. Events are suitable for things that happened during a session and that the character should be able to reference in order: "Trainee bypassed the manual lockout procedure", "Chemical alarm triggered at Bay 7".

Both primitives feed into the character's awareness simultaneously. States provide a stable, queryable snapshot of current conditions; events provide a chronological record of what has happened.

Canonical context format

When the SDK sends an update to Convai, it assembles a canonical context string from all tracked states and events:

{StateName} is {Value}
{AnotherState} is {Value}
Event text line one
Event text line two

States appear first, in the order they were first set — updating a state's value does not change its position. Events follow in call order after all states.

The reason states preserve insertion order across updates is to give the character a stable, predictable view of the world. If Station was the first thing set, it always appears first in the character's context, regardless of how many times the value has changed. This makes the context easier for the model to interpret consistently.

Example:

context.SetState("Station", "Bay 3");       // position 1
context.SetState("HazardLevel", "High");    // position 2
context.AddEvent("Operator bypassed interlock");
context.SetState("Station", "Bay 7");       // updates value; position stays at 1

Canonical context after all four calls:

You supply only names, values, and event text. The SDK assembles and delivers the canonical string automatically.

Two entry points

Dynamic Context has two entry points that write to the same underlying tracker and produce identical network behavior.

Inspector — ConvaiDynamicContextCommand

Add this MonoBehaviour to the NPC's GameObject and configure the command type, fields, and reaction mode in the Inspector. Call Execute() from a UnityEvent, trigger collider, timeline marker, or UI button. No scripting required. One component encapsulates one command; for multiple commands per NPC, place each on a child GameObject.

Use this entry point when:

  • Context changes are tied to scene events that already fire UnityEvent callbacks

  • Non-programmers need to configure or modify context triggers

  • You want to prototype quickly without writing glue code

Scripting — IConvaiDynamicContext

Access character.DynamicContext to get the IConvaiDynamicContext interface and call methods directly from C#. This gives full control over timing, batching, and reaction mode.

Use this entry point when:

  • Context updates depend on runtime logic or data that cannot be expressed as static Inspector fields

  • Multiple states must change atomically (use SetStates)

  • You need to read state values back (TryGetStateValue)

  • The update source is an external system such as a state machine or analytics pipeline

Pre-conversation queueing

Updates made before a conversation begins are automatically queued by all tracked methods — SetState, SetStates, AddEvent, RemoveState, and Reset. When the session connects, the SDK delivers a single Replace message containing the full canonical context at that moment.

This means you can set initial context freely from Awake or Start without timing concerns. The SDK handles delivery.

The reason this collapses into one Replace rather than replaying individual messages is efficiency: the character receives one authoritative snapshot rather than a stream of incremental updates that could arrive out of order or create redundant LLM turns.

When to use which command type

Goal
Use

Track one current condition

SetState

Track several conditions that change at the same moment

SetStates (one canonical rebuild, one network round-trip)

Record that something happened

AddEvent

Remove a condition that no longer applies

RemoveState

Clear all runtime context (for a new scenario phase)

Reset

Send externally constructed context text

Apply() — advanced; does not queue

Next steps

Dynamic context quick startCommand component referenceSync behavior and timing

Last updated

Was this helpful?