Populating a universe with an LLM¶
Writing a whole world by hand is work. The engine can draft one for you: the populate module sends your idea (or your existing lore) to the configured LLM and writes the results into the universe — entities, lore entries, rules, a map, scheduled events, stat definitions, metadata.
From the command line¶
$ axiom populate MyWorld.db -t meta -t entities -t lore \
--text "A noir city ruled by clockwork gods"
-t/--targetis repeatable, one per content kind:meta,stats,entities,rules,events,lore,map.--textgives a free-form instruction. Without it, the generation is inferred from the lore already present in the universe.
The universe argument accepts a .db, a source folder or a .axiom archive.
If the universe is folder-backed (Universe-as-Code), the generated content is
decompiled back into the source tree afterwards, so the text files stay
the source of truth.
What each target generates¶
Target |
Writes |
|---|---|
|
Universe name, system prompt, global lore, first message. |
|
Stat definitions appropriate for the setting. |
|
Characters and creatures, with initial stats. |
|
Mechanical rules (conditions/actions) matching the world. |
|
Scheduled in-game events on the timeline. |
|
Lore-book entries (history, factions, places…). |
|
Locations and their connections. |
Generation is idempotent in spirit: entity identifiers are derived from names, so regenerating tends to update rather than duplicate.
From Python¶
Each target is a function in axiom.populate, all sharing the same
shape — a database path, an optional instruction, an injectable LLM backend
and an optional status callback:
from axiom.populate import populate_entities
from axiom.config import load_config, build_llm_from_config
llm = build_llm_from_config(load_config())
populate_entities("MyWorld.db", text="A noir city of clockwork gods", llm=llm)
POPULATE_TARGETS maps the CLI target names to these functions.
Practical notes¶
Model choice matters. Generation asks for structured output; small local models sometimes return malformed JSON. If a run fails, retry or use a stronger model.
Quota resilience. On Gemini, rate limits (HTTP 429) are retried with the configured backoff and the optional fallback model — see LLM backends.
Review the output. Generated content is a draft. With a folder-backed universe, review the diff with
git difflike any other code.