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>
24 KiB
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 menace100 - 1 000: PMC petit5 000 - 50 000: Company moyenne100 000: État petit500 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 :
- Sword (attaquant) : Capacités offensives
- Shield (défenseur) : Capacités défensives
- 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 diplomatiquesai-framework.md: Menace influence décisions IA (achats, alliances)systeme-militaire.md: Valeurs combat équipements, générations, système conception modulaireeconomie-logistique.md: Production rates, capacités industrielles