Hands-On Usage
free_operative is commonly used in espionage mods to design "prison break" or "diplomatic negotiation" storylines: when the player completes a certain national focus or option, the captured operative of your side is released back to available status. It can also be used in AI events to simulate prisoner exchange scenarios where operatives from both sides are mutually released.
# When player selects "negotiate operative release" option
option = {
name = spy_event.1.a
# Specify target operative from country scope
GER = {
free_operative = PREV # PREV is the operative previously captured by capture_operative
}
}
# Or release from operative's own scope
any_operative_leader = {
limit = {
has_captured_operative = yes # Confirm operative is in captured state
}
free_operative = { captured_by = ROOT }
}
Synergy
[capture_operative](/wiki/effect/capture_operative): Capture and release are inverse operations. In scripts, typically use capture_operative to create a capture event first, then conclude with free_operative.
[turn_operative](/wiki/effect/turn_operative): Before releasing, you can first turn the operative, forming the classic counter-espionage storyline of "turn and release".
[kill_operative](/wiki/effect/kill_operative): Mutually exclusive outcome option with free_operative. Place them separately in different options of the same event to give players the choice of "release or execute".
[has_captured_operative](/wiki/trigger/has_captured_operative): Apply this trigger as a limit check before release to ensure the target operative is actually in captured state, avoiding script execution on invalid targets.
Common Pitfalls
- Confusion between scope and target: Beginners often forget that this effect supports two syntaxes—passing the operative as a value from country scope, or specifying the capturing country with
captured_by from operative scope. Mixing the two syntaxes causes silent script failure; the game log won't report errors but the operative won't be released.
- Using on non-captured operatives: If the target operative is not in captured state,
free_operative produces no effect but doesn't report an error, easily leading to the debugging frustration of "thought it was released but nothing happened"—always wrap with has_captured_operative as a condition check.