// Covert operations a spy may run abroad. The ids are shared by the client // (to label the Intelligence tab's operations) and, in time, the server (to // validate the orders), so they live here rather than in the view. // // Intelligence Agencies unlocks the spy and every operation below; // Counter-Intelligence is the defence against them. export const SPY_SABOTAGE = "sabotage"; export const SPY_CITY = "city_spying"; export const SPY_COMMS = "comms_spying"; // Covert-operation tuning. A sabotage cripples the tile the spy stands on for a // week; the tile's production is zeroed, not the physical resource trade, which // mirrors how pillaging already marks a tile (see `productionFactors`). export const SABOTAGE = { blockDays: 7, }; // Espionage tuning: how the intelligence agencies and their counter-intelligence // rivals decide who gets blamed, what a spy report really contains, and how // easily a secret leaks. export const ESPIONAGE = { // The chance a victim correctly pins a covert act on its author, before the // two nations' services shift it. A counter-intelligence service raises it; // the author's own agencies lower it. baseIdentifyChance: 0.5, counterIntelligenceWeight: 0.45, agencyWeight: 0.2, // When the author is not identified and chose a scapegoat, how often the // victim swallows the false flag. A correct blame and a successful frame are // deliberately indistinguishable to the victim. frameChance: 0.6, // The extra chance, per level of the target's counter-intelligence, that a // spy's city report is quietly falsified. falsifyChance: 0.7, // The extra chance, per level, that intercepted comms come back garbled. garbleChance: 0.6, // Covert operations spend their operatives, so the only way to stack the odds // against a counter-intelligence service is to send more spies: each operative // beyond the first cancels this much of the target's counter-intelligence. // Three spies (two extra) beat a full service outright. agentsPerCounter: 0.5, // How many recent messages comms spying reveals. interceptCount: 8, // How many reports a nation keeps for its Intelligence tab. reportLimit: 20, // How many chat lines the server keeps for comms spying. messageLogLimit: 400, // The chance a nation with Intelligence Agencies is warned when another nation // raises its first uranium enrichment centre. enrichmentWarningChance: 0.5, }; // Spy satellites: a launch is free once the (very expensive) space launch centre // stands, and each satellite uncovers a random patch of the world on a cadence. // A centre sustains this many satellites for every level it has, one each by // default. export const SATELLITE = { revealEveryDays: 2, revealRadius: 2, perLaunchCentreLevel: 1, }; // `description` is the reference text the Intelligence tab shows, not a // rules summary: the mechanics are applied server-side (see INTELLIGENCE.md). // The kinds of report a spy brings home. Kept as ids so the model and the view // can name them without magic strings. export const SPY_REPORT_CITY = "city"; export const SPY_REPORT_COMMS = "comms"; // Every operation spends the acting spies: a spy is single-use, so only one // operation is ever run per operative. A larger stack improves the odds against // counter-intelligence (see ESPIONAGE.agentsPerCounter). export const SPY_OPERATIONS = [ { id: SPY_SABOTAGE, name: "Sabotage", get description() { return `Cripple a tile's production for ${SABOTAGE.blockDays} days. The act may be pinned on another nation, or on no one at all. Spends the spies.`; }, }, { id: SPY_CITY, name: "Spy on a city", description: "Read a foreign city's buildings, garrison and stores. A counter-intelligence service can feed back false figures. Spends the spies.", }, { id: SPY_COMMS, name: "Intercept communications", description: "Read a nation's recent private messages from its capital. Counter-intelligence can garble or redirect them. Spends the spies.", }, ];