Game-agnostic agent-intelligence engine for Godot 4.7: perception, memory, knowledge, drives, decision-making, relationships and scheduling. Feeds on world facts, produces action intents.
  • GDScript 93.6%
  • Python 3%
  • GAP 2.2%
  • Shell 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
cmkrist d5b8259466 Audit IAM: fix eight correctness defects, add executable evidence
The addon shipped as a skeleton with a manifest, a dock and 3,312 lines of
contract code and no executable evidence. This adds that evidence and fixes every
defect it exposed.

Evidence:
- tests/test_audit.gd   contract suite, 379 checks, 16 sections, non-zero exit
- tools/audit_benchmark.gd  hot-path timings with a legacy control
- AUDIT.md              finding-by-finding record and the before/after table

Fixes: dead-agent intent leakage; non-atomic and id-trusting restore; float
blackboard defaults stored as int; IamSnapshot crash on a non-dictionary payload;
silent acceptance of a newer payload; engine using the envelope format version as
its payload version; StringName ordering nondeterminism in the intent comparator;
two docstrings that contradicted their code.

Performance: MemoryStore identity index and IamEngine maintained intent order
remove the per-operation key scan and the per-read sort (find over 1,024 records
188.6 -> 0.82 us).
2026-09-16 08:39:15 -04:00
addons/iam Audit IAM: fix eight correctness defects, add executable evidence 2026-09-16 08:39:15 -04:00
bench Add a standalone benchmark harness with a committed baseline 2026-09-15 19:16:01 -04:00
docs Initial commit: iam plugin skeleton 2026-09-15 16:55:05 -04:00
scenes Initial commit: iam plugin skeleton 2026-09-15 16:55:05 -04:00
tests Audit IAM: fix eight correctness defects, add executable evidence 2026-09-16 08:39:15 -04:00
tools Audit IAM: fix eight correctness defects, add executable evidence 2026-09-16 08:39:15 -04:00
.gitignore Add a standalone benchmark harness with a committed baseline 2026-09-15 19:16:01 -04:00
AUDIT.md Audit IAM: fix eight correctness defects, add executable evidence 2026-09-16 08:39:15 -04:00
LICENSE Initial commit: iam plugin skeleton 2026-09-15 16:55:05 -04:00
project.godot Initial commit: iam plugin skeleton 2026-09-15 16:55:05 -04:00
README.md Audit IAM: fix eight correctness defects, add executable evidence 2026-09-16 08:39:15 -04:00

IAM — Intelligent Agent Model

IAM is the suite's agent-AI engine. It turns a perception into a memory, memory plus drives into a plan, and a plan into a single ActionIntent that the game executes. It is a Godot 4.7 addon with no scene-tree dependency in its decision path, so its whole runtime can be exercised headlessly.

Status: skeleton. The MVP core is implemented and tested: determinism, memory store, blackboard, agent, brain registry, engine, world-fact query, intent routing, and snapshot/restore. The EnC behaviour port is not done — see docs/MIGRATION_FROM_ENC.md for the ordered plan and docs/ARCHITECTURE.md for the MVP-core/later split.

Layout

iam/
  addons/iam/          the installable plugin (this is what a game vendors)
    core/              data contracts and stateless runtime services
    runtime/           the facade, the per-agent state object, the intent router
  docs/                architecture, API reference, migration plan
  scenes/playground.*  standalone runnable demo
  tests/               headless SceneTree test suites
  bench/               standalone benchmarks + committed baseline
  tools/               packaging, test runner and benchmark runner

Quick start

var engine := IamEngine.new()
engine.world_seed = 1234
engine.register_brain(&"forager", ForagerBrain.new())
engine.set_world_facts(my_world_facts)   # a WorldFactQuery subclass
engine.add_agent(my_agent)               # an Agent with an AgentProfile

engine.intent_emitted.connect(_on_intent)
engine.step(tick)                        # one simulation tick

engine.intent_for(agent_id) returns the current intent. The game keeps its own motion, animation and rendering; IAM only decides.

Verify

From this directory:

export HOME=<this repo>/../.fakehome     # only needed in a sandboxed environment
godot --headless --path . --import
./tools/run_tests.sh
godot --headless --path .

The last command runs scenes/playground.tscn: two agents with different brains over a fake world-fact query, printing an intent log and quitting.

Suite relationship

IAM is deliberately independent of WorldMaker and WeatherPP. The suite shares conventions, not code. In particular IamSnapshot repeats the envelope field names of WorldMaker's SnapshotEnvelope so a game has one serialisation habit, but it is a separate implementation with its own migrations. The alternative — a shared dsp_core addon — and the tradeoff are recorded in docs/ARCHITECTURE.md as a decision flagged for the user.

Ownership

Owned by IAM Owned by the game
Perception, memory, knowledge and relationship contracts What senses exist and what they can detect
Drive and utility-curve shapes Specific drive weights and curve values (policy data)
ActionIntent production, priority, expiry and scheduling Executing intents: HumanMotion.step, animation, rendering, physics
Bounded memory, decay and hearsay semantics Save-file layout outside the IAM snapshot envelope
Deterministic per-agent random streams World seeds, tick cadence, the simulation clock

IAM does not own species content, recipes, traits, or needs values. Those are plugin-policy data, not engine code.

Benchmarks

Runs standalone with no game present and no scene tree: the world is a two-method fake query and the brains are registered in the benchmark itself.

./tools/run_bench.sh              # run and print the table
./tools/run_bench.sh --compare    # gate against bench/baseline.json
./tools/run_bench.sh --update     # rewrite the baseline (say why in the commit)

Results go to bench/results/iam.json, gitignored because it is machine-specific. bench/baseline.json is the tracked artifact; tools/compare_bench.py fails when a case is slower than +25%, comparing medians over 9 measured runs after 2 discarded warmup runs.

Engine cases run 100 agents over 100 ticks. Headline observations from the first baseline (2026-09-15); the 2026-09-16 audit (AUDIT.md) then rewrote the memory and intent-ordering paths, so the memory rows below are historical:

  • MemoryStore was O(n) per operation. At the first baseline a lookup against a 1,000-record store cost ~88 µs, and filling an unbounded store was O(n²), because every operation linearly scanned records and rebuilt a String identity key per comparison. The audit added a derived identity index; AUDIT.md records the before/after table (a 1,024-record find fell from 188.6 µs to 0.82 µs). That mattered before EnC ports its humans across, since human_memory.gd carries the same shape.
  • The identity index is rebuilt when records changes size, so records is store-owned and must not be mutated in place.
  • Determinism is cheap (~195 ns per stream), so hashing per decision instead of sharing an RNG is affordable.
  • Stepping is ~2.8 µs per agent-tick, which is the number to watch as species adapters are ported in.

The protocol is documented in EnC at docs/PLUGIN_BENCHMARK_PROTOCOL.md. The same harness, runner and gate are used by every plugin in the suite.

License

MIT — see LICENSE.