Scope Control

Guide to keeping early adventures feeling small and local, and later ones feeling grand - without relying on geographic distance data Campaign Cookbook doesn't have.

Before you read further: the parameters this page used to center on - sameState and withinRange - are not currently functional (see Parameter Syntax for why). This page has been rewritten around minPopulation/maxPopulation, which do work, since that's the one dimension of "scope" this app can actually enforce today.

The Globetrotting Problem

Without any constraint, a random town or dungeon can feel wildly out of place for the story you're telling - a level 2 party being sent to "the capital" for a minor errand undercuts how special that city should feel later:

Bad Example - No Scope Control

"readAloud": "<div class='read-aloud'><p>The bandits fled to {randomBurg}.</p></div>"

Problem: {randomBurg} could resolve to any town in your party's generated roster, including a large city that should feel important and rare, not an everyday bandit hideout.

The Solution: Population-Based Scope

Use minPopulation/maxPopulation to keep early content pointed at small villages, and reserve large cities/{capitalCity} for moments that should feel significant:

Good Example - Controlled Scope

"readAloud": "<div class='read-aloud'><p>The bandits fled to {randomBurg:maxPopulation=300}.</p></div>"

Result: Selects a small village from your party's roster - fitting for an early, low-stakes lead, not a sudden trip to a major city.

Scope Control Parameters

minPopulation / maxPopulation

Filter which towns are eligible by size.

{randomBurg:maxPopulation=300} // Small village
{randomBurg:minPopulation=500,maxPopulation=2000} // Mid-size town
{randomBurg:minPopulation=2000} // Large city
Population Range Feel Suggested Party Level
≤300 Small village Level 1-3
300-1500 Town Level 4-8
1500+ City Level 8+
{capitalCity} (largest in the roster) Capital High-level / end-game
Note: These are narrative suggestions, not enforced rules - population is just a number on a generated town, not a real simulation of importance. Use it as a lightweight steering wheel, not a hard constraint.

Campaign-Level Scope Strategy

Level 1-3: Small and Local

Keep the party's world feeling small:

// Home base - always the same for this party {nearestBurg} // Other settlements - keep them modest {randomBurg:maxPopulation=300} // Dungeons - easy difficulty {nearestDungeon:difficulty=easy} {randomDungeon:difficulty=easy}

Level 4-7: A Wider World

Let the party encounter real towns, not just villages:

// Home base {nearestBurg} // Mid-size destinations {randomBurg:minPopulation=500,maxPopulation=2000} // Regional dungeons {nearestDungeon:difficulty=medium} {randomDungeon:difficulty=medium}

Level 8-12: Cities Matter

Larger settlements start to feel earned, not random:

// Reference home base {nearestBurg} // Real cities {randomBurg:minPopulation=1000} // Challenging dungeons {nearestDungeon:difficulty=hard} {randomDungeon:difficulty=hard}

Level 13+: The Capital, and Beyond

Save the biggest location for when it counts:

// Capital city for high-level politics {capitalCity} // Any settlement {randomBurg:minPopulation=2000} // Deadly dungeons {randomDungeon:difficulty=deadly}

Scope-Controlled Narrative Patterns

Pattern 1: Local Investigation

"sceneId": "ep1-scene2", "readAloud": "<div class='read-aloud'><p>The merchant mentions he came from {randomBurg:maxPopulation=300}. He was attacked just outside {nearestBurg}.</p></div>"

Effect: Both locations read as small and unremarkable - fitting for an early, low-stakes lead.

Pattern 2: Expanding Threat

// Episode 1: A small village {randomBurg:maxPopulation=300} // Episode 2: A real town {randomBurg:minPopulation=500,maxPopulation=2000} // Episode 3: A major city {randomBurg:minPopulation=2000}

Effect: The threat grows, and so does the scale of the places it touches.

Pattern 3: Return Home

"readAloud": "<div class='read-aloud'><p>After days exploring {randomDungeon:difficulty=medium}, you finally return to the familiar streets of {nearestBurg}.</p></div>"

Effect: Reinforces {nearestBurg} as home base, creating emotional attachment.

Debugging Scope Issues

Symptom: Fallback Text Appears

Problem: "a nearby settlement" instead of actual name

Cause: Filters are too strict - nothing in your party's generated roster (or hand-authored locations.json, for dungeons) matches

Solution: Relax one or more parameters

✗ Too strict: {randomBurg:minPopulation=5000}
✓ Relaxed: {randomBurg:minPopulation=1000}

Symptom: Same Location Used Twice

Problem: {randomBurg:maxPopulation=300} resolves to "Millhaven" every time

Cause: Working as intended - caching ensures consistency

Solution: Use different parameters for different locations

{randomBurg:maxPopulation=300} // Location A
{randomBurg:minPopulation=500,maxPopulation=2000} // Location B (different params)

Scope Control Checklist

Before Publishing Your Campaign:
  • ✓ All level 1-3 content uses maxPopulation to stay small
  • ✓ {capitalCity} only used for high-level or end-game content
  • ✓ Population scope gradually expands as party levels up
  • ✓ Tested to confirm locations resolve (not fallback text)

See Also