Map Scene Overhaul — 2.5D Adventurer Scene

Status: Designed Author: game-designer Created: 2026-04-07 System Index: #15 — Solo Map UI (replaces flat node graph) Depends On: map-system.md, game-state-manager.md, player-resources.md


1. Overview

The Map Scene Overhaul replaces the current flat top-down node graph (solo_map_screen.gd

  • map_visual.gd) with an immersive 2.5D diorama. An adventurer figure stands center-screen holding a map scroll in one hand. The scene is populated with diegetic prop objects that correspond directly to the next available map nodes on the current floor — a cloaked merchant for a shop, a stone altar for a shrine, a campfire for a rest node, and so on. Players interact with the scene in two complementary ways: clicking a prop object directly, or opening the map scroll overlay for the familiar node-graph view. The backpack prop on the adventurer's back opens a build summary panel. The existing map generation logic, node data, and all navigation rules remain unchanged — only the presentation layer is replaced.

2. Player Fantasy

Target MDA Aesthetic: Fantasy + Discovery + Narrative

The player should feel like an adventurer standing at a crossroads, surveying what lies ahead. The scene makes the abstract node graph tangible — instead of clicking a colored icon on a graph, the player sees the silhouette of an armored elite waiting in the shadows, or a merchant's lantern flickering in the mist. The map scroll in-hand reinforces the fiction that the adventurer is actively navigating a dungeon. The backpack prop gives the player a natural, world-grounded reason to review their build. Every interaction feels like a decision made by the character, not a UI menu click.

Self-Determination Theory alignment:

  • Autonomy: multiple interaction paths (direct scene click OR map scroll) preserve choice.
  • Competence: scene props telegraph encounter difficulty (elite silhouette looks dangerous; campfire looks safe), rewarding players who learn the visual language.
  • Relatedness: the adventurer figure and their props create a persistent avatar the player identifies with across runs.

3. Detailed Design

3.1 Scene Layout

The scene is a single Control node rendered over a parallax background, consistent with the existing 1-bit pixel art style.

┌─────────────────────────────────────────────────────────┐
│  [FLOOR / ACT LABEL]           [HP Bar]  [Gold Counter] │
│                                                          │
│                                                          │
│   [PROP A]       [ADVENTURER]        [PROP B]            │
│                   (center)                               │
│              [PROP C]  [PROP D]                          │
│                                                          │
│─────────────────────────────────────────────────────────│
│  Inspect bar: hover text / node description              │
└─────────────────────────────────────────────────────────┘
  • Adventurer figure: always center-screen, slightly below vertical center to leave visual breathing room above.
  • Scene props: positioned left and right of the adventurer in a shallow arc, using fixed anchor positions (up to 4 slots). Positions are defined in assets/data/map_scene_config.tres as offset Vector2 values relative to screen center.
  • Inspect bar: identical panel to the existing hub_screen.gd inspect bar — bottom of screen, hover shows node title + description text.
  • Floor/Act label: top-left, e.g. "Act 1 — Floor 3".
  • HP and Gold: top-right, read from PlayerResources.

3.2 Adventurer Figure

The adventurer is a TextureRect using a dedicated sprite from the Kenney 1-bit pack or a custom composite. The figure has two visible interactive attachment points:

AttachmentSpriteInteraction
Left hand (map scroll)Rolled parchment scrollClick → open Map Scroll overlay
Back (backpack)Travel pack / satchelClick → open Backpack Panel

Both attachments use the same AlphaHitRect + outline shader hover system already established in hub_screen.gd. Hover outline color distinguishes them: map scroll uses gold tint, backpack uses warm brown tint.

The adventurer figure itself is not interactive — only the two attachment props are clickable. Mouse filter on the base figure texture is IGNORE.

3.3 Scene Props — Node Type Mapping

Scene props are TextureRect nodes placed at the available anchor slots. Each prop maps to exactly one map node type. When the player clicks a prop, the system navigates to that node (equivalent to clicking the node on the graph).

Node TypeProp NameVisual Description
combatSkull MarkerWeathered skull on a stake, basic enemy motif
eliteArmored SilhouetteBacklit silhouette of a large armored figure
bossBoss SilhouetteTowering dark silhouette, distinctive per act
shopHooded MerchantCloaked figure with a lantern and pack
restCampfireSmall campfire with ember particle effect
trapTrap GlyphGlowing floor rune or spike trap outline
shrineStone AltarFlat stone slab with glowing carved symbol
templeTemple PillarsTwo stone pillars with elemental glow
hidden_roomHidden DoorPartially-ajar stone door in a wall fragment
eventNotice BoardWooden signpost with a pinned parchment

Each prop has:

  • A default idle state (static sprite).
  • A hover state: outline shader activates, inspect bar shows node title + description (same text as NODE_INFO dictionary in solo_map_screen.gd).
  • A locked state: if the prop corresponds to a node NOT reachable from the player's current position, it is rendered at 40% opacity and is not clickable. This communicates path exclusivity — not every visible prop is accessible on every route.

3.4 Scene Props — Placement Rules

Up to 4 prop slots are available in the scene (left-far, left-near, right-near, right-far). The slot assignment algorithm:

assign_prop_slots(available_nodes: Array[MapNode]) -> Dictionary[int, MapNode]:
    # available_nodes: nodes reachable from the current node (1-4 nodes)
    # returns: slot_index → MapNode

    slots = [LEFT_FAR, LEFT_NEAR, RIGHT_NEAR, RIGHT_FAR]

    # Sort nodes by a canonical order: combat < elite < shop < rest < shrine
    # < temple < hidden_room < event < trap < boss
    # This ensures consistent slot assignment for the same node set.
    sorted_nodes = sort_by_node_priority(available_nodes)

    result = {}
    for i in min(sorted_nodes.size(), slots.size()):
        result[slots[i]] = sorted_nodes[i]
    return result

If fewer than 4 nodes are available, the unused slots remain empty (no prop rendered). If more than 4 nodes are somehow available (map generation edge case), only the first 4 in canonical order are shown as props; the rest remain accessible only via the map scroll overlay.

3.5 Map Scroll Overlay

The map scroll is the entry point to the existing node graph. Clicking the adventurer's scroll hand triggers:

  1. Unroll animation: a parchment TextureRect anchored to the left-hand position tweens its scale.y from 0.0 to 1.0 over 0.25 seconds (Tween.TRANS_BACK, ease_out), then fades in content at alpha 0 → 1 over 0.15 seconds.

  2. Overlay content: the existing MapVisual component renders inside the scroll panel. All existing map node click behavior is preserved exactly. The scroll is a modal overlay — it dims the scene behind it at 60% alpha.

  3. Close: a small "X" button in the scroll's top-right corner, or pressing Escape / UI Cancel input action. Closing plays the reverse animation (reroll).

The scroll overlay does not replace the map — it wraps the existing MapVisual component unchanged. No modifications to map_visual.gd are required for the overlay to function.

3.6 Backpack Panel

Clicking the adventurer's backpack opens a panel showing the player's current build state. This panel is distinct from the map scroll and covers the right-side of the screen as a slide-in drawer.

Panel sections (top to bottom):

SectionContent
Archetype headerArchetype name, icon, passive description
HP / GoldCurrent and max HP, current gold, block if any
RelicsGrid of relic icons with hover tooltips (name + effect)
ConsumablesRow of consumable slots (filled / empty), hover tooltips
Stats summaryDice count, rerolls remaining, manipulations available

The panel is read-only — no actions can be taken from it. It is a reference view only. Clicking anywhere outside the panel, or pressing Escape / UI Cancel, closes it.

Slide-in animation: the panel enters from the right edge, translating offset_right from +400 to 0 over 0.2 seconds (Tween.TRANS_QUART, ease_out). Close is the reverse.

3.7 Interaction Flow

The complete player journey through the Map Scene each floor:

[Arrive at Map Scene]
Scene displays: adventurer + props for next available nodes
Player hover prop → inspect bar shows node type description
Player choice: click prop OR open map scroll
    ├── [Click prop directly]
    │       → confirm_node_selection(node)
    │       → SoloGameManager transitions to the selected node's encounter
    └── [Open map scroll]
            → scroll unroll animation
            → MapVisual renders inside scroll
            → Player clicks node on graph
            → scroll roll-up animation
            → confirm_node_selection(node)
            → SoloGameManager transitions

confirm_node_selection is the single shared path regardless of interaction method. It calls the same select_node(node_index) function defined in the Map System GDD.

3.8 Coexistence with the Existing Map

The existing solo_map_screen.gd and map_visual.gd are not deleted. The new scene wraps them:

  • solo_map_screen.gd is renamed to map_scene.gd and extended with the new adventurer/prop logic.
  • map_visual.gd is used unmodified inside the map scroll overlay.
  • The NODE_INFO dictionary in solo_map_screen.gd is promoted to a shared resource in assets/data/node_info.tres so both the prop inspect text and the scroll overlay tooltips draw from the same source.

The SceneManager route &"map" continues to point to MapScene.tscn (renamed from SoloMap.tscn). No other system changes its scene routing.


4. Edge Cases

CaseResolution
Only 1 available node (linear path)One prop rendered center-screen. Slots 2-4 empty. Scroll still accessible for full map view.
4+ available nodesFirst 4 (canonical sort) shown as props. Remaining nodes accessible only via scroll. A tooltip on the scroll prompts: "More paths available — open map."
Boss node availableBoss prop rendered regardless of canonical sort position — boss always takes the rightmost filled slot (RIGHT_FAR or RIGHT_NEAR).
Hidden room nodeHidden door prop renders at partial opacity (60%) even when reachable, communicating its mysterious nature. Its inspect bar text reads: "Unknown — contents concealed."
Player arrives at a floor with 0 available nodesThis should not occur (map generation guarantees connectivity). If it does, log a warning and fall through to the scroll overlay with an error message: "Path unclear — consult the map."
Backpack panel open while map scroll is also openNot permitted. Opening one closes the other. If the backpack is open and the scroll is clicked, backpack closes first (reverse animation completes), then scroll opens.
Props from a previous floor remain visible during transitionScene props are cleared and rebuilt every time the Map Scene is entered via _ready(). No stale state.
Player has no relics or consumablesBackpack panel sections for relics/consumables show "None" placeholder text. Panel still opens normally.
Screen resolution smaller than panel widthBackpack panel caps at 90% screen width. Relic grid refluxes to 3 columns (from 4).
Prop node is locked (path not reachable)Prop is visible at 40% opacity, not clickable, hover shows: "[Inaccessible] This path diverged earlier." This gives players spatial context for map branching.

5. Dependencies

Upstream (what this system reads from)

SystemDependency TypeInterface
Map SystemHardget_available_nodes(current_node_index) — provides node list for prop generation
Game State ManagerHardconfirm_node_selection(node_index) — scene transition trigger
Player ResourcesHardReads HP, max HP, gold, block for status display
Relic SystemSoftReads active relic list for backpack panel
Consumable DatabaseSoftReads held consumables for backpack panel
Archetype DataSoftReads current archetype name + passive for backpack panel
Audio ManagerSoftPlays SFX for scroll open/close, prop hover, prop select

Downstream (what reads from this system)

SystemDependency TypeInterface
Map Visual (map_visual.gd)HardEmbedded inside scroll overlay, unchanged
Solo Map ScreenHardThis system replaces and wraps it

Contracts

  • This system NEVER modifies map state directly. It calls Map System functions.
  • This system NEVER modifies player state directly. It calls Game State Manager functions.
  • The NODE_INFO data source (assets/data/node_info.tres) is owned by this system and provided to Map Visual for tooltip parity.
  • Prop click and scroll-map click produce identical outcomes — the same select_node call path.

Bidirectional note for Map System GDD

The Map System GDD (map-system.md) lists Solo Map UI as a downstream dependent. This document extends that relationship: the Map Scene now wraps the Map Visual component AND provides a diegetic prop layer on top of the existing map UI. The Map System GDD should be updated to reference this document under its Dependencies section.


6. Tuning Knobs

All values live in assets/data/map_scene_config.tres. None are hardcoded.

KnobDefaultSafe RangeCategoryAffects
prop_slot_positions4 Vector2 offsetsAny screen-space valuesFeelProp spacing and visual balance
locked_prop_opacity0.400.20 – 0.60FeelHow visible inaccessible paths are
hidden_room_prop_opacity0.600.40 – 0.80FeelMystery level of hidden room prop
scroll_unroll_duration0.25s0.15s – 0.50sFeelMap scroll open speed
scroll_reroll_duration0.20s0.10s – 0.40sFeelMap scroll close speed
backpack_slide_duration0.20s0.10s – 0.35sFeelBackpack panel open/close speed
dim_overlay_alpha0.600.40 – 0.80FeelScene dimming when scroll is open
prop_hover_outline_tween_duration0.14s0.08s – 0.25sFeelHover feedback speed (matches hub)
max_props_visible42 – 4GateHow many nodes can be direct-clicked
node_priority_ordercombat, elite, shop, rest, shrine, temple, hidden_room, event, trap, bossReorderableGateWhich nodes get prop slots first

7. Visual and Audio Requirements

7.1 Sprite List Required

All sprites use the 1-bit pixel art style (4-tone greyscale, Kenney pack or custom matching the pack's visual language).

Sprite IDDescriptionSource
adventurer_centerAdventurer standing figure, facing camera 3/4 viewCustom / Kenney character
prop_scrollRolled parchment scroll (map scroll, left hand)Kenney 1-bit
prop_backpackTravel satchel / pack on backKenney 1-bit
prop_skull_markerSkull on a stake (combat)Kenney 1-bit
prop_elite_silhouetteLarge armored figure silhouetteCustom (solid fill)
prop_boss_silhouette_act1Beholder-esque silhouetteCustom
prop_boss_silhouette_act2Kraken tentacle silhouetteCustom
prop_boss_silhouette_act3Demon silhouetteCustom
prop_merchantHooded figure with lanternKenney 1-bit
prop_campfireSmall campfire (static frame)Kenney 1-bit
prop_trap_glyphGlowing rune circleCustom
prop_stone_altarFlat carved altarKenney 1-bit
prop_temple_pillarsTwo stone pillarsKenney 1-bit
prop_hidden_doorSlightly open stone door in wall sectionCustom
prop_event_noticeboardWooden signpost with parchmentKenney 1-bit
scroll_parchment_bgOpen scroll background for overlayKenney 1-bit

Boss silhouettes are per-act variants. The act index from SoloGameManager determines which boss prop sprite is loaded.

7.2 Animations Required

AnimationMethodDescription
Scroll unrollTween (scale.y 0→1)Parchment appearing from rolled state
Scroll rerollTween (scale.y 1→0)Parchment returning to rolled state
Backpack slide openTween (offset_right)Drawer entering from right edge
Backpack slide closeTween (offset_right)Drawer exiting to right edge
Prop hover outlineTween (shader_parameter/outline_alpha)Consistent with hub_screen.gd
Scene dim overlayTween (modulate.a)Behind-scroll scene dimming
Campfire emberAnimatedSprite2D or shaderLooping ember glow on rest prop
Trap glyph pulseShader (sin wave on emission)Slow pulse on trap prop
Temple pillar glowShader (elemental color pulse)Slow color pulse

All animations must be skippable and respect the user's motion preference setting (per ui-code.md rules). When motion is reduced, all tweens use Tween.TRANS_LINEAR at 0.05s duration (effectively instant).

7.3 Audio Requirements

All audio events route through AudioManager using existing SFX enum values or new entries. Required SFX events:

EventTriggerSuggested SFX Category
MAP_SCROLL_OPENScroll unroll beginsPaper / parchment rustle
MAP_SCROLL_CLOSEScroll reroll beginsPaper rustle (shorter)
BACKPACK_OPENBackpack panel slides inLeather creak / buckle
BACKPACK_CLOSEBackpack panel slides outLeather creak (softer)
PROP_HOVERMouse enters any prop hitboxSubtle ambient chime
PROP_SELECTProp clicked (node selected)Weight: boot step or stone scrape
PROP_LOCKEDLocked prop clickedMuted thud / no-entry sound

If SFX assets are unavailable, fall back to existing UI_CLICK and UI_HOVER events from the existing SFX enum. New entries should be added to AudioManager.SFX enum when audio assets are sourced.


8. UI Requirements

8.1 Layout Constraints

  • Scene must be functional at both minimum (1024×600) and maximum (1920×1080) supported resolutions.
  • Prop positions defined as screen-relative anchor offsets, not absolute pixel positions, to support resolution scaling.
  • The backpack panel must not overlap the adventurer figure at any resolution. At resolutions narrower than 1280px, the backpack panel uses a full-screen modal rather than a side drawer.

8.2 Keyboard / Gamepad Support

Per ui-code.md, all interactions must support keyboard and gamepad:

ActionKeyboardGamepad
Cycle through propsTab / Shift+TabD-pad left/right
Select focused propEnterA / Cross
Open map scrollMY / Triangle
Open backpackBX / Square
Close overlay / panelEscapeB / Circle

When a prop has keyboard focus, the outline shader activates (same visual as mouse hover). A small keyboard-focus indicator (pixel-art bracket corners) appears around the focused prop.

8.3 Inspect Bar

Identical implementation to hub_screen.gd's inspect bar:

  • Bottom of screen, full width.
  • Shows node title (bold, gold) and description text (muted warm tone).
  • Default state: "Hover a destination to inspect."
  • Inspect bar text comes from NODE_INFO / node_info.tres.

8.4 HUD Elements

  • Floor / Act label: top-left. Format: "Act [N] — Floor [N]". Reads from SoloGameManager.current_act and SoloGameManager.current_floor.
  • HP bar: top-right, same visual as combat screen HP bar for consistency. Shows current / max HP with color gradient (green → yellow → red).
  • Gold counter: top-right below HP. Coin icon + number. Both HP and gold update reactively via signals from PlayerResources.

9. Acceptance Criteria

Functional Criteria

#CriterionVerification Method
1Props rendered match available nodes from map systemUnit test: mock 3 available nodes of known types, assert 3 props with correct sprites appear
2Clicking a prop triggers the same node selection as clicking the scroll mapIntegration test: click prop, verify select_node called with correct index
3Locked props (unreachable paths) are non-clickable and visually distinctManual test: navigate past a fork, verify the non-taken path's props render at 40% opacity and do not respond to clicks
4Map scroll overlay opens and closes with animationManual test: click scroll, observe unroll animation; click X, observe reroll animation
5Map scroll embeds existing MapVisual component unchangedCode review: MapVisual instantiated inside scroll panel with no modifications
6Backpack panel shows correct relic, consumable, and archetype dataManual test: equip 3 known relics, open backpack, verify all 3 visible with correct names
7Backpack and scroll cannot both be open simultaneouslyManual test: open backpack, click scroll — backpack closes, scroll opens
8Prop slot count never exceeds 4Unit test: mock 6 available nodes, assert only 4 props rendered
9Boss node prop always occupies the rightmost available slotUnit test: mock boss + 2 combat nodes, assert boss prop is in RIGHT_FAR slot
10Floor and Act labels show correct valuesIntegration test: advance to floor 5 act 2, open map scene, verify labels read "Act 2 — Floor 5"
11HP and gold display updates when values changeIntegration test: take damage, verify HP bar updates before next frame
12Keyboard navigation cycles through props and activates selectionManual test: tab through props, press Enter, verify correct node selected

Experiential Criteria (Playtest Validation)

#Target ExperienceValidation Question
E1Player understands they can click props AND use the map scrollAfter 2 sessions with no tutorial, can players navigate using only props without being prompted?
E2Prop visual design communicates encounter danger levelCan 5 out of 5 playtesters correctly rank "safest to most dangerous" prop from visual alone?
E3Backpack panel feels like a natural "check your gear" momentDo playtesters open the backpack unprompted before engaging an elite or boss prop?
E4The scene does not feel slower than the previous flat mapTime-to-node-selection from scene entry is ≤ 8 seconds on average in playtesting
E5Map scroll feels like a safety valve, not the primary methodRatio of direct prop clicks to scroll-then-click is >= 60:40 after the first 3 runs
Built with LogoFlowershow