AI INFLUENCE - UPDATED 3.3.0
Added:
------
Added settlement mention parsing in dialogues for correct economic effects creation: now when creating dynamic events from player dialogues, the system automatically detects mentioned settlements (e.g., "Sargot") and provides AI with their exact string_ids (e.g., "town_S1") for correct economic_effects creation. AI now knows exact identifiers of all settlements mentioned in dialogues and can apply economic effects (prosperity, food, security, loyalty, income) to them with correct target_ids. Parsing works for all languages through text normalization and supports towns, castles, and villages.
Added comprehensive save system optimization for 200+ NPCs: implemented NPC relationship caching (NPCRelationsCache), file path caching, save batching for mass events (capture, release), increased SaveQueueManager semaphore pool from 10 to 50, added automatic trimming and cleanup of RecentEvents list. Performance for prisoner events improved 20-50x: capturing 1 lord now processes in <0.1 seconds instead of 2-5 seconds, battle with 5 prisoners in <0.5 seconds instead of 10-25 seconds.
Added MCM settings for memory and performance management: "Recent Events Lifetime (Days)" (7-90 days, default 30) controls automatic cleanup of old events from NPC memory; "Max Recent Events Per NPC" (10-200, default 50) limits number of events per NPC. When limit is exceeded, oldest event is automatically removed. Up to MaxRecentEvents can be stored per NPC in memory, but only Math.Min(MaxRecentEvents, 50) most recent events from last 10 days are sent to AI prompts for optimization.
Added automatic cache invalidation for important game events: on hero marriage (OnHeroesMarried) caches are invalidated for both spouses and their relatives; on clan kingdom change (OnClanChangedKingdom) caches are invalidated for all clan members. This ensures cached NPC relationship data stays current.
Added performance profiling system for WorldInfoManager.OnDailyTick: now each DailyTick writes detailed performance information to mod_log.txt showing execution time for each method (UpdateWarStatus, CleanOldEvents, ProcessRomanceDecay, UpdateLastSeenFriendsForAllNPCs, CleanupDeadNPCs), allowing precise identification of performance bottlenecks.
Added prisoner event tracking system in RecentEvents for NPCs: now when a lord is captured (PrisonerTaken) or released (PrisonerReleased/PrisonBreakRescue), events are added to RecentEvents not only for the prisoner themselves, but also for their friends, relatives, and clan/faction members. Events include complete information with string_id for all mentioned characters, clans, and locations, allowing AI to know about the fate of close people and mention it in dialogues. The system handles all types of release: escape, release, ransom, and release after battle.
Added two-way messenger correspondence system: now player can reply to NPC messages and send their own letters. When receiving a message from NPC, a "Send Reply" button appears in the window showing the messenger cost (calculated based on distance to NPC). Added MCM settings "Messenger Cost Per Distance" (10-50 denars, default 15) and "Messenger Delivery Hours Per Distance" (0.5-5.0 hours, default 1.0) for managing cost and delivery time. Letters are delivered with time delay depending on distance. NPCs receive player's letters, can reply to them or ignore (return null). When replying, NPC can perform a limited set of technical actions (go_to_settlement, wait_near_settlement, follow_player) if player explicitly requests it in the letter. All letters are marked in conversation history as "SENT VIA MESSENGER BY PLAYER" or "SENT VIA MESSENGER AS REPLY". The system automatically parses settlements mentioned in letters and provides NPC with their exact string_ids for correct action execution.
Added "Force Close Dialog" (Fix Stuck Dialog) button in MCM settings under "Debug & Fixes" section: the button allows forcefully closing a stuck dialog with NPC and resetting all blocking flags (CombatResponse, Decision, IsSurrendering, MarriageResponse, PendingDeath, PendingSettlementCombat, PendingAIResponse, and others). Used to unblock the game if dialog got stuck due to a crash and didn't close automatically. The button forcefully ends the conversation through ConversationManager and clears all NPC states, allowing normal interaction with the NPC again.
Added display of reasons for all diplomatic relation types in AI prompts: now shows reasons for alliances, trade agreements, tributes, and reparations, providing more complete context understanding for AI characters.
Added protective patch to prevent game crash when creating offspring (NullReferenceException): fixed issue occurring around 250+ days into the game, when during offspring birth a parent hero may have null EquipmentRoster, causing NullReferenceException in vanilla game code. The patch now intercepts this situation, checks for EquipmentRoster presence and uses fallback (hero's CivilianEquipment or empty equipment), preventing game crash.
Added protection system for non-combatant parties from vanilla game's automatic disbanding: previously, when AI Action created a real clan party for a non-combatant hero (no combat skills >= 100), vanilla TeleportationCampaignBehavior could automatically replace the party leader with another commander from the clan (through daily DailyTickParty check), leading to removal of the non-combatant from the party and subsequent party disbanding by DisbandPartyCampaignBehavior. Now created NonCombatantPartyProtector - a special CampaignBehavior that registers parties created by AI Actions (WaitNearSettlement, PatrolSettlement, GoToSettlement, FollowPlayer, CreateParty) and protects them from automatic leader replacement and disbanding while the action is active. When a party is created with a non-combatant leader, the player receives a yellow warning that after task completion, vanilla game may disband the party. All actions now track leader replacement in OnUpdate and automatically stop with an orange notification if vanilla system still replaced the leader. After action completion, protection is removed, allowing vanilla system to act normally (player was warned).
Fixed:
------
Fixed income_multiplier economic effect implementation: previously, settlement income multiplier (income_multiplier) was stored in the economic effects system but was never actually applied to settlement income. Now created a Harmony patch for DefaultClanFinanceModel.AddSettlementIncome that applies income_multiplier to each clan settlement's income. Multipliers stack additively relative to base income: each effect adds its percentage change to base income (e.g., effect 1.2 = +20%, effect 1.1 = +10%, effect 0.8 = -20%). With base income 100 and effects +20% and +10%, total income will be 130 (100 + 20 + 10), not 132 (100 * 1.2 * 1.1), preventing inflated profits/losses. When an effect expires, the corresponding percentage is correctly subtracted from total income. Added GetSettlementIncomeMultiplier() method to EconomicEffectsManager for retrieving aggregated settlement income multiplier.
Fixed dialog stuck issue when errors occur in critical AI actions: previously, if an error occurred while executing actions like attack, release, surrender, accept_surrender, or marriage, the dialog could get stuck and not close automatically. Now all catch-blocks for these actions force-close the dialog on errors and clear corresponding flags (CombatResponse, IsSurrendering, MarriageResponse), preventing interface freezes. Also fixed InitiateCombatLogic: now dialog is closed ALWAYS before combat initiation, even if EnableModification = false.
Fixed combat window opening issue when AI decides to leave conversation (release) on water: previously, when player was on water and AI decided to end conversation without combat (release), combat window would automatically open, even though everything worked correctly on land. Now the system correctly detects if player is on water during conversation in mission and properly handles PlayerEncounter: sets player protection, "do not attack" flag for NPC party for 24 hours, and finishes encounter, preventing combat window from opening.
Fixed issue with AI attacking player's following parties after release command: previously, when AI decided to release the player (release), only the main player party was protected for 12 hours, but parties following the player (follow_player) were not protected, leading to attacks on them immediately after peaceful parting. Now when release command is used, both the main player party and all parties following the player are protected: "do not attack" flag is set for all of them for 24 hours, preventing attacks on them after peaceful parting.
Fixed NPC emotional state logic for war declarations: previously, NPC mood would change to "tense" on any war declaration in the world, even if the war didn't affect their faction or clan. Now mood only changes if the war directly affects the NPC's faction (kingdom) or clan, making the reaction more realistic and logical.
Fixed missing notification issue when AI simultaneously decides to release and stops following (follow_player:STOP): previously, when AI simultaneously decided to release the player (decision: "release") and stop following (technical_action: "follow_player:STOP"), no notification was shown that AI stopped following the player. Now the system checks for decision: "release" when stopping follow_player and shows a notification, informing the player that following has stopped.
Fixed NPC role determination logic in settlement capture events (SettlementCapture): previously, NPCs who were army leaders or participants in an army that captured an enemy settlement could receive incorrect messages like "You lost control" instead of "You captured" or "You helped capture". Now the system correctly determines NPC participation in capture through SiegeEvent checks, capturer's army, and faction, distinguishing between army leaders ("You captured ... leading your army"), siege participants ("You helped capture ... participating in the siege"), and defenders ("Your faction lost ..." or "You lost control ...").
Fixed NPC context saving system: now contexts for kingdom leaders are created at game start and checked daily, ensuring all leaders have their contexts. Contexts for NPCs near the player are now properly marked as initialized and saved. Improved data merging logic when saving: all user edits in JSON files (KnownSecrets, KnownInfo, AIGeneratedPersonality, AIGeneratedBackstory, AIGeneratedSpeechQuirks, ConversationHistory, RecentEvents) are now preserved and not overwritten automatically. KnownSecrets and KnownInfo now work like AI generations - always loaded from file if it exists, allowing users to freely edit this data without needing to set special flags.
Fixed "Clear Current Save Data" button in MCM settings (diplomacy cleanup): previously, 6 diplomacy subsystems were not cleared (TradeAgreementSystem, TributeSystem, ReparationsSystem, TerritoryTransferSystem, ExpelledClanSystem, DialogueAnalysisEvents). 4 files on disk were not deleted (trade_agreements.json, territory_transfers.json, tributes.json, reparations.json). Now all subsystems are cleared in memory, all 9 diplomacy files are deleted from disk, and a new ClearDialogueAnalysisEvents() method was added that clears diplomatic events from dialogue analysis (DialogueAnalysisEvents) for all NPCs both in memory and in JSON files. DialogueAnalysisEvents belong to the diplomatic system (can trigger diplomatic actions), so they are correctly cleared together with diplomacy, not with regular NPC events (RecentEvents).
Fixed issue with AI attempting to attack own settlements: previously, AI could set siege_settlement or raid_village actions on settlements that belong to themselves or their faction, causing infinite self-declaration of war and errors. Now added settlement ownership check at code level: before executing action, system checks if settlement belongs to hero's clan, their kingdom, or bound castle/town (for villages). If settlement belongs to the hero, action is blocked with error logged, preventing attempts to attack own holdings.
Fixed incorrect order of events and ruler statements in World Events window after loading game: previously, events were sorted by creation time only within each source (active events and stored events), causing incorrect order when merging. Also, Timestamp field was used for statements, which was converted to CampaignDays with possible inaccuracies. Now LoadRealData() method has been refactored: events are merged from all sources before adding to UI, CollectEventEntries() method was created to collect all entries (events, updates, statements) with unified CampaignDays timestamps, all entries are sorted together by creation time (newest first). In DiplomaticStatementsStorage, statement time storage has been fixed: now CampaignDays is used directly instead of conversion through Timestamp. Event order is now stable and correct both when created in-game and after loading save. Removed 251 lines of duplicate code (old Add* methods replaced with compact Create* methods).
Fixed NPC roleplay death system: previously, player could kill any NPC through roleplay, even if NPC was on global map with an army, which was illogical. Now added death condition checks: NPC can be killed through roleplay ONLY if they are in an active mission/combat, are a prisoner held by player or in a town/castle, are in player's party (companion), are in a settlement without a party, or are alone on the map (1 person in party). NPC CANNOT be killed if they are on global map with troops (2+ soldiers in party) or are a prisoner of another party on the map. The `character_death` field in prompts is now shown to AI only when NPC can be killed in current situation - if conditions are not met, the field is not displayed at all, preventing AI attempts to kill unavailable NPCs. Added double protection: check at prompt level (field hiding) and at AI response processing level (execution blocking).
Fixed missing romance relationship bonus in NPC initiative chance calculation: previously, the romance bonus (RomanceLevel > 50) was not applied to NPC initiative chance because the context was taken from memory cache, which could be out of sync with saved data. Now before calculating the chance, the context is refreshed through GetOrCreateNPCContext(), ensuring that current RomanceLevel data from file is used. Added debug logging to check RomanceLevel value before applying bonus, allowing to track system correctness.
Fixed issue with relation increase for tone when AI sets positive state: previously, ApplyRelationChangeWithDelay method used ChangeRelationAction.ApplyRelationChangeBetweenHeroes, which through GetHeroesForEffectiveRelation replaced heroes with their clan leaders, causing relations to change with the entire clan instead of the specific NPC. Now the method directly sets relations through SetPersonalRelation, bypassing GetHeroesForEffectiveRelation, ensuring that relations change only with the specific NPC being talked to, not with their entire clan.
Improved:
---------
Improved task status display for AI prisoners: now for prisoners in player's party, the "Your Current Task" section displays full information that they have no tasks because they are prisoners, with player party name (string_id), and current location information (settlement with type, culture, owner, kingdom and region, or nearest settlement, or wilderness).
Improved AI speech quirks system in prompts: removed duplicate speech quirks information from "Speech Quirks" section, now they are displayed only in the response field instruction for clearer AI control.
Optimized UpdateWarStatus method to fix performance issues: previously the method was called separately for each NPC and each time iterated through all kingdoms and clans in the game, taking ~75ms per NPC (98.8% of OnDailyTick time). Now war status is calculated once per day and cached, then assigned to all NPC contexts, reducing execution time from ~2200ms to ~5ms (approximately 440x performance improvement).