# Skara Brae — Combat System & Stat Scaling Design Source: Joplin note 0ef630db4e3e4d6dab18ccaefccaaa5a, migrated 2026-10-03 ## The Core Tension **RoleMaster approach**: Open-ended d100 roll + critical tables. A level 1 can theoretically kill a level 60 with a lucky crit (roll 01-00 on the crit table → "Instant Death"). Thrilling unpredictability, terrible long-term retention — months of work undone by RNG. **Torn City approach**: Stats grow into hundreds of millions over years. Combat outcomes are overwhelmingly deterministic — a level 60 will always beat a level 1. Safe long-term progression, no surprise. **Decision**: Hybrid "Scaled Brutality" — Torn-scale numbers with RoleMaster-inspired crits that are capped by level difference but never reach zero. --- ## Exponential Stat Growth (Torn-Style) - Stats use `BIGINT` (up to 9.2 quintillion) — room for years of growth - Training, equipment, education, and crafting all feed into stat progression - Stats grow exponentially, not linearly — early levels feel meaningful, later levels require dedication - **No rebirth/prestige system for now** — stats only ever go up. Can revisit with player base later. ### Stat Display | Raw Value | Display | |---|---| | 1,247 | 1.2K | | 12,432 | 12.4K | | 4,721,000 | 4.7M | | 1,234,567,890 | 1.2B | | 3,800,000,000,000 | 3.8T | - Show **effective power rating** (composite of all stats) as a single number for quick comparison - Show **stat growth rate** (e.g., "+2.3K/day") so players feel momentum - Historical stat graphs (like Torn) for long-term engagement --- ## RoleMaster-Inspired Critical System Every attack rolls on a **critical table** (d100 open-ended: roll 96-100, roll again and add). But crit damage is **capped by level difference**. ### Crit Damage Caps | Level Difference (target above attacker) | Crit Damage Cap | |---|---| | Equal level | Full crit range (01-100) — no cap | | +10 levels | 60% of target's max HP | | +20 levels | 40% of target's max HP | | +50 levels | 15% of target's max HP | | +100 levels | 5% of target's max HP | The cap never reaches zero — a level 1 can always chip away at a level 60. ### Critical Effects Crits don't just do damage. They apply **status effects** based on the crit roll and weapon type: | Effect | Duration | Description | |---|---|---| | **Bleed** | 3-5 ticks | Damage over time (scaling with weapon) | | **Stun** | 1 turn | Target skips next action | | **Disarm** | 1 turn | Target loses weapon bonuses | | **Cripple** | 3-5 turns | Target agility/strength reduced | | **Blind** | 2-3 turns | Target accuracy reduced | **Key insight**: Status effects work **regardless of level difference**. A level 1 landing a lucky crit can *disrupt* a level 60 (stun them for a turn) even if the damage is negligible. This creates the RoleMaster feel of "anyone can affect anyone" without the frustration of instant death. ### Armor and Crit Mitigation - **Heavy armor** reduces crit roll by a flat amount (e.g., plate armor: -15 to crit roll) - **Crit Shield enchantments**: High-end enchantments absorb X crit damage per day - **Constitution** reduces bleed/cripple duration --- ## Why This Works - **Long-term players** keep their billions-scale progression and feel powerful — they will win 99% of encounters - **New players** feel the thrill of landing a lucky crit (15% HP off a whale is still exciting) - **Guild wars become strategic**: A swarm of low-level players can chip away at a high-level defender through coordinated crit effects - **Dueling has drama**: Crits are always possible, but rarely fight-ending between equals - **No instant death**: No months of work lost to a single bad roll --- ## Combat Formula (Draft) ``` base_damage = weapon_damage * (1 + strength / 100) mitigation = armor_rating * (1 + constitution / 200) net_damage = max(1, base_damage - mitigation) crit_roll = d100_open_ended() // 96-100: roll again and add if crit_roll >= crit_threshold(attacker_agility, target_level_diff): crit_multiplier = crit_table(crit_roll, weapon_type) crit_damage = net_damage * crit_multiplier crit_damage = min(crit_damage, target_max_hp * crit_cap(target_level_diff)) apply_critical_effect(crit_roll, target) else: apply_damage(net_damage, target) ``` ### Open-Ended d100 ``` fn d100_open_ended() -> u32: total = d100() while total >= 96: // 96-100: roll again and add total += d100() return total ``` This means most rolls are 1-95, but occasionally you get 96+100+3 = 199, or even rarer chains. The open-ended mechanic creates the "anything can happen" feel without instant death. --- ## Critical Tables (Structure) Crit tables are weapon-type specific. Each entry maps a roll range to an effect: ```toml # crit_tables/slash_unarmed.toml [entries.01_20] name = "Glancing blow" damage_multiplier = 1.5 effect = "none" [entries.21_50] name = "Deep slash" damage_multiplier = 2.0 effect = "bleed" effect_duration = 3 [entries.51_75] name = "Arterial strike" damage_multiplier = 2.5 effect = "bleed" effect_duration = 5 [entries.76_90] name = "Debilitating wound" damage_multiplier = 3.0 effect = "cripple" effect_duration = 4 [entries.91_100] name = "Devastating cleave" damage_multiplier = 4.0 effect = "bleed" effect_duration = 5 effect2 = "stun" effect2_duration = 1 [entries.101_plus] name = "Legendary strike" damage_multiplier = 5.0 effect = "bleed" effect_duration = 5 effect2 = "stun" effect2_duration = 2 ``` These tables live in `skara-brae-common/crit-tables/` and are loaded by both server (for combat resolution) and client (for display). --- ## Related Notes - [Game Concept Overview](joplin://9cf8a2e701654ffbbd6512cc837c7e2f) - [Idle Fantasy Inspirations](joplin://) *(to be created)* - [Tech Stack & Architecture](joplin://cecd2ef2690d4d1fba3450342aa63953) - [Project Plan](joplin://d243ae57778343fca997d46b73d0ee3b)