On-demand reference for idea structure and examples. For best practices, see AGENTS.md.
BRA_idea_higher_minimum_wage_1 = {
name = BRA_idea_higher_minimum_wage
allowed_civil_war = { always = yes }
picture = gold
modifier = {
political_power_factor = 0.1
stability_factor = 0.05
consumer_goods_factor = 0.075
population_tax_income_multiplier_modifier = 0.05
}
}
- Always include
picture = sprite_name— without it the idea shows a blank icon in-game. Find an existing sprite by searching the codebase:grep "picture = " common/ideas/*.txt | sed 's/.*picture = //' | sort -u - Include
allowed_civil_war = { always = yes }for civil war tags - Use
original_tagnottaginallowedblocks - Drop the
allowedblock entirely in a category with no slot (country,hidden_ideas). Nothing picks from those, soadd_ideais the only way in and it never consultsallowed— the gate is dead either way. A category that has a slot draws from a poolallowedfilters, so keep it there. Flagged byvalidate_ideas.py(allowed-in-slotless-category);tools/standardization/strip_idea_allowed_gates.pyremoves them in bulk - Drop the
availableblock entirely in a category with no slot (country,hidden_ideas). Same reason: nothing picks from those, soavailableis never consulted. Usecancelif the idea should remove itself. Flagged byvalidate_ideas.py(available-in-slotless-category); the same stripper removes them in bulk - Keep
allowed = { always = no }on slotted ideas that must not appear in the picker (religion, other laws).add_ideastill applies them. Do not use it in slotless categories (country,hidden_ideas); that gate is dead and the validator flags it - Remove
cancel = { always = no }(checked hourly, never true) - A slotted idea whose
availablecan turn false mid-game needs a mirroredcancelwith the negated condition.availablegates picking only — the engine never strips an already-slotted idea when it goes false — and the spirit categories areremoval_cost = -1, so the player cannot un-pick it either.cancelis checked hourly and frees the slot. Precedent: the doctrine-gated office core spirits incommon/ideas/zzz_{army,navy,air}_spirits.txt - Remove empty
on_add = { log = "" }unless actually doing something - Tiered ideas use suffix numbering:
TAG_idea_name_1,TAG_idea_name_2, with sharedname = TAG_idea_namefor display name = Xredirects both name and description loc lookups — game readsXfor the displayed name andX_descfor the tooltip body. The idea's own ID is no longer used for loc oncename =is set.- Pick a
name = Xvalue that no focus, decision, or other idea uses. A focus withid = Xand an idea withname = Xshare the sameX/X_descloc keys — duplicate definitions in.ymlresolve to the last one written, silently overwriting the other game object's text. If a tier needs unique flavor while sharing a display name with sibling tiers, give it a distinctname =and its ownname_descentry rather than reusing the shared key.