Phase 2: Custom Actions
Phase 1 used the four shipped default actions. Now you'll add your own action with no parameters and wire it to a Blueprint event. By the end of this phase, asking the bot "print hello" will run your Blueprint code.
What you'll need
The Phase 1 setup working — chatbot in a level,
Enable Actionsticked, NavMesh in place, character locomotion set up.The character Blueprint asset open (or accessible).
Step 1 — Declare the action template
Select the Convai character actor in the level.
In the Details panel, find the Convai Chatbot component → Convai → Actions → Environment → Actions.
Click
+to add a new entry. UE expands anFConvaiActionstruct.Fill in:
Name:
Print(this is the canonical action name your handler will dispatch on).Description:
Print a debug message to the screen.Leave
Parametersempty.
The Rendered String field below auto-populates with:
Print — Print a debug message to the screen.That's the wire-format string sent to the LLM. As you edit the Name or Description, the rendered string updates live.
Step 2 — Bind a handler in Blueprint
The chatbot fires OnActionReceivedEvent_V2 whenever the bot decides to act. You react to it in the character's Blueprint.
Open your character Blueprint.
In the Components tab, click the Convai Chatbot component to select it.
In the Details panel for that component, find the Events category. Click the
+next toOn Action Received Event V2. UE drops a bound event into the Event Graph.The event delivers a
Sequence Of Actionsarray (each entry is anFConvaiResultAction) plus references to the Chatbot Component and the interacting Player Component.
Step 3 — Dispatch by action name
Inside the bound event, for each action in the array:
Get
Action(the canonical name string).Switch on String with cases for each action you've declared:
Print→ call your custom logic, thenHandle Action Completion(Is Successful=true, Delay=0).Default → call
Handle Action Completion(Is Successful=true, Delay=0)to keep the queue moving (or leave un-handled actions to retry — that's anIs Successful=falsecase).
For the Print case:
Drag a
Print Stringnode off the execution pin and feed it a literal"Hello from Convai!"(or read from the Action — but for this phase the action has no params).After the print, drag in
Handle Action Completionoff the chatbot reference. Set:Is Successful:
true(the action ran).Delay:
0.Leave Event Text empty (advanced field) — this is for when you want to push an outcome back into the bot's dynamic context. Empty = no event.
That's the full handler. The bot now knows how to execute Print.
Step 4 — Play test
Hit Play and ask the character: "Print hello."
In the editor's viewport you should see "Hello from Convai!" (or whatever literal you used) appear via Print String. The bot will also speak its acknowledgment.
How the pipeline runs end-to-end
When the LLM emits an action:
The server sends
{name: "Print"}(no target, no params).The plugin's parser finds the
Printtemplate by name in yourEnvironment.Actions.Since the template has no declared parameters,
Parametersstays empty.OnActionReceivedEvent_V2fires on the chatbot with the parsed sequence.Your Blueprint dispatches by
Action == "Print"and runs the print.Handle Action Completion(true, 0)advances the queue. If there were more actions in the sequence, the next would now run.
Why the queue exists
The bot can emit a sequence of actions in one response, e.g. "Wait 2 seconds, then go to the cube, then print done." The queue makes sure each action completes before the next one starts. Your handler is responsible for telling the queue when the current action is done — that's what Handle Action Completion does.
Handle Action Completion(true, 0)
Mark current action successful, run the next one immediately.
Handle Action Completion(true, 1.5)
Successful, but wait 1.5s before the next action.
Handle Action Completion(false, 0)
Retry the same action.
You can also push an outcome event into the bot's context in the same call — useful for narration:
When things go wrong
If your handler can't recover (the target is gone, preconditions failed), don't retry forever — abort the whole sequence and let the LLM replan:
This clears the rest of the queued actions and fires a context event so the LLM acknowledges and likely emits a new action plan on its next turn.
Recap
You added one action template, wrote one handler, and got the bot doing custom things. The next step is typed parameters — telling the LLM that an action takes a number, an actor reference, or one-of-N choices. Onward to Phase 3 — Parameterized Actions.
Last updated
Was this helpful?