Valenar - Location Generation Contract
This document is the authoritative design contract for generating Valenar Locations. It explains what information a Location must carry, how readable terrain classes are derived, how production world facts become Valenar gameplay facts, and how those facts feed exploration, settlement development, pressure, UI, and Feature placement.
Feature placement has its own authority in Feature Generation Contract. Feature sections in this document describe the Location-side handoff and examples.
Related docs:
- World Generation Contract defines the top-level world-data-to-Valenar import boundary.
- Feature Generation Contract defines Feature placement, discovery, activities, rewards, and validation.
- Locations, Features, and Sites defines what a Location can contain.
- Location Dossier defines how the player inspects revealed Location content.
- World Pressure and Nexus defines shield, taint, gates, and starting Nexus rules.
- Settlements and Outposts defines claim, designation, districts, outposts, and development. Taxonomy rule for this contract: Location is the strategic unit. Features are notable contents, signs, or facts inside it. Sites are first-class places inside it once discovered, enterable, exploitable, or developed. Threat is attached danger or hostile presence, not a parallel place model. Dungeons follow the same handoff: clue, sign, or Feature first, Site once discovered or enterable. Status: planned authoritative contract. The current executable Valenar map is a stepping-in prototype fixture with server-side Voronoi geometry, prototype-scale Location counts, mostly-zero geography channels, and random inert Feature sprinkling. Target behavior below applies to the production generator unless explicitly marked current prototype behavior. Later campaign/world maps may be much larger and may use larger or variable-sized Locations.
Scope
This contract covers strategic map generation for Valenar:
- Location facts.
- Derived terrain and pressure labels.
- Location topology and route inputs.
- Location knowledge defaults.
- Location fields consumed by Feature generation.
- Validation.
- Runtime data responsibilities.
It does not define:
- 3D rendering implementation.
- Individual feature story scripts.
- Final numeric balance.
- MC combat internals.
- Feature template catalogs, which live in Feature Generation Contract.
- District development formulas beyond the Location inputs they consume.
Core Principle
The generated numeric facts are the truth. Labels are summaries.
A Location is not only:
terrain = Plains
A Location has continuous facts:
plainsCoverage = 52
forestCoverage = 36
wetlandCoverage = 3
waterCoverage = 4
fertility = 72
moisture = 47
slopeAvg = 8
routeImportance = 61
The player-facing label is derived:
derivedClass = Wooded Plains
tags = Fertile, ForestEdge, EasyTravel, GoodExpansionLand
Feature generation, activity availability, designation value, and threat calculation use the numeric facts and tags. The label is for readability, not simulation authority.
Generation Shape
The complete generation path is:
production WorldData layers
-> Location polygon and hierarchy ids
-> aggregated Location numeric facts
-> derived classes and tags
-> travel, pressure, and control facts
-> feature candidate scoring
-> regional feature budgets
-> selected Feature entities
-> discovery and knowledge state
-> generated activity availability
-> modifiers, channel effects, and UI readouts
-> validation
The current Valenar prototype uses an interim SECS MapGenerationSystem plus
server-side Voronoi geometry. That prototype may populate the same fields before
production world-data integration, but the final source of geographic truth is
production WorldData.
Location Scale
Each Location is a strategic cell of roughly 250-500 km² (an irregular Voronoi polygon at this scale). A Province (Järvamaa-sized, ~2,600 km²) contains 5-10 Locations; the player's starting Shielded Zone is 3-6 Provinces, so 15-60 Locations at game start; the full world is 50-150 Provinces (250-1500 Locations) across multiple Shielded Zones. The player operates at strategic scale, not city-builder scale.
The full scale budget — Province size, Locations per Province, Shielded Zone size, world-Province count — is owned by World Generation Contract. This section is the per-Location consequence.
The design must not require hand-authored feature lists per Location or independent random tables per Location.
Most Locations should not have a dramatic explicit Feature. A Location with no Feature is still meaningful because it has terrain, topology, resources, pressure, ownership, and travel state — at 250-500 km² per cell, the "interesting thing" is the cell itself, not a single landmark inside it.
Expected explicit Feature density:
ordinary land location: 0 notable Features
mildly interesting location: 1 notable Feature
rich, dangerous, or strategic location: 2 Features
rare landmark or story location: 3-4 Features
special Nexus / gate / capital site: hand-constrained by story rules
Production World-Data Alignment
Valenar consumes production world data through an explicit adapter contract; it does not bypass that contract.
The production world-data provider owns:
- heightmap-aligned scalar fields such as elevation, moisture, temperature, flow accumulation, and slope
- classification fields such as biome and water mask
- id textures for Location, Province, Area, and Region
locationHierarchy- topology graphs such as river, corridor, thalweg, and lake components
- world dimensions, coordinates, seed, and content hash
Valenar aggregates those facts per Location and turns them into gameplay data. If a Valenar UI, system, or renderer needs a generated map fact, that fact must exist in the data contract. It must not reach into generator internals.
Land And Water Locations
Production generation makes land and water Locations disjoint. Every texel belongs to one Location, and a Location has one high-level kind:
land-inland
land-coastal
water-narrow
water-coast
water-open
water-inland-lake
Valenar must respect this. A large lake, sea, or ocean area is a water Location, not a half-land Location. Coastal gameplay comes from adjacency between land-coastal and water-* Locations.
Within a land Location, Valenar can still have continuous land composition:
plainsCoverage
forestCoverage
hillCoverage
rockyCoverage
wetlandCoverage
barrenCoverage
ruinCoverage
corruptedCoverage
Tiny ponds, streams, springs, marsh patches, or drainage channels can contribute
to waterCoverage and generate water Features inside a land Location when they
are below the configured threshold for separate water Locations.
Location Data Contract
Every Location should have these generated or derived fields. Not every field must be visible to the player immediately.
Identity
locationId
seed
name
kind
parentProvinceId
parentAreaId
parentRegionId
kind is the high-level production Location kind, such as land-inland or
water-coast.
Geometry And Topology
polygon
centroid
areaSquareMetres
neighbourLocationIds
borderLengthsByNeighbour
routeDistanceByNeighbour
edgeSlopeByNeighbour
edgeCrossingTypeByNeighbour
Topology is gameplay data. Travel, claiming, patrol, road, route safety, outpost connection, district grouping, and scouting all depend on it.
Terrain Composition
Terrain composition is normalized coverage across the Location. For land Locations:
plainsCoverage
forestCoverage
hillCoverage
mountainCoverage
wetlandCoverage
rockyCoverage
barrenCoverage
ruinCoverage
corruptedCoverage
tinyWaterCoverage
For water Locations:
openWaterCoverage
shallowWaterCoverage
shoreAdjacency
reefOrRockCoverage
riverMouthInfluence
lakeCoverage
coastExposure
Do not force one exclusive terrain type where composition matters. A Location
can be Wooded Plains because it is 52 percent open ground and 36 percent
forest edge.
Physical Values
elevationMin
elevationAvg
elevationMax
slopeAvg
roughness
moisture
temperature
windExposure
floodRisk
soilQuality
fertility
visibility
cover
defensibility
These are generated from map layers and topology. They are host-owned facts.
Resource Values
foodPotential
foragePotential
gamePotential
timberPotential
herbPotential
clayPotential
stonePotential
orePotential
rareMineralPotential
salvagePotential
ancientRelicPotential
waterReliability
Resources are not all visible at first. The Location may know foodPotential
internally while the UI only shows unknown, signs of forage, or surveyed: high.
Travel Values
travelDifficulty
roadSuitability
routeImportance
riverCrossingDifficulty
chokepointScore
caravanViability
patrolViability
campSuitability
routeImportance is derived from graph position, such as how often a Location
lies on good paths between useful regions, resources, settlement anchors, gates,
or coastline access.
Pressure Values
baseThreat
predatorPressure
banditPressure
demonPressure
corruption
taintGrowth
nightDanger
weatherDanger
gateInfluence
shieldSuppression
Pressure fields can produce Features, activities, blockers, warnings, and
modifiers. For example, high demon pressure may generate DemonTracks, while a
true gate source becomes a stronger Feature with its own state and escalation.
Control Values
ownerId
controlState
claimability
designationType
settlementSuitability
outpostSuitability
districtSuitability
nexusCoverage
shieldCoverage
controlRouteState
Control is not binary. It is affected by knowledge, adjacency, route safety, Nexus or ward coverage, threat blockers, and act unlocks.
Knowledge Values
The Location knowledge ladder is the second of the three named state
axes documented in
../systems/gd-state-axes-and-thresholds.md
under "Location Knowledge Axis". The committed prototype is binary
(int Explored on LocationData); the full ladder below is target,
not yet implemented.
knowledgeState
surveyProgress
lastVisitedTick
knownThreat
knownResources
hiddenFeatureCountEstimate
visibleFeatureIds
hintedFeatureIds
Recommended Location knowledge ladder:
Unknown
Sighted
Scouted
Surveyed
Secured
Claimed
Cleansed
Developed
Binary Explored is only prototype scaffolding. Long-term Valenar needs
gradual knowledge because Features, risks, resource quality, and route safety
are revealed at different depths.
Derived Classes And Tags
The terrain-derived tag list below is planned — these labels are
description-only language until they are committed to
Content/common/tags.secs. The tag layer (namespace rules, modifier
vs structural-predicate split, Feature category vs tag distinction)
is documented in
../systems/gd-tags-and-classification.md,
and the catalog of committed and planned tags lives in
../catalogs/gd-tag-catalog.md. Do not
reference the planned tags below as Tags.<Name> constants in code
until they are committed.
Derived classes summarize numeric facts.
Example rules:
Open Plains:
plainsCoverage >= 70
forestCoverage < 15
wetlandCoverage < 15
Wooded Plains:
plainsCoverage >= 30
forestCoverage >= 25
slopeAvg < 35
River Meadow:
plainsCoverage >= 25
moisture >= 55
fertility >= 55
tinyWaterCoverage >= 5 or adjacent river/water route
Deep Forest:
forestCoverage >= 70
Rocky Upland:
hillCoverage + rockyCoverage >= 45
slopeAvg >= 20
Marsh:
wetlandCoverage >= 35
moisture >= 65
Blighted Field:
corruptedCoverage >= 25 or corruption >= 60
Tags are smaller derived facts:
Fertile
ForestEdge
OpenGround
EasyTravel
GoodRoadLand
Sheltered
Exposed
HighCover
LowCover
OreBearing
AncientTrace
Tainted
Shielded
GateShadow
Chokepoint
CoastalAccess
RiverAccess
GoodSettlementLand
PoorSettlementLand
Classes and tags can change when knowledge improves. The underlying generated facts do not change unless the world simulation changes them.
SECS Responsibility Split
Generated host fields are facts:
forestCoverage
fertility
orePotential
corruption
routeImportance
knowledgeState
featureState
SECS channels are resolved effective values:
FoodOutput
WoodOutput
MetalOutput
RouteSafety
RestSafety
SurveyDifficulty
ThreatLevel
SettlementSuitability
Actual economy readouts such as connected stockpiles, consumption, or throughput sit one layer above these. They are downstream settlement or outpost values, not generated Location facts and not a replacement for resolved SECS outputs.
Templates define static identity and channel sources. Modifiers express persistent effects from Features, sites, designations, events, or control state.
The host should not write gameplay channel values directly. If a value needs tooltip breakdowns, modifiers, formulas, or effects, it belongs in SECS channels. If a value is generated map truth or entity state, it belongs in host fields.
Feature Model
A Feature is a notable thing inside a Location:
spring
ore vein
forest stand
ancient road segment
ruined mill
demon tracks
bandit camp
gate fissure
standing stones
dormant Nexus
Features are not terrain labels. They are discoverable, inspectable, and often
actionable. A ForestEdge tag can make a Location wooded; a Forest Stand
Feature exists only when that wooded area is notable enough to expose activities,
risks, resources, or development hooks.
A Feature can stay a Feature for its whole life, or it can convert into a Site once the content becomes discovered, enterable, exploitable, or developed. Threat remains attached pressure or hostile presence on the Location, Feature, or resulting Site rather than a second place ontology.
Feature Categories
These categories classify Feature records. They do not create a competing player-facing place model.
NaturalResource
Water
Food
Forest
Mineral
Travel
Shelter
Ruin
Threat
Corruption
Landmark
Nexus
SettlementOpportunity
Story
Feature Template Contract
Each Feature template needs:
id
category
rarity
minSpacing
maxPerLocation
maxPerProvince
maxPerArea
maxPerRegion
hardRequirements
suitabilityWeights
conflictTags
synergyTags
discoveryDifficulty
surveyDifficulty
interactionDifficulty
possibleStates
available interactions
effects
modifiers
rewards
Template data answers:
- where the Feature can exist
- how rare it is
- what it conflicts with
- what it synergizes with
- how it is discovered
- what activities it creates
- what it does to the Location, routes, settlement, or world pressure
Feature Generation Formula
Do not roll every Location independently. Independent per-Location random chance creates noisy nonsense even at the 250-1500 Location world scale, because budgets, spacing, conflicts, and story rules all need cross-Location coherence the per-Location roll cannot give.
Use score-and-budget placement:
score(location, featureTemplate) =
hardGate(location, featureTemplate)
* suitability(location, featureTemplate)
* rarityModifier(featureTemplate)
* seededNoise(worldSeed, locationId, featureTemplateId)
* spacingPenalty(location, featureTemplate)
* storyBias(location, featureTemplate)
Where:
hardGate:
0 or 1. Required conditions must pass.
suitability:
weighted match between Location facts and template preferences.
rarityModifier:
global, regional, and category budget pressure.
seededNoise:
deterministic variation. Same seed and content gives same result.
spacingPenalty:
prevents bad clustering and respects min spacing.
storyBias:
forces or encourages required narrative geography, such as Nexus starts,
demon fronts, ancient roads, leyline anchors, or gate pressure arcs.
Candidate selection:
for each region:
for each feature template:
collect eligible candidates
score candidates
sort by score descending
select until regional/province budget is filled
enforce min spacing
enforce max features per Location
enforce conflict rules
This gives authored-feeling distribution without hand-authored placement.
Feature Capacity
Feature capacity prevents every Location from becoming cluttered.
capacityScore =
max(resourceRichness, threat, ancientness, routeImportance, settlementSuitability)
+ landmarkBias
+ seededNoise
Suggested capacity:
score < 35: 0 explicit Features
35-60: 1 explicit Feature
60-80: 2 explicit Features
80-95: 3 explicit Features
story or landmark override: 4 Features
Capacity can reserve slots by category. For example, a starting Nexus Location may reserve one story slot for the Nexus and still allow one natural survival Feature.
Feature Conflict And Synergy
Conflict rules prevent nonsense:
DormantNexus conflicts with duplicate Nexus/Wardheart anchor placement
OpenMarketCrossroads conflicts with DeepWildernessOnly
PristineSpring conflicts with SevereTaintSource unless explicitly corrupted
DenseForestFeature requires enough forestCoverage
LargeMineSite requires enough orePotential and terrain support
Synergy rules create meaningful clusters:
AncientRoadSegment increases chance of RuinedWatchtower nearby.
RiverMeadow increases chance of GoodFarmland and OldMill.
DemonGate increases chance of DemonTracks, BlightedField, and RefugeeCamp nearby.
OreBearingUpland increases chance of OreVein and CollapsedMine.
ForestEdge increases chance of GameTrail, HiddenCopse, and AmbushGrass.
Synergy should be deterministic and budgeted. It should not create unbounded chains.
Feature State
Feature state is more than discovered or cleared.
Recommended ladder:
Hidden
Hinted
Discovered
Surveyed
Interacting
Handled
Secured
Developed
Depleted
Destroyed
Not every Feature uses every state. The state model must support mystery, partial knowledge, local activities, long-term development, and cleanup.
Site-facing wording, once a Feature converts, should use explicit place states: wild, discovered, secured, active, owned, developed, depleted, sealed, destroyed.
Example:
Hidden Spring
Hidden:
not shown
Hinted:
damp reeds, insect noise, or greener grass
Discovered:
shown as Hidden Spring
Surveyed:
water reliability and taint safety revealed
Secured:
improves rest safety and camp suitability
Developed:
supports farm, pasture, settlement water, or outpost
Activity Generation
Activities come from Location facts, Feature state, MC location, site ownership, threat blockers, tools, resources, act unlocks, and Nexus/founding state.
availableActivity(feature, actor, location) =
feature exists
required state passes
actor is present or has valid remote access
required tools/resources/act pass
threat blockers pass or the activity handles the threat
route/control requirements pass
Common activity families:
Look Around
Scout
Survey
Forage
Hunt
Gather
Investigate
Clear
Secure
Harvest
Excavate
Consecrate
Cleanse
Build Outpost
Develop Site
Study
Patrol
Seal
Exploit
Establish the Core
Feature activities must be causal. Investigate Ruined Mill can unlock tools,
blueprints, local restoration, or production-site knowledge. It should not grant
a random global production bonus unrelated to the ruin.
Effects And Modifiers
Feature effects should attach to the entity they actually affect.
Examples:
WildGrainPatch discovered:
reveals food potential and forage activity
WildGrainPatch secured:
adds local FoodOutput or FarmingSuitability modifier
OreVein surveyed:
reveals ore quality and mine-site activity
OreVein developed:
adds MetalOutput to the owning Location, outpost, district, or settlement
through the proper scope
DemonNest active:
increases ThreatLevel
lowers RouteSafety and RestSafety
blocks safe survey, mining, or settlement work
DemonNest handled:
removes active threat modifier
may reveal salvage, shard, route safety, or taint source information
Use Location-scoped modifiers first. Promote to settlement or region effects only when ownership, route connection, designation, site development, or story state justifies it.
Plains Example
Plains are not empty. They are about food, grazing, visibility, roads, exposure, soft ground, old travel routes, and pressure.
Possible plains Features:
Food/resource:
WildGrainPatch
GrazingHerd
GoodFarmland
ForagingGround
HerbMeadow
Water:
SeasonalStream
ShallowPond
ReedPool
HiddenSpring
Travel:
RoadTrace
CaravanCamp
MarketCrossroads
OldBoundaryStones
Shelter/defense:
LoneHill
WindbreakCopse
EarthenRise
ExposedApproach
Threat:
AmbushGrass
PredatorTrail
BanditCamp
DemonTracks
BlightedField
History:
StandingStones
BattlefieldRemnant
BuriedRuins
AncientRoadSegment
FallenWatchtower
SealedBarrow
Example WildGrainPatch:
eligible if:
plainsCoverage >= 35
fertility >= 55
corruption <= 50
score =
plainsCoverage * 0.30
+ fertility * 0.45
+ moisture * 0.15
- forestCoverage * 0.10
- corruption * 0.25
+ noise * 0.10
Example RoadTrace:
eligible if:
slopeAvg <= 35
tinyWaterCoverage <= 35
routeImportance >= 40
score =
routeImportance * 0.45
+ plainsCoverage * 0.20
+ roadSuitability * 0.25
- wetlandCoverage * 0.20
- roughness * 0.15
+ noise * 0.10
Example DemonTracks:
eligible if:
demonPressure >= 35
knowledgeState >= Sighted
score =
demonPressure * 0.45
+ corruption * 0.25
+ visibility * 0.10
+ routeImportance * 0.10
+ noise * 0.10
Mixed Terrain Example
Generated facts:
plainsCoverage = 52
forestCoverage = 36
wetlandCoverage = 3
tinyWaterCoverage = 4
fertility = 72
moisture = 47
threat = 18
routeImportance = 61
Derived class:
Wooded Plains
Tags:
Fertile
ForestEdge
EasyTravel
GoodExpansionLand
Likely selected Features:
WildGrainPatch:
high fertility plus open ground
ForestEdgeGameTrail:
mixed forest and plains with low threat
RoadTrace:
good route importance plus low slope
Other Terrain Examples
Deep Forest:
high forestCoverage
medium cover
lower visibility
possible Features:
ForestStand
GameTrail
HiddenCopse
OldShrine
AmbushSigns
WitchPath
Rocky Upland:
high slope and rockyCoverage
lower fertility
higher defensibility
possible Features:
OreVein
QuarryFace
CollapsedMine
WatchHill
CaveMouth
FallenTower
Wet Meadow:
high moisture and fertility
moderate tinyWaterCoverage or water adjacency
possible Features:
SeasonalStream
ReedPool
GoodFarmland
OldMillRace
SoftGround
TaintedRunoff
Blighted Field:
high corruption or corruptedCoverage
lower rest safety
possible Features:
BlackAshPatch
DemonTracks
BlightedCrop
MinorFissure
DeadGrove
CleansingSite
Land-Coastal:
land location adjacent to water location
possible Features:
FishingCamp
LandingBeach
CliffPath
OldPier
SmugglerCove
StormWreck
Water-Coast or Water-Inland-Lake:
water location, not settlement land by default
possible Features:
FishingGround
ShallowReef
FerryRoute
LakeIsland
SunkenRuin
DangerousCurrent
Starting Location Rules
The starting Location is procedural but constrained. It must pass the Nexus/Wardheart rules:
inside Ancient Shield coverage
low taint
weak or no demons in immediate reach
water within 1-2 hops
food in the start or within 1 hop
shelter and fire materials in the start
at least 2 viable expansion directions
at least 1 visible mystery hint
no immediate lethal gate
contains a dormant or damaged Nexus Feature
The Nexus is a story-constrained Feature placement. It is not the result of ordinary ruin rarity. Not every ruin can become a Nexus.
Founding is unlocked by the starting Nexus chain:
find ruin clue
investigate ruin
identify dormant Nexus / Wardheart
stabilize Nexus
unlock Establish the Core
found once
remove founding activity forever
Generic settlement suitability must not unlock founding by itself.
Validation
Generation is incomplete without validation.
Location invariants:
every Location has a polygon, centroid, parent ids, and kind
every non-isolated Location has at least one neighbour
parent province/area/region membership is spatially contiguous
coverage values are normalized and bounded
physical and resource values are bounded
water and land Location kind rules match production world data
large water bodies are water Locations, not land coverage
tiny water features inside land Locations are below the configured threshold
Feature invariants:
every Feature has a valid Location
every selected Feature still passes hard requirements
Feature count does not exceed Location capacity
rare Features respect spacing
incompatible Features do not coexist
story Features required by start rules exist
no visible Feature is in Hidden state
no activity references a missing Feature, Site, or Location
Pressure and start invariants:
starting Location passes Nexus/Wardheart constraints
starting Nexus Feature exists and is hidden/dormant until discovered
no immediate lethal gate threatens the starting Location
taint and shield values produce survivable Act 0 pressure
gate pressure sources produce coherent nearby clues and threats
Route and control invariants:
travel graph is connected within intended landmasses
blocked routes explain their blockers
claimable Locations have valid control paths
district grouping can be derived from claimed adjacency
route safety uses topology plus pressure, not UI-only labels
Determinism invariants:
same seed, config, production WorldData, and content definitions produce the same
Location facts and Feature placements
feature placement order is stable
tie-breaks use deterministic ids or seeded noise
Runtime Migration Direction
The current prototype has the containers but not the full semantic generator.
Existing useful substrate:
LocationDataalready stores parent id, owner, designation, explored flag, five geography ints, feature ids, building substrate, geometry, neighbours, and area.FeatureDataalready stores location id, template id, name, discovered, cleared, and hostile.LocationandFeaturescopes already exist in.secs.- Feature lifecycle contracts already exist.
- The client already has a Location panel and expanded dossier shell.
Required direction:
1. Extend LocationData for the generated fields in this contract.
2. Extend FeatureData beyond binary discovered/cleared/hostile state.
3. Populate semantic Location facts after interim Voronoi generation now, and
from production WorldData later.
4. Replace random Feature sprinkling with score-and-budget placement.
5. Replace hard-coded Act 0 dossier facts with snapshot-backed facts,
Features, activities, and knowledge state.
6. Fire Feature lifecycle hooks on discovery, interaction, handling, clearing,
securing, and development transitions.
7. Enforce Nexus-gated founding in runtime, not only UI text.
The field names can evolve during implementation, but the architecture must preserve the contract:
numeric generated facts first
derived classes second
Features selected from facts
activities derived from Features and state
effects applied through channels and modifiers
UI reads real state
validation proves the world is coherent