Tyrell
More human than human.
Tyrell is a minds engine for games full of people. It decides what each person does, remembers what happened to them, keeps track of what they believe and how they feel about each other and about the player, and keeps them living when nobody is watching. It can also run the world faster, or backward: time walk is built into the core.
It knows about needs, places, time and other people, and nothing about tiles, side views, sprites or maps. Each game writes a thin adapter (a shell) that says what places exist, how long it takes to get between them and what people can do there, and draws whatever Tyrell decides.
Tyrell is written in TypeScript and ships as plain JavaScript with no dependencies: one <script> tag defines one global, Tyrell.
const world = Tyrell.create({ seed: 'my-town', start: 8 * 60 });
world.need({ id: 'hunger', rise: 0.07 }); // per game hour, 0 calm to 1 desperate
world.place({ id: 'cafe', tags: ['food'], hours: [7, 22], slots: { seat: 6 } });
world.place({ id: 'apartment', tags: ['home'] });
world.link('apartment', 'cafe', 10); // ten minutes' walk
world.action({ id: 'eat', at: 'tag:food', slot: 'seat', minutes: 30, relieves: { hunger: 0.6 }, pose: 'sit' });
world.person('ana', { home: 'apartment', routine: [[7, null, '*'], [23, 'home', 'sleep']] });
world.focus(['downtown']); // the regions the game has loaded
world.on('embody', (body) => spawnSprite(body));
world.on('step', (body) => moveSprite(body));
world.tick(1 / 60); // every frame
What’s in it
| Part | Named for | What it does |
|---|---|---|
| Bicameral (core) | Westworld’s bicameral mind | Needs, the layered priorities (story, job, routine, needs), considerations, the pick, habits that learn, instincts, pastimes that pall, wishes and dreams; skills that grow with practice |
| Ring (core) | The Expanse’s Ring | Places, travel times, opening hours, slots with a capacity, what each place offers |
| Entmoot (core) | The Ents’ council | The clock: an event queue that jumps between action ends; near and far; handing bodies to the game |
| Esper (core) | Blade Runner’s photo machine | Time walk: run faster, rewind, play backward, branch, bookmark |
| Reverie | Westworld’s reveries | Feelings, mood and emotion, breaking points, stress, memories that change people, beliefs that can be wrong, a file on the player |
| Fellowship | The Fellowship of the Ring | Regard, attraction, sentiments, compatibility, groups and households, standing (fame and infamy) |
| Wormtongue | Théoden’s whisperer | Witnesses, reports and heat, gossip, lies, silencing, secrets, favors |
| Cityspeak | Blade Runner’s street language | Lines chosen by the most specific rule, barks, practices with roles, social acts, an ink bridge |
| Mentat | Dune’s human computers | Planning: HTN tasks with methods, get: searches (GOAP) for getting hold of things, replanning |
| Gaff | Blade Runner’s origami watcher | The director: storylets, mean time between events, intensity phases, decks, unseen places |
| Ceres | The Expanse’s trading station | Money, prices, stock, wages, rent, incomes, household purses and pantries, production chains and a daily report |
| Cradle | Westworld’s Cradle | Ages and stages, couples, births with inherited traits, departures, grief and inheritance |
| Joi | Blade Runner 2049’s companion | An optional language-model voice that never changes the world |
| Athelas | The kingsfoil of the Houses of Healing | Conditions that run a course: phases that change needs and choices, contagion, immunity |
| Delos | Westworld’s Delos, which kept a copy of everyone | Genomes: genes with dominance, blended traits, talents and instincts, mutations, inherited through Cradle |
| Voice | The Voice of Dune | Branching conversations: threads of beats, answers whose approaches land by the listener’s nature, things learned (and recalled, and familiarity as trust), promises kept or broken |
| Bree | The village of the Prancing Pony | Interactions between people: chats, jokes, flirts, apologies, arguments and fights that come out by degrees, conversations over turns on topics in each one’s manner, escalation, grudges, feuds, avoidance and making up |
| Morgul | The Morgul-blade, whose wound won’t heal | Harm between people: wounds that heal or fester, hurt, down and (only if the game says) dead, pain, fear, grudges and revenge, witnesses and crimes, traps, poison that works unnoticed, suspicion that can be wrong, fights by numbers |
| Palantír (tool) | The seeing-stones | The inspector: every choice with its scores, “why not that?”, a readable account |
| Westmarch (tool) | The Red Book of Westmarch | The log of what happened, and chronicles of anyone’s day |
| Irulan (tool) | Princess Irulan, Muad’Dib’s historian | The narrator: the log told as a story, the routine left out, its storylines and headlines, in parts a game can style |
| Voight-Kampff (tool) | Blade Runner’s test | Headless seeded runs that check people still behave like people |
| Rocinante (example) | The Expanse’s ship | A sample town of ten people that exercises everything |
Using it in a game
Tyrell lives in the Tycho repository, which a game pulls in as a git submodule. The built files in Tycho’s dist/ are committed, so the game needs no build step and nothing installed:
git submodule add https://github.com/doctorallen/tycho vendor/tycho
<script src="vendor/tycho/dist/tyrell.js"></script>
If the game deploys from CI, its checkout needs submodules: true. A service worker that caches the game’s files should list vendor/tycho/dist/tyrell.js too. To update, git -C vendor/tycho pull and commit the new pointer: each game pins the engine version it was tested with.
Node and bundlers can use dist/tyrell.mjs or dist/tyrell.cjs; types are in dist/tyrell.d.ts (and dist/tyrell.global.d.ts for the global). A game with people on screen can load Tycho’s bridge too (dist/tycho-minds.js, see the Tycho README); a game without people loads neither.
Documentation
Start with docs/README.md. The guides walk through integrating a game; the reference covers every call. docs/tuning.md lists every setting, and the headline knobs that tune a whole behavior (how fast friendships form, how often breaks come, how readily gossip spreads), for everyone, for one person, or during play.
Building and testing
From the root of the Tycho repository, which builds Tyrell with the engine and the bridge:
npm install # TypeScript and esbuild, for building only
npm run build # src/ -> dist/ (commit dist/ with the change)
npm run test:tyrell # builds, then runs Tyrell's test suite
npm run typecheck
npm run vk # Voight-Kampff: a week of Rocinante