feat(events): add Feruchemy, training, metal supply, and sandbox events

Add Feruchemy activation chain (mistborn_feruchemy.0001/0010) for
Terris characters discovering their art and creating first metalminds.
Add Allomantic training events (mistborn_training.0001/0010/0020/0030)
for mentoring family members. Add metal supply events
(mistborn_metal.0001/0010/0020/0030) for reserve management and
wartime scarcity. Add sandbox testing event (mistborn_sandbox.0001)
for voluntary metallic arts discovery.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-07 22:36:31 +01:00
co-authored by Claude Opus 4.6
parent 5e44459a6f
commit 96bcaa3558
4 changed files with 1050 additions and 0 deletions
+211
View File
@@ -0,0 +1,211 @@
############################################
# Feruchemy Event Chain
# The art of storing attributes in metalminds
# Native to the Terris people
############################################
namespace = mistborn_feruchemy
# ============================================================
# DISCOVERING THE ART
# Fires on yearly pulse for Terris characters with dormant potential
# Feruchemy activates through practice, not trauma
# ============================================================
mistborn_feruchemy.0001 = {
type = character_event
title = mistborn_feruchemy.0001.t
desc = mistborn_feruchemy.0001.desc
theme = learning
left_portrait = {
character = root
animation = personality_rational
}
trigger = {
has_trait = trait_feruchemy_potential
NOT = { has_trait = trait_feruchemist }
age >= 14
# Feruchemy is native to the Terris people
OR = {
culture = culture:terris
any_parent = { culture = culture:terris }
}
}
weight_multiplier = {
base = 1
# High learning makes discovery more likely
modifier = {
add = 0.5
learning >= 10
}
modifier = {
add = 1.0
learning >= 16
}
# Being around another Feruchemist helps
modifier = {
add = 1.5
any_courtier = {
has_trait = trait_feruchemist
}
}
# Terris Worldbringers preserve Feruchemical knowledge
modifier = {
add = 1.0
faith = faith:terris_worldbringers
}
# Low base chance — the Lord Ruler's breeding programs suppress this
modifier = {
factor = 0.1
}
}
immediate = {
# Save any Feruchemist mentor in court
random_courtier = {
limit = {
has_trait = trait_feruchemist
}
save_scope_as = feruchemy_mentor
}
}
# Option A: Explore this strange ability
option = {
name = mistborn_feruchemy.0001.a
trigger_event = {
id = mistborn_feruchemy.0010
days = { 30 90 }
}
stress_impact = {
lazy = 10
}
ai_chance = {
base = 80
modifier = {
add = 20
has_trait = diligent
}
}
}
# Option B: Suppress it — too dangerous under the Lord Ruler
option = {
name = mistborn_feruchemy.0001.b
add_stress = 20
stress_impact = {
ambitious = 20
}
ai_chance = {
base = 20
modifier = {
add = 30
has_trait = craven
}
}
}
}
# ============================================================
# THE FIRST METALMIND
# Character creates their first metalmind and activates Feruchemy
# ============================================================
mistborn_feruchemy.0010 = {
type = character_event
title = mistborn_feruchemy.0010.t
desc = mistborn_feruchemy.0010.desc
theme = learning
left_portrait = {
character = root
animation = happiness
}
trigger = {
has_trait = trait_feruchemy_potential
NOT = { has_trait = trait_feruchemist }
}
immediate = {
# Nothing additional needed
}
# Option A: Store strength — a pewter metalmind
option = {
name = mistborn_feruchemy.0010.a
remove_trait = trait_feruchemy_potential
add_trait = trait_feruchemist
add_character_modifier = {
modifier = first_metalmind_strength
years = 1
}
# Check for Keeper status
if = {
limit = {
culture = culture:terris
faith = faith:terris_worldbringers
}
add_character_modifier = keeper_of_terris
}
ai_chance = {
base = 40
}
}
# Option B: Store memories — a copper metalmind (the Keeper's choice)
option = {
name = mistborn_feruchemy.0010.b
remove_trait = trait_feruchemy_potential
add_trait = trait_feruchemist
add_character_modifier = {
modifier = first_metalmind_memories
years = 1
}
# Check for Keeper status
if = {
limit = {
culture = culture:terris
faith = faith:terris_worldbringers
}
add_character_modifier = keeper_of_terris
}
ai_chance = {
base = 40
modifier = {
add = 30
faith = faith:terris_worldbringers
}
}
}
# Option C: Store health — a gold metalmind
option = {
name = mistborn_feruchemy.0010.opt_c
remove_trait = trait_feruchemy_potential
add_trait = trait_feruchemist
add_character_modifier = {
modifier = first_metalmind_health
years = 1
}
# Check for Keeper status
if = {
limit = {
culture = culture:terris
faith = faith:terris_worldbringers
}
add_character_modifier = keeper_of_terris
}
ai_chance = {
base = 20
}
}
}
+287
View File
@@ -0,0 +1,287 @@
############################################
# Mistborn Mod - Metal Supply Events
# Namespace: mistborn_metal
############################################
namespace = mistborn_metal
# ============================================================
# 0001 - Metal Reserves Running Low
# Fires on yearly pulse for Allomancers without metal_reserves_abundant
# ============================================================
mistborn_metal.0001 = {
type = character_event
title = mistborn_metal.0001.t
desc = mistborn_metal.0001.desc
theme = intrigue
override_background = {
reference = "gfx/interface/illustrations/event_scenes/corridor.dds"
}
trigger = {
is_allomancer_trigger = yes
NOT = { has_character_modifier = metal_reserves_abundant }
NOT = { has_character_modifier = metal_reserves_low }
NOT = { has_character_modifier = metal_reserves_depleted }
}
weight_multiplier = {
base = 1
modifier = {
factor = 2
is_at_war = yes
}
}
immediate = {
# Grant the low modifier
add_character_modifier = {
modifier = metal_reserves_low
years = 1
}
}
# Buy more metals (noble route)
option = {
name = mistborn_metal.0001.a
trigger = {
gold >= 50
NOT = { is_skaa_trigger = yes }
}
remove_short_term_gold = 50
remove_character_modifier = metal_reserves_low
add_character_modifier = {
modifier = metal_reserves_abundant
years = 2
}
ai_chance = {
base = 80
}
}
# Seek the black market
option = {
name = mistborn_metal.0001.b
trigger = {
intrigue >= 8
}
remove_short_term_gold = 20
random_list = {
70 = {
remove_character_modifier = metal_reserves_low
add_character_modifier = {
modifier = metal_reserves_abundant
years = 1
}
}
30 = {
increase_lord_ruler_attention_effect = yes
custom_tooltip = mistborn_metal.0001.b.fail
}
}
ai_chance = {
base = 40
}
}
# Ration supplies — keep the low modifier but extend awareness
option = {
name = mistborn_metal.0001.c
add_stress = 20
custom_tooltip = mistborn_metal.0001.c.tt
ai_chance = {
base = 10
}
}
}
# ============================================================
# 0010 - Metal Reserves Depleted
# Fires for Allomancers with metal_reserves_low who haven't resupplied
# ============================================================
mistborn_metal.0010 = {
type = character_event
title = mistborn_metal.0010.t
desc = mistborn_metal.0010.desc
theme = intrigue
override_background = {
reference = "gfx/interface/illustrations/event_scenes/corridor.dds"
}
trigger = {
is_allomancer_trigger = yes
has_character_modifier = metal_reserves_low
NOT = { has_character_modifier = metal_reserves_abundant }
NOT = { has_character_modifier = metal_reserves_depleted }
}
weight_multiplier = {
base = 1
}
immediate = {
remove_character_modifier = metal_reserves_low
add_character_modifier = {
modifier = metal_reserves_depleted
years = 1
}
}
# Desperate — we must find metals now
option = {
name = mistborn_metal.0010.a
trigger = {
gold >= 75
NOT = { is_skaa_trigger = yes }
}
remove_short_term_gold = 75
remove_character_modifier = metal_reserves_depleted
add_character_modifier = {
modifier = metal_reserves_abundant
years = 2
}
ai_chance = {
base = 90
}
}
# Risk the black market
option = {
name = mistborn_metal.0010.b
trigger = {
intrigue >= 6
}
remove_short_term_gold = 15
random_list = {
60 = {
remove_character_modifier = metal_reserves_depleted
add_character_modifier = {
modifier = metal_reserves_abundant
years = 1
}
}
40 = {
increase_lord_ruler_attention_effect = yes
custom_tooltip = mistborn_metal.0010.b.fail
}
}
ai_chance = {
base = 50
}
}
# Endure the emptiness
option = {
name = mistborn_metal.0010.c
add_stress = 40
ai_chance = {
base = 5
}
}
}
# ============================================================
# 0020 - Metal Supply Windfall
# Rare event: a lucky break provides metals for free
# ============================================================
mistborn_metal.0020 = {
type = character_event
title = mistborn_metal.0020.t
desc = mistborn_metal.0020.desc
theme = intrigue
override_background = {
reference = "gfx/interface/illustrations/event_scenes/corridor.dds"
}
trigger = {
is_allomancer_trigger = yes
OR = {
has_character_modifier = metal_reserves_low
has_character_modifier = metal_reserves_depleted
}
}
weight_multiplier = {
base = 0.1
}
immediate = {
remove_character_modifier = metal_reserves_low
remove_character_modifier = metal_reserves_depleted
}
# Accept the windfall
option = {
name = mistborn_metal.0020.a
add_character_modifier = {
modifier = metal_reserves_abundant
years = 2
}
ai_chance = {
base = 100
}
}
}
# ============================================================
# 0030 - Wartime Metal Scarcity
# Fires during wars for Allomancer characters — metal consumed faster
# ============================================================
mistborn_metal.0030 = {
type = character_event
title = mistborn_metal.0030.t
desc = mistborn_metal.0030.desc
theme = war
override_background = {
reference = "gfx/interface/illustrations/event_scenes/battlefield.dds"
}
trigger = {
is_allomancer_trigger = yes
is_at_war = yes
has_character_modifier = metal_reserves_abundant
}
weight_multiplier = {
base = 0.3
}
immediate = {
}
# Accept the accelerated consumption
option = {
name = mistborn_metal.0030.a
remove_character_modifier = metal_reserves_abundant
add_character_modifier = {
modifier = metal_reserves_low
years = 1
}
ai_chance = {
base = 30
}
}
# Ration metals carefully — keep abundant but take a stress hit
option = {
name = mistborn_metal.0030.b
add_stress = 30
custom_tooltip = mistborn_metal.0030.b.tt
ai_chance = {
base = 50
}
}
# Spend gold to resupply from wartime merchants
option = {
name = mistborn_metal.0030.c
trigger = {
gold >= 100
}
remove_short_term_gold = 100
custom_tooltip = mistborn_metal.0030.c.tt
ai_chance = {
base = 70
}
}
}
+168
View File
@@ -0,0 +1,168 @@
############################################
# Sandbox Mode Events
# "Discover Your Metallic Arts" — voluntary testing for potential
# Only available in Sandbox game mode
############################################
namespace = mistborn_sandbox
# ============================================================
# TESTING YOUR BLOOD
# Character undergoes voluntary trauma to test for metallic potential
# Results depend on culture — Noble Scadrian, Skaa, or Terris
# ============================================================
mistborn_sandbox.0001 = {
type = character_event
title = mistborn_sandbox.0001.t
desc = mistborn_sandbox.0001.desc
theme = learning
left_portrait = {
character = root
animation = stress
}
trigger = {
is_sandbox_mode_trigger = yes
NOT = { is_allomancer_trigger = yes }
NOT = { is_feruchemist_trigger = yes }
}
immediate = {
# Determine outcome based on culture
if = {
limit = { culture = culture:noble_scadrian }
random_list = {
40 = {
# Allomantic potential found
add_trait = trait_allomantic_potential
set_variable = {
name = sandbox_discovery_result
value = 1
}
}
60 = {
# No potential
set_variable = {
name = sandbox_discovery_result
value = 0
}
}
}
}
else_if = {
limit = { culture = culture:skaa }
random_list = {
20 = {
# Allomantic potential found (diluted bloodlines)
add_trait = trait_allomantic_potential
set_variable = {
name = sandbox_discovery_result
value = 1
}
}
80 = {
# No potential
set_variable = {
name = sandbox_discovery_result
value = 0
}
}
}
}
else_if = {
limit = { culture = culture:terris }
random_list = {
40 = {
# Feruchemical potential found
add_trait = trait_feruchemy_potential
set_variable = {
name = sandbox_discovery_result
value = 2
}
}
15 = {
# Allomantic potential found (rare for Terris)
add_trait = trait_allomantic_potential
set_variable = {
name = sandbox_discovery_result
value = 1
}
}
45 = {
# No potential
set_variable = {
name = sandbox_discovery_result
value = 0
}
}
}
}
else = {
# Other cultures — low chance
random_list = {
15 = {
add_trait = trait_allomantic_potential
set_variable = {
name = sandbox_discovery_result
value = 1
}
}
85 = {
set_variable = {
name = sandbox_discovery_result
value = 0
}
}
}
}
}
# Option A: Allomantic potential found — snap immediately
option = {
name = mistborn_sandbox.0001.a
trigger = {
has_variable = sandbox_discovery_result
var:sandbox_discovery_result = 1
}
# Immediately snap
activate_allomancy_effect = yes
add_stress = 30
remove_variable = sandbox_discovery_result
ai_chance = {
base = 100
}
}
# Option B: Feruchemical potential found — activate
option = {
name = mistborn_sandbox.0001.b
trigger = {
has_variable = sandbox_discovery_result
var:sandbox_discovery_result = 2
}
# Immediately activate Feruchemy
remove_trait = trait_feruchemy_potential
add_trait = trait_feruchemist
add_stress = 20
remove_variable = sandbox_discovery_result
ai_chance = {
base = 100
}
}
# Option C: No potential found
option = {
name = mistborn_sandbox.0001.c
trigger = {
has_variable = sandbox_discovery_result
var:sandbox_discovery_result = 0
}
add_stress = 40
add_gold = 100 # Partial refund
remove_variable = sandbox_discovery_result
ai_chance = {
base = 100
}
}
}
+384
View File
@@ -0,0 +1,384 @@
############################################
# Allomantic Training Event Chain
# A mentor trains a pupil to strengthen their Allomancy
# Completion can grant trait_allomantic_strong
############################################
namespace = mistborn_training
# ============================================================
# TRAINING BEGINS - Choose a training focus
# ============================================================
mistborn_training.0001 = {
type = character_event
title = mistborn_training.0001.t
desc = mistborn_training.0001.desc
theme = education
left_portrait = {
character = root
animation = personality_rational
}
right_portrait = {
character = scope:training_pupil
animation = personality_bold
}
trigger = {
exists = scope:training_pupil
}
immediate = {
# Find a mentor — prefer self if Allomancer, else a courtier
if = {
limit = {
is_allomancer_trigger = yes
}
save_scope_as = training_mentor
}
else = {
random_courtier = {
limit = {
is_allomancer_trigger = yes
}
save_scope_as = training_mentor
}
}
}
# Option A: Combat training - martial focus
option = {
name = mistborn_training.0001.a
scope:training_pupil = {
add_character_flag = {
flag = training_focus_combat
years = 5
}
}
trigger_event = {
id = mistborn_training.0010
days = { 365 730 }
}
ai_chance = {
base = 40
modifier = {
add = 20
scope:training_pupil = {
is_physical_allomancer_trigger = yes
}
}
}
}
# Option B: Subtlety training - intrigue focus
option = {
name = mistborn_training.0001.b
scope:training_pupil = {
add_character_flag = {
flag = training_focus_subtlety
years = 5
}
}
trigger_event = {
id = mistborn_training.0010
days = { 365 730 }
}
ai_chance = {
base = 40
modifier = {
add = 20
scope:training_pupil = {
is_mental_allomancer_trigger = yes
}
}
}
}
# Option C: Endurance training - health/stamina focus
option = {
name = mistborn_training.0001.c
scope:training_pupil = {
add_character_flag = {
flag = training_focus_endurance
years = 5
}
}
trigger_event = {
id = mistborn_training.0010
days = { 365 730 }
}
ai_chance = {
base = 20
}
}
}
# ============================================================
# MID-TRAINING CHALLENGE - A test arises
# ============================================================
mistborn_training.0010 = {
type = character_event
title = mistborn_training.0010.t
desc = mistborn_training.0010.desc
theme = education
left_portrait = {
character = root
animation = worry
}
right_portrait = {
character = scope:training_pupil
animation = personality_bold
}
trigger = {
exists = scope:training_pupil
scope:training_pupil = {
is_alive = yes
has_character_flag = undergoing_allomantic_training
}
}
immediate = {
# Nothing to do — challenge is presented in options
}
# Option A: Push them harder — risk injury for greater reward
option = {
name = mistborn_training.0010.a
scope:training_pupil = {
random_list = {
60 = {
# They rise to the challenge
modifier = {
add = 15
has_trait = brave
}
modifier = {
add = 10
root = { has_trait = trait_mistborn }
}
add_character_flag = {
flag = training_challenge_passed
years = 5
}
custom_tooltip = mistborn_training.0010.a.success
}
30 = {
# They struggle but persevere
add_stress = 20
custom_tooltip = mistborn_training.0010.a.partial
}
10 = {
# Injury during training
add_trait = wounded_1
add_stress = 30
trigger_event = {
id = mistborn_training.0030
days = 7
}
custom_tooltip = mistborn_training.0010.a.injury
}
}
}
# Schedule completion if no interruption
trigger_event = {
id = mistborn_training.0020
days = { 365 730 }
}
ai_chance = {
base = 50
}
}
# Option B: Take a measured approach — safer, lower chance
option = {
name = mistborn_training.0010.b
scope:training_pupil = {
random_list = {
40 = {
# Steady progress
add_character_flag = {
flag = training_challenge_passed
years = 5
}
custom_tooltip = mistborn_training.0010.b.success
}
60 = {
# No breakthrough — adequate but unremarkable
custom_tooltip = mistborn_training.0010.b.adequate
}
}
}
trigger_event = {
id = mistborn_training.0020
days = { 365 730 }
}
ai_chance = {
base = 50
}
}
}
# ============================================================
# TRAINING COMPLETE - Assess the results
# ============================================================
mistborn_training.0020 = {
type = character_event
title = mistborn_training.0020.t
desc = mistborn_training.0020.desc
theme = education
left_portrait = {
character = root
animation = happiness
}
right_portrait = {
character = scope:training_pupil
animation = personality_bold
}
trigger = {
exists = scope:training_pupil
scope:training_pupil = {
is_alive = yes
has_character_flag = undergoing_allomantic_training
}
}
immediate = {
scope:training_pupil = {
# Remove training flag
remove_character_flag = undergoing_allomantic_training
remove_character_flag = training_focus_combat
remove_character_flag = training_focus_subtlety
remove_character_flag = training_focus_endurance
}
}
# Option A: Training succeeds — the pupil grows stronger
option = {
name = mistborn_training.0020.a
trigger = {
scope:training_pupil = {
is_allomancer_trigger = yes
NOT = { has_trait = trait_allomantic_strong }
NOT = { has_trait = trait_allomantic_savant }
}
}
scope:training_pupil = {
# Success chance based on mentor quality and challenge performance
random_list = {
55 = {
modifier = {
add = 20
has_character_flag = training_challenge_passed
}
modifier = {
add = 10
exists = scope:training_mentor
scope:training_mentor = { has_trait = trait_allomantic_strong }
}
modifier = {
add = 15
exists = scope:training_mentor
scope:training_mentor = { has_trait = trait_mistborn }
}
# Success — grant strong Allomancy
if = {
limit = { has_trait = trait_allomantic_weak }
remove_trait = trait_allomantic_weak
}
add_trait = trait_allomantic_strong
custom_tooltip = mistborn_training.0020.a.strong
}
45 = {
modifier = {
add = -20
has_character_flag = training_challenge_passed
}
# Partial success — improvement but not strong
add_prestige = 50
custom_tooltip = mistborn_training.0020.a.improved
}
}
remove_character_flag = training_challenge_passed
}
add_prestige = 100
ai_chance = {
base = 100
}
}
# Option B: Training fails — the pupil did not improve
option = {
name = mistborn_training.0020.b
trigger = {
scope:training_pupil = {
OR = {
NOT = { is_allomancer_trigger = yes }
has_trait = trait_allomantic_strong
has_trait = trait_allomantic_savant
}
}
}
scope:training_pupil = {
add_stress = 15
remove_character_flag = training_challenge_passed
}
add_stress = 10
ai_chance = {
base = 100
}
}
}
# ============================================================
# TRAINING INTERRUPTED - Something disrupts the training
# ============================================================
mistborn_training.0030 = {
type = character_event
title = mistborn_training.0030.t
desc = mistborn_training.0030.desc
theme = secret
left_portrait = {
character = root
animation = worry
}
right_portrait = {
character = scope:training_pupil
animation = fear
}
trigger = {
exists = scope:training_pupil
}
immediate = {
scope:training_pupil = {
# Training ends prematurely
remove_character_flag = undergoing_allomantic_training
remove_character_flag = training_focus_combat
remove_character_flag = training_focus_subtlety
remove_character_flag = training_focus_endurance
remove_character_flag = training_challenge_passed
}
}
# The training is over
option = {
name = mistborn_training.0030.a
add_stress = 20
scope:training_pupil = {
add_stress = 30
}
ai_chance = {
base = 100
}
}
}