Tshivhidzo Mbedzi AI & Technology Specialist

Projects FRIEND//DEBT simulation engine

Delivered AI Systems & Agents October 2026

FRIEND//DEBT simulation engine

Deterministic social-reasoning engine with an enforced information boundary

A dependency-free simulation of eight characters who hold private knowledge, remember what they are told, track who owes whom, lie, and vote — with a test that proves the AI code cannot read the ground truth it is supposed to deduce.

My role
Sole builder
Period
October 2026
Category
AI Systems & Agents
  • 38 Automated tests Runnable with one command, no dependencies
  • 0 Runtime dependencies Plain JavaScript by deliberate constraint
  • 8 Simulated characters Each with private knowledge and goals
  • ≈60% / ≈45% Measured outcome balance Rate at which the group identifies the saboteur / clears its target

In short

  • Eight agents reasoning over private knowledge, each fact carrying where it came from.
  • An automated test fails the build if agent code reads the hidden truth it is meant to deduce.
  • 38 tests, fully deterministic from a seed, zero dependencies.

Project overview

FRIEND//DEBT simulates a group of people under social pressure. Each character holds private information, knows where they learned it, remembers interactions, maintains relationships and debts to the others, pursues goals through plans, and can deceive. The simulation produces the dialogue acts, the tells and the votes; the outcome is not scripted.

The architectural decision that matters is that the simulation is completely separate from its presentation. It is plain JavaScript with no dependencies, it is deterministic given a seed, and it runs and is tested without any graphics at all. The 3D engine is only a client that talks to it.

The problem being addressed

A social deduction system is easy to fake and hard to build. The faked version is a branching script: characters appear to scheme because an author wrote the scheming. It produces one good playthrough and nothing after that.

The real version has a specific technical hazard. If the code driving a character can see the hidden truth it is meant to be deducing, every character becomes subtly omniscient — they argue slightly too well, suspect the right person slightly too early, and the whole thing feels wrong in a way that is very hard to trace, because nothing is broken.

The solution

Model knowledge explicitly, with provenance. A character does not know a fact; a character knows a fact, from a source, learned at a time — and that chain is what makes deception, mistaken belief and second-hand rumour representable at all rather than requiring special cases.

The information boundary is then enforced by a test. An automated check scans the character-reasoning code for any access to the hidden-state structures, and fails the build if it finds one. The honesty of the simulation is a test assertion rather than a convention I remember to follow, which is the only version of that discipline that survives a late-night change.

Determinism is enforced the same way: all randomness goes through one seeded generator, so any run can be reproduced exactly from its seed. This was tightened after a bug revealed that consecutive seeds produced correlated runs.

How it works

Eight characters, each knowing different things, each with something to gain. They remember, they form plans, they lie, and they vote. Nothing about the outcome is scripted. Here is the machinery underneath.

  1. Knowledge carries its own history

    A character does not simply know a fact. They know it, from a particular source, learned at a particular moment. Modelling knowledge with that provenance is what makes rumour, mistaken belief and deliberate deception representable at all — without it, each one needs its own special case.

  2. Characters want things and make plans

    Each has goals and forms plans to reach them, which is where behaviour starts to look deliberate rather than random. A character who needs something from another behaves differently toward them, and that falls out of the model rather than being written.

  3. Lying is just saying something you do not believe

    Because belief is modelled separately from truth, deception needs no special machinery. A character can assert something their own knowledge contradicts. Other characters update on what they are told, not on what is true, so a lie propagates exactly like a fact.

  4. An automated test guards the boundary

    The hidden truth and what each character believes live next to each other in the same system, and one convenient line of code collapses the distinction. So a test scans the character-reasoning code for any access to hidden state and fails the build if it finds one. The honesty of the simulation is enforced, not remembered.

  5. Everything is reproducible from a seed

    All randomness goes through a single seeded generator, so any run can be replayed exactly. This is what makes it possible to measure balance across many runs and to detect when a change has altered emergent behaviour.

  6. Two views of the same world

    The player sees only what their character legitimately knows. A separate developer view shows everything. They are deliberately different payloads, because a single payload filtered at the interface eventually leaks.

Technology stack

Engine

  • Plain JavaScript (no dependencies)
  • Seeded deterministic RNG
  • Node.js test runner

Model

  • Knowledge with source chains
  • Episodic memory
  • Relationship and debt graph
  • 14 dialogue acts
  • Goal and plan system

Interface

  • Local HTTP bridge
  • Save / load
  • Separate player and developer views

Presentation

  • Unreal Engine 5.8 client
  • Transparent overlay UI

System architecture

FRIEND//DEBT engine and its information boundary Characters reason over what they believe, with provenance for every fact. An automated test fails the suite if reasoning code reads the hidden ground truth it is meant to deduce. Seed one generator · fully reproducible run Hidden ground truth who the saboteur actually is Per-character knowledge fact + source + when learned Character reasoning goals · plans · deception · memory An automated test fails the build if this layer touches the hidden truth. Dialogue acts, tells and votes Player view filtered to what the player knows Developer view full state, separate payload Outcome not scripted · measured across many seeds
FRIEND//DEBT engine and its information boundary — Characters reason over what they believe, with provenance for every fact. An automated test fails the suite if reasoning code reads the hidden ground truth it is meant to deduce.

My responsibilities

  • Designed the knowledge model with explicit provenance, which is what makes deception representable.
  • Built the engine, the dialogue act system, the goal and plan layer and the debt graph.
  • Wrote the information-boundary test that enforces the simulation's honesty automatically.
  • Enforced determinism through a single seeded generator after finding correlated-seed behaviour.
  • Built the separation between the player's view and the developer's view so hidden state cannot leak to the interface.
  • Repurposed the engine as the story generator for a produced season.

Development process

  1. Separate the simulation from the spectacle

    No graphics dependency, no engine dependency, no editor required. The practical reason was that this machine has no C++ toolchain; the better reason is that a simulation you can only observe through a renderer is a simulation you cannot test.

  2. Make the integrity constraint executable

    Rather than a rule in a document saying reasoning code must not read hidden state, a test asserts it. Documented conventions decay; a failing test does not.

  3. Measure balance rather than guessing it

    Running many seeded simulations gives the actual rate at which the group identifies the saboteur and clears its target. Those numbers are design feedback, not flavour text.

  4. Follow the evidence to a different product

    The engine produced better narrative than interaction. Rather than defend the original plan, it became the story generator for a produced and published season — which is a real outcome instead of an unfinished game.

Challenges encountered

Preventing accidental omniscience

This is the central difficulty of the whole genre. Character reasoning needs rich access to what a character believes and zero access to what is actually true. Those two live next to each other in the same data structures, and a single convenient property access collapses the distinction. An automated scan of the reasoning code for ground-truth access is what keeps the boundary real. It is the same class of control as preventing a model from seeing its test set.

Determinism that was not quite deterministic

Seeded runs are the basis of every balance measurement here. A defect meant consecutive seeds produced correlated results — so a batch of runs across a seed range was measuring far less variation than it appeared to. All randomness was routed through a single generator and the correlation went away. The uncomfortable part is that the measurements looked perfectly reasonable while they were wrong.

Hidden state leaking through the interface

Separating engine from client does not by itself protect the player: a debug view and a player view drawing from the same payload will eventually show something they should not. They are explicitly separate views over the state, and the player view is constrained to what that player legitimately knows.

Knowing when to stop building the game

The engine, its tests, the dialogue system and the first scenario were finished. Five further scenarios, the whole interactive client, voice and multiplayer were not. Rather than present a half-built game, the engine was pointed at a different outcome and shipped as a season. The unbuilt parts are listed below as unbuilt.

Testing and validation

38 automated tests

Covering knowledge propagation, memory, relationship and debt mechanics, dialogue acts and save/load, runnable with a single command and no install.

Information-boundary assertion

An automated scan fails the suite if character-reasoning code touches hidden ground truth.

Seeded reproducibility

Any run reproduces exactly from its seed, which is what makes a regression in emergent behaviour detectable at all.

Balance measurement over many runs

Outcome rates measured across batches of seeded simulations rather than inferred from a few playthroughs.

Evidence and demonstrations

There is no public URL for this project, and there are no screenshots on this page. That is deliberate: a screenshot is trivial to fabricate and I would rather show you a description of the real architecture than an image you have no way to verify. The diagram above is authored from the actual system.

Source code is not currently published. Publishing this portfolio repository and making my work reviewable is step 2 on my roadmap, and it is a hiring problem before it is a technical one. I am happy to walk through any of this code in a screen share.

Current development status

Built, tested and in use

  • Complete simulation engine with knowledge provenance, memory, relationships, debt, deception, goals and plans.
  • First scenario fully playable through to a resolved outcome.
  • Eight original characters with private knowledge and individual goals.
  • 38 passing automated tests including the information-boundary assertion.
  • Save/load, local HTTP bridge, and separated player and developer views.
  • Repurposed successfully as the story generator for a published ten-episode season.

Not built, or not proven

  • Five of the six planned scenarios.
  • The interactive game client — menus, rooms, interface and cameras. What exists is a presentation layer for the produced episodes.
  • Voice, language-model-driven dialogue and multiplayer. All three were planned and none were started.

Future improvements

  • Introduce a language model for dialogue surface only, with the information boundary extended to cover it and enforced by the same test.
  • Build the remaining scenarios on the existing primitives.
  • Publish the balance measurement harness, since the methodology is more broadly useful than the game.