Table of Contents

Namespace Map.Rendering

Classes

BillboardAtlasGenerator

Optional utility for generating texture atlases at runtime. Can generate numeric atlases (0-99) or custom character sets.

Use Cases:

  • Unit count badges (grand strategy games)
  • Score displays
  • Numeric indicators on map
  • Any instanced text rendering

Architecture:

  • Generates texture at runtime (no asset files needed)
  • Procedural bitmap font for digits
  • Point filtering for crisp text at any distance
  • Configurable colors and resolution

NOTE: This is an optional feature. Games don't need to use this if they don't need numeric badges or have their own text rendering.

BorderComputeDispatcher

Coordinator for border rendering systems Orchestrates multiple rendering modes: distance field, mesh geometry, and pixel-perfect

REFACTORED: Now uses specialized helper classes for single responsibility

  • BorderShaderManager: Compute shader loading and kernel management
  • BorderParameterBinder: Rendering parameters and shader binding
  • BorderStyleUpdater: Border style classification and updates
  • BorderDebugUtility: Debug utilities and benchmarking

Architecture: Facade pattern - provides unified interface to border rendering subsystems

BorderCurveCache

Caches pre-computed smooth border polylines and their runtime styles Separates static geometry (expensive to compute) from dynamic appearance (cheap to update)

Pattern: Static Geometry + Dynamic Appearance

  • Smooth polylines (RDP + Chaikin) computed once at map load
  • Styles updated at runtime when ownership changes
BorderCurveExtractor

Extracts smooth border curves from bitmap province boundaries Uses AdjacencySystem to process only known neighbor pairs (efficient) Pre-computes all curves at map load for zero-cost runtime updates

Architecture: Static Geometry + Dynamic Appearance Pattern

  • Geometry (curves) computed once and cached
  • Appearance (colors, thickness) updated at runtime via flags

REFACTORED: Now uses specialized helper classes for single responsibility

  • BorderPolylineSimplifier: RDP simplification, Chaikin smoothing, tessellation
  • BorderGeometryUtils: Geometric utilities (intersection, angles, distances)
  • BorderChainMerger: Chain merging with U-turn detection
  • JunctionDetector: Junction detection and endpoint snapping
  • MedianFilterProcessor: Median filtering and pixel chaining
BorderDistanceFieldGenerator

Generates distance field textures for modern Paradox-style smooth anti-aliased borders. Uses Jump Flooding Algorithm (JFA) for efficient GPU-based distance field generation.

Algorithm:

  1. Edge Detection: Mark border pixels
  2. Jump Flooding: Propagate closest border distance (log(n) passes)
  3. Finalize: Convert positions to distances

Result: Silky smooth borders at any zoom level (CK3/Stellaris quality)

BorderMeshGenerator

Generates quad meshes from smoothed polyline borders Converts Chaikin-smoothed curves into renderable triangle geometry Each line segment becomes a thin quad (2 triangles) with flat square caps

BorderMeshRenderer

Renders border meshes using Unity's Graphics.DrawMesh API Handles province and country borders as separate mesh objects Uses unlit vertex color material for simple flat-shaded borders

BorderTextureDebug
CoreTextureSet

Manages core gameplay-critical textures Province ID, Owner, Color, and Development textures Extracted from MapTextureManager for single responsibility

DynamicTextureSet

Manages runtime-generated dynamic textures Border, Highlight, and Fog of War RenderTextures for effects Extracted from MapTextureManager for single responsibility

BORDER TEXTURE ARCHITECTURE (Clean Separation):

  • DistanceFieldBorderTexture: Used by ShaderDistanceField mode (smooth JFA borders)
  • PixelPerfectBorderTexture: Used by ShaderPixelPerfect mode (sharp 1px borders) Each mode has its own dedicated texture - no sharing/reusing between modes.
FogOfWarSystem

ENGINE LAYER - Manages fog of war visibility state Universal grand strategy fog of war mechanics:

  • Unexplored: Never seen (0.0)
  • Explored: Previously seen but not currently visible (0.5)
  • Visible: Currently owned or adjacent to owned (1.0)

Visual appearance (colors, effects) is defined by GAME layer shaders

InstancedBillboardRenderer

Base class for GPU instanced billboard rendering. Renders thousands of billboarded sprites in a single draw call using Graphics.DrawMeshInstanced.

Architecture:

  • Maintains matrix lists for world positions
  • Uses MaterialPropertyBlock for per-instance data
  • Subclasses implement data source integration (event systems, polling, etc.)
  • Dirty flag system for efficient updates

Performance:

  • Single draw call for all instances
  • Billboard rotation in vertex shader (GPU-side)
  • Event-driven updates (no Update loop overhead)

Usage:

  • Inherit and implement abstract methods
  • Call MarkDirty() when data changes
  • RebuildInstances() is called automatically on dirty flag
MapRenderer

Creates and manages the single quad mesh for texture-based map rendering

MapRendererRegistry

ENGINE: Central registry for pluggable map rendering implementations.

ENGINE provides default renderers (DistanceField, PixelPerfect, MeshGeometry). GAME can register custom implementations during initialization.

Usage:

  1. ENGINE registers defaults automatically on initialization
  2. GAME registers custom renderers before map initialization: MapRendererRegistry.Instance.RegisterBorderRenderer(new MyCustomBorderRenderer());
  3. VisualStyleConfiguration references renderers by string ID

Pattern follows IMapModeHandler registration approach.

MapTextureManager

Facade coordinator for all map textures Delegates to specialized texture set managers Provides unified API for external consumers

MapTexturePopulator

Handles population of map textures from province data. Plain C# class - dependencies passed via constructor.

NormalMapGenerator

Generates normal map from heightmap using GPU compute shader. Based on EU5's approach - calculates gradients on GPU for maximum performance.

Algorithm:

  1. Sample heightmap at each pixel and 4 neighbors (LRUD)
  2. Calculate gradients using central difference
  3. Construct normal vector from gradients
  4. Pack normal into RG8 texture (XZ components, reconstruct Y in fragment shader)

Result: High-quality lighting with depth perception at any zoom level

OwnerTextureDispatcher

Manages GPU compute shader for high-performance owner texture population. Processes entire map in parallel to populate province owner texture from simulation data. Part of the texture-based map rendering system - dual-layer architecture compliance. Performance: ~2ms for entire map vs 50+ seconds on CPU

PaletteTextureManager

Manages province color palette texture (256×1 RGBA32) Handles palette generation and color updates Extracted from MapTextureManager for single responsibility

ProvinceMapping

Compatibility shim for legacy ProvinceMapping Bridges the gap between old system expectations and new ProvinceMapProcessor

ProvinceMapping.ProvinceInfo
ProvinceTerrainAnalyzer

ENGINE: Analyzes terrain.bmp to determine dominant terrain type per province Uses GPU compute shader for efficient majority voting across all pixels Refactored to use specialized components for RGB lookup, BMP reading, and overrides

SubdividedPlaneMeshGenerator

Utility to generate subdivided plane meshes for tessellation Use via menu: Tools/Archon/Generate Subdivided Plane Mesh

TextureStreamingManager

Manages texture streaming for very large maps (>10k provinces) Task 1.3: Add texture streaming for very large maps (>10k provinces) Uses tile-based streaming to handle massive maps efficiently

TextureUpdateBridge

Simple bridge component that listens to province change events and updates textures via MapTexturePopulator. Replaces the complex SimulationTextureUpdater with a lightweight event-driven approach.

Configuration comes from GameSettings - no Inspector assignments needed.

TreeInstanceGenerator

GPU-driven tree instance generation using compute shaders.

Architecture:

  • Reads terrain type texture to determine tree placement
  • Generates tree positions/rotations/scales procedurally on GPU
  • Outputs StructuredBuffer for DrawMeshInstancedIndirect
  • Deterministic (same terrain = same trees)

Performance:

  • Runs once at map load (or when terrain changes)
  • GPU parallel processing (8x8 thread groups)
  • Zero CPU overhead after generation

Usage:

  • Call GenerateTrees() to populate buffers
  • Use GetTreeMatrixBuffer() for indirect rendering
TreeInstanceRenderer

GPU-driven tree rendering using DrawMeshInstancedIndirect.

Architecture:

  • Renders trees from GPU buffer (no CPU array transfer)
  • Single draw call for all trees (millions possible)
  • Receives transform matrices from TreeInstanceGenerator
  • Fully GPU-driven (instance count read from buffer)

Performance:

  • Zero CPU overhead per frame
  • GPU reads instance count and matrices directly
  • Frustum culling handled by GPU
  • Supports shadows and LOD

Usage:

  • Call SetTreeData() to bind matrix buffer
  • Update() automatically renders each frame
UnitPathRenderer

ENGINE (Map Layer) - Renders movement path lines for units.

Simple LineRenderer-based visualization for unit movement paths. Subscribes to Core movement events and draws paths using ProvinceCenterLookup.

Can be disabled/replaced by GAME layer if custom visualization is needed.

VisualTextureSet

Manages visual enhancement textures Terrain, Heightmap, and Normal Map textures for visual fidelity Extracted from MapTextureManager for single responsibility

Structs

BorderStyle

Style information for rendering a border segment Static geometry (curves), dynamic appearance (colors, thickness)

Enums

BorderMode

Border mode - what borders to show

BorderRenderingMode

Border rendering mode - how to render borders

BorderType