ItemMapAsset — Maps, Charts, and Compass Navigation
Overview
ItemMapAsset extends ItemAsset and defines passive navigation aid items: maps, charts, and compasses. Unlike most item assets that trigger an active use behavior, map assets are passive — their effects are active as long as the item is present in the player's inventory (or equipped in a specific slot). The asset introduces three independent boolean flags (enablesCompass, enablesChart, enablesMap) that control which HUD navigation overlays are shown.
Multiple map items in the same inventory stack their effects. A player carrying a compass item and a separate chart item sees both the compass heading and the local area chart simultaneously.
Inheritance Chain
Asset
└── ItemAsset
└── ItemMapAssetNo intermediate classes. Map items do not fire projectiles, deal damage, or place structures. They are not equipment in the traditional sense — they are inventory items that modify HUD state by their presence.
The Three HUD Flags
csharp
public bool enablesCompass { get; protected set; }
public bool enablesChart { get; protected set; }
public bool enablesMap { get; protected set; }Each flag is read-only from outside the class, set during PopulateAsset. The flags are independent — an item can enable any subset. The three standard combinations seen in vanilla content:
| Combination | Example Item | Effect |
|---|---|---|
| Compass only | Compass | Heading ribbon at top of screen |
| Chart only | Chart | Local chart overlay showing explored territory |
| Map + Compass + Chart | GPS | Full satellite map, chart, and compass simultaneously |
| Map only | Map | Satellite map overlay, no compass or chart |
| Chart + Compass | — | (theoretically valid, not used in vanilla) |
Compass (enablesCompass)
When true, the compass heading ribbon displays at the top of the screen. The ribbon shows cardinal directions (N, NE, E, SE, S, SW, W, NW) and the player's current facing angle. The compass is a thin horizontal bar with tick marks and direction labels that rotate as the player turns.
The compass overlay is enabled by PlayerLife checking the player's equipped or carried items each frame. If any map asset with enablesCompass = true is found, the compass GameObject is set active.
Chart (enablesChart)
When true, the chart overlay displays an isometric or top-down view of the local area the player has explored. Unexplored territory is hidden until the player physically travels there. The chart shows terrain, roads, structures, and points of interest within the explored radius.
The chart uses a fog-of-war system: each tile the player has stood on or had line-of-sight to is marked as explored. The chart renders only explored tiles. The fog-of-war data is persisted per-player and grows over time as the player explores.
Map (enablesMap)
When true, the full satellite-style map overlay displays. Unlike the chart (which shows only explored territory), the map shows the entire level topography — terrain, water, roads, buildings — regardless of whether the player has visited those areas. The map is a top-down view rendered from the level's satellite data.
The map overlay is typically used with a GPS item. In vanilla, the GPS enables all three flags, giving the player full navigation: compass heading, local chart, and full satellite map simultaneously.
PopulateAsset: Presence-Check Parsing
All three flags use a presence-check pattern rather than reading boolean values:
csharp
public override void PopulateAsset(in PopulateAssetParameters p)
{
base.PopulateAsset(in p);
enablesCompass = p.data.ContainsKey("Enables_Compass");
enablesChart = p.data.ContainsKey("Enables_Chart");
enablesMap = p.data.ContainsKey("Enables_Map");
}This is the same pattern used by ItemKeyAsset.exchangeWithTargetItem. The mere presence of the .dat key sets the flag to true, regardless of any value assigned. This means:
Enables_Compass true→enablesCompass = trueEnables_Compass false→enablesCompass = true(still true!)- Key absent →
enablesCompass = false
Modders cannot disable a flag by writing Enables_Compass false — they must omit the key entirely. This is consistent with vanilla content conventions where flags are typically specified without values.
Runtime HUD Integration
The HUD overlay system is driven by PlayerLife, which iterates the player's inventory each frame to determine which navigation features are active.
Frame-by-Frame Check
Pseudocode for the runtime check:
bool showCompass = false;
bool showChart = false;
bool showMap = false;
foreach (var page in player.inventory.pages)
{
foreach (var slot in page.items)
{
if (slot.item.GetAsset() is ItemMapAsset mapAsset)
{
if (mapAsset.enablesCompass) showCompass = true;
if (mapAsset.enablesChart) showChart = true;
if (mapAsset.enablesMap) showMap = true;
}
}
}
compassUI.SetActive(showCompass);
chartUI.SetActive(showChart);
mapUI.SetActive(showMap);The check is additive: each map item in the inventory contributes its flags to the aggregate state. If ANY item has enablesCompass = true, the compass shows. Each flag is tracked independently.
Equipped vs. Carried
The inventory search looks at all inventory pages, not just the equipped slot. A map item in the backpack functions identically to one in the primary slot. There is no distinction between "equipped GPS" and "GPS in backpack" for navigation purposes.
This differs from many other item types where the item must be in a specific slot to provide its effects. Map items work from anywhere in the inventory.
Flag Stacking
Multiple map items stack. If a player carries:
- A compass item (
enablesCompass = trueonly) - A chart item (
enablesChart = trueonly) - A GPS item (
enablesCompass = true,enablesChart = true,enablesMap = true)
The result: all three HUD elements are active. The GPS alone would suffice, but the individual compass and chart items make no difference because the GPS already enables everything. No conflict arises from overlapping flags.
HUD Overlay GameObjects
Each navigation overlay corresponds to a child GameObject under the player's HUD root. PlayerLife enables/disables these GameObjects based on the flag state:
| Flag | GameObject (typical) | Visual |
|---|---|---|
enablesCompass | Compass | Horizontal heading bar at screen top |
enablesChart | Chart | Isometric or top-down local area view |
enablesMap | Satellite | Full-level satellite overlay |
The GameObjects are pre-instantiated in the HUD prefab. Toggling them is a simple SetActive call, cheap enough to perform every frame.
Compass UI Detail
The compass overlay typically consists of:
- A horizontal strip with tick marks at regular intervals (every 5 or 10 degrees).
- Cardinal direction labels (N, NE, E, SE, S, SW, W, NW) in a larger font.
- A player indicator (triangle or chevron) at the center.
- Optional: marked waypoints showing as colored dots at their bearing.
The compass position is driven by the player's camera yaw. As the player rotates, the tick marks and labels scroll horizontally while the center indicator stays fixed.
Chart UI Detail
The chart overlay renders:
- Explored terrain tiles in desaturated colors (typically browns/greens for land, blue for water).
- Unexplored tiles as black or dark gray.
- The player's position as a dot or arrow.
- Nearby roads, structures, and points of interest within explored territory.
- Optional: marked waypoints as icons.
The chart has a fixed zoom level showing roughly a 200-400 meter radius around the player. The player cannot zoom or scroll the chart from the vanilla UI.
Map UI Detail
The satellite map renders:
- The entire level's terrain from the satellite texture.
- The player's position marker.
- Optional: waypoint markers.
- Optional: group member markers (in multiplayer).
The map may be a full-screen overlay activated by a dedicated map key (default: M) or a minimap corner overlay. The enablesMap flag controls whether the map UI is available; the player still needs to press the map key to view it.
GPS Display Radius
The GPS item in vanilla Unturned displays player position within a certain radius on the map and chart. While ItemMapAsset itself doesn't define a radius field, the GPS radius is typically implemented in the HUD rendering layer or the PlayerLife component:
- On the chart: Player position is shown when the player is within the chart's render radius (explored territory).
- On the map: Player position is always shown when the map is enabled, regardless of distance from the map center.
The concept of "GPS radius" from earlier documentation refers to the player's position indicator being visible to other group members within a certain distance on their maps. This is a multiplayer feature, not an ItemMapAsset property. The map asset only controls whether the HUD elements are active, not who can see the player's position.
Map Item Stacking Priority
When multiple map items exist in the inventory, the flags are combined with OR logic:
finalCompass = item1.enablesCompass || item2.enablesCompass || ...
finalChart = item1.enablesChart || item2.enablesChart || ...
finalMap = item1.enablesMap || item2.enablesMap || ...There is no priority system — if any item enables a flag, that flag is on. This means:
- A compass item (compass only) plus a GPS (all three) = all three active.
- Two compass items = compass active (no duplication effect).
- An item with NO flags set (all three absent from .dat) contributes nothing but still passes the
is ItemMapAssetcheck, wasting a tiny amount of per-frame CPU.
Performance Implication
The per-frame inventory scan for map items is O(n) where n is the total inventory slot count. For a typical player with 50-80 slots, this is negligible. However, the scan runs EVERY frame for EVERY player. In a server with 24 players, that's 24 × 60 fps × 50 slots = 72,000 map asset checks per second. Each check is a simple type comparison (itemAsset is ItemMapAsset) — fast, but worth noting for optimization-conscious server operators.
The scan could be optimized by caching the map state and only re-scanning when the inventory changes, but the vanilla implementation does not do this.
.dat Configuration
Compass Only
ID 58060
ItemName "Compass"
ItemDescription "Shows compass heading."
Rarity Common
Size_X 1
Size_Y 1
Slot None
Enables_CompassChart Only
ID 58061
ItemName "Chart"
ItemDescription "Shows local area chart."
Rarity Common
Size_X 1
Size_Y 1
Slot None
Enables_ChartFull GPS (All Three)
ID 58062
ItemName "GPS"
ItemDescription "Full navigation system."
Rarity Rare
Size_X 2
Size_Y 1
Slot None
Enables_Compass
Enables_Chart
Enables_MapMap + Compass (No Chart)
ID 58063
ItemName "Military GPS"
ItemDescription "Map and compass only."
Rarity Epic
Size_X 2
Size_Y 1
Slot None
Enables_Compass
Enables_MapInteraction with Other Systems
PvP Server Visibility
In PvP servers, map visibility is often restricted. Server plugins or game mode configs can override the HUD GameObjects regardless of the ItemMapAsset flags. The flags only control whether the HUD elements are requested; the final decision rests with the game mode's HUD visibility rules.
Death and Map Items
When a player dies and drops their inventory, any map items dropped stop contributing their flags immediately. The HUD updates on the next frame when the inventory scan finds no map assets. This is visually jarring — the compass and map vanish simultaneously. Game mode configs may implement a grace period or a "persistent navigation" skill that delays the HUD loss.
Storage and Locker Interaction
Map items stored in lockers, crates, or vehicle storage do NOT contribute to HUD flags. Only items in the player's personal inventory pages count. This prevents players from leaving a GPS in a base storage and still benefiting from it.
Cargo Data Export
ItemMapAsset does not override BuildCargoData. It inherits the base ItemAsset cargo export, writing shared item fields (GUID, ID, rarity, size, etc.) to the generic item cargo table. The three navigation flags are not exported to Cargo tables.
Modding Guide
Creating a Navigation Item
Minimum .dat:
ID 58100
ItemName "Navigation Kit"
Rarity Uncommon
Size_X 2
Size_Y 1
Slot None
Enables_Compass
Enables_MapThis creates a 2×1 uncommon item that enables the compass and map HUD elements.
Creating a Hybrid Item
A map item can coexist with other item behaviors — it's still an ItemAsset. The map flags don't preclude the item from having use behaviors, crafting recipes, or trade values. However, ItemMapAsset itself has no Useable class, so using the item from the hotbar does nothing special. If you want a usable map item (e.g., a GPS with a "scan" ability), you need a custom plugin or code mod.
Common Pitfalls
Presence-check gotcha: Writing
Enables_Compass falsein the .dat still enables the compass. To disable, omit the key entirely.Empty map asset: An item with
ItemMapAssetas its asset type but no flags set compiles and loads without error, serves no purpose, but still passes the per-frameis ItemMapAssetcheck, consuming a tiny amount of CPU.Slot assignment: Map items should typically be
Slot Noneso they work from the backpack. Assigning a slot likeSlot Primarymeans the item must be equipped AND the inventory scan finds it anyway — the slot assignment doesn't affect map functionality, but it takes up a weapon slot unnecessarily.Overlapping items: Giving a player both a compass item AND a GPS is redundant for the compass flag. The GPS already provides it. The extra compass item wastes an inventory slot with no benefit.
Chart vs. Map confusion: Charts show ONLY explored territory. Maps show the ENTIRE level. A player with only a chart item cannot see unexplored regions. In PvE, this is a progression mechanic; in PvP, it's a significant tactical disadvantage.
No per-item visibility toggle: Once a map item is in the inventory, its flags are always on. There is no way to "turn off" one GPS while keeping another active — all map items' flags are ORed together. If a player wants to hide their compass temporarily, they must drop all compass-enabled items.
Multiplayer GPS sharing: In multiplayer, group members' positions appear on each other's maps within a configurable radius. This is a server-side feature controlled by game mode config, not by
ItemMapAsset. Modifying the map asset does not change GPS sharing behavior.
HUD Rendering Pipeline
Per-Frame Update Cycle
The map flags are evaluated by PlayerLife every frame as part of the HUD update cycle:
- Frame start:
PlayerLife.Update()executes. - Inventory snapshot: The player's inventory pages are iterated.
- Flag accumulation:
is ItemMapAssetchecks accumulate flag state. - GameObject activation: Each HUD overlay GameObject's
SetActive()is called with the accumulated flag. - Compass update: If the compass is active, the heading ribbon is repositioned based on camera yaw.
- Chart update: If the chart is active, explored tiles near the player are rendered.
- Map update: If the map is active, the satellite overlay texture is positioned.
Compass Rendering Details
The compass heading ribbon is a horizontal UI element positioned at the top-center of the screen. It consists of:
Tick Mark Generation: Tick marks are generated at regular angle intervals (typically every 5 degrees). Each tick is a thin vertical line. Every 45 degrees (cardinal/intercardinal direction), the tick is a larger line with a text label (N, NE, E, SE, S, SW, W, NW).
Scrolling Logic: The compass texture is wider than the screen, and only a portion is visible. The visible portion is determined by the player's camera yaw:
scrollOffset = (cameraYaw / 360.0f) * textureWidth - (screenWidth / 2)As the player rotates, the texture scrolls horizontally, giving the illusion of a rotating compass.
Waypoint Markers: Active waypoints (player-placed or quest markers) show as colored dots on the compass at their bearing relative to the player. The dot color indicates waypoint type (yellow for manual, blue for quest, red for hostile, green for friendly).
Chart Rendering Details
The chart displays explored terrain using a tile-based fog-of-war system:
Exploration Tracking: Each tile in the level has an "explored" flag. When the player stands on a tile or has line-of-sight to it, the flag is set to true. The flag is persisted per-player and grows over time. Tiles adjacent to explored tiles may also be marked as partially explored (dimmed).
Tile Rendering: The chart renders explored tiles in desaturated colors derived from the terrain type:
- Grass: muted green
- Dirt/road: tan/brown
- Water: dark blue
- Buildings: gray outlines
- Unexplored: solid black/dark gray
Render Radius: The chart renders tiles within a fixed radius around the player (typically 200-400 meters). Tiles outside this radius are not rendered, even if explored, to keep the chart localized to the immediate area.
Performance: The chart renderer uses a tile cache. Explored tiles are cached in a texture atlas. When the player moves, only newly explored tiles are rendered into the atlas. The atlas covers a sliding window around the player's position.
Map (Satellite) Rendering Details
The full satellite map renders the entire level at once:
Satellite Texture: The level has a pre-baked satellite texture generated during level compilation. This is a top-down image of the entire terrain with baked lighting, shadows, and structure outlines.
Overlay Positioning: The map overlay is positioned so the player's world position maps to the center of the screen. The texture is scaled based on the map's zoom level (configurable per game mode).
Player Marker: A triangle or arrow icon marks the player's position and facing direction on the map. The icon rotates with the camera yaw.
Group Markers: In multiplayer, group members' positions appear as colored dots or icons on the map. Group member display is gated by:
- The player having a map-enabled item.
- The group member being within the GPS sharing radius.
- The game mode config enabling group position sharing.
Waypoint Icons: Active waypoints display as named icons on the map. Waypoint names are rendered as text labels adjacent to the icon.
Performance Analysis and Optimization
Per-Frame Cost Breakdown
The per-frame cost of map item processing can be broken down:
| Operation | Frequency | Cost |
|---|---|---|
| Inventory scan for map flags | Every frame | ~50-80 type checks (O(n) over slots) |
| GameObject.SetActive (3 GameObjects) | Every frame | Negligible (Unity native call) |
| Compass scroll calculation | Every frame | 2 float operations |
| Chart tile rendering | On new tile explored | Texture blit per tile |
| Map overlay positioning | Every frame | 2 float operations |
| Group member marker updates | Every few frames | O(g) where g = group size |
Total per-frame CPU cost: ~0.01-0.05ms for a typical player. For a server with 24 players at 60fps, the combined cost is ~0.24-1.2ms per frame — well within budget.
Optimization Opportunities
For modders looking to optimize the map system:
Cache flag state: Instead of scanning the entire inventory every frame, cache the flag state and only re-scan when the inventory changes (detected via OnInventoryChanged events). This reduces per-frame cost from O(n) to O(1) for flag checks.
Throttle compass updates: The compass scrolls smoothly, but updating at 60fps may be overkill. Throttling to 30fps halves the per-frame cost with minimal visual impact.
LOD for chart tiles: Far-away explored tiles can render at lower resolution. The chart already limits render radius, but within that radius, tiles can use a mipmap-style LOD where distant tiles are aggregated.
Batch waypoint updates: Group member positions change continuously. Instead of updating each marker every frame, batch all group member position updates into a single UI rebuild cycle every 0.1-0.2 seconds.
Historical Context: Pre-Chart Era
Before the chart system was introduced, navigation was either full map (GPS) or nothing. The chart was added as an intermediate navigation tier:
- No navigation: Player has no idea where they are beyond visible landmarks.
- Chart: Player sees explored territory — they know where they've been.
- Map: Player sees everything — full situational awareness.
The chart filled a gameplay gap: new players with no gear had zero navigation, making the early game disorienting. The chart (common drop, easy craft) gives players a sense of progress as they explore while keeping the full map (rare GPS item) a valuable late-game upgrade.
GPS Sharing Radius and Multiplayer Dynamics
Configurable Radius
The GPS sharing radius is a game mode config value, typically 250-1000 meters. This radius defines how far a group member's position is shared on other members' maps. The radius check is:
distance_to_group_member <= gps_sharing_radiusStrategic Implications
Small radius (100-250m): Group members must stay close to maintain positional awareness. Encourages tight formation, punishes scouting ahead. Used in hardcore/survival modes.
Large radius (500-1000m): Group members can spread across the map while maintaining awareness. Enables coordinated multi-point attacks, split resource gathering. Used in PvP/competitive modes.
Infinite radius: All group members always visible. Removes navigation as a gameplay element — the map is always fully known. Typically only in creative/editor modes.
Dead Player Markers
When a group member dies, their position marker may persist on the map (as a death marker) to help the group locate and revive them. The death marker duration and color are configurable in game mode settings.
.dat Reference Table
ItemMapAsset Complete .dat Schema
| Key | Type | Default | Required | Description |
|---|---|---|---|---|
ID | ushort | — | Yes | Unique item ID |
ItemName | string | — | Yes | Display name |
ItemDescription | string | "" | No | Tooltip description |
Rarity | EItemRarity | Common | No | Item rarity tier |
Size_X | byte | 1 | No | Inventory slot width |
Size_Y | byte | 1 | No | Inventory slot height |
Slot | ESlotType | None | No | Equipment slot (typically None) |
Enables_Compass | presence | absent | No | Presence enables compass HUD |
Enables_Chart | presence | absent | No | Presence enables chart HUD |
Enables_Map | presence | absent | No | Presence enables satellite map HUD |
Presence-Only Key Behavior
All three navigation keys use presence-checking:
Enables_Compass → enablesCompass = true (regardless of value)
Enables_Chart → enablesChart = true (regardless of value)
Enables_Map → enablesMap = true (regardless of value)
(key absent) → respective bool = falseDebugging and Troubleshooting
Symptom: "Compass doesn't appear even with Compass item"
Check:
- Verify
Enables_Compassis present in the item's .dat. - Verify the item is in the player's inventory (not storage, not dropped).
- Verify the game mode config allows compass display (some modes disable it).
- Verify no plugin is hiding the compass HUD.
- Check the Unity GameObject hierarchy — the Compass child may be disabled by another system.
- Verify the HUD canvas is rendering (not hidden by UI state).
Symptom: "Chart shows nothing even in explored areas"
- Verify
Enables_Chartis present in the item's .dat. - Verify the player has actually explored the tiles (standing on them).
- Verify the fog-of-war data is persisting (check server save data).
- Verify chart rendering is enabled in game mode config.
- Check for GPU/driver issues affecting texture rendering.
Symptom: "Map shows the wrong level or is blank"
- Verify the level has a baked satellite texture.
- Verify
Enables_Mapis present. - Verify the player has the map item in inventory.
- The satellite texture is loaded from the level bundle — verify the bundle is intact.
Symptom: "Map/compass keeps flickering on and off"
This indicates the inventory scan is finding the map item on some frames but not others:
- Check if a plugin is rapidly adding/removing items.
- Check if the inventory system is mid-sync with the server.
- Verify no null reference exceptions are being swallowed in the HUD update loop.
Symptom: "GPS sharing shows group members too far away"
The GPS sharing radius is a game mode config value:
- Check the game mode's
GPS_Sharing_Radiussetting. - Verify the group members are actually in the same group.
- Verify the group members have map items in their inventory.
- Some configs require BOTH players to have map items for sharing.
