Expand description
Functions and constants here mirror the original balance.yaml script,
which contained the project’s fundamental combat and economic balance
formulas. Content-dependent lookups (item rarity quality, ability
rarity effectiveness, fixed-power items) are sourced from
ContentLookups, which is populated at engine init time by reading
the content_raw module’s data maps.
Structs§
- Ability
Combat Profile - Combat-honest contribution of one slotted ability to the power scalar.
- Balance
Tuning
Enums§
- Enemy
Curve Mode - Which formula
enemy_power_for_chapteruses.
Constants§
- ABILITY_
MILESTONES - Ability upgrade milestones: on top of the linear +5%/level, levels 5 and
10 grant a multiplicative jump — a proximate milestone that makes the
dup-shard chase eventful instead of a flat drip. UNIVERSAL for every
ability (gacha, class kits, pet ults) — no per-content flags; tooltips
(
ability_info(level)) and the honest power scalar recompute automatically because everything routes throughability_eff. Sizing: ×1.10 at L5 ≈ two extra linear levels, ×1.20 at L10 ≈ four — noticeable, but small enough that the shard economy absorbs it. - AOE_
COEF - ATTACKS_
PER_ SEC - INCOMING enemy hits/s on the player — prices counterattack (the scalar term
and the item roll are FD-invariant: FD cancels, only this rate matters).
Deliberately independent of
CASTS_PER_SEC— the player’s cast rate says nothing about enemy attack rate. Derivation: combat schedules each mob’s next cast atcurrent_tick + scaled_cooldown(logic/fighting.rs), so a mob attacks everycd— mob basic attacks run cd 1.0-1.7s (typ. 1.4 ⇒ ~0.7 atk/s). Campaign waves hold a median 5 mobs, declining as they die (time-avg attackers ≈ 2.5, further shaved by approach/spawn delays): ≈ 2.5 × 0.7 ≈ 1.8 hits/s. Boss fights run lower (single attacker) — this is the campaign-mix weight. - ATTR_
DEVIATION - ATTR_
DEVIATION_ LEVEL_ ONE - Level-1 rolls use a wider deviation than the 2..=25 band: level-1 stat values are tiny integers, so ±10% would be flattened by flooring and every roll of the single early template per (rarity, slot) cell came out a clone of the scripted starters.
- AUX_
ATTR_ IMPACT - BALANCE_
TUNING_ DEFAULT - Tuning with every knob at its constant default.
- BASE_
ATTACK - BASE_
CRIT_ CHANCE - BASE_
CRIT_ MOD - BASE_HP
- BASE_
POWER - BASE_
SPEED - BASE_
SPELL_ EFF - BOSS_
ENCOUNTER_ COEF_ SQ - One total normalized encounter coefficient for every boss on every chapter,
FTUE included:
sqrt(1.30). It covers the WHOLE encounter budget including a potential summon wave — adds never get a secondsqrt(1.30)on top. Hand-authored per-chapter boss ratios and the legacy ch12/13/14 bumps are removed: no chapter through ch21 may read as a wall. - BOSS_
OUTGOING_ EQUIVALENCE_ KNOTS - A2-BAL-001 frozen outgoing-equivalence correction after removal of the
automatic boss stun. These are measured
D_old / D_unstunnedratios from the signed reference matrix, not a reconstructed duty-cycle formula: boss kits contain both Attack-derived and flat payloads, so only the complete deterministic trace can preserve the previously shipped outgoing budget. - BRAVERY_
BUFF_ DURATION - BRAVERY_
BUFF_ QUANTITY - BUFF_
EFF - CASTS_
PER_ SEC - PLAYER cast rate (casts/s) — prices the bravery/deceit on-cast proc uptime
(
buff_uptime_mult*). Near-honest for a filled loadout: ~6 slotted abilities at cd 2-6s + class basic at cd 1s ⇒ Σ1/cd ≈ 1.5-2.5 casts/s. - CHAPTER_
POWER_ STEP - CLASS_
MAX_ RANK - CLASS_
RANK_ PAYLOAD_ STEP - Payload multiplier of a CLASS ability at
rank:×[1.0, 1.1, … 1.6]over ranks 1..=7 (BAL-034). - COUNTERATTACK_
POWER - DECEIT_
DEBUFF_ DURATION - DECEIT_
DEBUFF_ QUANTITY - DMG_K
- DOT_
TICK_ MAX_ PCT - EFF_A1
- EFF_A2
- EFF_B1
- EFF_B2
- EFF_C1
- EFF_C2
- EFF_
MIDGAME_ LEVEL - ENEMY_
CURVE_ ANCHOR_ CHAPTER - ENEMY_
CURVE_ ANCHOR_ POWER - ENEMY_
EARLY_ BUMP - Early-game stat-check bump strength.
1.0= OFF, deliberately: the hand-made→formula transition already lands the early chapters taut on its own, and playtesting showed a bump here makes stages 1-3..1-5 feel punishing (“cleared by luck”) — so the geometric step runs cleanly through the early game instead. Tune viaOVERLORD_BAL_ENEMY_EARLY_BUMP. - ENEMY_
MID_ BUMP - Mid-game enemy bump — applied only to CampaignBossFight, over the
ch12–14 window (see [
enemy_mid_chapter_mult]). Applied viaOVERLORD_BAL_ENEMY_MID_BUMP. stage2-bridge (2026-07-16) lowered it 8.0 → 2.5 and moved the window off the stage-2 boundary: at 8.0 the gate slammed ×5.67/×4.89 onto the ch10/ch11 bosses — the first stage-2 fights — an instant wall for a fresh-ladder player exiting the new easy stage 1. The legacy ch7 rationale is moot (ch0-9 is hand-authored now, the gate never fired there). At 2.5 the gear-check is a boss EMPHASIS (bot boss-win ~0.9 at ch12-14, vs wave ~1.0) landing mid-bridge where the wave curve is comfortable, not a wall; a frozen (non-gearing) player is already walled by the wave curve. Wave fights are unaffected (the bump is applied inenemy_power_scalar, not inenemy_power_for_chapter), so the global power curve stays monotone. stage2-bridge CYCLE 2 (2026-07-16): lowered 2.5 → 1.3 for the casual re-pacing test — a gentle ch12-14 boss emphasis (at-cadence boss ~80% win) rather than a gear-check, so no chapter reads as a wall. The smooth cadence-ramped wave curve now carries all the difficulty shaping. - ENEMY_
STEP_ LATE - ENEMY_
STEP_ TAPER_ START - E_
BASE_ KNOTS - Smooth early
E_basecalibration through chapter 45. The knots only bridge FTUE and the first-hour feature/power ramp; after chapter 45 one universal geometric multiplier owns the entire campaign tail (seee_base). - FIGHT_
DURATION - Ability-budget window (seconds) — the measured length of a typical campaign
fight (weighted median from battle-end telemetry; win-only fights run
longer). It is a WEIGHT in the ability-damage budget (
eff·FD/(FD+cd)·cd, combat AND scalar — the two share the primitive, so they cannot desync) and in the regen/HoT-as-EHP conversion. The counterattack term and the item counterattack roll are FD-invariant (FD cancels in their ratios — onlyATTACKS_PER_SECprices them). Changing this constant re-scales ability damage and the honest scalar together, so it requires the full coderive recalibration cycle (η + growth knots), same as any scalar-changing edit. - HAND_
AUTHORED_ CHAPTER_ MAX - Highest 0-based
current_chapter_levelat whichenemy_power_scalarresolves campaign enemy power from the hand-authoredFightTemplate.power(base_power) instead of the derived chapter curve. Set to 9 so the ENTIRE first stage (levels 0..=9 = stages 1-1..1-10) is hand-authored onboarding difficulty: the coderived curve AND the ch7-15 mid-boss gear gate do NOT apply inside stage 1 (the gate still starts at ch10 = stage 2-1). - HEAL_
COEF - HOT_
TICK_ MAX_ PCT - Per-tick caps for HoT/DoT effects, as a fraction of max HP — safety so a mis-tuned ability effect can’t out-heal all damage (HoT) or one-shot (DoT). Generous (these are ability-derived, already bounded by ability balance); the cap only catches pathological values. Seed; sim-calibrated.
- ITEM_
XP_ BREAK_ LEVEL - ITEM_
XP_ COEF - ITEM_
XP_ EXP - ITEM_
XP_ LATE_ EXP - K_ARMOR
- K_DODGE
- K_
HP_ KNOTS - Multiplier on encounter HP, checked against the player’s DPS.
- K_
OUT_ KNOTS - Multiplier on enemy outgoing damage, checked against the player’s EHP. See
K_HP_KNOTS— same shape, same default, the other axis. - LEVEL_
ONE_ ATTR_ MEAN - Mean of the level-1 attribute spread — level-1 items are deliberately weak (the scripted starters and the first chest drops share it).
- MAIN_
ATTRS_ QUANTITY - MIN_
RECEIVED_ DAMAGE_ K - Minimum
received_damagemultiplier (in /10000 units) so heavy mitigation (e.g. stackedprotection) can’t reach ≤0 → unkillable. 100 ⇒ ≤99% reduction. - MIN_
STAT_ MOD_ MULT - Floor on a stat’s
.modmultiplier inget_entity_stat, so a stacking.moddebuff (e.g.weaknesson attack,protectionon received_damage) can’t drive a stat to ≤0 (zero-damage / unkillable). 0.05 ⇒ ≤95% debuff. Only bites at mod ≤ −9500; no-mod / buff stats are unaffected. - OT_COEF
- PET_
ULT_ EFFECTIVE_ CD - Expected seconds between pet-ult casts for the honest scalar. The pet ult
is charge-gated, not cooldown-gated (
charge_rate_on_skill_use/_on_damage_dealt/_on_damage_takenfillmax_charge), so its template cooldown says nothing about throughput. With the shipped charge profiles (max_charge 1000, rates 5-40 per trigger) a fight fills the bar roughly once per ~12s of combat — a deliberate round number until a sim remeasure; the pet’s per-cast budget divided by this is the honest DPS/heal rate. - PLAYER_
GROWTH_ KNOTS - Reference player (free archetype) honest power per chapter — sparse
calibration knots
(chapter, power). - POWER_
NORM - Power-scalar normalisation. Anchors a reference character
(attack=
BASE_ATTACK, hp=BASE_HP, neutral elsewhere) atBASE_POWER, so the displayed Combat-Power integer stays on the established scale while the formula underneath isP = DPS × EHP. = 600·3000/1000 = 1800. - REGEN_
PERCENT_ CODE - Share of MAX HP an entity regenerates per second, in permyriad (
100=1%/s). BAL-034 gives the regen class a specialization that keeps meaning something as HP pools grow: a flat rate authored for early gear is noise by the time a player has ten times the HP. - REGEN_
TICK_ MAX_ PCT - Cap on per-tick combat regen, as a fraction of max HP. The
Regeneration_rateeffect fires ~1×/s, so over aFIGHT_DURATIONfight this bounds combat regen to ≈0.5×HP ⇒ ≈×1.5 EHP at the cap. The power scalar’s regen-as-EHP is derived from this same value (power_from_attrs) so display/matchmaking can never over-rate what combat delivers — there is deliberately no separate scalar regen cap. - RHO_
TARGET_ KNOTS - Designed pressure profile — sparse knots, geometric interpolation. THE designer-editable difficulty curve: raise a knot to make that zone easier (player further ahead), lower it for pressure.
- SELL_
PRICE_ COEF - SELL_
PRICE_ EXP - SPELL_
QUANTITY - S_
REF_ KNOTS - Early analytic
S_refseed for FTUE and first-hour diagnostics. Runtime difficulty after FTUE is authored byE_base; no second hand-written reference ladder exists beyond the universal-tail anchor. - WAVE_
DAMAGE_ SKEW - WAVE_
HP_ SKEW - ZONE_
DIFFICULTY_ KNOTS - Zone difficulty correction z(ch): how much harder (>1) or easier (<1) a chapter’s content plays than the honest per-fight scalar P/E predicts. The corrected ratio ρ̂ = P/(z·E) is a sufficient statistic for winrate: its 50%-crossing is ≈0.55 in EVERY zone (the stat-check contract “come with power” needs the ratio to mean the same thing everywhere).
Functions§
- ability_
combat_ profile - Combat-honest profile of one ability instance. Uses the per-ability
content::ability_infosplit where one exists; abilities without a bespoke closure (some class/buff abilities) fall back to a pure-damage assumption at theireff × FD/(FD+cd)throughput — the closest honest default. - ability_
damage_ from_ id - ability_
damage_ from_ rarity - ability_
eff - ability_
power_ mults - Aggregate the equipped abilities into the two power-axis multipliers:
(dps_mult, ehp_mult). - ability_
profile_ from_ info - Pure split of an
crate::mechanics::content::AbilityInfobudget into the (dps_add, heal_add) axes. Separated from the config lookup so the arithmetic is unit-testable without prod ability UUIDs. - armor_k
- attr_
spread_ for_ item - attr_
spread_ random - aux_
attr_ eff - aux_
attr_ eff_ for_ item - axis_
multiplier - Shared reader for both axes: log-space interpolation between sparse knots, held flat outside them, identity when unauthored.
- boss_
outgoing_ equivalence - bravery_
p_ from_ eff - buff_
uptime_ mult - Multiplicative buff/debuff factor from a proc chance
p(0..1): a buff of strengthBUFF_EFFheld for a mean uptime, stackedquantitytimes. Preserves the legacy(1 + (BUFF_EFF−1)·uptime)^quantityshape exactly. - buff_
uptime_ mult_ branches - Honest two-branch pricing for bravery/deceit: a proc picks RANDOMLY between an offensive branch (empower/vulnerability = ×1.5 in power terms) and a defensive one (protection/weakness = ×0.5 damage/attack ⇒ ×2.0 in power terms) — each branch runs at HALF the proc uptime. A single-EFF shape would under-value the defensive branch ~25% at high uptime. Power is DPS×EHP, so the combined factor applies wherever the caller multiplies it in.
- cap_
per_ tick - Per-tick heal/damage cap:
amountbounded above bypct × max_hp. Used by the regen / HoT / DoT combat ticks so a mis-tuned effect can’t out-heal all incoming damage (regen/HoT) or one-shot (DoT). Pure + testable;pctcomes from the matchingtuning()knob (regen|hot|dot_tick_max_pct). - character_
attrs_ power - The
attrs_powerterm ofcharacter_power: char-level attributes, inventory items and pet stats composed into anAttrMapand run throughpower_from_attrs— WITHOUT the trailing* ability_eff_summultiplier. - character_
attrs_ power_ raw character_attrs_powerbefore the floor, for callers that RANK loadouts rather than display a number. Seepower_from_attrs_rawfor why the integer is unusable as a sort key.- character_
power - Character power over the items+pets subset (marginal gear-compare path and
arena-bot power): composed attrs →
power_from_attrs→ honest ability multipliers (ability_power_mults, DPS/EHP-split). - character_
power_ from_ attrs - Combat-power scalar from an already-composed
AttrMapplus equipped abilities —floor(power_from_attrs(attrs) × dps_mult × ehp_mult)with the honest ability multipliers (ability_power_mults). - character_
power_ from_ attrs_ raw character_power_from_attrsbefore the floor — theP_staticterm ofP_ui = floor(P_static × Πq)(BAL-030).- class_
rank_ payload_ mult - compose_
character_ attrs - Compose the char-level + items + pets attribute map (the input to
power_from_attrs) plus the summed per-itempower_bonusjitter. Extracted fromcharacter_attrs_powersocharacter_powercan reuse the composed attrs for the honest ability EHP cap (it needshp/attack). - day_
by_ level - deceit_
p_ from_ eff - e_base
- Unrounded
E_base(ch)across the whole ladder. - eff_
by_ level - eff_
item_ with_ config - eff_
spell_ by_ level - effect_
cost - effect_
duration - enemy_
boss_ power - Boss encounter power at
chapter, floored once at the end. - enemy_
power_ derived - The derived-mode curve
G(ch)/(ρ̂(ch)·z(ch)), orNonewhen the calibration tables are not baked — callers fall back to legacy. ρ̂ is the zone-corrected pressure target and z the zone difficulty correction; their product is the raw-scalar pressure the curve implements. - enemy_
power_ for_ chapter - Absolute enemy power at
chapter:ANCHOR · ∏ step(c), where the per-chapter step is the constantchapter_power_stepuntilenemy_step_taper_start, then decays smoothly towardenemy_step_lateso late-game difficulty tracks the player’s decelerating power (no multi-day stalls). With the taper OFF (enemy_step_late >= chapter_power_step) this is the original closed formANCHOR · STEP^(chapter − ANCHOR_CH). A tapering early-chapter bump (see [enemy_early_chapter_mult]) multiplies the result. - enemy_
power_ scalar - Enemy “power” scalar for a fight — the value
spawn_wavefeeds into the HP/attack curve, and the apples-to-apples counterpart of the player’scharacter.power(both normalized toBASE_POWER). For campaign fights: at/belowHAND_AUTHORED_CHAPTER_MAX(the whole first stage) it is the hand-authoredFightTemplate.power(base_power) with NO mid-boss gate; above it the rebalanced geometric curve (enemy_power_for_chapter, which carries the sweepable anchor/step + the early-chapter bump), with a boss bump. For DUNGEON fights it is always the authored per-difficultybase_power(see below). Shared so the battle-end analytics report exactly the value the fight spawned. - enemy_
wave_ power - Ordinary wave power at
chapter, floored once at the end. There is no chapter-specific wall layer: the smooth base curve is the whole scalar. - get_
attr_ from_ attrs attrs.get_attr(name): read the composed attribute value from an attribute map. Returns(base + bonus) * (1 + bonus / 10000.0).- hp_
k_ for_ chapter - hp_
k_ for_ level - init_
tuning - Set the process-wide balance tuning once at startup (first call wins).
- interp_
geometric - Geometric (log-linear) interpolation over sparse
(chapter, value)knots: exact at knots, constant before the first, final-segment ratio extrapolation past the last (the measured late slope continues — the treadmill contract’s “progress never fully stops” shape). - item_
experience - Character XP paid by selling one item, from the item’s snapshot character
leveland its quality multiplierquality(the rarity axisM). - item_
q_ by_ day - k_hp
K_HP(ch).1.0while the table is unauthored.- k_out
K_OUT(ch).1.0while the table is unauthored.- level_
by_ day - optional_
attributes_ for_ chest_ level - A2-BAL-003 §3.3: how many optional stats a chest of this level rolls.
- pet_
ult_ combat_ profile - Combat-honest profile of a pet ult: the pet’s ability carries the donor
gacha ability’s per-cast budget (combat behaviors hardcode the donor uuid),
but fires at the charge-fill rate, not at the template cooldown — so the
throughput divides the per-cast budget by
PET_ULT_EFFECTIVE_CD. - player_
armor_ rating_ deflator - Player armor-rating deflator for character
level(seeBalanceTuning::armor_k_per_chapter; level ≈ chapter for players and is available for arena OPPONENT snapshots too, keeping PvP symmetric): multiply the aggregated player armor rating by this before it meets the constant-K DR curve. - power_
from_ attrs - Compute character power from a composed
AttrMapas P = DPS × EHP (balance v2).DPSis the offensive product (attack · rate · crit · multicast · bravery · counterattack);EHPthe survivability product (hp ÷ the damage that gets through), where armor and dodge use the diminishing-returns curvesarmor_kandev/(ev+K_DODGE). Normalised byPOWER_NORMso a reference character (attack=BASE_ATTACK, hp=BASE_HP, neutral elsewhere) anchors atBASE_POWER. - power_
from_ attrs_ raw power_from_attrsbefore the floor.- rand_
round_ f64 - Pure: stochastic round of a non-integer value.
- sell_
gold - BAL-008 sale price:
round(G0 × eff_level(snapshot)^α × M_quality). - sell_
price - Item sale price (sell-currency units) from an item’s effectiveness
eff:floor(eff^sell_price_exp · sell_price_coef). Sub-linear (exp < 1) so gold income grows ~linearly with item level and the geometric chest sink can bind. Pure + sim-tunable viatuning(); the call site isbehaviors::items::item_price. - sell_
price_ with_ config - Item sale price with the exponent/coefficient sourced from GameConfig
(
game_settings.sell_price_{exp,coef}). Per-knob precedence:OVERLORD_BAL_SELL_EXP/OVERLORD_BAL_SELL_COEFenv override (sim sweep) > GameConfig value (Some) > the compiledSELL_PRICE_EXP/SELL_PRICE_COEFconstants. With env unset and both config knobsNonethis is bit-identical tosell_price(the pre-config behavior), so deploying the config with the current constant values leaves every price unchanged. Call site:behaviors::items::item_price. - tuning
- The process-wide balance tuning (defaults until
init_tuningis called). Hot-path safe — an atomic load of a&'static. - zone_
difficulty - Zone difficulty correction z at
chapter(seeZONE_DIFFICULTY_KNOTS).
Type Aliases§
- AttrMap
- Ordered attribute accumulator used by
power_from_attrs/character_power.