If you’ve ever built a deterministic state machine for multi-agent simulations or NPC behavior, you know the absolute beauty of pure, predictable math. You pass in an action, the state machine applies a delta, and out comes the new state. No erratic LLM hallucinations, no runaway edge cases. Just clean engineering.
But recently, I hit a wall with my engine. The state machine was working perfectly, but the simulations felt... flat.
When I opened up the hood, the diagnostic was clear: I was feeding my brilliant engine completely dead data.
The Problem: Same Engine, No Context
Right now, every single simulation scenario, every persona, and every complex archetype starts with the exact same identical, baseline values:
Plaintext
SocialPhysics: trust=0.5, tension=0.3, leverage=0.5, credibility=0.5
Emotions: anger=0.2, joy=0.5, fear=0.2, shame=0.2, surprise=0.2Think about how absurd that is. Whether the agents are stepping into a high-stakes corporate PR Crisis, pitching a VC for an Investor Seed Round, or shooting a laid-back Podcast episode, they start with the same emotional temperature.
Worse yet, my system already has highly detailed PersonalityProfile configs (aggressiveness, empathy, stubbornness, verbosity) and distinct behavioral Archetypes (The Agitator, The Diplomat, The Guardian). But they were just sitting there in cold storage—defined, but completely unwired from the core behavioral engine.
If a generic challenge action occurred, the engine applied the exact same arithmetic delta, regardless of whether it was a Diplomat on a podcast or an Agitator in a legal deposition.
The Vision: A 5-Stage Delta Pipeline
I don't want to fix this by writing messy, hardcoded, scenario-specific if/else statements. That breaks the entire philosophy of a generic engine.
Instead, I am implementing a 5-Stage Delta Pipeline. Every single action’s impact will pass through a sequence of generic modulation formulas. The math stays universal; the inputs change the output.
Plaintext
base_delta
↓
personality_modulate
↓
archetype_multiply
↓
relationship_multiply
↓
scenario_override
↓
apply_to_stateHere is exactly how I am wiring it up in less than 300 lines of code.
Stage 1: Setting Real Scenario Baselines
I am stripping out global defaults and moving initial states into my template JSON configurations. A crisis should feel like a crisis from millisecond zero.
Crisis:
tension=0.7,fear=0.6,joy=0.15,trust=0.4Podcast:
tension=0.3,fear=0.1,joy=0.6,trust=0.5
Now, when a challenge action happens in a Crisis, that high initial tension and fear naturally push the agents toward an escalation threshold. The exact same challenge in a Podcast scenario feels like playful banter because the ambient joy is high. Same deltas, entirely different systemic behavior.
Stage 2: Personality Modulation
Every agent has traits rated from 0 to 100. I am introducing a generic modulation formula to scale raw deltas based on who is acting and reacting:

In internal_state.py, I map actions to traits. A challenge maps to aggressiveness → anger.
An aggressive agent (agg=80) getting challenged spikes their anger delta by +30%.
An empathetic agent (emp=80) getting challenged dampens that same anger delta by -9%.
Stage 3: Wiring the Archetypes
My 6 existing behavioral archetypes are finally getting their hands on the wheel via static delta_multipliers:
Plaintext
Agitator: challenge tension × 1.5, interrupt dominance × 1.4
Diplomat: compromise trust × 1.3, coalition trust × 1.4An Agitator’s challenge will now naturally spike simulation tension 50% more than a Diplomat's. I don't have to prompt an LLM to "act mean"—the deterministic math handles the gravity of their personality natively.
Stage 4: Relationship Context
Agents don't operate in a vacuum; they have history. I am tagging role pairs with relationship types that host their own multiplier tables:
CEO ↔ CFO (Peer Executive): High trust baseline, softened conflict deltas.
Buyer ↔ Seller (Adversarial): Low trust baseline, highly sensitive to leverage deltas.
A challenge between adversaries instantly hits leverage and trust much harder than the same challenge between executive peers.
Stage 5: Scenario Overrides (The Fine-Tuning)
By the time an action clears Stages 1 through 4, roughly 65% of the situational differentiation is already done. Stage 5 acts as a minor mathematical safety valve for unique scenario physics (e.g., in a legal deposition, a challenge dampens leverage updates by 0.8).
The Secret Sauce: Cross-Cutting Emotional Contagion
To make the simulation truly alive, emotions need to bleed across the room. I am adding a minor cross-cutting function where fear, joy, and anger spread to observers based on relationship proximity and trust:
The Contagion Rule: High trust amplifies emotional contagion. If your ally panics, you panic.
Because this runs downstream of my pipeline, it creates beautiful emergent behavior. In a Crisis template (high ambient tension), fear contagion multiplies exponentially, creating a psychological cascade. In a Podcast template, the fear baseline is too low to catch fire, so it barely spreads.
Conclusion
Adding emotions to these AI agents has been a game-changer. What started as structured debates has transformed into surprisingly realistic, dynamic conversations that feel truly human.
Agents no longer just exchange logical arguments — they get angry, cautious, excited, or defensive. They form alliances, stay quiet at the right moment, rebuild trust, or shut down when pushed too far. The simulation now captures the messy, emotional side of real decision-making.
This approach opens the door to much more authentic AI simulations — whether for executive training, negotiation practice, team dynamics research, or creative storytelling.
I’m now working on taking this into production environments and adding even more depth.
If you’ve ever wanted AI agents that don’t just think — but also feel and react like real people, this is the direction worth exploring.
What do you think — should emotions be a core part of future AI systems?

