LLM NPC setup

"The droid talked for an hour and it was marvellous. The invoice arrived on the Tuesday." — Comptroller Ivek Sarn

LLM NPCs hand an NPC to a language model, which improvises its replies to whatever players say nearby.

Every reply is a paid API call, billed to you. The server sends each exchange to the Anthropic API using your own key. Nothing about this is free, nothing is capped by default, and the players triggering the calls never see the cost. Set sf_llmnpc_budget before you set anything else.

The current build has this system compiled out. A hard switch in the source disables casting, the /llm command and all API traffic, whatever the settings below say. Re-enabling it means changing that switch and rebuilding the game module.


What it does

A director casts an NPC with the /llm command, giving it a description and a set of behaviour instructions. From then on, a player who speaks near that NPC gets a reply written by the model. The NPC remembers the conversation, and can quietly remember people it has met before.

3 NPCs can be cast at once. Each reply is short by design, because it has to fit a single chat line. Casting and directing them is covered in LLM NPCs. This page is the server side only.


Before you turn it on

The feature needs 3 things in place:

  • an Anthropic API key, which you pay for and which is billed per request
  • the llm/ folder from the server download, sitting in your StoryForce folder
  • an HTTPS library the game can reach, which is built in on Windows and comes from libcurl elsewhere

The llm/ folder holds llm_prompt.txt, the base instruction sent with every request. StoryForce falls back to a built-in prompt if the file is missing, so a missing folder is quiet rather than obvious. The same folder is where persona files are written during play, one folder per persona and one file per character the NPC has met.

The container image does not include llm/. Copy it in from the server zip. See Docker hosting.


Turning it on

Set these in storyforce_server.cfg. The shipped file already lists every LLM setting, with the master switch set to 0 and the rest commented out. Filling in real values is usually enough:

set sf_llmnpc        "1"
set sf_llmnpc_token  "your-api-key"
set sf_llmnpc_budget "200"

sf_llmnpc_token deliberately carries no archive flag. The game never writes it into its own saved config, which keeps it out of files that get copied off the machine. The cost is that it only exists while your config file sets it. That means it has to be in that file on every boot.


Settings

Cost control

Server-side. Maximum API requests per map, counting replies, pokes and memory summaries alike. 0 means unlimited. Range 0 to 1,000,000. Default 0. Server-side. Seconds one player must wait between triggering replies. Range 0 to 3600. Default 3. Server-side. Output token cap per request, which is what you are billed on. Range 16 to 1024. Default 160.

The budget counter resets on every map load, so a value of 200 is 200 requests per map and not 200 per day. Every map change grants the full allowance again, so 5 map changes in an evening allow up to 1,000 requests at a budget of 200.

Model and reply shape

Server-side. The model to call. Accepts a full model name, or the shorthand haiku or opus. Default claude-haiku-4-5. Server-side. Hard character limit on a reply, trimmed after the model responds. Range 20 to 149, leaving room for the name prefix in a 150-character chat line. Default 130. Server-side. Conversation turns an NPC remembers within a scene. Range 0 to 12. Default 12. Server-side. Seconds between a player speaking and the NPC replying, measured from when they spoke. Range 0 to 60. Default 4.

A longer history costs more, because every remembered turn is sent again with the next request.

What triggers a reply

Server-side. Maximum distance in units from the NPC for speech to reach it. Range 1 to 100000. Default 400. Server-side. Set to 0 to stop an ordinary say routing to whichever LLM NPC is under your crosshair. Default 1. Server-side. Distance in units within which cast NPCs silently remember nearby chat without replying. 0 turns it off. Range 0 to 100000. Default 300. Server-side. Distils finished conversations into per-character memories, written under llm/ for NPCs linked to a saved persona. Default 1.

Overhearing costs nothing on its own, because no request is sent. Auto-summary does cost, because each summary is its own API call drawn from the same budget.


Things to note

  • Nothing here limits your bill by default. sf_llmnpc_budget ships at 0, which is unlimited. Set a real number before you open the server.
  • The budget resets on every map change. It is a per-map allowance, not a daily one.
  • Summaries and pokes spend budget too. They are not free background work.
  • The token is never saved anywhere. Leave it out of your config and the system stays silent rather than warning you.
  • A token with whitespace or control characters is rejected. The request is skipped and a line goes to the server console.
  • Only 3 NPCs can be cast at once. A fourth needs an existing one cleared first.
  • Long histories multiply cost. Every remembered turn is resent with each new request.
  • An NPC with no display name gets its replies dropped. Set one before casting.
  • On Linux and macOS the feature needs libcurl present. Without it the server cannot make HTTPS requests at all, and the same applies to the database mirror.
  • Persona files are written into llm/. That folder needs to be writable and needs backing up if you care about what the NPCs remember.

Next

  • LLM NPCs: casting, personas and directing the NPCs once the server side is on
  • Server configuration: the config file that holds these settings