Hands-On Usage
release_puppet_on_controlled is commonly used in post-WWII peace treaty scenarios or puppet empire collapse mods—for instance, when a nation needs to release a new puppet using territory it controls or occupies after a civil war or war's end, without having to complete formal annexation first. Its advantage lies in the ability to include states under occupation but not yet formally ceded within the puppet's territory, eliminating the tedious step of annex_country followed by release.
# Germany releases Vichy France as a puppet after occupying France (including controlled states)
GER = {
release_puppet_on_controlled = FRA
}
Synergy
[controls_state](/wiki/trigger/controls_state): Check before execution whether the target states are actually controlled, avoiding the awkward situation where the new puppet's territory ends up empty due to insufficient control range.
[diplomatic_relation](/wiki/effect/diplomatic_relation): Immediately adjust bilateral diplomatic relations after release (such as establishing non-aggression pacts), providing additional diplomatic constraints for the puppet relationship.
[has_autonomy_state](/wiki/trigger/has_autonomy_state): Verify after the fact whether the released nation has reached the expected autonomy level, ensuring the puppet chain aligns with design intent.
[add_state_core](/wiki/effect/add_state_core): Add core states to the new nation after releasing the puppet, guaranteeing the puppet's territorial claims on the map remain logically consistent.
Common Pitfalls
- Confusing "ownership" with "control": This effect uses states from both owner and controller, but if the scope nation neither owns nor controls target states, those states are simply skipped rather than triggering an error—newcomers often assume "occupation at any point in the past" suffices, when in reality the nation must be in active control at the moment of release, otherwise the new puppet will be missing expected territory.
- Calling under the wrong scope: This effect only executes within
COUNTRY scope; placing it in state or unit_leader blocks will fail silently without obvious error messages during debugging, easily creating logic gaps in your script.