﻿# Marriage Planner scoring. Candidate scope; scope:ddm_match_subject and scope:ddm_match_actor are saved
# by the preparation effect. Scores are recommendations only — CK3's own marriage availability remains
# authoritative because candidates come from CK3's spouse-candidate pool and are validated through
# can_marry_character_trigger.

ddm_match_genetic_component_value = {
    value = ddm_quality_trait_value

    # Current adult skills/fertility/reproductive runway are useful for adult spouse selection, but they
    # are intentionally not used to judge a child whose adult stats have not developed yet. This lets the
    # planner rank childhood betrothals primarily by persistent congenital/family qualities rather than
    # treating a six-year-old's temporary skill or fertility values as an adult forecast.
    if = {
        limit = { is_adult = yes }
        add = { value = diplomacy multiply = 1.5 }
        add = { value = martial multiply = 1.5 }
        add = { value = stewardship multiply = 1.5 }
        add = { value = intrigue multiply = 1.5 }
        add = { value = learning multiply = 1.5 }

        if = { limit = { fertility >= 0.80 } add = 90 }
        else_if = { limit = { fertility >= 0.60 } add = 70 }
        else_if = { limit = { fertility >= 0.40 } add = 45 }
        else_if = { limit = { fertility >= 0.20 } add = 20 }
        else_if = { limit = { fertility <= 0 } add = -80 }

        if = {
            limit = { is_female = yes }
            if = { limit = { age <= 24 } add = 60 }
            else_if = { limit = { age <= 29 } add = 45 }
            else_if = { limit = { age <= 34 } add = 25 }
            else_if = { limit = { age <= 39 } add = 5 }
            else = { add = -90 }
        }
        else = {
            if = { limit = { age <= 40 } add = 30 }
            else_if = { limit = { age <= 50 } add = 15 }
            else_if = { limit = { age >= 65 } add = -25 }
        }
    }

    # Current health remains meaningful at any age and is deliberately a modest signal rather than a
    # prediction of exact future fertility.
    if = { limit = { health >= 5 } add = 50 }
    else_if = { limit = { health >= 4 } add = 30 }
    else_if = { limit = { health >= 3 } add = 15 }
    else_if = { limit = { health <= 1 } add = -60 }
    else_if = { limit = { health <= 2 } add = -25 }

    # Reinforcing the same positive congenital line is more valuable than merely adding unrelated
    # traits. The subject is fixed while candidates are ranked.
    if = { limit = { has_trait = intellect_good_3 scope:ddm_match_subject = { has_trait = intellect_good_3 } } add = 180 }
    else_if = { limit = { has_trait = intellect_good_2 scope:ddm_match_subject = { OR = { has_trait = intellect_good_2 has_trait = intellect_good_3 } } } add = 100 }
    else_if = { limit = { has_trait = intellect_good_1 scope:ddm_match_subject = { OR = { has_trait = intellect_good_1 has_trait = intellect_good_2 has_trait = intellect_good_3 } } } add = 45 }

    if = { limit = { has_trait = physique_good_3 scope:ddm_match_subject = { has_trait = physique_good_3 } } add = 135 }
    else_if = { limit = { has_trait = physique_good_2 scope:ddm_match_subject = { OR = { has_trait = physique_good_2 has_trait = physique_good_3 } } } add = 75 }
    else_if = { limit = { has_trait = physique_good_1 scope:ddm_match_subject = { OR = { has_trait = physique_good_1 has_trait = physique_good_2 has_trait = physique_good_3 } } } add = 35 }

    if = { limit = { has_trait = beauty_good_3 scope:ddm_match_subject = { has_trait = beauty_good_3 } } add = 90 }
    else_if = { limit = { has_trait = beauty_good_2 scope:ddm_match_subject = { OR = { has_trait = beauty_good_2 has_trait = beauty_good_3 } } } add = 55 }
    else_if = { limit = { has_trait = beauty_good_1 scope:ddm_match_subject = { OR = { has_trait = beauty_good_1 has_trait = beauty_good_2 has_trait = beauty_good_3 } } } add = 25 }

    if = { limit = { has_trait = fecund } add = 80 }

    # In unmodified CK3, an opposite-sex pairing is the ordinary route to biological children. Keep
    # same-sex candidates available for Love Match, but naturally rank them down when child quality is
    # the objective.
    if = { limit = { sex_opposite_of = scope:ddm_match_subject } add = 90 }
    else = { add = -260 }

    # Kinship is never hidden. 'Allow Dynasty' permits close/extended relatives when CK3 itself permits
    # the marriage, but still carries an explicit risk penalty. Pure-Blood Program relaxes — not erases —
    # that warning because the player deliberately chose a consanguineous strategy.
    if = {
        limit = { is_close_family_of = scope:ddm_match_subject }
        if = { limit = { scope:ddm_match_actor.var:ddm_match_dynasty_mode = 2 } add = -100 }
        else = { add = -260 }
    }
    else_if = {
        limit = { is_extended_family_of = scope:ddm_match_subject }
        if = { limit = { scope:ddm_match_actor.var:ddm_match_dynasty_mode = 2 } add = -30 }
        else = { add = -90 }
    }

    # Pure-Blood Program explicitly prioritizes the dynasty and the Pure-Blooded trait. Candidate
    # availability is still controlled by vanilla marriage rules and the current faith.
    if = {
        limit = { scope:ddm_match_actor.var:ddm_match_dynasty_mode = 2 }
        if = { limit = { dynasty ?= scope:ddm_match_subject.dynasty } add = 175 }
        if = { limit = { has_trait = pure_blooded } add = 300 }
        if = { limit = { has_trait = pure_blooded scope:ddm_match_subject = { has_trait = pure_blooded } } add = 300 }
    }
}


# Optional preference fit. These checks intentionally use only raw character variables/flags, so DDM
# remains completely standalone. When Dominion of Communion is also loaded, its stored preference profile
# becomes an additional love-match signal; when those variables do not exist, this value simply stays 0.
ddm_match_pref_length_delta_value = {
    value = scope:ddm_match_subject.var:domcom_pref_length_tenths
    subtract = var:domcom_length_tenths
}
ddm_match_pref_length_distance_value = {
    value = ddm_match_pref_length_delta_value
    if = { limit = { ddm_match_pref_length_delta_value < 0 } multiply = -1 }
}
ddm_match_pref_girth_delta_value = {
    value = scope:ddm_match_subject.var:domcom_pref_girth_tenths
    subtract = var:domcom_girth_tenths
}
ddm_match_pref_girth_distance_value = {
    value = ddm_match_pref_girth_delta_value
    if = { limit = { ddm_match_pref_girth_delta_value < 0 } multiply = -1 }
}
ddm_match_pref_endowment_distance_value = {
    value = 0
    add = { value = ddm_match_pref_length_distance_value multiply = 0.6 }
    add = { value = ddm_match_pref_girth_distance_value multiply = 0.4 }
}

ddm_match_optional_preference_component_value = {
    value = 0

    # Body build.
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_body = flag:lean_mild } if = { limit = { current_weight <= -20 } add = 6 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_body = flag:lean_strong } if = { limit = { current_weight <= -20 } add = 12 } else = { add = -8 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_body = flag:average_mild } if = { limit = { current_weight > -20 current_weight < 20 } add = 6 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_body = flag:average_strong } if = { limit = { current_weight > -20 current_weight < 20 } add = 12 } else = { add = -8 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_body = flag:heavy_mild } if = { limit = { current_weight >= 20 } add = 6 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_body = flag:heavy_strong } if = { limit = { current_weight >= 20 } add = 12 } else = { add = -8 } }

    # Age preference.
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_age = flag:young_mild } if = { limit = { age < 28 } add = 6 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_age = flag:young_strong } if = { limit = { age < 28 } add = 12 } else = { add = -8 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_age = flag:prime_mild } if = { limit = { age >= 28 age < 45 } add = 6 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_age = flag:prime_strong } if = { limit = { age >= 28 age < 45 } add = 12 } else = { add = -8 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_age = flag:mature_mild } if = { limit = { age >= 45 } add = 6 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_age = flag:mature_strong } if = { limit = { age >= 45 } add = 12 } else = { add = -8 } }

    # Same/different culture preference.
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_culture = flag:same_mild } if = { limit = { culture = scope:ddm_match_subject.culture } add = 5 } else = { add = -5 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_culture = flag:same_strong } if = { limit = { culture = scope:ddm_match_subject.culture } add = 10 } else = { add = -10 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_culture = flag:different_mild } if = { limit = { NOT = { culture = scope:ddm_match_subject.culture } } add = 5 } else = { add = -5 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_culture = flag:different_strong } if = { limit = { NOT = { culture = scope:ddm_match_subject.culture } } add = 10 } else = { add = -10 } }

    # Beauty and intellect preferences.
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_beauty = flag:beautiful_mild } if = { limit = { OR = { has_trait = beauty_good_1 has_trait = beauty_good_2 has_trait = beauty_good_3 } } add = 7 } else = { add = -5 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_beauty = flag:beautiful_strong } if = { limit = { OR = { has_trait = beauty_good_1 has_trait = beauty_good_2 has_trait = beauty_good_3 } } add = 14 } else = { add = -10 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_beauty = flag:plain_mild } if = { limit = { NOR = { has_trait = beauty_good_1 has_trait = beauty_good_2 has_trait = beauty_good_3 has_trait = beauty_bad_1 has_trait = beauty_bad_2 has_trait = beauty_bad_3 } } add = 7 } else = { add = -5 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_beauty = flag:plain_strong } if = { limit = { NOR = { has_trait = beauty_good_1 has_trait = beauty_good_2 has_trait = beauty_good_3 has_trait = beauty_bad_1 has_trait = beauty_bad_2 has_trait = beauty_bad_3 } } add = 14 } else = { add = -10 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_beauty = flag:unconventional_mild } if = { limit = { OR = { has_trait = beauty_bad_1 has_trait = beauty_bad_2 has_trait = beauty_bad_3 } } add = 7 } else = { add = -5 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_beauty = flag:unconventional_strong } if = { limit = { OR = { has_trait = beauty_bad_1 has_trait = beauty_bad_2 has_trait = beauty_bad_3 } } add = 14 } else = { add = -10 } }

    if = { limit = { scope:ddm_match_subject.var:domcom_pref_intellect = flag:brilliant_mild } if = { limit = { OR = { has_trait = intellect_good_1 has_trait = intellect_good_2 has_trait = intellect_good_3 } } add = 6 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_intellect = flag:brilliant_strong } if = { limit = { OR = { has_trait = intellect_good_1 has_trait = intellect_good_2 has_trait = intellect_good_3 } } add = 12 } else = { add = -8 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_intellect = flag:ordinary_mild } if = { limit = { NOR = { has_trait = intellect_good_1 has_trait = intellect_good_2 has_trait = intellect_good_3 has_trait = intellect_bad_1 has_trait = intellect_bad_2 has_trait = intellect_bad_3 } } add = 6 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_intellect = flag:ordinary_strong } if = { limit = { NOR = { has_trait = intellect_good_1 has_trait = intellect_good_2 has_trait = intellect_good_3 has_trait = intellect_bad_1 has_trait = intellect_bad_2 has_trait = intellect_bad_3 } } add = 12 } else = { add = -8 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_intellect = flag:simple_mild } if = { limit = { OR = { has_trait = intellect_bad_1 has_trait = intellect_bad_2 has_trait = intellect_bad_3 } } add = 6 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_intellect = flag:simple_strong } if = { limit = { OR = { has_trait = intellect_bad_1 has_trait = intellect_bad_2 has_trait = intellect_bad_3 } } add = 12 } else = { add = -8 } }

    # Prowess / physicality and social status.
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_prowess = flag:low_mild } if = { limit = { prowess < 8 } add = 5 } else = { add = -3 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_prowess = flag:low_strong } if = { limit = { prowess < 8 } add = 10 } else = { add = -6 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_prowess = flag:balanced_mild } if = { limit = { prowess >= 8 prowess < 16 } add = 5 } else = { add = -3 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_prowess = flag:balanced_strong } if = { limit = { prowess >= 8 prowess < 16 } add = 10 } else = { add = -6 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_prowess = flag:high_mild } if = { limit = { prowess >= 16 } add = 5 } else = { add = -3 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_prowess = flag:high_strong } if = { limit = { prowess >= 16 } add = 10 } else = { add = -6 } }

    if = { limit = { scope:ddm_match_subject.var:domcom_pref_status = flag:unlanded_mild } if = { limit = { is_landed = no } add = 5 } else = { add = -3 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_status = flag:unlanded_strong } if = { limit = { is_landed = no } add = 10 } else = { add = -6 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_status = flag:landed_mild } if = { limit = { is_landed = yes highest_held_title_tier < tier_kingdom } add = 5 } else = { add = -3 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_status = flag:landed_strong } if = { limit = { is_landed = yes highest_held_title_tier < tier_kingdom } add = 10 } else = { add = -6 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_status = flag:royal_mild } if = { limit = { highest_held_title_tier >= tier_kingdom } add = 5 } else = { add = -3 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_status = flag:royal_strong } if = { limit = { highest_held_title_tier >= tier_kingdom } add = 10 } else = { add = -6 } }

    # Personality archetypes. These are only activated when the corresponding DoC variable exists.
    if = { limit = { OR = { scope:ddm_match_subject.var:domcom_pref_personality = flag:gentle_mild scope:ddm_match_subject.var:domcom_pref_personality = flag:gentle_strong } } if = { limit = { OR = { has_trait = compassionate has_trait = forgiving has_trait = calm has_trait = generous } } add = 8 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_personality = flag:gentle_strong } if = { limit = { OR = { has_trait = compassionate has_trait = forgiving has_trait = calm has_trait = generous } } add = 8 } else = { add = -4 } }
    if = { limit = { OR = { scope:ddm_match_subject.var:domcom_pref_personality = flag:forceful_mild scope:ddm_match_subject.var:domcom_pref_personality = flag:forceful_strong } } if = { limit = { OR = { has_trait = brave has_trait = wrathful has_trait = ambitious has_trait = arrogant } } add = 8 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_personality = flag:forceful_strong } if = { limit = { OR = { has_trait = brave has_trait = wrathful has_trait = ambitious has_trait = arrogant } } add = 8 } else = { add = -4 } }
    if = { limit = { OR = { scope:ddm_match_subject.var:domcom_pref_personality = flag:cunning_mild scope:ddm_match_subject.var:domcom_pref_personality = flag:cunning_strong } } if = { limit = { OR = { has_trait = deceitful has_trait = callous has_trait = arbitrary has_trait = sadistic } } add = 8 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_personality = flag:cunning_strong } if = { limit = { OR = { has_trait = deceitful has_trait = callous has_trait = arbitrary has_trait = sadistic } } add = 8 } else = { add = -4 } }
    if = { limit = { OR = { scope:ddm_match_subject.var:domcom_pref_personality = flag:social_mild scope:ddm_match_subject.var:domcom_pref_personality = flag:social_strong } } if = { limit = { OR = { has_trait = gregarious has_trait = lustful has_trait = generous } } add = 8 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_personality = flag:social_strong } if = { limit = { OR = { has_trait = gregarious has_trait = lustful has_trait = generous } } add = 8 } else = { add = -4 } }
    if = { limit = { OR = { scope:ddm_match_subject.var:domcom_pref_personality = flag:reserved_mild scope:ddm_match_subject.var:domcom_pref_personality = flag:reserved_strong } } if = { limit = { OR = { has_trait = shy has_trait = temperate has_trait = diligent has_trait = chaste } } add = 8 } else = { add = -4 } }
    if = { limit = { scope:ddm_match_subject.var:domcom_pref_personality = flag:reserved_strong } if = { limit = { OR = { has_trait = shy has_trait = temperate has_trait = diligent has_trait = chaste } } add = 8 } else = { add = -4 } }

    # If DoC has measured the candidate and stored an exact preferred length/girth on the subject,
    # incorporate that fit too. This is deliberately a secondary signal behind an actual lover/soulmate.
    if = {
        limit = {
            is_male = yes
            has_variable = domcom_length_tenths
            has_variable = domcom_girth_tenths
            scope:ddm_match_subject = {
                has_variable = domcom_pref_length_tenths
                has_variable = domcom_pref_girth_tenths
            }
        }
        if = { limit = { ddm_match_pref_length_distance_value <= 2 ddm_match_pref_girth_distance_value <= 2 } add = 64 }
        else_if = { limit = { ddm_match_pref_endowment_distance_value <= 5 } add = 48 }
        else_if = { limit = { ddm_match_pref_endowment_distance_value <= 10 } add = 32 }
        else_if = { limit = { ddm_match_pref_endowment_distance_value <= 15 } add = 16 }
        else_if = { limit = { ddm_match_pref_endowment_distance_value <= 20 } add = 0 }
        else_if = { limit = { ddm_match_pref_endowment_distance_value <= 30 } add = -20 }
        else_if = { limit = { ddm_match_pref_endowment_distance_value <= 40 } add = -32 }
        else = { add = -40 }
    }

    min = -100
    max = 140
    round = yes
}

ddm_match_love_component_value = {
    value = 0

    # Existing feelings dominate a love match.
    if = { limit = { has_relation_soulmate = scope:ddm_match_subject } add = 700 }
    else_if = { limit = { has_relation_lover = scope:ddm_match_subject } add = 500 }
    else_if = { limit = { has_relation_crush = scope:ddm_match_subject } add = 300 }
    if = { limit = { has_relation_friend = scope:ddm_match_subject } add = 90 }

    # Sexual orientation and Dominion body preferences are adult relationship signals. Childhood planning
    # deliberately does not score either child through adult sexual systems; friendship, crushes, opinion,
    # culture and faith can still distinguish Love-oriented childhood matches.
    if = {
        limit = {
            is_adult = yes
            scope:ddm_match_subject = { is_adult = yes }
        }
        if = {
            limit = {
                is_attracted_to_gender_of = scope:ddm_match_subject
                scope:ddm_match_subject = { is_attracted_to_gender_of = prev }
            }
            add = 180
        }
        else_if = {
            limit = {
                OR = {
                    is_attracted_to_gender_of = scope:ddm_match_subject
                    scope:ddm_match_subject = { is_attracted_to_gender_of = prev }
                }
            }
            add = 40
        }
        else = { add = -140 }

        # If Dominion of Communion is present, honor the adult character's stored partner preferences too.
        # DDM does not depend on DoC; absent preference variables contribute exactly zero.
        add = ddm_match_optional_preference_component_value
    }

    # Candidate's own opinion is useful evidence of willingness/affection and is cheap to evaluate.
    add = { value = "opinion(scope:ddm_match_subject)" multiply = 1.5 }

    # Shared culture/faith are modest compatibility tie-breakers, not hard requirements.
    if = { limit = { faith = scope:ddm_match_subject.faith } add = 35 }
    if = { limit = { culture = scope:ddm_match_subject.culture } add = 25 }
}

ddm_match_child_score_value = {
    value = ddm_match_genetic_component_value
}

# ---------------------------------------------------------------------------
# FIRST-PASS / SHORTLIST SCORING
#
# The shortlist no longer uses an approximation for children. Every candidate gets the FULL child-quality
# calculation before the pool is cut: congenital-trait quality, same-line reinforcement, Pure-Blooded
# weighting, fertility, health, reproductive runway, parental skills, sex and kinship all count here.
#
# Love remains lightweight in this first pass so Dominion preference variables and the more detailed
# compatibility work are only evaluated on the shortlist. Best Children therefore has an exact child
# ranking at the shortlist gate; Love + Good Children and Love Match have an exact child component plus a
# lightweight love component, followed by their full score on the retained candidates.
# ---------------------------------------------------------------------------

ddm_match_prescreen_children_value = {
    value = ddm_match_child_score_value
}

ddm_match_prescreen_love_value = {
    value = 0

    if = { limit = { has_relation_soulmate = scope:ddm_match_subject } add = 700 }
    else_if = { limit = { has_relation_lover = scope:ddm_match_subject } add = 500 }
    else_if = { limit = { has_relation_crush = scope:ddm_match_subject } add = 300 }
    if = { limit = { has_relation_friend = scope:ddm_match_subject } add = 90 }

    add = { value = "opinion(scope:ddm_match_subject)" multiply = 1.5 }

    if = { limit = { faith = scope:ddm_match_subject.faith } add = 35 }
    if = { limit = { culture = scope:ddm_match_subject.culture } add = 25 }
}

ddm_match_candidate_prescreen_value = {
    value = 0

    # 1 = Best Children, 2 = Love + Good Children, 3 = Love Match.
    if = {
        limit = { scope:ddm_match_subject.var:ddm_match_effective_policy = 1 }
        add = ddm_match_prescreen_children_value
    }
    else_if = {
        limit = { scope:ddm_match_subject.var:ddm_match_effective_policy = 2 }
        add = { value = ddm_match_prescreen_children_value multiply = 0.70 }
        add = ddm_match_prescreen_love_value
    }
    else = {
        add = { value = ddm_match_prescreen_children_value multiply = 0.20 }
        add = { value = ddm_match_prescreen_love_value multiply = 1.50 }
    }
}

# Cache-stamp comparisons. Kept as script values so the cache trigger compares a stored variable against
# a value rather than against another variable expression.
ddm_match_effective_policy_value = {
    value = var:ddm_match_effective_policy
}
ddm_match_actor_dynasty_mode_value = {
    value = scope:ddm_match_actor.var:ddm_match_dynasty_mode
}
ddm_match_actor_scan_generation_value = {
    value = scope:ddm_match_actor.var:ddm_match_scan_generation
}

ddm_match_candidate_score_value = {
    value = 0

    # 1 = Best Children, 2 = Love + Good Children, 3 = Love Match.
    if = {
        limit = { scope:ddm_match_subject.var:ddm_match_effective_policy = 1 }
        add = ddm_match_child_score_value
    }
    else_if = {
        limit = { scope:ddm_match_subject.var:ddm_match_effective_policy = 2 }
        add = { value = ddm_match_child_score_value multiply = 0.70 }
        add = ddm_match_love_component_value
    }
    else = {
        add = { value = ddm_match_child_score_value multiply = 0.20 }
        add = { value = ddm_match_love_component_value multiply = 1.50 }
    }
}

ddm_match_subject_priority_value = {
    value = 0
    if = { limit = { this = scope:ddm_match_actor } add = 10000 }
    if = { limit = { exists = scope:ddm_match_actor.player_heir this = scope:ddm_match_actor.player_heir } add = 7000 }
    if = { limit = { is_close_family_of = scope:ddm_match_actor } add = 2500 }
    add = ddm_dynastic_value
    if = { limit = { age <= 35 } add = 250 }
}


# Marriage Planner list sorting. These are deliberately cheap character values so the normal Individual view
# can sort huge dynasties without running a spouse-candidate search for every member.
ddm_match_subject_dynastic_sort_value = {
    value = ddm_dynastic_value
}
ddm_match_subject_age_sort_value = {
    value = age
}
ddm_match_subject_fertility_sort_value = {
    value = fertility
    multiply = 100
}
ddm_match_subject_skills_sort_value = {
    value = diplomacy
    add = martial
    add = stewardship
    add = intrigue
    add = learning
    add = prowess
}

# Pair-board sorting reads the cached values stored on the subject when the non-conflicting plan is built.
ddm_match_pair_score_sort_value = {
    value = var:ddm_match_pair_score
}
ddm_match_pair_child_sort_value = {
    value = var:ddm_match_pair_genetic
}
ddm_match_pair_love_sort_value = {
    value = var:ddm_match_pair_love
}
ddm_match_pair_kinship_sort_value = {
    value = var:ddm_match_pair_kinship
}

# Dynasty Plan decides contested candidates in descending Individual-match strength, then reserves both
# characters. This is a fast global heuristic rather than an exponential all-pairings optimizer.
ddm_match_plan_subject_priority_value = {
    value = var:ddm_match_best_score
}

# ---------------------------------------------------------------------------
# Display reference scales.
# These are intentionally reference denominators rather than hard engine caps: CK3 and other mods can
# push skills beyond vanilla ranges. They make a raw score legible without changing ranking mathematics.
# ---------------------------------------------------------------------------
ddm_match_child_reference_max_value = { value = 2500 }
ddm_match_love_reference_max_value = { value = 1320 }

ddm_match_total_reference_max_value = {
    value = 2500
    if = {
        limit = { var:ddm_match_effective_policy = 2 }
        add = 570 # 70% of 2500 + 1320 = 3070
    }
    else_if = {
        limit = { var:ddm_match_effective_policy = 3 }
        subtract = 20 # 20% of 2500 + 150% of 1320 = 2480
    }
}

ddm_match_pair_direct_sort_value = {
    value = 0
    if = { limit = { has_variable = ddm_match_pair_managed } add = 1000 }
}
