Proposal: interactive map elements (Lotus/Summit doors) Γ  la valoplant#109

open1
main
research/valoplant-interactive-doors
openedAug 4, 2026byDDara Adedeji
View on GitHubTwo-way sync enabledPR last imported 1d ago

What this is

Research only β€” no implementation. Adds docs/proposals/interactive-map-elements.md, a design proposal for clickable, stateful map elements requested by users: click a Lotus door to spin it open/closed, click a Summit door to turn it black (dropped), "like valoplant".

Summary

What valoplant does: draws door markers on top of the map art that are directly clickable. Lotus's two rotating doors toggle open/closed with a rotation of the door graphic; Summit's three droppable walls toggle between up and dropped, drawn as a solid dark bar, and their state also feeds valoplant's agent pathing and vision cones.

Proposed Icarus design:

  • lib/const/map_interactables.dart β€” static per-map MapInteractable definitions (id, kind, normalized position/size/angle), same style as Maps constants. Only Lotus and Summit have entries.
  • Per-page state: Map<String, int> interactableStates on StrategyPage (absent = default), serialized through the existing page JSON so Hive, .ica round-trip, and old files work unchanged; version bump, no migration.
  • MapInteractableLayer in interactive_map.dart between the map SVG and PlacedWidgetBuilder, using MouseWatch for hover/tap; AnimatedRotation spin for Lotus, near-black color tween for dropped Summit doors; defense side reuses the existing Transform.flip overlay pattern.
  • Extensions ride existing rails: smoke/Viper Wall fade and Sage Wall segment breaking as additive AbilityVisualState / PlacedAbility fields, toggled via the existing undoable updateVisualState path.
  • Phases: 1) Summit doors, 2) Lotus doors, 3) placed-element states, 4) stretch β€” vision-cone integration and transition animation.

See the doc for file-level details, open questions, and risks.

πŸ€– Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added a research proposal for clickable Lotus and Summit map doors.
    • Documented proposed static interactable definitions, persisted toggle state, undo support, serialization, hover behavior, and animated transitions.
    • Outlined phased implementation considerations, including exports, vision handling, gesture priority, migration, and calibration.
    • Captured potential future support for placed elements such as fading smokes, walls, and breakable Sage Wall segments.

Checks

Some checks failed

Added 1 commit

  • Add proposal for interactive map elements (Lotus/Summit doors)80fe787
Synced from GitHub

Review Change Stack

πŸ“ Walkthrough

Walkthrough

The proposal documents clickable Lotus and Summit map elements. It describes static definitions, persisted undoable state, interactive rendering, future ability-state support, and phased implementation considerations.

Changes

Interactive map elements

Layer / File(s)Summary
Interactive map elements proposal
docs/proposals/interactive-map-elements.md
Documents the current map and persistence architecture, the proposed MapInteractable model, per-page state handling, rendering and interaction behavior, future ability-state extensions, affected areas, implementation phases, and risks.

Estimated code review effort: 1 (Trivial) | ~5 minutes

πŸš₯ Pre-merge checks | βœ… 5
βœ… Passed checks (5 passed)
Check nameStatusExplanation
Description Checkβœ… PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title checkβœ… PassedThe title clearly identifies the interactive map proposal and its Lotus and Summit door scope.
Docstring Coverageβœ… PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues checkβœ… PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkβœ… PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch research/valoplant-interactive-doors

Comment @coderabbitai help to get the list of available commands.

Synced from GitHub

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
1putComment timed out
CcoderabbitaiBotreviewed Β· 2 inline threadsAug 4, 2026
Synced from GitHub

Actionable comments posted: 2

πŸ€– Prompt for all review comments with AI agents
1Verify each finding against current code. Fix only still-valid issues, skip the
2rest with a brief reason, keep changes minimal, and validate.
3
4Inline comments:
5In `@docs/proposals/interactive-map-elements.md`:
6- Around line 119-142: Update the interactable state transition logic in
7InteractableStateProvider.toggle to branch on MapInteractableKind: preserve
8bidirectional closed/open toggling for Lotus, but allow Summit only to
9transition from up to dropped and ignore subsequent clicks. Keep undo behavior
10based on restoring the prior page snapshot rather than permitting a second
11toggle to reopen Summit walls, and update the related Summit descriptions to
12reflect the one-way transition.
13- Around line 44-45: Update the ValoPlant reference in the β€œtoggle-able doors +
14pathing/vision” entry to link the exact Summit announcement post rather than the
15account profile, or explicitly label the described behavior as an assumption if
16the announcement cannot be identified.
πŸͺ„ Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
βš™οΈ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 363d1051-91e2-4b1c-808f-9fb4f8e661d9

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 07c8cb7bda9df66e68f4c1decbcc0c18afcb2df5 and 80fe7873bfde0f6289c4dedf36b16d801bc91d39.

πŸ“’ Files selected for processing (1)
  • docs/proposals/interactive-map-elements.md
……@@ -0,0 +1,251 @@
42+- Summit walls: https://wiki.playvalorant.com/en-us/Summit,
43+ https://www.thespike.gg/valorant/maps/summit
44+- valoplant Summit announcement (toggle-able doors + pathing/vision):
45+ https://x.com/ValoPlant
CcoderabbitaiBoton lines 44–45Aug 4, 2026

πŸ“ Maintainability & Code Quality | 🟑 Minor | ⚑ Quick win

Link the exact ValoPlant announcement.

https://x.com/ValoPlant identifies the account, not the announcement that supports the pathing and vision-cone claim. Link the exact post or mark this behavior as an assumption.

πŸ€– Prompt for AI Agents
1Verify each finding against current code. Fix only still-valid issues, skip the
2rest with a brief reason, keep changes minimal, and validate.
3
4In `@docs/proposals/interactive-map-elements.md` around lines 44 - 45, Update the
5ValoPlant reference in the β€œtoggle-able doors + pathing/vision” entry to link
6the exact Summit announcement post rather than the account profile, or
7explicitly label the described behavior as an assumption if the announcement
8cannot be identified.
docs/proposals/interactive-map-elements.mdlines 119–142Open thread
……@@ -0,0 +1,251 @@
139+ the existing providers so page switching flushes/hydrates it; route
140+ toggles through `actionProvider.notifier.performTransaction` (the same
141+ path `updateVisualState` uses) so door clicks are undoable and mark the
142+ strategy dirty for auto-save.
CcoderabbitaiBoton lines 119–142Aug 4, 2026

🎯 Functional Correctness | 🟠 Major | πŸ—οΈ Heavy lift

Model Summit as a one-way transition.

toggle(String id) permits up β†’ dropped β†’ up, but Line 26 says a dropped Summit wall permanently blocks the route for the rest of the round. Lines 169-174 repeat this contradiction. Current Summit references also describe dropped walls as non-reopenable during the round. (forbes.com)

Define legal transitions per MapInteractableKind: Lotus closed ↔ open; Summit up β†’ dropped. Let undo restore the previous page snapshot, but do not make a second click reopen the wall.

Also applies to: 163-174

πŸ€– Prompt for AI Agents
1Verify each finding against current code. Fix only still-valid issues, skip the
2rest with a brief reason, keep changes minimal, and validate.
3
4In `@docs/proposals/interactive-map-elements.md` around lines 119 - 142, Update
5the interactable state transition logic in InteractableStateProvider.toggle to
6branch on MapInteractableKind: preserve bidirectional closed/open toggling for
7Lotus, but allow Summit only to transition from up to dropped and ignore
8subsequent clicks. Keep undo behavior based on restoring the prior page snapshot
9rather than permitting a second toggle to reopen Summit walls, and update the
10related Summit descriptions to reflect the one-way transition.

Source: MCP tools

Synced from GitHub

Greptile Summary

This documentation change proposes persisted, clickable Lotus and Summit map elements, with per-page door state, editor interaction, export behavior, and future placed-ability extensions.

The proposed editor-only rendering approach would omit door state from screenshots and video exports because those features use a separate ScreenshotView stack. The proposed coordinate handling also mixes full-world positions with an inset map frame, which displaces interactables in both attack and defense views. Finally, bumping the archive version solely for an additive defaulted field would prevent older clients from opening otherwise compatible .ica exports.

T-Rex validation blocked

The focused .ica import-version test could not run because the required dart and flutter tools are unavailable. The archive import guard and page decoder behavior were inspected, but executable confirmation could not be completed.

Confidence Score: 3/5

Do not merge this proposal as implementation guidance until export composition and coordinate-frame handling are corrected.

Direct checks confirmed independent failures in exported-media rendering and coordinate placement, both affecting core map interactions. The archive compatibility concern remains open because its focused runtime test could not start without the Dart and Flutter tools.

Files Needing Attention: docs/proposals/interactive-map-elements.md, especially the persistence/versioning guidance, map-layer positioning guidance, and export-rendering claim.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced a proof for a posted P1 finding and attached a log showing export-stack validation that ScreenshotView does not use InteractiveMap.
  • T-Rex added a coordinate-frame validation script and captured placement and conversion checks for the inset map frame.
  • T-Rex reviewed docs/proposals/interactive-map-elements.md and documented exact results including screenshot_uses_InteractiveMap=False, screenshot_contains_proposed_layer=False, and video_constructs_ScreenshotView=True.
  • T-Rex ran a precise map-coordinate validation showing pre-run misalignment and post-run exact mapping to X=960.000, including notes that the Flutter test command was not found, and that the validation script was used to verify the result.
  • T-Rex examined how StrategyProvider imports and validates version guards, and confirmed decoding behavior for known page properties without requiring a version bump.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (3)

  1. General comment

    P1 Interactive-map-only door layer is omitted from screenshot and video exports

    • Bug
      • The proposal lists lib/interactive_map.dart as the layer insertion point, but PNG captures use the separate ScreenshotView stack and video frames are built from that same ScreenshotView. Neither path composes InteractiveMap, so exported doors/interactable state would be absent.
    • Cause
      • ScreenshotView duplicates the map/overlay/placed-widget/drawing renderer instead of reusing InteractiveMap; VideoExporter._pageView returns ScreenshotView.
    • Fix
      • Add an export-safe interactable layer to ScreenshotView using page-persisted interactable state, and define how it renders during video transition frames; revise lines 179-180 to remove the no-extra-work claim.

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P1 Inset map frame cannot directly consume full-world interactable coordinates

    • Bug
      • docs/proposals/interactive-map-elements.md:155-157 claims that full-world attack-frame coordinates can be positioned in the inset mapLeft/mapWidth layer and flipped there. The executed repro shows that direct placement adds mapLeft on attack and reflects around the inset map width on defense, producing a 290.400-pixel error at 1080px height in both frames.
    • Cause
      • CoordinateSystem.coordinateToScreen maps normalized coordinates into the full 16:9 world (1777.8 Γ— 1000), while the map SVG frame is only 1.24Γ—height and starts at mapLeft. Transform.flip reflects inside the bounds of the widget it wraps; the drawing layer is full-world (Positioned.fill), but the proposed interactable layer is inset (left: mapLeft, width: mapWidth).
    • Fix
      • Either place MapInteractableLayer in a full-world Positioned.fill layer and apply the drawing-layer Transform.flip, or retain the inset map layer but convert each full-world screen coordinate to map-local coordinates by subtracting mapLeft before positioning and document that conversion explicitly.

    T-Rex Ran code and verified through T-Rex

  3. General comment

    P1 Global version bump would reject otherwise forward-compatible .ica exports on older clients

    • Bug
      • Exact comment lines: docs/proposals/interactive-map-elements.md:129-132. Bumping Settings.versionNumber for the new optional StrategyPage.interactableStates field causes any archive exported by the newer build to carry the higher top-level version. An older client rejects that archive before decoding pages, even though its page JSON decoder would ignore the unknown optional field.
    • Cause
      • loadFromFilePath gates all imports on the archive-level version number (importedVersion > Settings.versionNumber) before StrategyPage.listFromJson; the proposed field is additive/defaulted and StrategyPage.fromJson does not validate or reject unknown JSON keys.
    • Fix
      • Do not prescribe a Settings.versionNumber/archive compatibility bump solely because this optional defaulted page field is added. Regenerate/update the Hive adapter as required for local persistence, but reserve the global import gate bump for a change that older clients cannot safely decode or migrate. If a release-wide version bump is mandatory for another reason, document the intentional loss of backward .ica import compatibility.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "Add proposal for interactive map element..." | Re-trigger Greptile

docs/proposals/interactive-map-elements.mdlines 179–180Open thread
……@@ -0,0 +1,251 @@
177+maps stay coherent (DESIGN.md palette).
178+
179+Screenshot and video export render the same stack, so exports show door
180+state with no extra work.
Ggreptile-appsBoton lines 179–180Aug 4, 2026

P1 Exports omit the interactable layer

ScreenshotView builds an independent rendering stack, and video export constructs that view for each frame. Adding MapInteractableLayer only to InteractiveMap therefore leaves exported screenshots and videos without persisted door state. Pass the page's interactableStates into ScreenshotView, render the layer in its export stack, and specify its behavior for transition frames instead of claiming this needs no export work.

Artifacts

Export-stack validation output showing ScreenshotView does not use InteractiveMap

  • Ran the narrow validation from `/home/user/repo`; it shows the independent ScreenshotView stack is used for video and lacks the proposed interactable layer, so InteractiveMap-only work will not export.

Validation script for the interactive-map export stack

  • The executable validation source reads the proposal and renderer wiring, asserts the relevant composition relationships, and prints the observed export-path result.

View artifacts

T-Rex Ran code and verified through T-Rex

docs/proposals/interactive-map-elements.mdlines 130–132Open thread
……@@ -0,0 +1,251 @@
129+- Bump `Settings.versionNumber` and regenerate Hive adapters
130+ (`dart run build_runner build --delete-conflicting-outputs`) since
131+ `StrategyPage` is a Hive model. No data migration needed β€” only a new
132+ optional field with a safe default; .ica export/import go through
Ggreptile-appsBoton lines 130–132Aug 4, 2026

P2 Version bump rejects older clients

The additive field can use a generated Hive-adapter default and tolerant page JSON without a migration, while increasing Settings.versionNumber makes preceding releases reject exported .ica files as too new. Avoid the global version bump unless this feature introduces an actual migration or incompatible archive contract.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

docs/proposals/interactive-map-elements.mdlines 155–157Open thread
……@@ -0,0 +1,251 @@
154+
155+- Positioned with the same `mapLeft`/`mapWidth` frame as the map SVG and
156+ wrapped in the same `Transform.flip` used by the drawing layer, so
157+ attack-frame coordinates work on both sides for free.
Ggreptile-appsBoton lines 155–157Aug 4, 2026

P1 Inset map frame misplaces full-world coordinates

MapInteractable.position is described as using full-world coordinates, but this layer is scoped to the inset mapLeft/mapWidth map rectangle. The drawing layer can reuse its flip because it fills the full world; applying that transform inside the inset layer offsets both attack-side and defense-side positions. Either make this layer full-world too, or convert each world coordinate to map-local coordinates before positioning it.

Artifacts

Coordinate-frame validation script source

  • The authored Python source reads the live map stack markers and validates direct full-world placement versus map-local conversion, with the takeaway that the proposal needs a coordinate-frame conversion or a full-world layer.

Direct full-world placement in the inset map frame

  • This executed `python3 trex-artifacts/interactive-map-elements-coordinate-validation.py --mode before` capture shows the attack and defense positions are each displaced by 290.400 pixels, with the takeaway that direct placement fails.

Map-local conversion in the inset map frame

  • This executed `python3 trex-artifacts/interactive-map-elements-coordinate-validation.py --mode after` capture shows converted map-local placement matches the expected attack and defense positions exactly, with the takeaway that conversion fixes the frame mismatch.

Flutter narrow-validation command unavailable

  • This captured `flutter test trex-artifacts/interactive-map-elements-coordinate-validation_test.dart -r expanded` command exited 127 because Flutter is not installed, with the takeaway that native Dart execution was blocked by the environment.

Existing defense painter widget-test command unavailable

  • This captured existing defense painter widget-test command exited 127 because Flutter is not installed, with the takeaway that the repository widget test could not run in this environment.

View artifacts

T-Rex Ran code and verified through T-Rex