warfactoryracine/docs/calcul-menace.md
StillHammer f393b28d73 Migrate core engine interfaces to GroveEngine repository
Removed core engine infrastructure from warfactoryracine:
- Core interfaces: IEngine, IModule, IModuleSystem, IIO, ITaskScheduler, ICoordinationModule
- Configuration system: IDataTree, IDataNode, DataTreeFactory
- UI system: IUI, IUI_Enums, ImGuiUI (header + implementation)
- Resource management: Resource, ResourceRegistry, SerializationRegistry
- Serialization: ASerializable, ISerializable
- World generation: IWorldGenerationStep (replaced by IWorldGenerationPhase)

These components now live in the GroveEngine repository and are included
via CMake add_subdirectory(../GroveEngine) for reusability across projects.

warfactoryracine remains focused on game-specific logic and content.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 00:22:36 +08:00

24 KiB
Raw Blame History

Calcul de Menace Contextuelle

Vue d'Ensemble

Le système de calcul de menace évalue la dangerosité qu'une entité représente pour une autre en analysant non seulement les forces brutes, mais aussi les capacités défensives, la qualité des équipements, et la production industrielle.

Principes Fondamentaux

  • Contextuel : Menace calculée selon capacités des deux parties
  • Asymétrique : A menace B ≠ B menace A
  • Sword & Shield : Qualité défenses réduit menace, jamais totalement
  • Baseline 20% : Toute arme reste dangereuse à minimum 20% effectiveness
  • Production : Capacité industrielle = menace future
  • Multi-domaines : Terre, air, mer évalués séparément puis agrégés
  • Perte coûteuse : Perdre unité chère = désastre stratégique même avec victoire

Distinction Menace vs Victoire Tactique

CRITIQUE : La menace mesure la capacité de nuisance stratégique, pas l'issue du combat tactique.

Exemple : 20 tanks modernes peuvent être détruits par saturation, MAIS avant destruction ils peuvent :

  • Percer défenses et atteindre objectifs profonds
  • Détruire infrastructure critique (QG, dépôts, ponts)
  • Infliger pertes massives
  • Forcer mobilisation coûteuse

→ Menace élevée même si tanks finalement détruits → Perte d'un Leopard 2A7 (8M€) = toujours désastre stratégique

Échelle de Menace

Valeurs : 0 à 2 000 000+ (pas de maximum strict, type int32_t)

Ordres de grandeur :

  • 0 : Aucune menace
  • 100 - 1 000 : PMC petit
  • 5 000 - 50 000 : Company moyenne
  • 100 000 : État petit
  • 500 000 : État moyen (France, UK, Allemagne)
  • 900 000 : Superpower (USA, Chine, Russie)
  • 1 000 000+ : Menace existentielle

Architecture Calcul

Formule Globale

int calculateThreat(Entity attacker, Entity defender) {
    auto params = attacker.getThreatParams();

    // Composantes
    int current_military = evaluateCurrentForces(attacker, defender);
    int production_capacity = evaluateProduction(attacker, defender, params.projection_months);

    // Pondération configurable par entité
    return current_military * params.current_weight +
           production_capacity * params.production_weight;
}

struct ThreatCalculationParams {
    int projection_months = 12;      // Horizon projection (défaut 12 mois)
    float current_weight = 0.6f;     // Poids forces actuelles (60%)
    float production_weight = 0.4f;  // Poids production (40%)
};

Personnalisation par entité :

  • Company agressive : current: 0.8, production: 0.2 (focus court-terme)
  • State prudent : current: 0.4, production: 0.6 (focus long-terme)
  • PMC réactif : current: 0.9, production: 0.1 (menace immédiate prioritaire)

Évaluation Forces Actuelles

Principe : Sword & Shield avec Effectiveness Float

Pour chaque domaine (terre, air, mer), on évalue :

  1. Sword (attaquant) : Capacités offensives
  2. Shield (défenseur) : Capacités défensives
  3. Effectiveness : Ratio pénétration/armure avec baseline 20% minimum
int evaluateCurrentForces(Entity attacker, Entity defender) {
    int land_threat = evaluateLandThreat(attacker, defender);
    int air_threat = evaluateAirThreat(attacker, defender);
    int naval_threat = evaluateNavalThreat(attacker, defender);

    return land_threat + air_threat + naval_threat;
}

Système Armor vs Penetration

Référence de Base

Chaque équipement possède des valeurs mesurables :

struct Tank {
    float armor_average;  // Moyenne armure (mm RHA equivalent)
    int combat_value;     // Valeur au combat
    int quantity;

    // Exemple Leopard 2A7:
    // - Frontal: 950mm RHA
    // - Flancs: 200mm RHA
    // - Arrière: 100mm RHA
    // - Average (pondéré surface): ~400mm
};

struct ATWeapon {
    float penetration;    // Pénétration max (mm RHA)
    int combat_value;
    int quantity;

    // Exemples:
    // - RPG-7: 260mm
    // - Milan Gen2: 530mm
    // - Javelin Gen3 (top-attack): 800mm
    // - Kornet Gen4+ (tandem): 1200mm
};

Calcul Effectiveness (Float)

Formule baseline 20% : Toute arme reste dangereuse (flancs, arrière, chance)

float calculateCounterEffectiveness(ATWeapon weapon, Tank tank) {
    float pen_ratio = weapon.penetration / tank.armor_average;

    // BASELINE 20% : TOUJOURS dangereux
    const float BASE_EFFECTIVENESS = 0.20f;

    if (pen_ratio >= 1.0f) {
        // Arme peut percer : scaling jusqu'à 90% max
        float bonus = (pen_ratio - 1.0f) * 0.5f;
        return min(0.90f, BASE_EFFECTIVENESS + bonus);
    }
    else {
        // Arme sous-dimensionnée : reste à 20% (flancs, arrière, chance)
        return BASE_EFFECTIVENESS;
    }
}

Exemples Effectiveness

// Leopard 2A7 (armor_avg = 400mm) vs différentes armes

RPG-7 (260mm) :
  pen_ratio = 260 / 400 = 0.65
  effectiveness = 20%
   100 RPG-7 needed = 20 "équivalents kill"
   Coût: 100 × 500 = 50k vs Leopard 8M = 0.625% ratio
   Menace présente mais faible, économiquement viable en masse

Milan Gen2 (530mm) :
  pen_ratio = 530 / 400 = 1.325
  effectiveness = 20% + (0.325 × 0.5) = 36.25%
   ~3 missiles = 1 kill probable
   Menace sérieuse

Javelin Gen3 (800mm top-attack) :
  pen_ratio = 800 / 400 = 2.0
  effectiveness = 20% + (1.0 × 0.5) = 70%
   ~1.5 missiles = 1 kill probable
   Menace très élevée

Kornet Gen4+ (1200mm tandem) :
  pen_ratio = 1200 / 400 = 3.0
  effectiveness = 20% + (2.0 × 0.5) = 90% (plafonné)
   ~1.1 missiles = 1 kill quasi-certain
   Menace maximale

Évaluation Domaine Terrestre

Inventaire Forces

Attaquant :

struct LandForces {
    std::vector<Tank> tanks;
    std::vector<IFV> ifvs;
    std::vector<APC> apcs;
    std::vector<Artillery> artillery;
    std::vector<Infantry> infantry;
};

Défenseur :

struct LandDefenses {
    std::vector<ATSystem> anti_tank;      // Systèmes anti-char
    std::vector<Tank> counter_tanks;      // Tanks défensifs
    std::vector<Infantry> anti_tank_inf;  // Infanterie AT
    std::vector<Fortification> fortifications;
};

Couples Équipement ↔ Contre-mesures

Principe : Chaque type d'équipement offensif a des contre-mesures spécifiques.

struct EquipmentCounters {
    std::map<EquipmentType, std::vector<CounterType>> counters = {
        {TANK, {AT_MISSILE, AT_GUN, COUNTER_TANK, AT_INFANTRY}},
        {IFV, {AT_MISSILE, AT_GUN, AUTOCANNON}},
        {APC, {AUTOCANNON, MACHINE_GUN, RPG}},
        {INFANTRY, {MACHINE_GUN, ARTILLERY, AUTOCANNON}},
        {ARTILLERY, {COUNTER_BATTERY, AIR_STRIKE}}
    };
};

Calcul Defensive Effectiveness

float calculateDefensiveEffectiveness(
    std::vector<Equipment> swords,
    std::vector<Defense> shields
) {
    float total_sword_value = 0;
    float neutralized_value = 0;

    for (auto& sword : swords) {
        float sword_value = sword.quantity * sword.combat_value;
        total_sword_value += sword_value;

        // Trouver défenses applicables
        auto applicable_shields = findApplicableDefenses(sword, shields);

        // Calculer valeur défensive totale contre ce sword
        float shield_value = 0;
        for (auto& shield : applicable_shields) {
            // ✅ EFFECTIVENESS FLOAT (20%-90%)
            float effectiveness = calculateCounterEffectiveness(shield, sword);
            shield_value += shield.quantity * shield.combat_value * effectiveness;
        }

        // Neutralisation proportionnelle
        float neutralization = min(1.0f, shield_value / sword_value);
        neutralized_value += sword_value * neutralization;
    }

    return total_sword_value > 0 ? (neutralized_value / total_sword_value) : 0.0f;
}

Score Final avec Menace Résiduelle

int evaluateLandThreat(Entity attacker, Entity defender) {
    auto swords = attacker.getLandForces();
    auto shields = defender.getLandDefenses();

    // Menace brute (sans défenses)
    int raw_threat = 0;
    for (auto& sword : swords) {
        raw_threat += sword.quantity * sword.combat_value;
    }

    // Réduction par défenses
    float defensive_effectiveness = calculateDefensiveEffectiveness(swords, shields);

    // ✅ MENACE RÉSIDUELLE : Jamais totalement nulle si attaquant existe
    float residual_multiplier = max(0.05f, 1.0f - defensive_effectiveness);
    int final_threat = raw_threat * residual_multiplier;

    return final_threat;
}

Exemples Concrets Terre

Exemple 1 : Tech Obsolète Viable en Masse

Attaquant :

  • 20 tanks Gen4 (Leopard 2A7)
    • armor_average : 400mm RHA
    • combat_value : 1000/tank
    • Menace brute : 20 000
    • Valeur totale : 20 × 8M€ = 160M€

Défenseur :

  • 5000 RPG-7 (Gen1, ancien)
    • penetration : 260mm
    • pen_ratio : 260/400 = 0.65
    • effectiveness : 20% (baseline)
    • combat_value : 50/RPG
    • shield_value : 5000 × 50 × 0.20 = 50 000
    • Coût : 5000 × 500€ = 2.5M€

Résultat :

defensive_effectiveness = min(1.0, 50000 / 20000) = 100%
residual_multiplier = max(0.05, 1.0 - 1.0) = 5%
final_threat = 20000 × 0.05 = 1 000

→ Menace quasi-neutralisée (5% résiduel)
→ Nécessite 5000 RPG-7 (masse logistique)
→ Ratio coût défenseur/attaquant = 2.5M€ / 160M€ = 1.56%
→ Défense économiquement viable ✅
→ MAIS perte Leopard reste désastre (8M€ + prestige + formation)

Exemple 2 : Tech Moderne Efficace

Attaquant :

  • 20 tanks Gen4 (Leopard 2A7)
    • armor_average : 400mm
    • Menace brute : 20 000

Défenseur :

  • 100 missiles Javelin Gen3
    • penetration : 800mm (top-attack)
    • pen_ratio : 800/400 = 2.0
    • effectiveness : 70%
    • combat_value : 300/missile
    • shield_value : 100 × 300 × 0.70 = 21 000
    • Coût : 100 × 200k€ = 20M€

Résultat :

defensive_effectiveness = min(1.0, 21000 / 20000) = 100%
residual_multiplier = 5%
final_threat = 20000 × 0.05 = 1 000

→ Menace quasi-neutralisée
→ Ratio coût : 20M€ / 160M€ = 12.5%
→ Plus cher que RPG-7 mais logistique simplifiée (100 vs 5000)

Exemple 3 : Défense Insuffisante

Attaquant :

  • 20 tanks Gen4
    • Menace brute : 20 000

Défenseur :

  • 500 RPG-7
    • effectiveness : 20%
    • shield_value : 500 × 50 × 0.20 = 5 000

Résultat :

defensive_effectiveness = 5000 / 20000 = 25%
residual_multiplier = max(0.05, 0.75) = 75%
final_threat = 20000 × 0.75 = 15 000

→ Menace reste élevée (75%)
→ Défense insuffisante

Exemple 4 : Défense Mixte Économique

Attaquant :

  • 20 tanks Gen4
    • Menace brute : 20 000

Défenseur :

  • 30 Javelin Gen3 : shield = 30 × 300 × 0.70 = 6 300
  • 1000 RPG-7 : shield = 1000 × 50 × 0.20 = 10 000
  • Shield total : 16 300
  • Coût total : 30 × 200k€ + 1000 × 500€ = 6.5M€

Résultat :

defensive_effectiveness = 16300 / 20000 = 81.5%
residual_multiplier = max(0.05, 0.185) = 18.5%
final_threat = 20000 × 0.185 = 3 700

→ Menace réduite à 18.5% (acceptable)
→ Défense mixte optimise coût-efficacité
→ Ratio coût : 6.5M€ / 160M€ = 4.06%

Exemple 5 : Système de Conception Modulaire - Retrofit Anti-AT

Attaquant :

  • 20 tanks Leopard 2A7 retrofittés Gen5
    • Chassis Gen4 base
    • APS Trophy Gen5 : intercepte 80% missiles avant impact
    • ERA Gen5 : neutralise pénétration Gen2-3
    • armor_effective : 400mm × 2.5 (ERA bonus) = 1000mm equivalent
    • Menace brute : 20 000

Défenseur :

  • 1000 missiles Milan Gen2
    • penetration : 530mm
    • pen_ratio : 530/1000 = 0.53 (sous-dimensionné avec ERA)
    • effectiveness : 20% (baseline)
    • APS reduction : 20% × (1 - 0.80) = 4% effectiveness finale
    • shield_value : 1000 × 300 × 0.04 = 12 000

Résultat :

defensive_effectiveness = 12000 / 20000 = 60%
residual_multiplier = max(0.05, 0.40) = 40%
final_threat = 20000 × 0.40 = 8 000

→ Menace reste significative (40%)
→ APS + ERA réduisent drastiquement effectiveness Gen2
→ Système de conception permet adaptation doctrine
→ Joueur peut designer tanks spécifiquement anti-saturation

Évaluation Domaine Aérien

Spécificités Air

Complexité supplémentaire :

  • Qualité prime : Furtivité et ECM dominent
  • ECM/ECCM : Guerre électronique critique
  • Compatibilité stricte : AA anti-hélicoptère ne touche pas jets
struct AirForces {
    std::vector<Fighter> fighters;
    std::vector<Bomber> bombers;
    std::vector<Helicopter> helicopters;
    std::vector<Drone> drones;

    // Capacités spéciales
    bool has_stealth;
    bool has_ecm;           // Electronic Counter-Measures
    int electronic_warfare_level;
};

struct AirDefenses {
    std::vector<AAMissile> aa_missiles;
    std::vector<AAGun> aa_guns;
    std::vector<Fighter> interceptors;

    // Capacités
    bool has_eccm;          // Electronic Counter-Counter-Measures
    int radar_quality;
    std::map<AASystem, TargetCapability> capabilities;
};

enum TargetCapability {
    HELICOPTER_ONLY,        // Seulement hélicoptères
    LOW_ALTITUDE,           // Avions basse altitude
    HIGH_ALTITUDE,          // Avions haute altitude
    ALL_AIRCRAFT            // Tous types
};

Effectiveness Air avec Stealth/ECM

float calculateAirDefenseEffectiveness(Aircraft aircraft, AASystem aa) {
    // Base effectiveness selon pénétration radar vs stealth
    float base_eff = calculateCounterEffectiveness(aa, aircraft);

    // Multiplicateurs tech
    float stealth_reduction = 1.0f;
    if (aircraft.has_stealth && !aa.has_advanced_radar) {
        stealth_reduction = 1.0f - aircraft.stealth_rating; // Ex: 0.1 si 90% stealth
    }

    float ecm_reduction = 1.0f;
    if (aircraft.has_ecm && !aa.has_eccm) {
        ecm_reduction = 1.0f - (aircraft.ecm_power / (aa.radar_quality + 1));
    }

    // Effectiveness finale (baseline 20% toujours appliqué)
    float final_eff = max(0.20f, base_eff * stealth_reduction * ecm_reduction);

    return final_eff;
}

Exemple Air : Furtivité + ECM

Attaquant :

  • 20 jets furtifs Gen4 (F-35)
    • stealth_rating : 0.90 (réduit détection 90%)
    • ecm_power : 8
    • combat_value : 2000/jet
    • Menace brute : 40 000

Défenseur :

  • 1000 missiles AA Gen3 (Patriot)
    • radar_quality : 6
    • has_eccm : false
    • base_effectiveness : 70% (tech Gen3 vs Gen4)
    • stealth_reduction : 1.0 - 0.90 = 0.10
    • ecm_reduction : 1.0 - (8/7) = -0.14 → 0.0 (plancher)
    • final_effectiveness : max(0.20, 0.70 × 0.10 × 0.0) = 20% (baseline)
    • shield_value : 1000 × 400 × 0.20 = 80 000

Résultat :

defensive_effectiveness = min(1.0, 80000 / 40000) = 100%
residual_multiplier = 5%
final_threat = 40000 × 0.05 = 2 000

→ Furtivité + ECM ramènent effectiveness au baseline 20%
→ Nécessite masse importante (1000 missiles) pour compenser
→ F-35 peuvent accomplir raid avant saturation (menace 5% résiduelle)

Évaluation Domaine Naval

Similaire à terrestre/aérien mais avec spécificités :

  • Torpilles vs sonars (submersibles)
  • Anti-ship missiles vs CIWS (Close-In Weapon Systems)
  • Portée extrême : Naval combat à 100+ km

Structure identique avec couples spécifiques (penetration vs armor pour missiles anti-navire).

Évaluation Production

Principe

La menace ne vient pas seulement des forces actuelles, mais aussi de la capacité à produire plus d'équipements.

int evaluateProduction(Entity attacker, Entity defender, int projection_months) {
    int production_threat = 0;

    // Pour chaque type d'équipement
    for (auto& equipment_type : all_equipment_types) {
        // Taux production attaquant
        int attacker_rate = attacker.getProductionRate(equipment_type);  // unités/mois

        // Taux production défenses défenseur
        int defender_rate = defender.getProductionRate(getCounterType(equipment_type));

        // Projection future
        int attacker_produced = attacker_rate * projection_months;
        int defender_produced = defender_rate * projection_months;

        // Menace nette production
        int net_production = attacker_produced - defender_produced;
        if (net_production > 0) {
            int equipment_value = getEquipmentValue(equipment_type);
            production_threat += net_production * equipment_value;
        }
    }

    return production_threat;
}

Exemple Production

État A :

  • Production actuelle : 50 tanks/mois
  • Projection 12 mois : 600 tanks
  • Combat value : 400/tank
  • Production threat : 600 × 400 = 240 000

État B (défenseur) :

  • Production AT : 100 missiles/mois
  • Projection 12 mois : 1200 missiles
  • Combat value : 300/missile
  • Effectiveness moyenne : 40%
  • Défense production : 1200 × 300 × 0.40 = 144 000

Net production threat :

Attacker gain : 240 000
Defender gain : 144 000
Net : 240 000 - 144 000 = 96 000

production_threat = 96 000

→ État A a avantage production malgré défenses

Agrégation Finale

Formule Complète

int calculateThreat(Entity attacker, Entity defender) {
    auto params = attacker.getThreatParams();

    // Forces actuelles (sword & shield par domaine)
    int land_threat = evaluateLandThreat(attacker, defender);
    int air_threat = evaluateAirThreat(attacker, defender);
    int naval_threat = evaluateNavalThreat(attacker, defender);

    int current_military = land_threat + air_threat + naval_threat;

    // Production future
    int production_threat = evaluateProduction(
        attacker,
        defender,
        params.projection_months
    );

    // Pondération finale
    int total_threat = current_military * params.current_weight +
                       production_threat * params.production_weight;

    return total_threat;
}

Exemples Complets

Superpower vs État Moyen

USA vs France

USA forces :

  • Tanks : 8000 (Gen3-4) → 3 200 000
  • Aircraft : 2000 (Gen4, furtifs) → 4 000 000
  • Naval : 500 ships → 2 500 000
  • Total brut : 9 700 000

France défenses :

  • AT systems : 3000 (Gen3, eff 60%) → Shield 60% tanks
  • AA systems : 1500 (Gen3, eff 40% vs furtifs) → Shield 40% aircraft
  • Naval defenses : 200 (eff 50%) → Shield 50% naval

Après sword & shield :

  • Land : 3 200 000 × max(0.05, 0.40) = 1 280 000
  • Air : 4 000 000 × max(0.05, 0.60) = 2 400 000
  • Naval : 2 500 000 × max(0.05, 0.50) = 1 250 000
  • Current threat : 4 930 000

Production (12 mois) :

  • USA : +600 tanks, +100 aircraft → 360 000
  • France : +100 tanks, +50 aircraft → 70 000
  • Net production : 290 000

Total (60% current, 40% prod) :

4 930 000 × 0.6 + 290 000 × 0.4 = 3 074 000

→ Menace colossale, mais France peut tenir avec alliances

PMC vs Company

PMC_Alpha vs RheinmetallCorp

PMC forces :

  • Infantry : 500 (léger armement)
  • Vehicles : 20 APCs
  • Total : 50 000

Rheinmetall défenses :

  • Security : 100 guards (effectiveness 30%)
  • Fortifications : minimal
  • Shield : 15%

Threat :

residual = max(0.05, 1.0 - 0.15) = 85%
final_threat = 50000 × 0.85 = 42 500

→ PMC peut menacer installations Company

Cas Spéciaux

Menace Économique Pure

Pour Companies sans capacités militaires :

int calculateEconomicThreat(Company attacker, Company defender) {
    // Part de marché
    float market_dominance = attacker.market_share / (defender.market_share + 0.01f);

    // Capacité production
    float production_ratio = attacker.production_capacity / defender.production_capacity;

    // Qualité produits
    float quality_advantage = attacker.avg_product_quality / defender.avg_product_quality;

    // Menace économique
    int economic_threat = (market_dominance * 100000) +
                          (production_ratio * 80000) +
                          (quality_advantage * 50000);

    return economic_threat;
}

Menace Géographique

Distance géographique module menace :

float getGeographicModifier(Entity attacker, Entity defender) {
    float distance_km = calculateDistance(attacker.position, defender.position);

    // Projection power diminue avec distance
    if (distance_km < 500) {
        return 1.0f;  // Menace pleine
    }
    else if (distance_km < 2000) {
        return 0.7f;  // 30% réduction
    }
    else if (distance_km < 5000) {
        return 0.4f;  // 60% réduction
    }
    else {
        return 0.1f;  // 90% réduction (trop loin)
    }
}

Implications Stratégiques

1. Coût-Efficacité Défensive

struct DefenseCostAnalysis {
    float threat_neutralized;
    float cost;
    float cost_efficiency;  // menace neutralisée par €
};

// Neutraliser 20 Leopard 2A7 (160M€ total)

Option A - RPG-7 masse (effectiveness 20%) :
  - Quantité nécessaire : 100 RPG × 20 tanks = 2000 RPG
  - Coût : 2000 × 500 = 1M
  - Ratio : 1M / 160M = 0.625%
  - Avantage : Très économique
  - Inconvénient : Logistique massive

Option B - Javelin Gen3 (effectiveness 70%) :
  - Quantité nécessaire : 1.5 Javelin × 20 tanks = 30 Javelin
  - Coût : 30 × 200k = 6M
  - Ratio : 6M / 160M = 3.75%
  - Avantage : Logistique légère
  - Inconvénient : Plus cher

 RPG-7 est 6× plus cost-efficient, mais logistique 67× plus lourde
 Choix stratégique selon capacités logistiques

2. Perte Asymétrique

// Exemple bataille : Menace neutralisée mais pertes coûteuses

Attaquant : 20 Leopard 2A7 (160M)
Défenseur : 5000 RPG-7 (2.5M)

Outcome tactique :
  - Tous Leopards détruits (saturation)
  - 2000 RPG-7 utilisés effectivement

Bilan stratégique :
  Attaquant pertes :
    - 160M équipement
    - 20 crews élites (formation coûteuse)
    - Prestige international
    - Capacités offensives réduites

  Défenseur pertes :
    - 1M munitions consommées (2000 RPG effectifs)
    - +Victoire propagande
    - +Moral défensif

 Victoire tactique défenseur = victoire stratégique
 Système menace reflète cette asymétrie via residual 5%
 Perdre Leopard = toujours désastre même si menace "neutralisée"

Performance et Optimisation

Cache Threat

class ThreatCache {
private:
    struct CachedThreat {
        int value;
        int timestamp;
        int ttl = 3600;  // 1 heure
    };

    std::map<std::pair<EntityId, EntityId>, CachedThreat> cache;

public:
    int getThreat(EntityId attacker, EntityId defender) {
        auto key = std::make_pair(attacker, defender);

        if (cache.contains(key)) {
            auto& cached = cache[key];
            if (getCurrentTime() - cached.timestamp < cached.ttl) {
                return cached.value;
            }
        }

        // Recalculer
        int threat = calculateThreat(attacker, defender);
        cache[key] = {threat, getCurrentTime()};
        return threat;
    }

    void invalidate(EntityId entity) {
        // Invalider tous les caches impliquant cette entité
        for (auto it = cache.begin(); it != cache.end();) {
            if (it->first.first == entity || it->first.second == entity) {
                it = cache.erase(it);
            } else {
                ++it;
            }
        }
    }
};

Invalidation Cache

Événements invalidant cache :

  • Production nouvelle unité
  • Perte unité au combat
  • Nouvelle recherche technologique
  • Changement doctrine militaire
  • Retrofit/upgrade équipement

Calcul Lazy

// Ne calculer que si demandé par IA
int getThreatOnDemand(EntityId attacker, EntityId defender) {
    return threatCache.getThreat(attacker, defender);
}

// Pas de recalcul automatique chaque tick

Références Croisées

  • systeme-diplomatique.md : Utilisation menace dans relations diplomatiques
  • ai-framework.md : Menace influence décisions IA (achats, alliances)
  • systeme-militaire.md : Valeurs combat équipements, générations, système conception modulaire
  • economie-logistique.md : Production rates, capacités industrielles