Files
lords-of-ash/docs/milestones/M8-the-art-of-metals.md
T
jpmschweitzerandClaude Opus 4.6 84255ab819 docs(meta): add testing protocol and link from all milestones
Create docs/TESTING.md with debug game rule, debug decisions per
milestone, log analysis commands, pre-launch validation script,
post-run analysis script, and Claude Code testing capabilities.
Add cross-reference to TESTING.md in each milestone's Testing
Checkpoints section (M1-M8).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 17:34:33 +01:00

42 KiB

M8: The Art of Metals

Custom Scadrial map, full graphics, publication polish. The mod is ready for Steam Workshop.

Prerequisites

  • M7 (The Deepness) must be complete: all event arcs functional, endgame tested, atmosphere events firing
  • M1-M6 must be complete and stable: all systems (metallic arts, characters, crew, narrative arcs) working
  • All content that will appear in the final mod must exist before this milestone begins -- M8 is about presentation, polish, and stability, not new mechanics
  • error.log should already be relatively clean (no critical errors from M1-M7 content)

Current State

Relevant files and their status:

  • common/landed_titles/00_landed_titles.txt — 731 lines. 5 kingdoms, 16 duchies, ~45 counties, ~90 baronies. All mapped to vanilla Swiss/Swabian/Tyrolean/Burgundian/Lombard province IDs (e.g., province = 2046 for Kredik Shaw mapped to Bern). These province IDs must all be remapped to custom map province IDs.
  • common/traits/ — 6 trait files defining ~25 traits. All reference gfx/interface/icons/traits/trait_*.dds paths. No actual .dds files exist yet.
  • common/modifiers/00_mistborn_modifiers.txt — ~20+ modifiers (after M7). All reference gfx/interface/icons/modifiers/modifier_*.dds. No actual .dds files exist yet. Several modifiers share the same placeholder icon path (modifier_compounder.dds).
  • common/culture/cultures/00_scadrial_cultures.txt — 3 cultures, all using ethnicities = { 100 = caucasian }. Need custom ethnicity definitions for Scadrial-appropriate appearances.
  • history/provinces/00_mistborn_provinces.txt — Single file. Will need complete rewrite for new province IDs.
  • lords_of_ash/ — No map_data/ directory exists. No gfx/ directory exists. These must be created from scratch.
  • localization/english/ — Multiple .yml files with 874+ lines (before M7 additions). Needs final review pass.

Implementation Tasks

8.1 -- Custom Map: Province Layout and Image Files

Context: The custom map is the single highest-risk task in the entire project. CK3 maps require pixel-perfect province boundaries in provinces.png, exact RGB-to-ID mappings in definitions.csv, and properly formed heightmap and rivers.png files. Any error crashes the game hard. The map must depict Scadrial's Final Empire: a roughly circular landmass with Luthadel at the center, Ashmounts scattered throughout, Terris mountains in the north, the Pits of Hathsin in the south, and the River Channerel flowing through the Central Dominance.

Steps:

  1. Create the directory structure:
    lords_of_ash/map_data/
    lords_of_ash/map_data/geographical_regions/
    
  2. Design the province layout document. Before creating image files, plan the province mapping on paper/digitally:
    • Assign new province IDs starting from 1. Use ID ranges per Dominance:
      • 1-30: Central Dominance (Luthadel and surroundings)
      • 31-55: Northern Dominance (Terris homeland)
      • 56-80: Eastern Dominance
      • 81-105: Western Dominance
      • 106-130: Southern Dominance (Pits of Hathsin)
      • 131-150: Remote Dominance (frontier)
      • 151-160: Sea zones / impassable
    • Each barony in 00_landed_titles.txt needs exactly one province ID
    • Count all baronies in the current title file (~90 baronies) and ensure each gets a unique ID
  3. Create map_data/definitions.csv. Format:
    province_id;red;green;blue;name;x
    0;0;0;0;Wasteland;x
    1;200;70;70;Kredik Shaw;x
    2;195;72;72;Luthadel City;x
    3;190;74;74;Luthadel Slums;x
    ...
    
    Each province needs a unique RGB color. Use systematic color assignment:
    • Central Dominance: reds (R: 150-220, G: 50-100, B: 50-100)
    • Northern Dominance: greens (R: 50-100, G: 120-200, B: 50-100)
    • Eastern Dominance: blues (R: 40-80, G: 70-120, B: 130-200)
    • Western Dominance: yellows (R: 150-200, G: 120-180, B: 40-90)
    • Southern Dominance: purples (R: 90-140, G: 40-80, B: 100-160)
    • Remote Dominance: greys (R/G/B: 80-130)
    • Sea/impassable: distinct blues/blacks
  4. Create map_data/provinces.png. Specifications:
    • Dimensions: The image dimensions determine the map size. CK3 vanilla is 8192x4096. For a total conversion with ~150 provinces, a smaller map like 4096x3072 or 2048x2048 is acceptable and will perform better. Choose dimensions that give provinces reasonable visual size.
    • Format: 24-bit RGB PNG, no anti-aliasing, no transparency
    • Each pixel must be exactly one color from definitions.csv
    • Province borders must be clean 1-pixel boundaries (no blending, no gradients)
    • Provinces must be contiguous (no disconnected regions for a single province)
    • The landmass should roughly match the Scadrial map from the Mistborn books: circular continent, mountain range in the north (Terris), ashmounts scattered across the interior, Luthadel centrally placed
    • Impassable terrain (ocean, wasteland beyond the Empire) must use the wasteland/ocean province colors
    • Critical: Use an image editor that supports indexed color or at minimum does NOT apply anti-aliasing. GIMP with pencil tool (not brush) works. Photoshop requires anti-aliasing turned off on all tools.
  5. Create map_data/heightmap.bmp. Specifications:
    • Same dimensions as provinces.png
    • 8-bit grayscale BMP
    • Values: 0 (sea level) to 255 (maximum elevation)
    • Ashmounts: 220-250 (tall volcanic peaks)
    • Terris mountains (north): 180-220
    • Central Dominance plains: 40-60
    • River valleys: 20-35
    • Ocean/wasteland: 0
  6. Create map_data/rivers.png. Specifications:
    • Same dimensions as provinces.png
    • RGB PNG
    • River pixels use specific colors defined by CK3's river system:
      • River source: RGB(0, 255, 0) -- green
      • River flow: RGB(0, 0, 255) -- blue
      • River merge: RGB(255, 0, 0) -- red
    • Background: RGB(255, 255, 255) -- white (no river)
    • Rivers must flow continuously from source to sea/lake
    • The River Channerel should flow from the Terris mountains south through the Central Dominance past Luthadel
    • Critical: Broken river paths crash CK3. Test rivers independently before combining with other map data.
  7. Create map_data/default.map. This file defines province groupings:
    definitions = "definitions.csv"
    provinces = "provinces.png"
    rivers = "rivers.png"
    heightmap = "heightmap.bmp"
    
    sea_zones = LIST { 151 152 153 }
    impassable_mountains = LIST { 155 156 }
    lakes = LIST { 154 }
    
    List all sea zone, impassable, and lake province IDs.

Files:

  • map_data/ -- create directory
  • map_data/definitions.csv -- create
  • map_data/provinces.png -- create
  • map_data/heightmap.bmp -- create
  • map_data/rivers.png -- create
  • map_data/default.map -- create

References:

  • CK3 map data requirements: docs/ck3-modding/ck3-modding-reference.md lines 397-409
  • Current province mapping: common/landed_titles/00_landed_titles.txt (all province = XXXX lines)
  • Scadrial geography: docs/lore/mistborn-universe.md lines 30-41 (key locations)
  • Atlantis TC template for map_data structure (referenced in modding docs)

8.2 -- Province Remapping

Context: After creating the custom map with new province IDs, every province = XXXX reference in the landed titles must be updated to match the new IDs from definitions.csv. Province history files must also be rewritten.

Steps:

  1. Create a province mapping table (old vanilla ID -> new custom ID) based on the province layout from 8.1. Example:
    # Central Dominance
    2046 (Bern/Kredik Shaw) -> 1
    2047 (Thun/Luthadel City) -> 2
    2048 (Lucerne/Luthadel Slums) -> 3
    2049 (Biel/Fellise) -> 4
    2037 (Lausanne/Fellise Estates) -> 5
    ...
    
  2. Update all province = XXXX lines in common/landed_titles/00_landed_titles.txt. There are approximately 90 barony entries that each reference a vanilla province ID. Every single one must be updated to the corresponding new ID. This is a systematic find-and-replace operation. Verify the count matches: the number of province entries in landed_titles must exactly equal the number of land provinces in definitions.csv.
  3. Rewrite history/provinces/00_mistborn_provinces.txt (or split into multiple files) for the new province IDs. Each province needs:
    1 = {           # Kredik Shaw
        culture = noble_scadrian
        religion = steel_ministry
        holding = castle_holding
        buildings = { ... }    # If special buildings exist
        900.1.1 = { ... }      # Date block if needed
    }
    
    Assign culture, religion, and holding type based on location:
    • Central Dominance: noble_scadrian, steel_ministry, castle_holding or city_holding
    • Northern Dominance: terris, terris_keepers (or steel_ministry for controlled regions), castle_holding
    • All others: noble_scadrian, steel_ministry, mixed castle_holding/city_holding
    • Southern Dominance (Pits): skaa, steel_ministry, castle_holding (prison camp)
  4. Verify consistency: every province ID referenced in landed_titles exists in definitions.csv and has a corresponding color in provinces.png. Every province ID in definitions.csv that is a land province has a history entry.

Files:

  • common/landed_titles/00_landed_titles.txt -- modify (~90 province lines)
  • history/provinces/00_mistborn_provinces.txt -- rewrite
  • map_data/definitions.csv -- reference (from 8.1)

References:

  • Current landed titles: common/landed_titles/00_landed_titles.txt:1-731 (all province = lines)
  • Province history format: docs/ck3-modding/ck3-modding-reference.md lines 339-370

8.3 -- Geographic Regions and Terrain

Context: CK3 uses geographic regions for AI behavior, cultural spread, de jure drift, and weather. Terrain types affect combat, development, and visuals. Scadrial has unique geography: ashmount wastelands, ash plains, fortified cities, and the fertile (relatively) areas near rivers.

Steps:

  1. Create map_data/geographical_regions/00_scadrial_regions.txt. Define regions matching the Dominance structure:

    world_scadrial = {
        regions = {
            scadrial_central_dominance
            scadrial_northern_dominance
            scadrial_eastern_dominance
            scadrial_western_dominance
            scadrial_southern_dominance
            scadrial_remote_dominance
        }
    }
    
    scadrial_central_dominance = {
        provinces = { 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 }
    }
    
    # ... repeat for each Dominance with appropriate province IDs
    
  2. Create common/province_terrain/00_scadrial_terrain.txt. Assign terrain types to each province:

    • plains — Most Central Dominance provinces (flat ash plains around Luthadel)
    • mountains — Terris homeland provinces, Ashmount provinces
    • hills — Mining regions (Pits of Hathsin area), transitional zones
    • farmlands — River-adjacent provinces in Central and Western Dominance
    • desert or drylands — Remote Dominance (ash-covered wastelands)
    • urban — Luthadel, Urteau, Fadrex City (major cities)
    • wetlands — River Channerel delta/flood plains

    Format:

    1 = plains     # Kredik Shaw - urban heart of empire, flat
    2 = plains     # Luthadel City
    3 = plains     # Luthadel Slums
    ...
    45 = mountains # Terris mountain province
    ...
    
  3. Optionally create common/terrain_types/00_scadrial_terrain_types.txt if custom terrain types are needed. Consider:

    • ashmount_terrain — volcanic wasteland near ashmounts. Very hostile. Attrition, low supply, minimal development.
    • ash_plains — standard Scadrial terrain. Slightly worse than vanilla plains due to constant ashfall. If custom types are too complex for this milestone, use vanilla terrain types with appropriate province assignments.

Files:

  • map_data/geographical_regions/00_scadrial_regions.txt -- create
  • common/province_terrain/00_scadrial_terrain.txt -- create
  • common/terrain_types/00_scadrial_terrain_types.txt -- create (optional)

References:

  • CK3 geographic regions: vanilla map_data/geographical_regions/ for format examples
  • Dominance structure: common/landed_titles/00_landed_titles.txt (kingdom/duchy groupings)
  • Scadrial geography: docs/lore/mistborn-universe.md lines 30-41

8.4 -- Trait Icons

Context: Every trait needs a custom .dds icon to appear correctly in-game. CK3 trait icons are 60x60 pixel DDS files with DXT5 compression (supports transparency). The mod defines ~25-30 traits across 6 files, each referencing a gfx/interface/icons/traits/trait_*.dds path.

Steps:

  1. Create the directory structure:

    lords_of_ash/gfx/
    lords_of_ash/gfx/interface/
    lords_of_ash/gfx/interface/icons/
    lords_of_ash/gfx/interface/icons/traits/
    
  2. Create trait icon .dds files. Each icon should be 60x60 pixels, DDS format with DXT5 compression and alpha channel. Complete list of required icons (from trait files):

    Allomancy Misting traits (12 icons) -- from common/traits/00_allomancy_traits.txt:

    • trait_misting_coinshot.dds -- Steel metal icon, blue/silver pushing-coins motif
    • trait_misting_lurcher.dds -- Iron metal icon, dark pulling-metals motif
    • trait_misting_thug.dds -- Pewter metal icon, fist/strength motif
    • trait_misting_tineye.dds -- Tin metal icon, eye/senses motif
    • trait_misting_soother.dds -- Brass metal icon, calming wave motif
    • trait_misting_rioter.dds -- Zinc metal icon, flame/emotion motif
    • trait_misting_smoker.dds -- Copper metal icon, cloud/shield motif
    • trait_misting_seeker.dds -- Bronze metal icon, detection/pulse motif
    • trait_misting_augur.dds -- Gold metal icon, mirror/past-self motif
    • trait_misting_oracle.dds -- Atium metal icon, eye-of-the-future motif
    • trait_misting_duralumin.dds -- Enhancement metal icon, amplification motif
    • trait_misting_nicroburst.dds -- Enhancement metal icon, external-amplification motif

    Mistborn (1 icon) -- from common/traits/01_mistborn_trait.txt:

    • trait_mistborn.dds -- Full Mistborn icon, all-metals motif, mist-swirling figure

    Allomantic strength (3 icons) -- from common/traits/02_allomantic_strength.txt:

    • trait_allomantic_strength_weak.dds -- Dim/faded metal glow
    • trait_allomantic_strength_strong.dds -- Bright metal glow
    • trait_allomantic_strength_savant.dds -- Intense/dangerous glow with cracks

    Allomantic potential (2 icons) -- from common/traits/03_allomantic_potential.txt:

    • trait_allomantic_potential.dds -- Dormant spark, hidden potential motif
    • trait_mistborn_potential.dds -- Brighter dormant spark (Mistborn-level potential)

    Feruchemy (2 icons) -- from common/traits/04_feruchemy_traits.txt:

    • trait_feruchemist.dds -- Metalmind/arm-band motif, Terris styling
    • trait_feruchemy_potential.dds -- Dormant metalmind motif

    Hemalurgy (6 icons) -- from common/traits/05_hemalurgy_traits.txt:

    • trait_hemalurgist.dds -- Dark spike motif, blood/corruption
    • trait_hemalurgic_steel.dds -- Steel spike
    • trait_hemalurgic_pewter.dds -- Pewter spike
    • trait_hemalurgic_bronze.dds -- Bronze spike
    • trait_hemalurgic_atium.dds -- Atium spike (rare, glowing)
    • trait_knows_hemalurgy.dds -- Book/knowledge with dark undertone

    Total: ~26 trait icons

  3. Use a DDS creation tool (GIMP with DDS plugin, Paint.NET with DDS plugin, or texconv from DirectXTex). Workflow:

    • Design icon at 60x60 in PNG with transparent background
    • Export to DDS with DXT5 compression (BC3, supports alpha)
    • Name file exactly as referenced in trait definition
    • Place in gfx/interface/icons/traits/
  4. Verify every icon = "gfx/interface/icons/traits/..." path in all 6 trait files matches an actual .dds file.

Files:

  • gfx/interface/icons/traits/ -- create directory and all 26 .dds files

References:

  • Trait icon paths: common/traits/00_allomancy_traits.txt (icon field in each trait)
  • CK3 trait icon specs: 60x60 DDS, DXT5, with alpha channel
  • docs/ck3-modding/ck3-modding-reference.md lines 236-258 (trait structure)

8.5 -- Modifier and UI Icons

Context: Modifiers also need icons. Many modifiers currently share the same placeholder icon path. Loading screens, bookmark art, and decision icons add visual polish. This task creates all remaining graphical assets.

Steps:

  1. Create modifier icon directory:

    lords_of_ash/gfx/interface/icons/modifiers/
    
  2. Create modifier icon .dds files. Same specs as trait icons (60x60, DXT5). Required icons (from common/modifiers/00_mistborn_modifiers.txt and M7 additions):

    • modifier_compounder.dds -- Golden dual-power motif (Allomancy + Feruchemy fused)
    • modifier_lord_ruler_attention.dds -- Red eye/gaze of the Lord Ruler
    • modifier_steel_ministry_favor.dds -- Steel Ministry sigil, positive
    • modifier_steel_ministry_displeasure.dds -- Steel Ministry sigil, negative/cracked
    • modifier_ash_blight.dds -- Grey ash covering land
    • modifier_koloss_rampage.dds -- Blue koloss fist/destruction
    • modifier_eleventh_metal_insight.dds -- Mysterious golden metal shard
    • modifier_duel_veteran.dds -- Crossed coin and sword
    • modifier_atium_contract_holder.dds -- Atium geode with contract scroll
    • modifier_mist_empowerment.dds -- Swirling mist with inner glow
    • modifier_beauty_in_ash.dds -- Small flower against grey background
    • modifier_hero_of_ages.dds -- Radiant figure in the mists
    • modifier_ashmount_eruption.dds -- Erupting volcano with ash clouds
    • modifier_mist_fear.dds -- Cowering figure in fog
    • modifier_post_empire_chaos.dds -- Crumbling tower/empire motif

    Total: ~15 modifier icons

  3. Update all modifier definitions in common/modifiers/00_mistborn_modifiers.txt to reference unique icon paths. Currently several modifiers share modifier_compounder.dds as placeholder:

    • great_house_status -> modifier_great_house_status.dds
    • atium_supply -> modifier_atium_supply.dds
    • breeding_for_allomancy_modifier -> modifier_breeding_for_allomancy.dds
    • ruin_influence -> modifier_ruin_influence.dds
    • steel_inquisitor_power -> modifier_steel_inquisitor_power.dds

    Create these additional icons and update the paths.

  4. Create loading screen art:

    lords_of_ash/gfx/loadingscreens/
    

    Create 3-5 loading screen images. Specifications:

    • Resolution: 1920x1080 minimum (CK3 scales loading screens)
    • Format: .dds or .png (CK3 supports both for loading screens)
    • Subjects: Luthadel skyline with ash and mists, Kredik Shaw palace, Ashmounts at sunset, Vin in the mists, Kelsier overlooking Luthadel
  5. Create bookmark art:

    lords_of_ash/gfx/interface/bookmarks/
    
    • Bookmark background image for "End of an Empire"
    • Character portrait frames for Kelsier and Vin (if custom portraits aren't feasible, use existing portrait system with scripted DNA)
  6. Create decision icons:

    lords_of_ash/gfx/interface/illustrations/decisions/
    

    Create icons for major decisions. Use 500x300 DDS images (CK3 decision illustration size):

    • decision_host_ball.dds -- Noble ball scene
    • decision_snapping.dds -- Character in pain, awakening power
    • decision_hemalurgy.dds -- Dark ritual with spike
    • decision_hire_kandra.dds -- Shapeshifter in shadows
    • decision_raid.dds -- Night raid on a noble keep
    • decision_assault_kredik_shaw.dds -- Siege of the Lord Ruler's palace

Files:

  • gfx/interface/icons/modifiers/ -- create directory and ~20 .dds files
  • gfx/loadingscreens/ -- create directory and 3-5 images
  • gfx/interface/bookmarks/ -- create directory and bookmark art
  • gfx/interface/illustrations/decisions/ -- create directory and 6 decision illustrations
  • common/modifiers/00_mistborn_modifiers.txt -- modify (update icon paths)

References:

  • Current modifier icons: common/modifiers/00_mistborn_modifiers.txt (all icon = lines)
  • CK3 loading screen specs: standard resolution, placed in gfx/loadingscreens/
  • CK3 decision illustration specs: 500x300 DDS

8.6 -- Portraits and Ethnicity

Context: CK3 generates character appearances from ethnicity definitions. The current mod uses 100 = caucasian for all three cultures, which doesn't match Mistborn lore. Noble Scadrians are pale-skinned (European-like), skaa are darker (centuries of sun exposure and different ancestry), and Terris people are dark-skinned per lore. Custom ethnicity definitions and portrait modifiers for Hemalurgic spikes and ash-stained aesthetics add immersion.

Steps:

  1. Create common/ethnicities/00_scadrial_ethnicities.txt. Define custom ethnicities:

    scadrial_noble = {
        # Pale skin, dark hair (nobles have lived indoors for generations)
        # Use vanilla caucasian as base with skin tone adjustments
        template = caucasian
        # Override skin color to be paler
    }
    
    scadrial_skaa = {
        # Darker skin from outdoor labor, weathered features
        # Mix of caucasian and other templates for variety
        template = caucasian
        # Override skin color to be darker/weathered
    }
    
    scadrial_terris = {
        # Dark skin per lore
        template = african
        # Terris are described as dark-skinned with distinctive features
    }
    

    Note: CK3 ethnicity definitions are complex and version-dependent. The exact format should be verified against vanilla files in the CK3 game directory (game/common/ethnicities/). Copy a vanilla ethnicity file as a starting template and modify skin tone parameters.

  2. Update common/culture/cultures/00_scadrial_cultures.txt to reference new ethnicities:

    noble_scadrian = {
        ...
        ethnicities = {
            100 = scadrial_noble
        }
        ...
    }
    
    skaa = {
        ...
        ethnicities = {
            100 = scadrial_skaa
        }
        ...
    }
    
    terris = {
        ...
        ethnicities = {
            100 = scadrial_terris
        }
        ...
    }
    
  3. Create portrait modifiers for Hemalurgic spikes. This is complex and depends on CK3's portrait modifier system. The goal: characters with steel_inquisitor_power modifier or multiple Hemalurgic traits should have visible spikes (particularly the eye spikes). Options:

    • Option A (simpler): Use has_scripted_appearance = yes in character history for named Inquisitors, with manually designed DNA strings that include scarring/eye effects.
    • Option B (more complex): Create portrait modifier entries in gfx/portraits/portrait_modifiers/ that trigger based on traits. This allows dynamic spike appearance for any character who becomes an Inquisitor.

    For this milestone, implement Option A for named Inquisitors and note Option B as a future enhancement.

  4. Add ash-stained clothing aesthetic:

    • If CK3 supports clothing texture overrides per culture, create slightly greyed/ash-tinted versions of western clothing
    • If not feasible, this is cosmetic polish and can be deferred. The culture clothing_gfx = { western_clothing_gfx } setting will at minimum prevent characters from looking completely wrong.
  5. Verify all characters render correctly in-game: no bald heads, no missing portraits, no ethnicity mismatches. Use the character browser in debug mode to check a representative sample from each culture.

Files:

  • common/ethnicities/00_scadrial_ethnicities.txt -- create
  • common/culture/cultures/00_scadrial_cultures.txt -- modify (3 ethnicity lines)
  • gfx/portraits/portrait_modifiers/ -- create (optional, for Hemalurgic spike visuals)
  • history/characters/ -- modify (add has_scripted_appearance for Inquisitors)

References:

  • Current cultures: common/culture/cultures/00_scadrial_cultures.txt:1-75
  • CK3 ethnicity format: docs/ck3-modding/ck3-modding-reference.md lines 413-418
  • Mistborn lore on appearance: docs/lore/mistborn-universe.md lines 19-28 (nobility vs skaa), lines 98-100 (Terris)

8.7 -- Balance Pass

Context: With all content implemented, the mod needs systematic balance testing. This means playing multiple campaigns at different power levels and verifying that the difficulty curve, resource economy, event frequency, and trait effects create a fun and fair experience.

Steps:

  1. Play a full Narrative Mode campaign (Kelsier start) from bookmark to endgame. Track:
    • Gold balance: is the player too rich/poor at each stage?
    • Prestige/piety economy: do the values feel right for the setting?
    • Lord Ruler attention curve: does it escalate at a reasonable pace?
    • Event frequency: are atmosphere events too common/rare?
    • Combat balance: are Mistborn/Inquisitor duels too easy/hard?
    • Endgame difficulty: can a well-prepared player complete Fall of Kredik Shaw?
  2. Play a Sandbox Mode campaign as a Great House lord (Straff Venture or similar) for 30+ years. Track:
    • Are metallic arts traits appearing at reasonable rates through inheritance?
    • Is the atium economy functional and meaningful?
    • Do AI houses use raids, balls, and political intrigue events?
    • Is the Lord Ruler attention system punishing enough to feel threatening but not so punishing it's unfun?
  3. Play a Sandbox Mode campaign as a Terris character. Verify:
    • Feruchemy inheritance works correctly
    • Breeding program events fire
    • Keeper mechanics (coppermind discoveries) work
    • Terris characters have appropriate names and appearance
  4. Adjust balance based on findings. Common areas that need tuning:
    • Trait stat bonuses (are Mistborn too overpowered at prowess 15?)
    • Decision costs (gold/prestige costs should scale with game stage)
    • Event weight multipliers (tune weight_multiplier and random chances)
    • Lord Ruler attention gain/decay rates
    • Men-at-arms stats (Hazekillers, Koloss, Mistborn Agents)
    • Modifier durations and magnitudes
  5. Document all balance changes in a changelog or balance notes file.

Files:

  • common/traits/ -- potentially modify (stat adjustments)
  • common/modifiers/00_mistborn_modifiers.txt -- potentially modify (value tuning)
  • events/ -- potentially modify (weight and random_list tuning)
  • common/men_at_arms_types/ -- potentially modify (stat tuning)
  • common/decisions/ -- potentially modify (cost tuning)

References:

  • All trait files in common/traits/ for current stat values
  • All event files in events/ for current weight multipliers
  • All modifiers in common/modifiers/ for current modifier values

8.8 -- Localization Review

Context: Every user-visible string in the mod must have a localization entry. All entries must be consistent in tone, free of typos, and properly formatted. Missing localization keys display as raw key names in-game, which breaks immersion immediately.

Steps:

  1. Compile a complete list of all localization keys needed by scanning all files:
    • Trait names and descriptions (from common/traits/)
    • Event titles, descriptions, and options (from events/)
    • Decision names, descriptions, and confirmations (from common/decisions/)
    • Modifier names and descriptions (from common/modifiers/)
    • Title names (from common/landed_titles/)
    • Religion, culture, tradition names (from common/religion/, common/culture/)
    • Building names (from common/buildings/)
    • CB and scheme names (from common/casus_belli_types/, common/schemes/)
    • Custom tooltips referenced in events
  2. Cross-reference the compiled list against existing .yml files in localization/english/. Identify any missing keys.
  3. Review all existing localization for:
    • Tone consistency: Dark fantasy with moments of hope. Formal for noble events, gritty for skaa events, scholarly for Terris events, menacing for Steel Ministry events.
    • Typos and grammar: Standard proofing pass.
    • Variable substitution: Ensure all $VARIABLE$ references resolve correctly (character names, title names, trait names).
    • Line length: Event descriptions should be 2-4 sentences. Option text should be 1-2 sentences. Overly long text gets cut off in the UI.
  4. Ensure all .yml files have UTF-8 BOM encoding. Verify by checking the first bytes of each file (EF BB BF in hex). Files without BOM silently fail to load.
  5. Add any missing localization keys. Pay special attention to:
    • Custom tooltip keys (custom_tooltip = key_name in events)
    • Interface messages (send_interface_message with title = key)
    • Opinion modifier names
    • Province names (should show Scadrial names, not vanilla names)

Files:

  • localization/english/*.yml -- review and modify all files
  • localization/english/replace/ -- create if needed for vanilla overrides

References:

  • Localization format: docs/ck3-modding/ck3-modding-reference.md lines 158-191
  • Existing localization files: localization/english/ directory
  • Common pitfalls: missing BOM encoding causes silent failures

8.9 -- Error Log Cleanup and Performance

Context: A clean error.log is the primary quality indicator for CK3 mods. Every error represents a potential crash, broken mechanic, or visual glitch. Performance matters too: excessive event firing or script loops can make the game unplayable on slower machines.

Steps:

  1. Launch the mod with -debug_mode -develop flags. Let the game load fully and check error.log located at ~/.local/share/Paradox Interactive/Crusader Kings III/logs/error.log (Linux).
  2. Categorize errors:
    • Critical (must fix): Missing files, invalid references, scope errors, syntax errors in event/trigger/effect files
    • Warning (should fix): Unused localization keys, trait index conflicts, undefined modifiers
    • Info (nice to fix): Minor cosmetic warnings, non-essential missing icons
  3. Fix all critical and warning errors. Common error types and fixes:
    • Missing trait icon "gfx/..." -- create the .dds file or fix the path
    • Reference to undefined modifier "X" -- add the modifier definition
    • Invalid scope "Y" in trigger -- fix the scope chain in the event/trigger
    • Localization key "Z" not found -- add the key to the appropriate .yml file
    • Duplicate object "W" -- remove the duplicate definition (check load order)
  4. Performance testing:
    • Run the game in observer mode for 50 years
    • Check error.log periodically for recurring errors
    • Monitor game speed: if years start taking significantly longer to process, identify which events are firing too frequently
    • Check for infinite loops: events that trigger other events that trigger back
    • Verify hidden = yes events don't have unnecessary portrait blocks (wasted rendering)
  5. After fixing all errors, do a final clean boot test:
    • Delete error.log
    • Launch the mod fresh
    • Load a game, play 1 year
    • Check error.log is completely empty (no errors at all)
    • Play 20 more years
    • Check error.log again -- should remain clean

Files:

  • All files in the mod -- potentially any file may need fixes
  • Primary focus: events/, common/, localization/

References:

  • Debug mode and error.log: docs/ck3-modding/ck3-modding-reference.md lines 450-485
  • Common pitfalls: docs/ck3-modding/ck3-modding-reference.md lines 507-519

8.10 -- Final Integration and Steam Workshop Preparation

Context: The final step before release. Package the mod for distribution, prepare Steam Workshop metadata, and verify the complete player experience from installation to endgame.

Steps:

  1. Verify both .mod descriptor files are correct and consistent:
    • Outer file lords-of-ash.mod: must have path field pointing to mod directory, supported_version="1.18.*", correct name, version (set to "1.0.0")
    • Inner file lords_of_ash/descriptor.mod: same content but WITHOUT path field
    • Add tags = { "Total Conversion" } if not present
  2. Create lords_of_ash/thumbnail.png for Steam Workshop:
    • 256x256 or 512x512 PNG
    • Mod logo / key art (Mistborn silhouette, Scadrial landscape, metallic arts symbol)
  3. Verify the complete new player experience:
    • Install the mod fresh (copy to CK3 mod directory)
    • Launch CK3, enable the mod in launcher
    • Select "End of an Empire" bookmark
    • Verify bookmark art and descriptions display correctly
    • Select Kelsier, start the game
    • Verify: map looks correct, characters have proper names/portraits/traits, no vanilla content visible
    • Play through the first few events
    • Verify game rule toggle works (Narrative vs Sandbox)
    • Save and reload -- verify save compatibility
  4. Write a Steam Workshop description (can be stored in docs/steam-workshop-description.md for reference):
    • Mod name, brief pitch, features list
    • Required DLC (Roads to Power)
    • Compatibility note (CK3 version 1.18.*)
    • Credits and acknowledgments (Brandon Sanderson for the setting)
  5. Final checklist before release:
    • error.log clean after 20-year playthrough
    • All trait icons display correctly
    • All modifier icons display correctly
    • Loading screens display
    • Bookmark art displays
    • Map renders correctly with no visual artifacts
    • Rivers don't crash the game
    • Province borders are clean (no artifacts, no bleed)
    • All 3 cultures have correct ethnicity/appearance
    • Named characters (Kelsier, Vin, Elend, Lord Ruler) have appropriate stats and traits
    • Narrative Mode: full story playthrough possible from bookmark to endgame
    • Sandbox Mode: play any house lord, metallic arts mechanics work, game rule suppresses narrative events
    • No vanilla anachronisms visible (no vanilla decisions, events, names, religions)
    • Save/reload works without errors
    • AI plays reasonably (uses decisions, attends balls, manages attention)

Files:

  • lords-of-ash.mod -- verify/modify
  • lords_of_ash/descriptor.mod -- verify/modify
  • lords_of_ash/thumbnail.png -- create

References:

  • Mod descriptor format: docs/ck3-modding/ck3-modding-reference.md lines 75-125
  • Steam Workshop publishing: docs/ck3-modding/ck3-modding-reference.md lines 493-501

Testing Checkpoints

See docs/TESTING.md for the full testing protocol, debug decisions, log analysis commands, and helper scripts.

  • After 8.1 (Map Files): Boot test with ONLY the map files and minimal game data. CK3 should load the map without crashing. Verify: provinces render as distinct colored regions, heightmap creates visible terrain elevation, rivers flow correctly without gaps. Do NOT proceed to 8.2 until the map loads cleanly -- broken maps crash CK3 instantly.

  • After 8.2 (Province Remapping): Boot test with remapped provinces. Every barony should resolve to a valid province on the new map. Verify: Luthadel appears in the center of the map, Terris provinces are in the north, Pits of Hathsin in the south. Check error.log for "province not found" errors.

  • After 8.3 (Regions and Terrain): Verify geographic regions in-game via debug mode. Terrain types should be visible on the terrain map mode. Verify: mountains appear where Ashmounts and Terris should be, plains in the Central Dominance.

  • After 8.4 (Trait Icons): Open the trait browser in debug mode. Every metallic arts trait should display its custom icon (not a missing-texture placeholder). Verify all 26 icons render at correct size and are visually distinguishable.

  • After 8.5 (Modifier/UI Icons): Check modifier tooltips -- each should show its unique icon. Loading screens should cycle through custom art. Bookmark should display custom background.

  • After 8.6 (Portraits): Browse characters of each culture in debug mode. Noble Scadrians should appear pale, skaa should appear weathered/darker, Terris should appear dark-skinned. No bald characters. Inquisitors should have scripted disfigured appearance.

  • After 8.7 (Balance Pass): Play a 30-year campaign without feeling either overpowered or helpless. The Lord Ruler should feel threatening but beatable with preparation. Mistborn characters should feel powerful but not invincible.

  • After 8.8-8.9 (Localization + Error Log): Complete playthrough. No raw localization keys visible anywhere. error.log completely clean. All interface text reads naturally and consistently.

  • After 8.10 (Final Integration): Fresh install test. The mod installs, loads, plays, saves, and reloads without any issues. A friend who has never seen the mod can install it and understand what's happening.

Acceptance Criteria

  • Custom Scadrial map loads without errors -- provinces, heightmap, rivers, and terrain all render correctly
  • All province = XXXX references in landed_titles match new custom province IDs from definitions.csv
  • Province history files assign correct culture, religion, and holdings for all new provinces
  • Geographic regions match the 5 Dominances + Remote Dominance structure
  • All ~26 trait icons are custom .dds files that display correctly in-game
  • All ~20 modifier icons are custom .dds files (no more placeholder sharing)
  • At least 3 custom loading screens display during game load
  • Bookmark displays custom art and descriptions
  • Noble Scadrian, skaa, and Terris characters have visually distinct appearances via custom ethnicities
  • Steel Inquisitor characters have visually distinct disfigured appearance
  • Balance: a Narrative Mode playthrough from bookmark to endgame takes 15-30 in-game years and feels neither trivially easy nor impossibly hard
  • All localization keys are present and display correctly -- no raw key names visible in any UI
  • error.log is completely clean after a 20-year playthrough (zero errors, zero warnings)
  • Game performance is acceptable: years process in reasonable time in observer mode for 50 years
  • Save/reload works without introducing errors
  • Both .mod descriptor files are correct and the mod loads from a fresh install
  • The mod is ready for Steam Workshop upload (thumbnail, tags, supported_version all set)

Risks & Mitigations

  1. Map crashes. This is the highest-risk task in the entire project. provinces.png pixel errors, rivers.png discontinuities, and definitions.csv mismatches all crash CK3 hard with minimal error messages. Mitigation: Build the map incrementally. Test after EVERY change to provinces.png. Start with a minimal map (10 provinces) and expand. Keep a working backup at each stage. Test rivers independently. Use the CK3 map validator if available in debug mode.

  2. DDS format issues. Wrong compression format, missing alpha channel, or wrong dimensions can cause invisible icons or crashes. Mitigation: Use a known-good DDS export pipeline (GIMP with nvidia DDS plugin set to DXT5, or Paint.NET with DDS plugin). Test a single icon before mass-producing all 46+ icons. Verify by checking if the icon appears in-game, not just in the file system.

  3. Province count mismatch. If the number of provinces in definitions.csv doesn't match provinces.png colors, or if landed_titles references a province ID that doesn't exist, the game crashes or generates errors. Mitigation: Maintain a single source-of-truth mapping document. Validate programmatically: script that counts unique colors in provinces.png and compares to definitions.csv rows. Validate all province = lines in landed_titles against the CSV.

  4. Ethnicity definition complexity. CK3's ethnicity system is poorly documented and has changed across versions. Custom ethnicities may not work as expected. Mitigation: Start by cloning vanilla ethnicity definitions and making minimal changes (skin tone only). Test each culture independently. If custom ethnicities prove too unstable, fall back to using vanilla ethnicities with the closest match (caucasian for nobles, a mixed set for skaa, african-template for Terris).

  5. Scope creep in polish phase. During balance testing, it's tempting to add new features, events, or mechanics. Mitigation: M8 is strictly polish and presentation. Any new mechanical ideas should be logged as "future milestone" items, not implemented now. The goal is to ship what exists in the best possible state.

  6. Performance regression from many events. M7 added 50+ new events. If on_action hooks fire too many checks per tick, the game slows down. Mitigation: Profile during the 50-year observer test. If slow, reduce event check frequency (change yearly pulse to every-3-years for rare events), add is_ruler = yes gates to prevent checks on non-ruler characters, and ensure hidden events skip portrait rendering.

Open Questions

  1. Map dimensions. What exact pixel dimensions should provinces.png be? Larger maps (4096x4096+) look better but require more detailed province art and take longer to load. Smaller maps (2048x2048) are faster to create and test but may look blocky. Recommend starting with 2048x2048 and scaling up only if it looks unacceptable.

  2. Art creation pipeline. Who creates the icon and loading screen art? If AI-generated art is acceptable for initial release, tools like DALL-E or Midjourney can produce consistent fantasy art. If hand-drawn art is preferred, this task becomes significantly longer. The milestone doc assumes art is created by whatever means are available.

  3. Custom terrain types vs. vanilla reuse. Creating custom terrain types (ashmount_terrain, ash_plains) requires defining combat modifiers, supply values, and visual properties. This is a significant sub-project. If vanilla terrain types (mountains, plains, desert) suffice with appropriate province assignment, skip custom types for this milestone.

  4. Ethnicity compatibility across CK3 versions. The ethnicity system has changed between CK3 patches. Custom ethnicities written for 1.18.* may break in future updates. Should we use the simplest possible implementation (just changing the ethnicities = { } block in cultures to reference vanilla ethnicities with different weights) rather than creating fully custom ethnicity definitions?

  5. River complexity. How detailed should the river system be? The River Channerel is the main waterway. Adding tributaries adds visual quality but significantly increases crash risk. Recommend: one main river with 2-3 short tributaries for initial release. Expand river network in a post-release patch if desired.