Locations
locationsLocations are the named places on the map - cities, ruins, dungeons, waypoints - the specific points of interest players visit inside a region.
"Locations that exist in the world"
- Editor location
- Files → World → Locations
- Editor type
- Edit in Studio + View JSON
- API endpoint
/sections/locations.json/sections/locations.md- Size limits
locations.*.basicInfo— 4,000locations.*.hiddenInfo— 4,000locations.*.areas.*.description— 4,000locations(entire section) — 2,000,000
Schema
{
"locations": {
"<key>": {
"name": "string",
"basicInfo": "string",
"x": "number",
"y": "number",
"region": "string",
"radius": "number",
"complexityType": "simple | complex | wilderness",
"detailType": "basic | detailed",
"hidden": "boolean",
"areas": {
"<key>": {
"description": "string",
"paths": [
"string"
],
"name": "string",
"images": {
"establishingShot": {}
},
"visualTags": [
"string"
]
}
},
"factions": [
"string"
],
"visualTags": [
"string"
],
"hiddenInfo": "string",
"initialKnown": "boolean",
"npcLevelRange": {
"min": "number",
"max": "number"
},
"images": {
"establishingShot": {
"crop": {
"focus": "...",
"zoom": "..."
},
"imageUrl": "string"
}
}
}
}
}Example
{
"locations": {
"The Capital": {
"name": "The Capital",
"basicInfo": "The largest city in the realm. A walled city of towers, markets, and bureaucracy. The ruling council's seat dominates the skyline. Gatekeepers at every entrance, petitioners in every corridor, and information that costs money to obtain.",
"x": -27,
"y": 5,
"radius": 6,
"region": "The Heartland",
"complexityType": "complex",
"detailType": "detailed",
"hiddenInfo": "A criminal syndicate has an active cell operating in the lower district. The mage guild's restricted archive holds three documents officially declared destroyed.",
"areas": {
"Council Hall": {
"description": "The formal chamber of the ruling council. Stone galleries and tiered seating for petitioners, every surface worn smooth from centuries of use. The air carries the smell of old paper and lamp oil. Guards at every door watch the visitors more than the council members.",
"paths": ["Market Quarter", "Academy Gate"]
},
"Market Quarter": {
"description": "The city's commercial heart — a permanent noise of competing vendors, loaded carts, and shouted prices. Dense enough that a conversation can happen three feet from a city watchman without being overheard. Merchants here know where information is bought and sold as well as goods.",
"paths": ["Council Hall", "Lower District", "Academy Gate"]
}
},
"factions": ["The Merchant Council", "The Mage Guild", "The City Watch"],
"initialKnown": true,
"hidden": false
}
}
}Simple location (no areas):
{
"Border Watchtower": {
"name": "Border Watchtower",
"basicInfo": "One of the frontier's forward observation posts. Manned by a rotating garrison detachment. Sparse, functional, and chronically under-supplied.",
"x": 12,
"y": -8,
"radius": 2,
"region": "The Frontier",
"complexityType": "simple",
"detailType": "basic",
"areas": {},
"factions": ["The Border Watch"],
"hiddenInfo": "The garrison rotation is on a fortnight cycle and the next swap is two days late. The current crew know it; the Border Watch command does not.",
"initialKnown": true
}
}Each location must be a plain object with all fields merged (not an array or split objects).
Note:
hiddenInfois available to the AI during play but players never see it directly. The AI uses it to stay consistent with the world's secrets - dropping hints in atmosphere and description rather than stating secrets outright. This pattern applies consistently across locations, NPCs, and factions:basicInfois the surface,hiddenInfois what drives the AI's behavior beneath it. On regionshiddenInfois unused — put region secrets in a location or NPC instead.
Fields
name
Display name of the location, shown to players. Required. Required, and the outer key must match it exactly: Voyage rejects a world whose key and name differ.
complexityType
Required, and one of "simple", "complex" or "wilderness": Voyage rejects a world whose location omits it. The correct field name is complexityType, not complexity. Using the shortened form complexity is not a valid schema field and is ignored by the codec. "linear" is NOT a valid value. Use "complex" for any location with multiple areas.
detailType
Required, and one of "basic" or "detailed": Voyage rejects a world whose location omits it. A "basic" location of complexityType: "complex" is fleshed out by generateLocationDetails, which writes its areas and hiddenInfo; a "detailed" one is used as authored.
areas
areas use description not basicInfo, and every area needs both description and paths. A strong area description usually runs longer than a single sentence and covers three things: (1) physical character of the space, (2) what function or activity happens here, (3) one atmospheric or sensory detail that makes the area distinct. The third element — a smell, a sound, a social rule, a visual anomaly — is what makes areas feel inhabited rather than labelled.
Use display names for area keys, not snake_case. The area key is what the game displays to the player: "Council Hall", not "council_hall". An area can also carry an optional name; paths, an NPC's currentArea and a story start's locationAreas all resolve by the area key. The key is also referenced directly in paths, npcs.currentArea, and storyStarts.locationAreas — a rename requires updating all three, so get the names right from the start.
Warning: Location area objects use
"description", not"basicInfo"; an area withoutdescriptionfails validation.
An area's own artwork takes the same images.establishingShot object, with the same crop framing, as the location's, and is generated during play the same way when it has no image.
factions
Optional Array<string> of faction keys present at this location; a key that names no faction raises a warning. Tells the narrator which factions have a presence here, influencing NPC affiliations and political framing in the scene.
npcLevelRange
Optional { min, max } integer band constraining the levels of AI-generated NPCs in this specific location. Takes priority over the parent region's npcLevelRange for NPCs generated here. Use it for outliers -- a high-tier dungeon inside a low-tier region, or a starter-friendly hub inside a high-tier region. NPCs with an explicit authored level ignore the band; only level-less generated NPCs are rolled near party level and then clamped into it. Omit to use the region's band, if it has one. Both values must be positive whole numbers; Voyage rejects anything else.
images.establishingShot.imageUrl
Optional string. URL of a banner or map image for this location, shown in the location view. A location image is shown two ways in play: a tall full-screen card on arrival, and a wide banner under Map → Location. Both are crops of the same file, so no single size avoids cropping — keep the subject centred and clear of the edges. Minimum 600×600. In the editor you can upload your own image or generate one from a prompt; both set this URL. Without one, the engine generates an image during play and saves it back, and an existing image is never regenerated. Whenever images.establishingShot is present, its crop is required.
images.establishingShot.crop.focus.x
Positions the visible window over the source image along the horizontal axis, as a percentage: 0 holds the left edge, 50 centres it, 100 holds the right edge. Defaults to 50. Out-of-range values are clamped. Saved by the crop control rather than typed by hand.
images.establishingShot.crop.focus.y
Positions the visible window over the source image along the vertical axis, as a percentage: 0 holds the top edge, 50 centres it, 100 holds the bottom edge. Defaults to 50. Out-of-range values are clamped. Saved by the crop control rather than typed by hand.
images.establishingShot.crop.zoom
Scales the image inside its frame, as a percentage of the unzoomed fit: 100 fills the frame with no magnification, 150 shows it at one and a half times, cropping to the area picked by the focus fields. Ranges from 100 to 300, default 100. Out-of-range values are clamped. Saved by the crop control rather than typed by hand.
basicInfo
The public-facing description of a location. It should answer: what is this place, who is here, and what is the dominant feeling of being in it? Keep it to 2–3 sentences.
x
Horizontal coordinate (a finite number) within the parent region's cell, ranging from -regionSize/2 to +regionSize/2 (regionSize lives in Location Settings, default 100 so -50 to +50). The unit is local kilometres, and the two coordinate systems compose: a location's global position is region.x * regionSize + x, and the same for y. The Builder's Map view sets it by dragging.
y
Vertical coordinate within the parent region's cell, same range as x; positive y is north. The Builder's Map view sets it by dragging.
radius
The location's size on the map, as a positive finite number in local kilometres. Worlds commonly author 1, 2, or 3, which is a convention rather than a limit — any positive value is accepted, and the map marker is drawn from the value itself rather than from a fixed set of size classes.
The radius is also the travel catchment. A coordinate belongs to a location when it lies within that radius of the centre, and where two locations both contain a point, the one with the smaller radius takes it. Keep circles from overlapping so arrivals resolve where you expect, and give a location that should win a contested area the tighter radius rather than the wider one.
region
Key of the parent region in regions; the location renders inside that region's map cell. Voyage rejects a world whose location omits it. An empty or unknown key is accepted but raises a warning.
visualTags
Visual metadata tags for the location.
initialKnown
Whether players know the location from the start. Set it to true for a location they should see from the start; without it, the location starts unknown and counts as known once the party has visited it.
paths
Required key in every area object. Every area must include "paths", even as []. Paths name sibling area keys within the same location; a path to an area that doesn't exist there raises a warning, and moving between locations is travel, not a path. Remove a deleted area from every other area's paths. Keep paths symmetric (if area A lists area B, area B lists area A back); Voyage adds a missing reverse path. An area with no path to it can't be reached by moving within the location.
Movement and engine behavior
Movement types
Four distinct movement modes the engine recognizes:
| Type | Scope | Behavior |
|---|---|---|
| MOVE | Within a location | Moves between areas using paths. Respects the path graph. |
| TRAVEL | Between locations | Moves between locations via map coordinates. Distance and travel time apply. |
| TELEPORT | Anywhere | Bypasses all distance, path, and travel constraints. Instant. |
| FAST TRAVEL | Anywhere | Like teleport with explicit targeting — bypasses constraints but player must name a destination. |
MOVE is the default within a complex location. TRAVEL is the default between locations. TELEPORT and FAST TRAVEL are instant. Arriving at a location in another region or realm updates the party's region and realm too (see Realm travel).
Travel difficulty
Travel is simple unless the party is restrained, in combat, or the destination is not yet established; those cases call for a skill check. Naming a destination that isn't a defined location doesn't fail: the party travels toward it as an untracked destination. Travel is impossible only when the destination is explicitly locked by its text (a boss guarding it, sealed access, a required access item, authority clearance), so a location or area that should be gated must state the lock in its basicInfo, hiddenInfo, or area description.
generateLocationDetails
generateLocationDetails runs only for locations with complexityType: "complex" and detailType: "basic". It reads basicInfo and any existing areas, and generates areas (with paths) and hiddenInfo.
Wilderness fallback
When the party ends a scene in untracked space and no permanent settlement is established, the engine falls back to a synthetic location named Wilderness with area Wilderness. Parsing is case-insensitive on the AI side, so wilderness, Wilderness, and WILDERNESS all canonicalize to the same Wilderness location.
Authoring tips
Simple vs complex
complexityType: "simple"— a single point of interest with no internal navigation. Good for taverns, shrines, waypoints.complexityType: "complex"— multiple areas connected bypaths. Use for dungeons, cities, estates, major landmarks.
Complex location design
- Give a dungeon or major landmark enough areas to explore.
- Make sure
pathsare bidirectional where logical (if you can walk from A to B, usually you can walk back). - Put different encounters, NPCs, or items in each area — don't duplicate.
- Use
hiddenInfoat the location level for secrets that only reveal after exploration or specific quest progress.
Areas inside a complex location
areas within a complex location define the navigable sub-zones. A city needs at minimum a public space and a private one — the distinction creates social texture. paths should be symmetric: if Market Quarter lists Council Hall as a path, then Council Hall should list Market Quarter back.
Settlements need a social area
Settlements (locations with NPCs, quest hooks, or hospitality) should include at least one social gathering area — a tavern, market, plaza, parlor, or equivalent — where the player can seek information and quests.
Endgame locations
- Start with
initialKnown: false— they're discovered, not given. - Have several areas forming a linear or branching progression.
- Have their own
hiddenInfothat recontextualises something the player thought they knew. - Be tied to the quests that lead there and resolve there.
Region coverage
A region with a single location has no internal exploration; a settlement or hub, a danger site, and a ruin or secret site make a good core.
Map and radius
radius is measured from the centre outward, so a radius of 3 spans 6 km across. Overlapping circles are resolved rather than rejected — a point inside two locations goes to the one with the smaller radius — but keeping them apart is still the way to be sure arrivals land where you intended.
There is no street view in the game — players cannot navigate inside a location visually. Use areas within a complex location to represent navigable sub-zones. Multiple separate location circles in a region can make a dense area (like a city) feel more navigable on the map.
City design choice: A city can be one large complex location (single circle, many areas) or multiple smaller complex locations filling a region. Multiple circles are more map-readable; a single circle with many areas gives deeper internal navigation.