Map Tiles, Fog of War, and Cartography¶
Purpose¶
This file defines the actual map exploration model for the MMO.
Survey expeditions should not only return vague text or route flags. They should produce structured tile knowledge, fog-of-war clearing, and tradable cartography data.
Core Rule¶
The game world should be explored as tile knowledge, not as a fully revealed static map.
Players can:
- reveal tiles for themselves
- record tiles into chart data
- verify old tiles again when they become stale
- share or sell charted tile information if they have enough Cartography skill
That keeps exploration valuable over time and gives Survey expeditions a concrete output.
Map Hierarchy¶
Use three map layers:
1. Region Map¶
This is the planning layer.
- shows major regions, towns, roads, coastlines, and known landmarks
- used for route planning and board browsing
- does not need fine-grained local detail
2. Area Tile Grid¶
This is the main exploration layer.
- the world map is a hex grid — flat-top hexagons, axial coordinates (q, r)
- every hex has a terrain type, movement class, and hidden content layer
- marches travel hex by hex along a chosen path
- fog of war is applied at this layer
- passing through a hex and spending time exploring it produce different levels of knowledge
3. Site Footprint¶
This is the point-of-interest layer.
- ruins, dens, springs, ore seams, and camps occupy one or more hexes
- site footprints can be hidden, partial, discovered, or stale
- a site footprint is only revealed when the hex reaches
exploredstate — not from mere traversal
The authoritative backend stores hex ids and site ids. The client renders them as SVG hex overlays with knowledge-state styling.
Hex Movement Model¶
March parties move hex by hex along a chosen path. The player or the expedition resolver selects a route as a sequence of hexes.
Each hex has a movement_class — road, trail, or wilderness — that overrides the base speed for that hex. Road and trail movement classes represent maintained paths cleared through the terrain; they apply their own speed rather than the underlying terrain's wilderness modifier.
Every hex a march crosses is marked traversed at minimum. If the party stops and performs survey work in a hex, it advances to explored for that player.
For full traversal times by terrain type and the complete movement modifier table (including armor, encumbrance, and cartographer familiarity bonuses), see Tile Types Reference.
Tile Model¶
The map uses a flat-top hex grid with axial coordinates. Each hex stores:
hex_q— axial column coordinatehex_r— axial row coordinate (s = -q - r is derived)terrain_family— plains, forest, marsh, hills, mountain, ocean, lake, riverwater_coverage— 0.0 to 1.0; fraction of the hex covered by a water body. Ocean and lake-deep tiles are 1.0. A river crossing a plains hex might be 0.25–0.45. Fully dry land tiles are 0.0.movement_class— road, trail, wilderness (sets base speed modifier)elevation_bandhazard_tagsvisibility_tagssite_refif present
The following fields are hidden from the player until a hex is explored (not just traversed):
resource_nodes— specific resources present and yield bandscreature_presence— creature types, density, and aggression leveltreasure_flags— buried caches, hidden caches, ruins lootsite_ref(if the site footprint is concealed)drift_score— staleness rate for this hex type
The game does not show hidden fields to the player until the hex is in explored or charted state.
Fog Of War States¶
Each player or guild tracks tile knowledge per hex in the following bands.
unknown¶
- hex is hidden by full fog
- no terrain, no route detail, no site information
rumored¶
- player has heard of this area from NPCs, other players, or low-quality intel
- vague biome type may be shown; no reliable content data
- does not count as survey completion
traversed¶
- a march party passed through this hex without stopping to explore
- player knows: terrain type, movement cost, rough hazard level
- player does not know: resource nodes, creature types, treasure locations, hidden sites
- this is the minimum knowledge gained from any march that crosses a hex
explored¶
- a party spent meaningful time in this hex (survey activity, deliberate exploration)
- player knows: all traversed data plus resource nodes and yield, creature types and density, treasure possibility flags, any concealed site presence
- this is the knowledge tier required for cartography recording and trade
charted¶
- hex has been recorded into a tradable map item or archive entry
- detail level requires
exploredstate as source - includes freshness timestamp and confidence value
- can be shared, sold, or used to fulfill survey contracts
stale¶
- previously charted hex whose data has aged past its drift threshold
- terrain and movement data remain valid; resource, creature, and event data may be outdated
- rendered with desaturated art and a dashed warning border
- re-exploration refreshes to
exploredand re-charting resets the drift clock
Survey Expedition Outputs¶
Survey expeditions should reveal structured tile results instead of only generic knowledge gains.
Typical outputs:
- route strips of revealed tiles
- local clusters around discovered sites
- hazard notes for specific tiles
- site footprints
- freshness and confidence changes on already known tiles
Different survey jobs should reveal different shapes of knowledge:
Route Survey¶
- reveals a corridor of tiles between two known points
- improves route confidence and travel safety
Area Sweep¶
- reveals a tile cluster around a target area
- good for hidden sites, monster dens, and gather spots
Site Verification¶
- refreshes a previously charted site and nearby tiles
- mainly used to fight staleness
Emergency Recon¶
- reveals only urgent risk tiles such as washed roads, bandit routes, plague zones, or monster pressure pockets
- lower detail, higher urgency
Skill Split¶
Exploration should use two distinct but related skills:
Surveying¶
Surveying is about finding, confirming, and traversing.
It improves:
- tile reveal amount
- route confirmation
- hidden site discovery
- confidence on field findings
Cartography¶
Cartography is about recording, packaging, and sharing knowledge.
It improves:
- how many revealed tiles can be saved into map items
- map precision and freshness retention
- hazard notes and annotations
- copy quality when maps are traded or archived
Cartography Threshold Rule¶
The player should not automatically be able to monetize every discovered tile.
Recommended progression:
UntrainedorFamiliar: can personally reveal tiles but cannot create high-quality chart itemsPracticed: can save specific tiles and short route strips into shareable chart dataSkilled: can package contiguous tile clusters and annotate hazards or site notesExpert: can produce cleaner copies, merge reports, and reduce staleness loss on shared mapsMaster: can create highly trusted archive-grade maps with strong precision and long freshness
This is the main reason Cartography should exist as its own skill.
Knowledge Quality Model¶
Every charted tile, route, or site record should carry three distinct values:
confidence: how likely the information is correctfreshness: how recently it was verifiedprecision: how exact the tile bounds, route corridor, or site approach is
Recommended responsibility split:
- Surveying mostly improves discovery confidence and hidden-site confirmation
- Cartography mostly improves recorded precision, annotation depth, and freshness retention
- fast-changing areas such as coasts, monster dens, depleted resource sites, and event zones should lose freshness faster than stable roads or civic tiles
Suggested formulas:
confidence = field_result_quality + surveying_bonus + verification_bonus - hazard_penalty
freshness_loss = base_drift × area_change_rate × event_multiplier × copy_penalty
Map Item Types¶
Use structured cartography goods instead of generic text notes.
tile_snapshot¶
- one tile or a very small cluster
- useful for hazard reports, rare nodes, or contract proof
route_chart¶
- ordered tile corridor between two points
- useful for travel safety and caravan work
map_sheet¶
- contiguous block of charted tiles
- useful for exploration trade and guild archives
site_chart¶
- site footprint plus surrounding approach tiles
- useful for ruins, dens, springs, seams, and seasonal sites
Each cartography item should store:
- tile bounds
- detail level
- confidence rating
- freshness value
- annotations
- creator identity
- secrecy or sharing permissions
Reading or trading a chart should use those values rather than a flat rarity tag. A beautifully recorded but stale map should behave differently from a rough but freshly verified field sketch.
Copy and Lineage Rules¶
A chart item should remember whether it is an original field record or a copy.
- source surveys create generation
0originals - every copy increments
copy_generation - copies can never exceed the source item's confidence, freshness, or precision
- copied annotations should degrade before core tile bounds do
Recommended copy loss by Cartography band:
| Crafter Band | Confidence Loss | Freshness Loss | Annotation Loss |
|---|---|---|---|
| Practiced | 15 |
15 |
loses one detailed annotation layer |
| Skilled | 10 |
10 |
keeps hazards, drops fine notes first |
| Expert | 5 |
5 |
nearly complete copy |
| Master | 2 |
2 |
archive-grade copy |
After generation 3, most map goods should be poor trade stock unless reverified in the field.
Sharing And Trade¶
Cartography data should move through multiple channels:
- direct trade
- guild archives
- expedition group auto-share
- contract attachments
- market sale of map goods where allowed
Important rule:
- personal
revealedknowledge is not automatically public - only
chartedknowledge can become a tradable or shareable object
That keeps exploration and cartography distinct and valuable.
Access and Sharing Permissions¶
Map items and archives should support explicit permission scopes:
privatepartyguildcontract-limitedpublic sale
Rules:
- personal
revealedknowledge stays private until charted into an item or archive record - expedition auto-share should create permissioned chart records, not leak permanent global knowledge
- guild archives store shared copies or deposited originals, depending on guild policy
- contract-limited maps should expire or revoke access when the contract closes if the design wants secrecy to matter
Guild Archive Rules¶
Guild archives should keep both provenance and a usable merged read model.
- every submission should record contributor, submission time, and source generation
- the archive should keep the immutable submitted version plus the current best merged version
- archive permissions should be separable from guild treasury or officer permissions
- archives never refresh automatically; only new survey or verification work updates them
Knowledge Import and Merge Rules¶
Acquiring a map item should update player knowledge without pretending the player personally visited the area.
- high-confidence, fresh charts grant
chartedknowledge - middling charts grant
rumoredknowledge with usable route hints - stale charts import as
stale - bought or copied charts never count as
revealed; only personal travel or survey does
When multiple charts disagree, merge in this order:
- highest freshness
- highest confidence
- highest precision
- newest archive entry as tiebreaker
If two nearby sources conflict within close quality bands, mark the affected tiles or site as disputed and queue them as strong candidates for Site Verification or Route Survey.
Drift And Reverification¶
Map knowledge should not stay perfect forever.
Tiles can become stale because of:
- raids
- storms
- monster migration
- depleted resource sites
- new public works or destroyed roads
- magical or corruption events
Reverification should be a normal reason to run Survey expeditions.
Use tiered drift rates so staleness feels believable.
- stable road and civic tiles: slow drift
- frontier travel corridors and common resource sites: medium drift
- coasts, monster territory, raid-prone roads, and event zones: fast drift
- active crisis or magical anomaly zones: extreme drift until reverified
Any world event that changes roads, resource supply, monster pressure, or town building state should be allowed to write direct freshness loss to nearby tiles.
Client Model¶
The client renders map state as tile knowledge, not as one giant painted image. SvelteKit SVG component reads from the player's tile knowledge store and renders only what is known.
Rendering Architecture¶
The full 160×120 hex grid (19,200 tiles) must not be fully mounted in the SVG DOM. SVG element budget is roughly 3,000 before browser performance degrades. Use 2D viewport culling:
all tile records (plain JS flat array, precomputed px coords)
↓ filter by: pan offset + viewport rect + 2-hex buffer
visible tile set ($derived, ~300–500 tiles at 1080p)
↓ Svelte {#each} keyed by tile id
SVG DOM (only visible tiles mounted)
Pan model: translate the inner <g> group with CSS transform: translate(x, y). No individual tile coordinate changes on pan — only the group transform updates.
Buffer zone: always keep 2 hex rows/cols beyond each viewport edge in the visible set. Prevents pop-in during normal pan speed.
Filter cost: flat array scan with 4 numeric bounds checks per tile. At 19,200 tiles this runs in ~0.1ms — safe on every pointermove.
SVG Layer Stack (back to front)¶
Layer <g> id |
Content | Culled? |
|---|---|---|
#terrain |
hex fill, biome color, terrain props | yes |
#stale-overlay |
hatched overlay on stale and uncertain tiles |
yes |
#fog |
fog fill, opacity by knowledge state | yes |
#sites |
site footprint icons | yes |
#routes |
road and path lines | yes (by bounding box) |
#annotations |
player markers, guild pins, event warnings | no (usually sparse) |
#ui |
tooltip targets, selection ring | no |
Fog Rendering¶
Fog is not a separate image — it is per-tile fills on the #fog layer using the same culled visible tile set.
| Tile knowledge state | Fog fill | Opacity |
|---|---|---|
unknown |
--bg-base solid fill |
100% |
traversed |
--bg-base solid fill |
40% |
surveyed |
none | 0% |
explored |
none | 0% |
stale |
none (stale overlay handles it separately) | 0% |
Map Area Completion Meter¶
Each named map area tracks a chart completion percentage: the fraction of its hexes the player has in surveyed, explored, or charted knowledge state (not traversed or lower).
- Displayed as a compact percentage in the corner of the map view when that area is in focus: "Ashfen: 34% charted"
- Shown on expedition planning screen for any expedition targeting that area
- Updates after each expedition settlement that writes tile knowledge to the area
- 100% completion for an area unlocks a Survey Master recognition entry in the character codex for that area — no mechanical gate, but visible in the character record and on the area map header
Completion counts only tiles the player has personally charted. Knowledge imported from a purchased chart item counts toward the map display but not toward the player's personal completion percentage.
Chunk Loading¶
Server tile data is loaded in area chunks, not individual tiles. Chunk boundary size should match a logical sub-region (e.g. 20×20 hex blocks). Load a chunk when pan brings its nearest edge within 3 hex rows of the current viewport edge. Client caches loaded chunks for the session; never re-request an already-loaded chunk unless explicitly marked stale by a server event.
Server-Gating Rule¶
The server must never send terrain content for tiles the player does not have knowledge of. Client fog is purely presentational — it is not a security boundary.
The API response for a tile chunk must be filtered server-side by the requesting player's character_tile_knowledge records before being serialised:
| Knowledge state | What the server sends |
|---|---|
unknown |
Hex coordinates and state: unknown only. No terrain type, no biome, no content. |
rumored |
Coordinates, state, and vague biome hint only. No terrain props, no site data. |
traversed |
Terrain type and movement class. No hidden content layer. |
surveyed |
Full terrain data. Hidden content layer omitted until explored. |
explored |
Full terrain data including revealed site footprints. |
charted |
Same as explored plus confidence and freshness metadata for cartography use. |
stale |
Last-known data with a stale_since timestamp. Marked as potentially inaccurate. |
A player who inspects their network traffic or modifies client JS must see only the above — no extra fields hidden behind the fog layer. Any terrain or content not in the player's knowledge state is absent from the payload entirely, not merely hidden client-side.
For area maps using the Tiny Swords pack, use the 64×64 terrain grid. Keep fog as its own layer above terrain but below markers and annotations.
The world map route should show:
- known region boundaries
- charted routes
- fogged unexplored area tiles
- player and guild map markers
- event warnings on relevant tile clusters
Browser-Fit Rule¶
Tile discovery should be expedition-driven, not manual one-tile clicking.
The player should review map state from:
- survey result summaries
- route overlays
- chart items
- town board map requests
That keeps exploration compatible with short sessions and async resolution.
Technical Model¶
Core Records¶
Store:
map_areamap_tilecharacter_tile_knowledgetile_snapshotmap_sheetmap_sheet_tilemap_annotationguild_map_archive_entrytile_drift_statemap_item_copy_lineagemap_access_granttile_knowledge_merge_log
Commands¶
Support commands such as:
- start survey expedition
- record tile knowledge from survey result
- create tile snapshot
- assemble map sheet
- consume chart item
- copy chart item
- archive chart
- share chart to group or guild
- merge archive entry
- verify stale map data
Resolution Rules¶
- survey results write
revealedtile knowledge first - cartography conversion writes
charteditems second - stale drift runs independently over time based on tile state and world events
- map item trade references structured tile ids, not freeform text
- using a chart item writes imported knowledge state based on freshness and confidence thresholds
- copying or archiving a chart writes lineage and permission records
- verification can promote
rumoredorstaledata back towardrevealedorcharted - event or drift updates should invalidate route-safety summaries and archive freshness automatically
Related Systems¶
- exploration, cartography, and resource discovery
- expedition types
- market contracts and logistics
- dynamic events and world state
- client and SVG pipeline