Scaling Curves
Scaling curves limit late-game stat inflation. When an attribute exceeds a threshold, only the exceeding part is reduced by a curve. This keeps progression valuable while preventing equipment, gems, strengthening, and sets from breaking combat balance.
Recommended use cases
Apply scaling curves first to:
- Main damage attributes:
physical_attack,projectile_attack,spell_attack. - Defense attributes:
physical_defense,projectile_defense,spell_defense. - Probability attributes such as critical chance, dodge chance, and lifesteal chance.
- Resource caps such as health and mana.
- Penetration, damage reduction, cooldown reduction, or other attributes near hard caps.
Configuration
Scaling curves are configured in config.yml. The section is empty by default, so no decay applies until you add a rule.
scaling_curves:
physical_attack_cap:
attribute: "physical_attack"
threshold: 500
curve_type: "logarithmic"
factor: 100The entry key is the rule id. When attribute is omitted the key itself is used as the attribute id, so the rule above can also be written as physical_attack: {threshold: 500, factor: 100}.
| Field | Description |
|---|---|
attribute | Attribute id affected by this rule. |
threshold | Value where diminishing returns begin; negative values are treated as 0. |
curve_type | logarithmic (default), sqrt, or piecewise_linear (alias linear). Unrecognized values fall back to logarithmic and are reported by the config precheck. |
factor | Curve factor; exact meaning depends on curve type. logarithmic / sqrt divide by it, so values <= 0 are treated as 1. piecewise_linear uses it as a retention ratio, where 0 is valid and drops the whole excess. |
Final value can be understood as:
final = threshold + reduced_excessCurve types
logarithmic
Good for main damage and defense attributes. Growth continues after the threshold but slows down smoothly.
sqrt
Also has a decreasing slope. Suitable for defense, mitigation, or resource caps.
CAUTION
Two caveats:
- At the same
factor, sqrt is actually weaker than logarithmic (withfactor: 100and an excess of 500, logarithmic yields 179 while sqrt yields 224). For stricter control, use logarithmic or lowerfactorsubstantially. - It is implemented as
sqrt(factor * excess), so when the excess is smaller thanfactorthe result exceeds the excess, amplifying instead of reducing. Withfactor: 80, a raw value of 440 (excess 40) resolves to400 + 56.6 = 456.6. Keepfactorbelow the smallest excess you care about to stay out of that range.
piecewise_linear
Keeps a fixed ratio of the excess part. Useful for probability attributes or rules that should be easy to reason about.
NOTE
Despite the name, this is a single excess * factor discount and does not support multiple segments. The name is kept for compatibility with existing configs.
scaling_curves:
crit_rate_cap:
attribute: "physical_crit_rate"
threshold: 80
curve_type: "piecewise_linear"
factor: 0.3If the raw value is 100, the final value is about 80 + (20 * 0.3) = 86.
Relationship with attribute value limits
Scaling curves run first; the min_value / max_value / allow_negative limits from the attribute definition run after. The full order is: aggregate all sources → scaling curves → derived attributes → value limits.
A curve result is therefore still bound by the attribute's own range. The 86 above sits inside physical_crit_rate's [0, 100] range and is unaffected, but if a loose curve still leaves the value above max_value, the final value is pushed back to max_value. The two layers complement each other: curves keep growth smooth, ranges enforce the hard cap.
Tuning notes
- Set thresholds near reasonable endgame values, not beginner values.
- Avoid multiple curve rules for the same attribute unless you have a clear reason.
- Test low, mid, endgame, and extreme-stacked characters after changing curves.
- If growth feels too weak, increase
thresholdorfactor; if too strong, lower them or use a stronger curve.