Overview
The attribute_evaluator_device acts as branching logic in your island. You configure thresholds directly in the UEFN editor (e.g., "player must have 3 or more eliminations"), then call EvaluateAgent(Agent) from Verse to test a specific player against those conditions. The device responds by firing one of two events:
PassEvent— the agent met all conditions.FailEvent— the agent did not meet all conditions.
When to reach for it:
- A vault door that only opens for players with enough eliminations.
- A reward granter that hands out a legendary weapon only to top scorers.
- A cinematic trigger that fires only when the MVP walks into a zone.
- Any time you need stat-gated branching without writing the comparison logic yourself in Verse.
The device also exposes runtime controls — Enable/Disable, trigger-count limits via SetMaxTriggerCount, and timing controls via SetResetDelay and SetTransmitDelay — so you can tune exactly when and how often the evaluation can fire.
API Reference
attribute_evaluator_device
Evaluates attributes for
agentwhen signaled from other devices. Acts as branching logic, checking whether theagentassociated with the signal passes all of the tests setup in this device, then sends a signal on eitherPassEventorFailEvent.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse). Inherited members are merged from trigger_base_device.
attribute_evaluator_device<public> := class<concrete><final>(trigger_base_device):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
PassEvent |
PassEvent<public>:listenable(agent) |
Signaled when the agent from EvaluateAgent passes the requirements specified by this device. Sends the agent originally passed to this device in EvaluateAgent. |
FailEvent |
FailEvent<public>:listenable(agent) |
Signaled when the agent from EvaluateAgent fails the requirements specified by this device. Sends the agent originally passed to this device in EvaluateAgent. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
EvaluateAgent |
EvaluateAgent<public>(Agent:agent):void |
Tests whether the specified agent satisfies the required conditions specified on the device (e.g. eliminations/score), and fires either the PassEvent or FailEvent accordingly. |
Enable |
Enable<public>():void |
Enables this device. |
Disable |
Disable<public>():void |
Disables this device. |
SetMaxTriggerCount |
SetMaxTriggerCount<public>(MaxCount:int):void |
Sets the maximum amount of times this device can trigger. * 0 can be used to indicate no limit on trigger count. * MaxCount is clamped between [0,20]. |
GetMaxTriggerCount |
GetMaxTriggerCount<public>()<transacts>:int |
Gets the maximum amount of times this device can trigger. * 0 indicates no limit on trigger count. |
GetTriggerCountRemaining |
GetTriggerCountRemaining<public>()<transacts>:int |
Returns the number of times that this device can still be triggered before hitting GetMaxTriggerCount. Returns 0 if GetMaxTriggerCount is unlimited. |
SetResetDelay |
SetResetDelay<public>(Time:float):void |
Sets the time (in seconds) after triggering, before the device can be triggered again (if MaxTrigger count allows). |
GetResetDelay |
GetResetDelay<public>()<transacts>:float |
Gets the time (in seconds) before the device can be triggered again (if MaxTrigger count allows). |
SetTransmitDelay |
SetTransmitDelay<public>(Time:float):void |
Sets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered. |
GetTransmitDelay |
GetTransmitDelay<public>()<transacts>:float |
Gets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered. |
Walkthrough
Scenario: A vault door opens only for players who have earned enough eliminations. A pressure plate in front of the vault triggers the check. If the player passes, a cinematic sequence device plays and the door unlocks. If they fail, a UI message device shows a "not enough eliminations" warning.
This example wires together:
- A
trigger_device(the pressure plate) - An
attribute_evaluator_device(the stat check) - A
cinematic_sequence_device(the vault opening cutscene) - A
hud_message_device(the rejection message)
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Place this Verse device on your island, then wire up the four
# @editable fields to the corresponding placed devices in UEFN.
vault_gate_manager := class(creative_device):
# The pressure plate in front of the vault door.
@editable
VaultPlate : trigger_device = trigger_device{}
# Configured in the editor: e.g. "Eliminations >= 3".
@editable
EliminationCheck : attribute_evaluator_device = attribute_evaluator_device{}
# Plays the vault-door-opening cutscene.
@editable
VaultCinematic : cinematic_sequence_device = cinematic_sequence_device{}
# Shows a "You need more eliminations!" HUD message.
@editable
RejectionMessage : hud_message_device = hud_message_device{}
# Called when the island starts.
OnBegin<override>()<suspends> : void =
# Allow the evaluator to fire at most 5 times total,
# so the vault can't be spammed indefinitely.
EliminationCheck.SetMaxTriggerCount(5)
# Wait 2 seconds after each evaluation before accepting another.
EliminationCheck.SetResetDelay(2.0)
# Subscribe to the pressure plate.
VaultPlate.TriggeredEvent.Subscribe(OnPlateTriggered)
# Subscribe to both outcomes of the evaluator.
EliminationCheck.PassEvent.Subscribe(OnEvaluationPassed)
EliminationCheck.FailEvent.Subscribe(OnEvaluationFailed)
# Fired when a player steps on the pressure plate.
# trigger_device sends ?agent, so we unwrap it.
OnPlateTriggered(Agent : ?agent) : void =
if (A := Agent?):
# Hand the agent to the evaluator — it will fire
# PassEvent or FailEvent asynchronously.
EliminationCheck.EvaluateAgent(A)
# The player met the elimination threshold — open the vault!
OnEvaluationPassed(Agent : agent) : void =
# Play the cinematic for everyone on the island.
VaultCinematic.Play()
# The player did not meet the threshold — show the warning.
OnEvaluationFailed(Agent : agent) : void =
RejectionMessage.Show(Agent)
Line-by-line breakdown:
| Lines | What's happening |
|---|---|
@editable fields |
Bind placed UEFN devices to Verse without hardcoding. |
SetMaxTriggerCount(5) |
Caps total evaluations at 5; pass 0 for unlimited. |
SetResetDelay(2.0) |
Prevents rapid re-evaluation — the device ignores triggers for 2 s after each fire. |
VaultPlate.TriggeredEvent.Subscribe(OnPlateTriggered) |
Listens for the plate; note trigger_device sends ?agent. |
EliminationCheck.PassEvent.Subscribe(OnEvaluationPassed) |
Listens for the "passed" branch. |
EliminationCheck.FailEvent.Subscribe(OnEvaluationFailed) |
Listens for the "failed" branch. |
if (A := Agent?): |
Safely unwraps the optional agent before passing to EvaluateAgent. |
EliminationCheck.EvaluateAgent(A) |
The key call — submits the player for evaluation. |
VaultCinematic.Play() |
Reward: plays the vault-opening cutscene. |
RejectionMessage.Show(Agent) |
Consequence: shows the HUD rejection message to the specific player. |
Common patterns
Pattern 1 — Dynamically enable/disable the evaluator based on round phase
Some games only want stat-gating active during a specific round phase. Use Enable and Disable to turn the evaluator on and off at runtime.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
# Enables the attribute evaluator only during the "final round"
# and disables it when the round ends.
round_phase_controller := class(creative_device):
@editable
StatCheck : attribute_evaluator_device = attribute_evaluator_device{}
# A timer device that fires when the final round begins.
@editable
FinalRoundTimer : timer_device = timer_device{}
# A class_designer_device or similar that fires when the round ends.
@editable
RoundEndTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
# Start with the evaluator disabled — no stat-gating yet.
StatCheck.Disable()
FinalRoundTimer.SuccessEvent.Subscribe(OnFinalRoundStart)
RoundEndTrigger.TriggeredEvent.Subscribe(OnRoundEnd)
OnFinalRoundStart(Agent : agent) : void =
# Activate stat-gating for the final round.
StatCheck.Enable()
OnRoundEnd(Agent : ?agent) : void =
# Deactivate when the round is over.
StatCheck.Disable()
Pattern 2 — Inspect trigger-count budget before evaluating
Before spending a trigger, check how many evaluations remain. This lets you show a "gate is sealed" message when the budget is exhausted rather than silently doing nothing.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
# Checks the remaining trigger budget before calling EvaluateAgent.
# If the budget is zero (and the max is not unlimited), the gate is sealed.
budget_aware_evaluator := class(creative_device):
@editable
GateCheck : attribute_evaluator_device = attribute_evaluator_device{}
@editable
AccessPlate : trigger_device = trigger_device{}
@editable
SealedMessage : hud_message_device = hud_message_device{}
OnBegin<override>()<suspends> : void =
# Allow exactly 3 total evaluations for this gate.
GateCheck.SetMaxTriggerCount(3)
GateCheck.PassEvent.Subscribe(OnPassed)
GateCheck.FailEvent.Subscribe(OnFailed)
AccessPlate.TriggeredEvent.Subscribe(OnPlayerArrived)
OnPlayerArrived(MaybeAgent : ?agent) : void =
if (A := MaybeAgent?):
Max := GateCheck.GetMaxTriggerCount()
Remaining := GateCheck.GetTriggerCountRemaining()
# Max == 0 means unlimited; only block when limited AND exhausted.
if (Max > 0, Remaining = 0):
# No evaluations left — show the sealed message.
SealedMessage.Show(A)
else:
GateCheck.EvaluateAgent(A)
OnPassed(Agent : agent) : void =
# Handle pass — e.g., open a door device.
false
OnFailed(Agent : agent) : void =
# Handle fail — e.g., play a denial sound.
false
Note:
GetTriggerCountRemainingreturns0whenGetMaxTriggerCountis0(unlimited). Always checkMax > 0first, as shown above.
Pattern 3 — Adjust transmit delay for a dramatic reveal
The transmit delay controls how long after evaluation the device signals connected external devices (in the UEFN event graph). Use it to create a dramatic pause between the stat check and the downstream device reaction.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
# Sets a 3-second transmit delay so there's a suspenseful pause
# before downstream devices (wired in the UEFN event graph) react.
dramatic_reveal_setup := class(creative_device):
@editable
RevealCheck : attribute_evaluator_device = attribute_evaluator_device{}
@editable
RevealPlate : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
# 3-second delay before external wired devices react.
RevealCheck.SetTransmitDelay(3.0)
# Confirm the delay was applied.
Delay := RevealCheck.GetTransmitDelay()
RevealCheck.PassEvent.Subscribe(OnRevealPassed)
RevealCheck.FailEvent.Subscribe(OnRevealFailed)
RevealPlate.TriggeredEvent.Subscribe(OnPlayerStepsIn)
OnPlayerStepsIn(MaybeAgent : ?agent) : void =
if (A := MaybeAgent?):
RevealCheck.EvaluateAgent(A)
# Verse handlers fire immediately; only UEFN-wired devices
# are delayed by SetTransmitDelay.
OnRevealPassed(Agent : agent) : void =
false # Replace with your pass logic.
OnRevealFailed(Agent : agent) : void =
false # Replace with your fail logic.
Gotchas
1. PassEvent and FailEvent send agent, not ?agent
Unlike trigger_device.TriggeredEvent (which sends ?agent), both PassEvent and FailEvent hand your handler a non-optional agent. You do not need to unwrap it:
# CORRECT — agent is already unwrapped
OnEvaluationPassed(Agent : agent) : void =
SomeDevice.DoSomething(Agent)
# WRONG — ?agent is the wrong type for PassEvent/FailEvent handlers
# OnEvaluationPassed(Agent : ?agent) : void = ...
But the plate (trigger_device) sends ?agent, so you do need to unwrap before calling EvaluateAgent:
OnPlateTriggered(Agent : ?agent) : void =
if (A := Agent?):
EliminationCheck.EvaluateAgent(A)
2. SetMaxTriggerCount is clamped to [0, 20]
Values outside this range are silently clamped. Pass 0 for unlimited. There is no runtime error — the value just won't exceed 20.
3. GetTriggerCountRemaining returns 0 for unlimited devices
When GetMaxTriggerCount() returns 0 (unlimited), GetTriggerCountRemaining() also returns 0. Always check the max first before using the remaining count as a "budget exhausted" signal.
4. Conditions are configured in the editor, not in Verse
The actual attribute thresholds (e.g., "Eliminations >= 3") are set on the device in the UEFN editor, not in Verse code. Verse only controls when to evaluate and what to do with the result. If your evaluator always passes or always fails, check the device settings in the editor first.
5. SetTransmitDelay only affects UEFN-wired devices
SetTransmitDelay delays the signal sent to devices connected via the UEFN event graph. Your Verse PassEvent/FailEvent handlers fire immediately — the transmit delay does not affect them.
6. The device must be enabled to evaluate
Calling EvaluateAgent on a disabled device does nothing — neither PassEvent nor FailEvent will fire. Always ensure the device is enabled (either by default in the editor or via Enable()) before submitting agents for evaluation.