/** * Scaled Random World Events: the frozen random-spawn dungeons (frozenDungeons.ts) meet a player at their own level, * anywhere from 10 to 40 (James, 2026-10-03, on the frozen sheets: "yes it can scale with level and difficulty", "xp can * increase by scale too"; PLAN_1_TO_40.md slice C4, decision D9: the first set piece for levels 10-40). * * One number drives it: the scale level, the player's combat level held to the band plus the dungeon's difficulty. * - Enemies: each stream spawns at the scale level of the party inside plus the stream's own offset, a level either way, * held inside the stream's range and the band (never 41+: build focus, `dreadwoods/CLAUDE.md`). * - The cache: a line marked `scales` gives more the higher the opener's scale level; a line whose kind holds `{metal}` * gives that tier's piece (bronze, iron, steel). * - Explorer XP for going in and for the cache grows the same way. * * EVERY NUMBER HERE IS A PLACEHOLDER for the balance pass (balance is last, PLAN_1_TO_40.md). Change them here only: * the dungeons' data and the backend read them, and the tests check the shape (monotonic, inside the band), not values. */ import type { LevelRange, WorldEventDef, WorldEventStream } from './worldEvents.js'; /** What a scaled dungeon carries (WorldEventDef `scaling`). */ export type WorldEventScaling = { /** * 0 is the easiest (Frostpine Trapper Hollow); each step lifts the scale level by * SCALED_EVENT_TUNING.levelsPerDifficulty (the Smuggler Grotto above Frostwatch, Shiverbell the hardest). */ difficulty: number; }; /** Every scaled dungeon lives in this band: the gate lets you in at its floor, and nothing in it is ever above its top. */ export declare const SCALED_EVENT_BAND: LevelRange; export type ScaledMetal = 'bronze' | 'iron' | 'steel'; /** PLACEHOLDERS (balance pass). */ export declare const SCALED_EVENT_TUNING: { /** Scale levels each difficulty step adds. */ readonly levelsPerDifficulty: 2; /** A spawn's level lands this many either side of its aim. */ readonly spread: 1; /** A `scales` loot line gives this much more per scale level above the band's floor (x1 at 10, x2.5 at 40). */ readonly qtyPerLevel: 0.05; /** Explorer XP likewise (x1 at 10, about x2.8 at 40). */ readonly xpPerLevel: 0.06; /** * A stream creature's health, as a share of what a creature of its level has anywhere else (npcs.ts * npcHealthRangeForLevel): they keep coming, so each one is lighter work than a lone beast of its level (at 36 a full * one has about 560 health, and a pair of them at a time wore down a level-60 tester in full Frozen plate, 2026-10-12). */ readonly streamHealthShare: 0.4; /** A stream creature's biggest hit per level (the game's creatures hit for about 0.55 of their level). */ readonly streamHitPerLevel: 0.42; /** The metal a `{metal}` line gives, by the opener's scale level (iron from Combat 20, steel from 32: wearable). */ readonly metalTiers: readonly { upTo: number; metal: ScaledMetal; }[]; }; /** * A trapper's snare (role 'snare'): the share of the victim's own maximum health it takes (so it bites alike at every * level), never less than `minHit`; how long they are held; how near the dungeon's creatures must be to hear it and come. * PLACEHOLDERS (balance pass). */ export declare const SNARE_TUNING: { readonly healthShare: 0.12; readonly minHit: 2; readonly holdMs: 2500; readonly alertRadius: 7; }; /** The combat level held to the band. */ export declare function clampToScaledBand(level: number): number; /** The scale level for a combat level in this dungeon (its difficulty on top), never past the band's top. */ export declare function scaledEventLevel(def: Pick, combat: number): number; /** * A stream NPC's level in a scaled dungeon: the party's scale level plus the stream's offset, a level either way, held * inside the stream's own range and the band. */ export declare function scaledEnemyLevel(def: Pick, stream: Pick, partyCombat: number, roll: () => number): number; /** How much a `scales` loot line is multiplied by at this scale level. */ export declare function scaledRewardMultiplier(scaleLevel: number): number; /** The metal a `{metal}` line gives at this scale level. */ export declare function scaledMetal(scaleLevel: number): ScaledMetal; /** A loot kind with its `{metal}` filled in for this scale level (a plain kind comes back as it is). */ export declare function scaledLootKind(kind: string, scaleLevel: number): string; /** Explorer XP for going in or for the cache, for this player in this dungeon (unscaled events: the def's own). */ export declare function worldEventXp(def: Pick, which: 'entry' | 'cache', combat: number): number; /** * One character's share from a scaled dungeon's cache: each line rolls its chance (`roll` once per line, then once for * the quantity), a `scales` line's quantity is multiplied and rounded, a `{metal}` kind takes the opener's tier. */ export declare function rollScaledEventLoot(def: Pick, combat: number, roll: () => number): { kind: string; qty: number; }[]; /** The levels a stream can show at in a scaled dungeon, for the guide: its lowest and highest after the band. */ export declare function scaledStreamLevels(def: Pick, stream: Pick): LevelRange; //# sourceMappingURL=worldEventScaling.d.ts.map