/** * Current cap. Levels are derived from stored XP on load (see db/characters.ts), * so raising this later restores any progress banked above the cap rather than * losing it. Level 60 is the cap since 2026-09-22 (James; it was 40, and * the Frozen Depths gear is what the last twenty levels are for); reaching * it is deliberately a substantial commitment rather than a starter-area * milestone. */ export declare const MAX_LEVEL = 60; /** * The level at which the per-level curves reach their ceiling: gear lands its * full printed damage (gearDamageScale) and a cast lands at its best rate * (fishingCatchChance). It stays at the old cap of 40 so raising MAX_LEVEL * did not take a quarter of every level-40 player's weapon away overnight; * the levels past it buy hit chance, health and the gear gated behind them. */ export declare const SKILL_CURVE_FULL_LEVEL = 40; /** * A welcoming early curve that rises steadily into a long-term level-60 goal. * The first level costs 49 XP instead of 664; each following level takes a * little more work, without the old exponential wall. */ export declare const PLAYER_MAX_HIT_CAP = 20; /** * Bare fists land half of the trained roll. The base roll is the same with * or without a weapon (a weapon only adds its printed damage on top, scaled * by gearDamageScale), which had a level-19 character punching for 19; a * weapon is now what carries the number, and fists are for getting one. */ export declare const UNARMED_DAMAGE_SCALE = 0.5; export declare const XP_TABLE: readonly number[]; export declare function xpForLevel(level: number): number; export declare function levelForXp(xp: number): number; export type XpProgress = { level: number; intoLevel: number; span: number; totalXp: number; }; export declare function xpProgress(xp: number): XpProgress; export declare function maxHitForStrength(strengthLevel: number): number; /** * Unboosted player health is exactly their combat level. Equipment and other * temporary boosts can layer on top later, while the base remains predictable. */ export declare function maxHealthForLevel(combatLevel: number): number; /** * Fraction of an incoming hit that armour removes: `A / (A + ARMOUR_SOFTNESS)`. * * Replaces a subtractive soak (`damage - random(0..armour)`), which had a nasty * cliff: once armour approached the attacker's max hit, damage collapsed toward * zero, so two points either way swung survival from a few minutes to over half * an hour. Measured, not guessed - see scripts/sim-combat.ts. * * A ratio curve has none of that. It gives diminishing returns, never reaches * immunity, and stays predictable to tune. */ export declare const ARMOUR_SOFTNESS = 18; export declare function armourReduction(armour: number): number; /** * Combat is derived, not trained directly: it is the average of Weapon Mastery * and the better of Strength or Archery. Taking the higher primary skill means * switching weapons never lowers combat level. */ export declare function combatLevelFrom(strengthLevel: number, archeryLevel: number, precisionLevel: number): number; /** * Effective attack level from a weapon's primary skill (Strength or Archery) * combined with Mastery. Caps at PLAYER_MAX_HIT_CAP for damage, but hit chance * uses the uncapped blend below MAX_LEVEL. */ export declare function effectiveAttackLevel(primaryLevel: number, precisionLevel: number): number; /** Flat damage bonus from a weapon's craft precision (woodwork level when made). */ export declare function weaponPrecisionBonus(weaponPrecision: number | null | undefined): number; /** * Fraction of a weapon's / ammo's flat damage the wielder actually lands. * * Gear damage used to be added raw, entirely independent of the combat skill * swinging it. That made skill almost irrelevant at the low end: a level-1 * archer holding a pine bow crafted at woodwork 40 hit for 13-16, of which * exactly 1 came from their archery level and 8 from the *crafter's* woodwork. * Levelling archery from 1 to 20 barely moved the number, while a hand-me-down * bow moved it enormously. * * Scaling the flat bonuses by the wielder's level keeps good gear worth having * without letting it stand in for training: at SKILL_CURVE_FULL_LEVEL the * weapon performs at its full printed damage, and at level 1 it lands a * quarter of it. The floor is deliberately non-zero so a starter weapon still * beats bare fists. */ export declare const GEAR_DAMAGE_SCALE_MIN = 0.25; export declare function gearDamageScale(attackLevel: number): number; //# sourceMappingURL=xp.d.ts.map