Trigger Budgets
| Field / Pattern | Limit | Measured as |
|---|
| Mechanical triggers (count) | 500 | count |
| Semantic triggers (count) | 200 | count |
| Per-trigger size (compact JSON) | 10,000 | compact JSON |
| Per-trigger conditions (count) | 5 | count |
| Per-trigger effects (count) | 5 | count |
Trigger condition .text | 1,000 | raw characters |
Trigger condition .value | 100 | raw characters |
Trigger effect .text | 1,000 | raw characters |
Trigger effect .value | 100 | raw characters |
Trigger script field | 0 | n/a |
Narrative & Story
| Field / Pattern | Limit | Measured as |
|---|
storySettings.worldBackground | 5,000 | raw characters |
storySettings.questGenerationGuidance | 5,000 | raw characters |
narratorStyle | 2,000 | raw characters |
death.instructions | 4,000 | raw characters |
worldLore (entire section) | 500,000 | pretty-printed JSON |
worldLore.*.text | 4,000 | raw characters |
storyStarts (entry count) | 100 | count |
storyStarts.* (each entry, pretty JSON) | 8,000 | pretty-printed JSON |
Catalogs
| Field / Pattern | Limit | Measured as |
|---|
items.*.description | 4,000 | raw characters |
factions.*.basicInfo | 4,000 | raw characters |
factions.*.hiddenInfo | 4,000 | raw characters |
npcTypes.*.description | 8,000 | raw characters |
npcs.* (each entry, compact JSON) | 8,000 | compact JSON |
premadeCharacters (entry count) | 100 | count |
premadeCharacters.* (each, compact JSON) | 20,000 | compact JSON |
Geography
| Field / Pattern | Limit | Measured as |
|---|
realms.*.basicInfo | 100,000 | raw characters |
regions.*.basicInfo | 4,000 | raw characters |
regions.*.hiddenInfo | 4,000 | raw characters |
locations.*.basicInfo | 4,000 | raw characters |
locations.*.hiddenInfo | 4,000 | raw characters |
locations.*.areas.*.description | 4,000 | raw characters |
realms (entire section) | 100,000 | pretty-printed JSON |
Mechanics Limits
| Field / Pattern | Limit | Measured as |
|---|
traits.*.description | 4,000 | raw characters |
locations (entire section) | 1,000,000 | pretty-printed JSON |
npcs (entire section) | 1,000,000 | pretty-printed JSON |
npcTypes (entire section) | 500,000 | pretty-printed JSON |
factions (entire section) | 100,000 | pretty-printed JSON |
regions (entire section) | 500,000 | pretty-printed JSON |
items (entire section) | 100,000 | pretty-printed JSON |
traitCategories (entire section) | 100,000 | pretty-printed JSON |
itemSettings (entire section) | 5,000 | pretty-printed JSON |
gameModes (entire section) | 100,000 | pretty-printed JSON |
gameModes.*.name | 120 | raw characters |
gameModes.*.description | 500 | raw characters |
gameModes.*.instructions | 5,000 | raw characters |
gameModes.*.askTheNarratorPrompt | 1,000 | raw characters |
| Entire world config (pretty JSON) | 10,000,000 | pretty-printed JSON |
abilities (entry count) | 1,000 | count |
abilities.*.description | 2,000 | raw characters |
abilities.*.requirements (array length) | 10 | count |
abilities.*.bonus | 0 | n/a |
AI Instructions Limits
| Field / Pattern | Limit | Measured as |
|---|
Each string leaf under a task (aiInstructions.<task>.<key>) | 5,000 | raw characters |
Per task (aiInstructions.<task> total, sum of instruction chars) | 20,000 | raw characters |
Image Prompts
| Field / Pattern | Limit | Measured as |
|---|
imagePromptConfiguration.npcs / .locations / .regions | 5,000 | raw characters |
imagePromptConfiguration (combined npcs+locations+regions) | 15,000 | raw characters |
Settings Caps
| Field / Pattern | Limit | Measured as |
|---|
combatSettings.damageTypes (entry count) | 40 | count |
combatSettings.damageTypes.* (each) | 60 | raw characters |
itemSettings.itemCategories (entry count) | 40 | count |
itemSettings.itemCategories.* (each) | 60 | raw characters |
itemSettings.itemSlots (slot count) | 60 | count |
itemSettings.itemSlots.*.slot (slot name) | 64 | raw characters |
itemSettings.itemSlots.*.category (slot category) | 60 | raw characters |
itemSettings.currencyName | 64 | raw characters |
attributeSettings.attributeNames (entry count) | 30 | count |
attributeSettings.attributeNames.* (each) | 64 | raw characters |
nameFilterSettings (entire section) | 150,000 | pretty-printed JSON |
nameFilterSettings.*.replacements.* (each replacement) | 64 | raw characters |
import SizeLimitsTables from "~/components/static/SizeLimitsTables.astro";
Hard caps enforced by the Voyage editor's validation. Exceeding these causes the wand validator to reject the document. Every figure below is derived directly from the live Voyage schema, so the grouped tables and the per-section "Size limits" rows in each section hero always reflect the current enforced limits.
📋
Note (How limits are measured):
- Raw character length (
value.length in JS, len(value) in Python) -- used for every individual string field: description, basicInfo, hiddenInfo, narratorStyle, death.instructions, aiInstructions leaf strings, storySettings.worldBackground, storySettings.questGenerationGuidance, trigger condition/effect text and value fields, and similar. Counts every codepoint as 1 -- newlines count as 1 char, em dashes count as 1 char. This is what the Voyage editor's character counter reports and what the engine enforces.
- Pretty-printed JSON (
json.dumps(obj, indent=2)) -- used for all section totals (items, factions, regions, npcs, npcTypes, locations, worldLore, traitCategories, itemSettings) and for storyStarts per-entry. The structure is serialized with 2-space indentation, and that indentation counts toward the limit -- every nesting level adds 2 spaces per line against your budget, so deeply nested entries cost more than their text alone.
- Compact JSON (
json.dumps(obj)) -- used for individual NPC entries and individual trigger entries.