Drive Prompts and Retrieval from Game State¶
Inject live game state — player level, mood, quest progress — into a prompt template and a
Retrieve filter, and have both pick up changes on the very next turn with no ChangeParam
round-trip and no filter recompile.
Prerequisites
- A graph with at least one
Generate,GenerateAndSpeak, orTransformnode (for the template) and, optionally, aRetrieveorClassifyIntentnode (for the filter). - Read Agent Variables first for the full model — this page is a task-oriented walkthrough, not the reference.
1. Declare the variables at CreateAgent¶
Declare every variable the graph will ever reference, with its initial value. This locks each name to a type for the agent's lifetime.
In the Inspector, on the TryllWorkflowAsset: add to Variables —
level (Int, 1), mood (String, "neutral"), quests_reached (StringSet, empty).
In the workflow asset's Variables array: level (Int, 1), mood (String,
"neutral"), quests_reached (StringSet, empty).
std::vector<Tryll::Client::AgentVariableDecl> variables = {
{"level", std::int64_t{1}},
{"mood", std::string{"neutral"}},
{"quests_reached", std::vector<std::string>{}},
};
// variables is the last CreateAgent parameter (there is no agent-name arg).
auto agent = client.CreateAgent(graph, /*enableDiagnostics=*/false,
std::nullopt, /*maintainDialogueHistory=*/true, variables);
2. Reference them in a template¶
On a Generate (or GenerateAndSpeak/Transform) node's template field — not
system_prompt, which is inserted verbatim and never Mustache-rendered:
The player is level {{var.level}} and seems {{var.mood}}.
They have completed: {{var.quests_reached}}.
A set<string> variable renders as its elements sorted and comma-joined (e.g.
lost_amulet, silver_key) — it is a single string value, not an iterable, so Mustache
section syntax ({{#var.quests_reached}}…{{/var.quests_reached}}) does not enumerate it.
Every reference uses the var. prefix.
3. Reference them in a Retrieve filter¶
Gate which lore records come back based on the same variables — see Retrieve filter grammar for the full operand grammar:
{ "op": "and", "args": [
{ "op": "ge", "lhs": { "var": "level" }, "rhs": { "knowledge": "min_level" } },
{ "op": "in", "needle": { "knowledge": "quest_reached" },
"haystack": { "var": "quests_reached" } }
] }
4. Mutate them from gameplay code¶
Call the typed setters whenever game state changes. Writes update the local mirror
immediately; the actual wire update is batched and flushed automatically right before the
next SendMessage/Resume/ChangeParams call — you don't need to flush manually.