/** * Level value object — constrained to 1..10. * * "I can't believe it's not Haskell": invalid states are unrepresentable. * Level progression (next) and combat modifiers (diff) belong to later stories. */ export class Level { #value: number; private constructor(n: number) { this.#value = n; } static create(n: number): Level { if (n < 1 || n > 10) { throw new Error(`Level must be between 1 and 10, got ${n}`); } return new Level(n); } get value(): number { return this.#value; } /** Maximum health for this level: 1000 until level 6, 1500 from level 6 onward. */ static maxHealthForLevel(level: number): number { return level >= 6 ? 1500 : 1000; } /** Signed level difference: this level minus target level. Positive = this is higher. */ diff(target: Level): number { return this.value - target.value; } /** Damage threshold to reach the given level. * Level 1→2: 1000, Level 2→3: 3000, Level 3→4: 6000, etc. * Formula: 1000 * N * (N+1) / 2 */ static damageThresholdForLevel(level: number): number { return (1000 * level * (level + 1)) / 2; } }