Builders » Guide

Building AI-enabled NPCs

How to turn a mob into a "smart" NPC that answers tells, greets visitors, reacts to socials, and trash-talks in combat — using the LLM-backed AI service. Covers the four MOB_AI_* flags, writing personality strings, balance considerations, and when to use AI vs DG triggers.

Last updated: 2026-05-19

📥 Download as Markdown

Building AI-enabled NPCs

JediMUD has an AI service that lets NPCs respond dynamically to player input via an LLM. When a player types tell <npc> <message>, walks past an AI greeter, bows at an AI emoter, or gets hit by an AI taunter, the engine builds a prompt from the NPC’s personality + the situation, sends it to the AI backend, and delivers the response a couple seconds later in the NPC’s voice.

For builders, this means: any mob you make can have dynamic dialogue without writing a single trigger. You define the personality once; the AI handles the rest.

For the implementation details (worker queue, prompt sanitization, OpenAI/Ollama fallback chain, caching), see AI service on the staff docs.

The four MOB_AI_* flags

Set on the mob via medit <vnum>A (NPC flags). Each flag enables one behavior:

FlagBehavior
AI_ENABLEDMaster switch — the mob responds to tell <npc> <msg>
AI_GREETERNPC greets PCs walking into the room (60s cooldown per NPC)
AI_EMOTERNPC reacts to socials targeting it (30s cooldown)
AI_TAUNTERNPC trash-talks PCs when it lands damage in combat (90s cooldown)

You can combine all four — the wise oracle who greets, reacts to bows, taunts in combat, AND answers questions. Or pick the ones that fit the character.

AI_ENABLED is the gate for tell. Without it, all four flags do nothing — the master switch matters.

Cooldowns

The cooldowns are per-NPC — not per-player. If the Baker greets Foo at minute 0, he won’t greet Bar (or Foo) until minute 1. This is intentional: it makes the NPC feel like a person rather than a slot machine, and it keeps the API costs bounded.

Personality string

The AI’s response is shaped by the NPC’s personality — a short prose description of who they are, how they talk, what they care about. Stored in the ai_npc_personalities SQL table by mob vnum.

To add one, SQL is the canonical interface:

INSERT INTO ai_npc_personalities (mob_vnum, personality, enabled)
VALUES (3001,
  'You are Hans the Baker, a kindly old man in Midgaard. You speak with warmth, occasionally reference the weather, and care deeply about quality flour. You distrust elves but try to hide it.',
  1);

If no row exists for the mob, the AI uses a generic personality built from the mob’s short desc — usable but bland.

What makes a good personality

QualityWhy it matters
2-4 sentences maxLonger = the LLM forgets details and drifts.
Specific traits, not generic”Speaks with warmth, taps the counter when amused” beats “is friendly.”
One quirk per personalityAn NPC who hates elves AND loves dwarves AND stutters AND grieves a dead son AND… is confused. Pick one.
In-fiction contextReference the zone, the era, the local politics. “Forty years in this fountain square” places the NPC in time.
No meta-instructionsDon’t write “respond in one line” or “stay in character.” The prompt template handles that.

Examples

Good:

You are Gertrude, the Midgaard fountain-keeper. You have lived in this square for forty years and know every secret. You speak slowly, look people in the eye, and remember names. You have a soft spot for orphans.

Good:

You are Captain Brennar, the no-nonsense quartermaster of the City Watch. You speak in short clipped sentences, suspect everyone of something, and respect only competence. You served on the southern wall during the orc siege twenty years ago.

Bad — too long and meta:

You are an NPC in a fantasy MUD. You should always stay in character and respond in one line. You are a baker who is friendly. Try not to break the fourth wall. Be helpful but not too helpful. Respond to greetings warmly. Don't reveal that you are AI.

Bad — too generic:

You are a baker. You are friendly. You sell bread.

Editing personalities

There’s no in-game personality editor yet. Two paths:

  • SQL directly: UPDATE ai_npc_personalities SET personality = '…' WHERE mob_vnum = 3001;
  • Web staff page: /staff/ has links to the data; check with staff if a personality-edit UI exists for your tree.

After editing, changes take effect immediately for new prompts. Cached responses for the old prompt may keep coming back for up to an hour — clear the cache via ai cache clear (staff command) if you need immediate fresh responses.

Building an AI NPC step-by-step

1. Build the mob normally

medit <vnum> and set the basics (name, descriptions, position, level, etc.) just like any other mob. The AI doesn’t replace anything else — your stats / class / NPC flags all still apply.

2. Set the AI flags

In medit … A:

  • Always set AI_ENABLED so tell works.
  • Add AI_GREETER for a “comes alive when you walk in” feel.
  • Add AI_EMOTER for social interactions.
  • Add AI_TAUNTER for combat presence (only for fighting NPCs).

3. Write a personality

INSERT INTO ai_npc_personalities (mob_vnum, personality, enabled)
VALUES (
  <vnum>,
  'Your personality string here (2-4 sentences).',
  1
);

4. Save the mob

Qy in medit.

5. Test

load mob <vnum>          spawn next to you
tell <name> hello        try a direct conversation
bow <name>               try a social if AI_EMOTER set
                         (walk out and back in for greeter)
                         (start a fight for taunter)

You should see responses arrive 1-3 seconds after the input. The lag is the LLM thinking.

Common patterns

A welcoming shopkeeper

The baker who greets, has personality, but doesn’t fight:

  • Flags: AI_ENABLED, AI_GREETER, AI_EMOTER
  • No AI_TAUNTER — he’s not a combatant.
  • Personality: warm, talks about bread / the weather / passing customers.

A combat boss with menace

The dragon who taunts mid-fight:

  • Flags: AI_ENABLED, AI_TAUNTER
  • No AI_GREETER — encounter-level mob; the entrance is dramatic enough.
  • Personality: arrogant, ancient, references the smallness of mortals.

A quest-giver oracle

The seer who answers questions:

  • Flags: AI_ENABLED, AI_GREETER
  • Personality: cryptic, references prophecies + the local lore. Don’t put quest information in the personality — the LLM will hallucinate quest steps inconsistently. Use DG triggers for the actual quest logic.

A guard with attitude

The city guard who scowls at trespassers:

  • Flags: AI_ENABLED, AI_EMOTER, AI_TAUNTER
  • Personality: cynical, distrustful, references their duty.
  • Pair with a Quest_block spec proc for the actual gate-keeping behavior; AI handles the flavor.

What players see

When the AI fires, the NPC says, emotes, or tells back to the player. From the player’s perspective, it’s normal NPC speech — they don’t see “AI thinking…” or any indication the line is generated.

Latency is typically 1-3 seconds (LLM round trip). For combat taunts, there’s an instant audio cue (a grunt via the sound layer) so the player knows the NPC is engaging, then the spoken line arrives a moment later.

If the AI service is disabled or fails, the NPC falls back to:

  • For tell: silence, or the legacy Stock_speech spec proc if attached.
  • For ambient hooks (greet/emote/taunt): nothing fires.

AI + DG triggers — they coexist

You can put AI flags AND DG triggers on the same mob. They don’t conflict — triggers fire first; if a trigger handles the event (returns 1), the AI hook doesn’t fire.

This means you can:

  • Use a TELL trigger for specific keywords (“password”, “quest”, “help”) and let AI handle the rest.
  • Use a GREET trigger for the first greeting (quest hook), and let the AI greeter handle subsequent visits.
  • Override AI taunts for scripted combat phases (e.g. “phase 2: the boss summons minions and roars”).

In general:

  • AI = flavor, atmosphere, “this NPC feels alive.”
  • Triggers = mechanics, quest state, conditional logic.

Use both for the best result.

When NOT to use AI

SituationBetter tool
NPC needs to give a specific quest item on a specific phraseDG TELL or RECEIVE trigger
Combat needs deterministic boss behavior (phase 2, enrage, summon adds)DG HITPRCNT trigger or spec procs
Shop dialogue (buy/sell prompts)Shop_keeper spec proc
Quest accept/info/complete flowsQuestmaster spec proc + qedit
Dialogue that must be word-for-word reproducibleDG SPEECH trigger with fixed responses
Anything where token cost or rate-limit pressure mattersPlain triggers (free)

AI is great for atmosphere. It’s bad for anything that needs to be exactly the same every time, or that the game logic needs to consume.

Cost & rate awareness

The AI service has a rate limit (per-minute + per-hour caps on OpenAI calls). When the rate limit is hit, requests fall back to a local Ollama instance (slower, smaller model, but free) — and eventually to silent fallback.

A busy zone with many AI greeters can burn through rate limit budget fast. Some discipline:

  • Don’t put AI_GREETER on every NPC in a crowded city — pick a few flavor characters.
  • Use cooldowns to your advantage — frequent re-entries to the same room don’t re-trigger the greeter for 60 seconds.
  • Combat zones with many taunters multiply the load — concentrate taunters on bosses, not minions.

The system is designed to be lossy when overloaded (silent fallback rather than queueing), so over-flagging won’t crash anything — just produces less talkative NPCs as the budget runs out.

See also

  • AI service — staff-side technical deep dive: API integration, async handoff, security, SQL schema.
  • Building mobiles — the main mob-building guide; AI is a layer on top.
  • Building triggers — for deterministic / scripted behavior to pair with AI.
  • Spec procs (catalog) — service NPCs (Shop_keeper, Questmaster, Postmaster) that handle mechanics; AI adds flavor on top.