GAI is Gumpian AI, the Gump AI agent architecture. It is not a bundle of techniques that happen to ship together. It is one decision loop built from four layers that need each other: a heritable genome, a utility layer, a behaviour tree, and a set of leaky-integrator signals. Two optional layers sit above them: a squad that shares an intent, and a gene pool that breeds the next generation.
The source is public at github.com/3211/GAI. The project page is at /projects/gai. The full argument — the formulation, the stability analysis, the comparison with behaviour trees, utility systems, and GOAP, and the limits of the evidence — is in the technical report, GAI-TR-1.0.
Three ways game AI fails
Most game AI fails in one of three ways.
The scripted role. “If class == sniper, hold long angles.” The agent cannot discover that today the right move is to push, because the class already answered the question.
The hierarchy of noses. A chain of command where every layer samples one point. It can smell, but it has no structure: a star-shaped squad and a line-shaped squad think the same thoughts.
The argmax monoculture. A hard “best action wins” pick makes every agent with the same genes do the same thing forever. The colony oscillates between all-foragers and all-diggers.
GAI is the smallest set of changes that fixes all three at once. Genes become tendencies instead of roles. Utility scores the whole action set instead of a single sampled point. A softmax keeps the population diverse. A behaviour tree carries out the chosen intent without re-deciding it.
The loop
The genome is read twice. Once to score the choice, once to parameterise the tree that carries it out.
Utility is deliberation. The tree is commitment. The architecture separates them in time: the utility layer decides on a cadence, and the tree runs every frame until the next decision. Outcomes feed a fitness function, and the next generation is bred from the agents that did well.
Genes are tendencies, not roles
A genome is a plain object with one number in [0, 1] per gene. The core set has eleven: aggression, caution, patience, curiosity, teamwork, leadership, loyalty, discipline, greed, chaos, and favourite number.
A gene biases a choice. It never assigns a class. The moment a gene becomes if (aggression > 0.8) role = 'berserker', the population stops evolving and starts cosplaying. The label “berserker” is read off the traits after the fact; it is a description, not a branch.
The five presets — grunt, elite, berserker, sniper, scout — are not classes either. They are starting points in gene space. A sniper is a genome with high patience and discipline, not a branch in a switch statement.
Utility picks the intent; the tree executes it
Every action is scored by a gene term, a sensed demand, a local smell, a personal circumstance term, and an optional bias:
score = (0.05 + 2.2 × gene) × pull × personal × bias
pull = 0.5 + 0.55 × order + 0.4 × smell + 0.2 × demandThe gene term is deliberately wide. With a plain gene × pull, the gene is a [0, 1] multiplier on a [0, 2] pull, and the softmax washes the difference out: the measured correlation between a gene and the matching action goes to zero. The 0.05..2.25 expansion makes the genome the dominant term, which is the point of a genetic agent.
A gate is a hard impossibility (“no cover exists”). A low score is a soft preference (“cover exists, but I would rather push”). A gate that encodes judgement is a script.
The chosen action selects one behaviour tree. The tree sequences, gates, waits, and cools down. It never re-scores the action set. One tree per action, and the tree is stateful: a sequence that is halfway through a move does not restart the move on the next frame.
The pick is a softmax
The score vector is turned into a distribution over verbs:
P(i) = exp(score_i / T) / Σ exp(score_j / T)T is the temperature, and it is the most important knob in the system. The working range is 0.10 – 0.18. Below 0.08 the population becomes a monoculture; above 0.30 the genes stop predicting behaviour.
The source ant colony bottomed out at 0.06 and produced a colony that was entirely foragers or entirely diggers, oscillating with a heartbeat. At 0.10..0.26 the same colony held several jobs at once, which is what a colony is. The lesson generalises: a population should be able to disagree.
Signals are leaky integrators
A signal is a memory with a half-life:
s ← s + (target − s) × (1 − exp(−dt / τ))
τ = max(0.05, base × (0.6 + gene × gain))The time constant is gene-derived, so the same stimulus produces a different duration of thought in different agents. A patient agent holds a threat for longer than a restless one. A brave agent’s threat signal decays slowly, so it stays keyed up after the fight.
Signals also give the utility layer hysteresis for free. An agent that has been under fire for three seconds has a high threat signal even if the current frame is quiet, so it does not instantly switch from cover to advance the moment the shooting stops.
A squad is a shared intent
A squad is not a second brain. The living agent with the highest leadership gene thinks first and sets the intent. Every other agent receives that intent as ctx.order, which is the strongest single bias in the utility function. Teamwork decides how hard the order pulls:
orderStrength = 0.35 + 0.65 × teamworkThe order is a bias, never a leash. A high-curiosity grunt may still peel off to check a corridor, and that is the point: the squad has a plan, and the individuals have tendencies. A squad that cannot disagree is a squad that cannot discover.
Outcomes breed
Fitness is a weighted sum of measured outcomes, floored at zero:
F = max(0, Σ w_k × stat_k)The weights are the design document: they say what the game values. The corridor FPS used damage, fractional kill credit, survival time, ground covered, outposts captured, accuracy, and a penalty for friendly fire. The ant colony used food delivered, brood raised, and colony survival. The market used return, drawdown, and a penalty for churn.
The breeding rules that survived contact with all three: keep the best genome unchanged, cull the bottom 30%, breed from the top five rather than one alpha, blend each gene independently, and nudge a fraction of the genes by a bounded step. A single alpha is a clone; five alphas are a lineage.
Determinism
A genome hashes to a seed, and the seed drives every random draw the agent makes. The hash is FNV-1a over the gene ids and the gene values rounded to four decimal places. The PRNG is Mulberry32.
The same genome and seed produce the same brain, the same tie-breaks, and the same “occasional second-best” choices. That is not a nicety; it is what makes a bug reproducible and a lineage inspectable. Rounding before hashing is part of the contract: a port that hashes raw floats produces a different seed and a different brain.
What you write
You write verbs and sensors. A verb is an action the engine can perform. A sensor is a reading the engine can supply. Neither has to know anything about the decision layer.
You do not write behaviour-tree graphs, and you do not maintain an archive of utility behaviours. Adding a verb should not require editing a graph, and changing a preference should not require a code change.
What is in the repository
- A dependency-free JavaScript runtime. One ES module:
src/gump.js. It runs in Node and in the browser. - A Unity package. Plain C# classes, not a MonoBehaviour soup.
GumpAgentBehaviourowns a brain and ticks it;GumpSquadDirectorholds the squad;GumpTuningis a ScriptableObject preset;Genome,GeneSpec, andGumpGenePoolare the genetics layer. - Five runnable examples. Utility, behaviour trees, genetics, squads, and a live tuning bench. Each is a single HTML file.
- Documentation. Architecture, API, tuning, and porting guides, plus
skills.md, a single-file operating manual for a coding agent. - A verification harness. 58 behaviour checks against the reference runtime, a DOM harness that drives every example, a local link checker, and a headless C# type-check.
Status
GAI is active. The runtime is usable, the API is documented, and the examples are the demonstration. The technical report is explicit about what the current evidence does and does not establish: there is no formal benchmark at swarm scale, no head-to-head comparison against commercial middleware, and no user study of authoring effort. The report treats those as open work, not as settled claims.
The licence is the World Gump Licence.