djeada 1232c50a4e apply format 1 month ago
..
README.md 1232c50a4e apply format 1 month ago
campaign_state.json c3faa134b4 Fix map pipeline gating for clean runs (#843) 1 month ago
hannibal_path.json 9eb0fdbc7c Fix mode indicator (#851) 1 month ago
valid_provinces.json 9ede197744 Improve campaign UI and data management with province ID synchronization (#666) 2 months ago

README.md

Campaign Map Assets

This directory contains campaign map resources for the Mediterranean strategic map.

Rendering Improvements (TODO.md Implementation)

Visual Enhancements

  1. Inked Cartography Path Lines

    • Replaced basic GL line strips with triangulated ribbon meshes
    • Multi-pass rendering: dark border → golden highlight → red core
    • Proper miter joins and round caps for polished stroke appearance
    • Age-based fading for historical route progression
  2. Spline-Smoothed Routes

    • Catmull-Rom spline interpolation for smooth, curved trajectories
    • 8 samples per segment removes jagged segments
    • Coastline-hugging paths look natural and authentic
  3. Double-Stroke Coastlines

    • Dark outer stroke + light inner stroke for printed-map legibility
    • Cartographic style matches historical atlas aesthetics
    • Proper z-layering prevents visual artifacts
  4. Province Fills with Parchment Texture

    • Faint parchment/ink texture mask effect
    • Owner tint as multiply overlay for aged paper look
    • Slight warm tinting for authentic period feel
  5. Cinematic Camera Defaults

    • Yaw: 185° (slight northwest tilt)
    • Pitch: 52° (more oblique for terrain visibility)
    • Distance: 1.35 (closer for detail appreciation)
    • Showcases relief and depth by default

Shader Files

New shaders for enhanced rendering (in assets/shaders/):

  • campaign_terrain.vert/.frag - Height-displaced terrain with hillshade and AO
  • campaign_stroke.vert/.frag - Improved stroke rendering with ink texture
  • campaign_province.vert/.frag - Province fills with parchment texture
  • campaign_badge.vert/.frag - Mission marker badges (shield, seal, banner)
  • campaign_symbol.vert/.frag - Cartographic symbols (mountains, cities, ports)
  • campaign_coastline.frag - Double-stroke coastline rendering

Utility Header

ui/campaign_map_render_utils.h provides:

  • Catmull-Rom spline smoothing
  • Triangulated stroke mesh generation with joins/caps
  • Multi-pass stroke rendering configurations
  • Hillshade and terrain coloring utilities
  • Parchment texture pattern generation
  • Cartographic symbol generation (mountains, cities, anchors)
  • Mission badge geometry generation

Files

  • campaign_base_color.png - Base terrain texture for the Mediterranean map
  • campaign_water.png - Water texture
  • coastlines_uv.json - Coastline geometry in UV space
  • rivers_uv.json - River geometry in UV space
  • land_mesh.bin - Binary land mesh data
  • terrain_height.png - 16-bit heightmap (ETOPO2022 60s bedrock) for terrain relief
  • terrain_height.json - Heightmap metadata (min/max meters, size, dataset)
  • hannibal_path.json - Hannibal's campaign route visualization with coastline-aware paths
    • Contains 8 progressive route lines, one per campaign mission
    • Routes follow North African coast west to Gibraltar before crossing to Spain
    • Coastal segments along Mediterranean use smooth curves
    • Open-sea crossings only at Gibraltar and Sicily→Carthage
    • Rendered with three-pass system for historical map appearance (10px border, 6.5px gold highlight, 3.5px red core)
    • Generated by tools/map_pipeline/hannibal_path.py
  • provinces.json - Generated province boundaries and metadata (generated by tools/map_pipeline/provinces.py)
  • valid_provinces.json - Province ID validation and mission mapping

Province ID Synchronization

The valid_provinces.json file serves as the single source of truth for valid province IDs and their mapping to missions.

Province IDs (from provinces.py)

The following province IDs are generated by tools/map_pipeline/provinces.py:

  • iberia_carthaginian - Carthaginian Iberia
  • iberia_interior - Iberian Interior
  • transalpine_gaul - Transalpine Gaul (Rhône region)
  • cisalpine_gaul - Cisalpine Gaul (Northern Italy)
  • etruria - Etruria (Central Italy)
  • roman_core - Roman Core (Rome and surroundings)
  • southern_italy - Southern Italy (includes Apulia/Cannae region)
  • sicily_roman - Roman-controlled Sicily
  • sicily_carthaginian - Carthaginian-controlled Sicily
  • sardinia - Sardinia
  • corsica - Corsica
  • carthage_core - Carthage and surrounding territory
  • numidia - Numidia (Western North Africa)
  • libya - Libya (Eastern North Africa)
  • illyria - Illyria (Balkans)

Mission to Province Mapping

Missions reference provinces via world_region_id field in campaign JSON files:

  • crossing_the_rhonetransalpine_gaul
  • battle_of_ticinocisalpine_gaul
  • battle_of_trebiacisalpine_gaul
  • battle_of_trasimeneetruria
  • battle_of_cannaesouthern_italy
  • campania_campaignsouthern_italy
  • crossing_the_alpscisalpine_gaul
  • battle_of_zamacarthage_core

Important Notes

  1. Always use province IDs from valid_provinces.json when adding new missions or features
  2. The province IDs must match those generated by provinces.py
  3. UI code (e.g., MediterraneanMapPanel.qml) should reference these validated IDs
  4. If you modify provinces.py, update valid_provinces.json accordingly
  5. Historical region names (like "Apulia" or "Campania") may not have direct province IDs - use the closest matching province (e.g., southern_italy)

Regenerating Province Data

To regenerate the provinces.json file:

cd tools/map_pipeline
python3 provinces.py

This will update the province boundaries, triangulation, and borders based on the definitions in provinces.py.