Skip to content

Broke Fog of war manager to vision manager and fog of war node#43

Merged
rluders merged 27 commits into
rluders:mainfrom
amitnos123:enhancement/vision
May 13, 2025
Merged

Broke Fog of war manager to vision manager and fog of war node#43
rluders merged 27 commits into
rluders:mainfrom
amitnos123:enhancement/vision

Conversation

@amitnos123

@amitnos123 amitnos123 commented Apr 19, 2025

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Introduced a comprehensive vision system with advanced 3D fog of war visualization using real-time shader rendering.
    • Added a dedicated fog of war scene and manager with customizable fog appearance and debug visualization controls.
    • Implemented a new resource class to manage unit vision data, synchronizing sight indicators and minimap visuals.
  • Improvements

    • Unified and simplified unit vision data management for efficient updates and improved minimap integration.
    • Enhanced minimap to leverage vision data directly for accurate, responsive unit visibility.
    • Exposed public methods for accessing vision data and fog textures, boosting extensibility.
  • Refactor

    • Replaced legacy fog of war manager with a streamlined vision-based architecture and updated scene structure.
    • Updated demo scenes to incorporate the new vision and fog of war systems.
    • Removed outdated fog of war shaders and resources, introducing a generic blur shader for vision effects.

@coderabbitai

coderabbitai Bot commented Apr 19, 2025

Copy link
Copy Markdown

Walkthrough

This update introduces a new fog of war visualization system for a Godot-based RTS framework, centering around a new FogOfWarManager script and scene, and a refactored VisionManager. The fog of war rendering is now handled by a dedicated mesh instance with a custom shader, and vision data for units is encapsulated in a new UnitVisionData resource. The minimap and vision management systems are updated to interact with this new architecture, removing direct shader parameter manipulation from the vision logic and consolidating unit vision state. Obsolete shader and manager files are removed, and the demo scene is restructured to use the new components.

Changes

File(s) Change Summary
addons/rts_framework/features/vision/fog_of_war.gd, addons/rts_framework/features/vision/fog_of_war.tscn Introduced a new FogOfWarManager script and scene for 3D fog of war rendering, exposing properties for vision integration, shader parameters, and debug options. The scene uses a quad mesh and custom shader material for fog visualization.
addons/rts_framework/features/vision/fog_of_war_manager.gdshader, addons/rts_framework/features/vision/fog_of_war_manager.gdshader.uid Removed the old canvas item blur shader and its UID, deprecating the previous fog of war shader resource.
addons/rts_framework/features/vision/minimap.gd Refactored minimap to depend on VisionManager instead of FogOfWarManager, using new vision data structures for unit mapping and fog texture retrieval. Simplified internal state and mapping logic.
addons/rts_framework/features/vision/unit_vision_data.gd, addons/rts_framework/features/vision/unit_vision_data.gd.uid Added a new UnitVisionData resource class to encapsulate per-unit vision and visual data, with property accessors, position syncing, and cleanup logic.
addons/rts_framework/features/vision/vision_manager.gd, addons/rts_framework/features/vision/vision_manager.gd.uid Refactored VisionManager to use the new UnitVisionData abstraction, removed direct shader parameter manipulation, consolidated internal data structures, and added methods for exposing vision data and fog textures.
addons/rts_framework/features/vision/vision_manager.tscn Renamed and refactored the scene from FogOfWarManager to VisionManager, removed fog-specific resources, and added a new blur shader and material as sub-resources. Updated node structure and exported properties.
demo/game.tscn Updated the demo scene to replace the old fog of war manager with the new VisionManager and FogOfWar nodes, updated minimap integration, and removed obsolete nodes and resources.

Sequence Diagram(s)

sequenceDiagram
    participant GameScene
    participant VisionManager
    participant FogOfWarManager
    participant UnitVisionData
    participant Minimap

    GameScene->>VisionManager: Initialize and set up vision parameters
    GameScene->>FogOfWarManager: Initialize and link to VisionManager
    VisionManager->>UnitVisionData: Create/Update per-unit vision data
    FogOfWarManager->>VisionManager: Request fog texture
    VisionManager-->>FogOfWarManager: Provide fog texture for rendering
    Minimap->>VisionManager: Request vision data and fog texture
    VisionManager-->>Minimap: Provide vision data and fog texture
    Minimap->>UnitVisionData: Access unit minimap circle info
Loading

Possibly related PRs

  • rluders/rts-framework#35: Adds an initial Minimap implementation relying on the older FogOfWarManager. This PR refactors minimap integration to use the new VisionManager and updated vision data structures, replacing and superseding the concepts introduced in PR first version minimap #35.

Suggested reviewers

  • rluders

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 23

🔭 Outside diff range comments (5)
addons/rts_framework/features/vision/unit_vision_data_weak_ref.gd (1)

1-39: 🧹 Nitpick (assertive)

Add class documentation for better code clarity.

This class would benefit from documentation explaining its purpose, usage patterns, and how it fits into the vision system architecture.

+## A weak reference wrapper for UnitVisionData objects.
+##
+## This class provides safe access to UnitVisionData properties without maintaining
+## a strong reference that would prevent garbage collection. It's used by systems
+## that need to reference vision data without owning it.
extends WeakRef
class_name UnitVisionDataWeakRef
demo/game.tscn (1)

137-141: 🧹 Nitpick (assertive)

Scene‑hard reference duplicates the VisionManager path

Both the FogOfWar and the Minimap serialise a NodePath to ../RTSController/VisionManager.
If the hierarchy changes you must fix two places. Consider exporting the property as a Node reference in each script and assign it via the editor’s “Node” picker – this keeps the correct reference even after moving nodes.

addons/rts_framework/features/vision/vision_manager.gd (3)

22-29: 🧹 Nitpick (assertive)

value vs map_mesh_node – possible slip & missing null‑checks
Inside the setter you rely on the parameter value (value.mesh.size) instead of the already‑assigned map_mesh_node. This is OK but makes the code harder to read and may throw if value.mesh is null.
Recommend replacing with the assigned field and adding a guard for value.mesh == null:

if value and value.mesh:
-    fog_size = value.mesh.size
+    fog_size = value.mesh.size

A quick early‑return would make it even clearer.


30-39: ⚠️ Potential issue

fog_size getter returns a Vector3 but the property is declared Vector2i
map_mesh_node.mesh.size yields a Vector3. Converting a 3‑component vector to a Vector2i silently drops the Z component, which may not be the intent and can break tooling relying on a 2‑D size.
Either:

  1. Return only the X/Z components explicitly (Vector2i(size.x, size.z)), or
  2. Promote fog_size itself to Vector3i if height ever matters.
    Failing to reconcile the types will surface as editor warnings or subtle bugs.

89-104: 🛠️ Refactor suggestion

Dictionary mutated while iterating – will raise at runtime
for mapped_unit in _unit_to_vision_data: iterates over the dictionary keys, yet _cleanup_mapping calls erase, mutating the very dictionary mid‑loop. In Godot 4 this throws: "Dictionary was modified during iteration".
Fix by iterating over a copy:

-for mapped_unit in _unit_to_vision_data:
+# Make a snapshot to avoid 'modified during iteration' errors
+for mapped_unit in _unit_to_vision_data.keys():
     if not mapped_unit in units_synced:
         _cleanup_mapping(mapped_unit)
♻️ Duplicate comments (1)
addons/rts_framework/features/vision/fog_of_war.gd (1)

36-46: Identical problem for debug properties

debug_texture_view and debug_texture_view_size inherit the two issues above (recursion + missing material_override check). Refactor accordingly.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e5dd632 and e2651d5.

📒 Files selected for processing (15)
  • addons/rts_framework/features/vision/fog_of_war.gd (1 hunks)
  • addons/rts_framework/features/vision/fog_of_war.tscn (1 hunks)
  • addons/rts_framework/features/vision/fog_of_war_manager.gdshader (0 hunks)
  • addons/rts_framework/features/vision/fog_of_war_manager.gdshader.uid (0 hunks)
  • addons/rts_framework/features/vision/fog_of_war_manager.tscn (0 hunks)
  • addons/rts_framework/features/vision/minimap.gd (2 hunks)
  • addons/rts_framework/features/vision/minimap.tscn (3 hunks)
  • addons/rts_framework/features/vision/unit_vision_data.gd (1 hunks)
  • addons/rts_framework/features/vision/unit_vision_data.gd.uid (1 hunks)
  • addons/rts_framework/features/vision/unit_vision_data_weak_ref.gd (1 hunks)
  • addons/rts_framework/features/vision/unit_vision_data_weak_ref.gd.uid (1 hunks)
  • addons/rts_framework/features/vision/vision_manager.gd (6 hunks)
  • addons/rts_framework/features/vision/vision_manager.gd.uid (1 hunks)
  • addons/rts_framework/features/vision/vision_manager.tscn (1 hunks)
  • demo/game.tscn (6 hunks)
💤 Files with no reviewable changes (3)
  • addons/rts_framework/features/vision/fog_of_war_manager.gdshader.uid
  • addons/rts_framework/features/vision/fog_of_war_manager.gdshader
  • addons/rts_framework/features/vision/fog_of_war_manager.tscn
🧰 Additional context used
🧠 Learnings (1)
addons/rts_framework/features/vision/minimap.gd (1)
Learnt from: amitnos123
PR: rluders/rts-framework#35
File: addons/rts_framework/features/vision/minimap.gd:40-53
Timestamp: 2025-04-04T19:36:28.105Z
Learning: The minimap implementation in addons/rts_framework/features/vision/minimap.gd has been tested with over 100 units and performed well without noticeable performance issues.
🔇 Additional comments (18)
addons/rts_framework/features/vision/vision_manager.tscn (4)

6-35: Shader implementation looks good

The blur shader implementation is well structured with appropriate uniforms for customization. The ability to toggle between screen texture and node texture sampling provides good flexibility.


90-98: Check for potential sizing issue with BlurrOverlay

The BlurrOverlay has offset_right and offset_bottom values of -100.0, making it smaller than its parent viewport. This might be intentional, but verify that this won't cause any rendering issues with the blur effect at the edges.


100-101:

Details

✅ Verification successful

VisibilityField may need additional configuration

The VisibilityField Area3D node is added but doesn't have any collision shapes or specific configuration. Ensure that the VisionManager script properly configures this node for detecting visibility changes.


🏁 Script executed:

#!/bin/bash
# Check how VisibilityField is configured in the VisionManager script
rg -A 5 -B 2 "VisibilityField" --type gdscript

Length of output: 79


I’m not seeing any references to VisibilityField in scripts due to the gdscript type error. Let’s search both the scene and any GDScript files directly:


🏁 Script executed:

#!/bin/bash
# Search for VisibilityField in the scene file
rg -n "VisibilityField" -g "*.tscn"
# Search for any references in GDScript files
rg -n "VisibilityField" -g "*.gd"

Length of output: 481


🏁 Script executed:

#!/bin/bash
# Inspect how visibility_shape_3d is created and configured in VisionManager
rg -A 10 -B 10 "visibility_shape_3d" -g "addons/rts_framework/features/vision/vision_manager.gd"

Length of output: 4849


VisibilityField is configured at runtime in VisionManager
The VisionManager.gd script dynamically instantiates the VisibilityShape3D PackedScene, sets its shape.radius to the unit’s sight range, and adds it as a child of the VisibilityField Area3D node. This ensures the field has the proper collision shape for visibility detection—no additional setup is needed in the TSCN.


80-89:

Details

✅ Verification successful

Verify the purpose of the hidden Revealer node

The Revealer ColorRect is set to be invisible by default. Its purpose isn't immediately clear from the scene structure alone. Make sure its usage is properly documented in the VisionManager script.


🏁 Script executed:

#!/bin/bash
# Check for references to the Revealer node in the codebase
rg -A 2 -B 2 "Revealer" --type gdscript

Length of output: 72


🏁 Script executed:

#!/bin/bash
# Locate the VisionManager script
fd -e gd vision_manager.gd

# Search for any references to the Revealer node across .gd and .tscn files
rg -n 'Revealer' -C3 --glob '*.{gd,tscn}'

Length of output: 2223


The Revealer node’s purpose is already documented in VisionManager.gd
The Revealer ColorRect is tied to the exported revel_fog property, with a clear comment and setter/getter controlling its visibility. No additional documentation is required.

• addons/rts_framework/features/vision/vision_manager.gd@42–47:
– “## Revels the whole fog.” comment
@export var revel_fog setter/getter calling find_child("Revealer")
• addons/rts_framework/features/vision/vision_manager.gd@71:
@onready var _revealer : ColorRect = find_child("Revealer")

addons/rts_framework/features/vision/unit_vision_data_weak_ref.gd.uid (1)

1-2: UID file looks good

This UID file correctly provides a unique identifier for the UnitVisionDataWeakRef resource.

addons/rts_framework/features/vision/vision_manager.gd.uid (1)

1-2: UID file looks good

This UID file correctly provides a unique identifier for the VisionManager script.

addons/rts_framework/features/vision/unit_vision_data.gd.uid (1)

1-1: Resource identifier file looks good.

This UID file provides a stable reference ID for the new UnitVisionData resource class, which is part of the refactored vision system architecture.

addons/rts_framework/features/vision/minimap.tscn (4)

1-1: Scene load steps updated to reflect new components.

The increased load steps count (from 5 to 6) correctly accounts for the new viewport texture resource added to the scene.


13-15: New viewport texture added for fog of war rendering.

This new viewport texture resource is properly configured to reference the SubViewport that will render the fog of war overlay.


45-45: FogOfWarTexture now uses the new viewport texture.

The FogOfWarTexture has been properly connected to the new SubViewport through the ViewportTexture resource, supporting the modular fog of war rendering approach.


51-56: Added SubViewport with black background for fog of war rendering.

This addition properly separates the fog of war rendering into its own viewport, which aligns with the modular design goal of splitting fog of war functionality from vision management.

addons/rts_framework/features/vision/fog_of_war.tscn (1)

1-29: Fog of War implementation uses efficient shader-based approach.

The new FogOfWar scene effectively implements fog of war visualization using a shader-based approach with a MeshInstance3D. Notable aspects:

  1. Uses a custom shader with configurable parameters for appearance
  2. Employs a flipped quad mesh that will render over the game world
  3. Optimizes rendering with disabled shadow casting and appropriate cull margin
  4. Provides debug visualization options

This implementation follows best practices for efficient fog of war rendering in 3D games.

addons/rts_framework/features/vision/unit_vision_data_weak_ref.gd (2)

1-3: Good use of weak references for vision data.

Using WeakRef as a base class is appropriate for managing references to vision data without preventing garbage collection.


37-38: 🧹 Nitpick (assertive)

Add return type annotation to the factory method.

The create method is missing a return type annotation, which would improve code clarity.

-static func create(unit_vision_data : UnitVisionData) -> UnitVisionDataWeakRef:
+static func create(unit_vision_data : UnitVisionData) -> UnitVisionDataWeakRef:
	return weakref(unit_vision_data)

Also consider adding documentation to explain the purpose of this factory method.

Likely an incorrect or invalid review comment.

addons/rts_framework/features/vision/fog_of_war.gd (1)

22-32: Getter/Setter asymmetry for fog_color and outer_margin_for_fade_out

The setters never store value, so the getters will always read from the shader even if material_override is null.
Store the value in a local field and gate the shader call behind a material_override check to avoid Invalid call. Non‑existent function ‘set_shader_parameter’ ....

demo/game.tscn (1)

104-107: fog_size is serialised but script may override it

Confirm that VisionManager does not overwrite fog_size in _ready().
If it does the value saved here is wasted noise in the scene file.

addons/rts_framework/features/vision/vision_manager.gd (2)

126-137: Colour naming swap & parent choice might be inverted
Comment says shroud_circle is a white circle, yet you assign fog_circle_color (dark). The variables look swapped:

shroud_circle.color = fog_circle_color   # probably fow_circle_color?
...
fow_circle.color    = shroud_circle_color

Additionally, fow_circle is added as a sibling of _fog_viewport_container. If the intent is to draw into the fog viewport, use _fog_viewport.add_child(fow_circle); otherwise the circle may not render where you expect.

Would you confirm the intended colour semantics and render parents?


175-187: 🧹 Nitpick (assertive)

get_fog_texture() can be simplified & null‑safe
The method contains two nearly identical branches and may still return null. A concise, safe version:

func get_fog_texture() -> ViewportTexture:
-    var fog_texture_result
-    if combined_viewport:
-        fog_texture_result = combined_viewport.get_texture()
-    else:
-        fog_texture_result = $CombinedViewport.get_texture()
-    if fog_texture_result:
-        return fog_texture_result
-    return null
+    if combined_viewport:
+        return combined_viewport.get_texture()
+    return null

This removes dead code and makes intent clearer.

Likely an incorrect or invalid review comment.

Comment thread addons/rts_framework/features/vision/vision_manager.tscn
Comment thread addons/rts_framework/features/vision/vision_manager.tscn
Comment thread addons/rts_framework/features/vision/unit_vision_data.gd
Comment thread addons/rts_framework/features/vision/unit_vision_data.gd
Comment thread addons/rts_framework/features/vision/unit_vision_data.gd Outdated
Comment thread addons/rts_framework/features/vision/minimap.gd
Comment thread addons/rts_framework/features/vision/minimap.gd Outdated
Comment thread addons/rts_framework/features/vision/vision_manager.gd
Comment thread addons/rts_framework/features/vision/vision_manager.gd Outdated
Comment thread addons/rts_framework/features/vision/vision_manager.gd
@amitnos123 amitnos123 requested a review from rluders April 19, 2025 20:20

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

♻️ Duplicate comments (3)
demo/game.tscn (2)

37-38: Hard‑wired CombinedViewport path is fragile

The texture relies on a node called CombinedViewport existing at the exact relative path.
If someone renames or restructures the VisionManager internals, the reference silently breaks and the material turns black.

Consider exposing the texture from VisionManager via a getter (as you already do with get_fog_texture()) and assign it from script instead of serialising a NodePath.


110-110: skeleton still points to a non‑Skeleton3D node

MeshInstance3D.skeleton expects a Skeleton3D, but the path is ../RTSController (a plain Node).
At runtime this spams warnings and disables GPU skinning.

Either clear the property or reference an actual Skeleton3D.

addons/rts_framework/features/vision/minimap.gd (1)

13-13: Initialise _vision_data to an empty dictionary

The variable is declared but not given a default value.
Accessing it from other scripts before _ready() would yield null and crash on iteration.

-var _vision_data : Dictionary
+var _vision_data : Dictionary = {} # Dictionary<BaseEntity, UnitVisionData>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2651d5 and 3ea9fde.

📒 Files selected for processing (5)
  • addons/rts_framework/features/vision/fog_of_war.gd (1 hunks)
  • addons/rts_framework/features/vision/minimap.gd (2 hunks)
  • addons/rts_framework/features/vision/unit_vision_data.gd (1 hunks)
  • addons/rts_framework/features/vision/vision_manager.gd (6 hunks)
  • demo/game.tscn (6 hunks)
🧰 Additional context used
🧠 Learnings (4)
addons/rts_framework/features/vision/minimap.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#35
File: addons/rts_framework/features/vision/minimap.gd:40-53
Timestamp: 2025-04-04T19:36:28.105Z
Learning: The minimap implementation in addons/rts_framework/features/vision/minimap.gd has been tested with over 100 units and performed well without noticeable performance issues.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:11-15
Timestamp: 2025-04-19T19:15:02.215Z
Learning: In the RTS Framework, the `_vision_data` in `minimap.gd` stores direct references to `UnitVisionData` objects, not weak references. It should be initialized as an empty dictionary to prevent null access.
addons/rts_framework/features/vision/unit_vision_data.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/unit_vision_data.gd:4-9
Timestamp: 2025-04-19T19:24:21.696Z
Learning: In Godot, classes that extend Resource cannot use @export annotations for their properties, unlike classes that extend Node.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:138-147
Timestamp: 2025-04-19T19:18:47.550Z
Learning: UnitVisionData is a Resource class that automatically cleans up its associated nodes (fow_circle, shroud_circle, minimap_circle, shape_3d) when deleted by implementing the _notification method with NOTIFICATION_PREDELETE.
addons/rts_framework/features/vision/vision_manager.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:138-147
Timestamp: 2025-04-19T19:18:47.550Z
Learning: UnitVisionData is a Resource class that automatically cleans up its associated nodes (fow_circle, shroud_circle, minimap_circle, shape_3d) when deleted by implementing the _notification method with NOTIFICATION_PREDELETE.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:18-21
Timestamp: 2025-04-19T19:42:33.849Z
Learning: In the VisionManager class, `texture_units_per_world_unit` is a central parameter that other nodes read from directly, rather than being updated through setter propagation. This acts as a single source of truth for pixel-to-world unit conversion.
addons/rts_framework/features/vision/fog_of_war.gd (1)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/fog_of_war.gd:55-59
Timestamp: 2025-04-19T19:12:10.486Z
Learning: In Godot, `await` requires a signal or coroutine as its target. To wait for a node to be ready, use `await node_reference.ready` instead of `await node_reference`.
🔇 Additional comments (2)
addons/rts_framework/features/vision/unit_vision_data.gd (1)

129-145: Local vs. global position for shape_3d

shape_3d.position sets the local translation relative to its parent.
If the shape is not parented directly under the world root, its position will drift from the unit when the hierarchy moves.

Prefer global_position (or global_transform.origin) to keep the collider aligned in world space:

-    if shape_3d:
-        shape_3d.position = unit_pos_3d
+    if shape_3d:
+        shape_3d.global_position = unit_pos_3d
addons/rts_framework/features/vision/vision_manager.gd (1)

128-136: Colours swapped between shroud and fog circles

The comment says shroud_circle should be white and fow_circle grey, but the assignments are reversed.

-    shroud_circle.color = fog_circle_color # Set color
+    shroud_circle.color = shroud_circle_color
 ...
-    fow_circle.color = shroud_circle_color
+    fow_circle.color = fog_circle_color

Comment thread demo/game.tscn Outdated
Comment thread addons/rts_framework/features/vision/fog_of_war.gd
Comment thread addons/rts_framework/features/vision/fog_of_war.gd
Comment thread addons/rts_framework/features/vision/unit_vision_data.gd Outdated
Comment thread addons/rts_framework/features/vision/vision_manager.gd
Comment thread addons/rts_framework/features/vision/vision_manager.gd
Comment thread addons/rts_framework/features/vision/vision_manager.gd

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🔭 Outside diff range comments (2)
addons/rts_framework/features/vision/vision_manager.gd (2)

26-33: ⚠️ Potential issue

Infinite recursion in map_mesh_node setter – crashes on first assignment

The setter assigns to map_mesh_node inside the setter, which calls itself again and causes a stack overflow.

-var map_mesh_node : MeshInstance3D:
-	set(value):
-		map_mesh_node = value
+var _map_mesh_node : MeshInstance3D
+@export var map_mesh_node : MeshInstance3D:
+	set(value):
+		_map_mesh_node = value
+		if _map_mesh_node and _map_mesh_node.mesh:
+			fog_size = _map_mesh_node.mesh.size
+	get:
+		return _map_mesh_node

34-44: ⚠️ Potential issue

fog_size setter also self‑recurses

The same pattern appears here. Introduce a backing field to break the recursive loop.

-var fog_size : Vector2i = DEFAULT_SIZE:
-	set(value):
-		var map_effective_size = value * texture_units_per_world_unit
-		find_child("CombinedViewport").size = map_effective_size
-		fog_size = value
+var _fog_size : Vector2i = DEFAULT_SIZE
+@export var fog_size : Vector2i = DEFAULT_SIZE:
+	set(value):
+		_fog_size = value
+		var map_effective_size = _fog_size * texture_units_per_world_unit
+		find_child("CombinedViewport").size = map_effective_size
 	get:
-		if map_mesh_node:
-			if map_mesh_node.mesh:
-				return map_mesh_node.mesh.size
-		return fog_size
+		if map_mesh_node and map_mesh_node.mesh:
+			return map_mesh_node.mesh.size
+		return _fog_size
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3ea9fde and 2d96fc4.

📒 Files selected for processing (3)
  • addons/rts_framework/features/vision/fog_of_war.gd (1 hunks)
  • addons/rts_framework/features/vision/unit_vision_data.gd (1 hunks)
  • addons/rts_framework/features/vision/vision_manager.gd (6 hunks)
🧰 Additional context used
🧠 Learnings (3)
addons/rts_framework/features/vision/fog_of_war.gd (1)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/fog_of_war.gd:55-59
Timestamp: 2025-04-19T19:12:10.486Z
Learning: In Godot, `await` requires a signal or coroutine as its target. To wait for a node to be ready, use `await node_reference.ready` instead of `await node_reference`.
addons/rts_framework/features/vision/unit_vision_data.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/unit_vision_data.gd:4-9
Timestamp: 2025-04-19T19:24:21.696Z
Learning: In Godot, classes that extend Resource cannot use @export annotations for their properties, unlike classes that extend Node.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:138-147
Timestamp: 2025-04-19T19:18:47.550Z
Learning: UnitVisionData is a Resource class that automatically cleans up its associated nodes (fow_circle, shroud_circle, minimap_circle, shape_3d) when deleted by implementing the _notification method with NOTIFICATION_PREDELETE.
addons/rts_framework/features/vision/vision_manager.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:138-147
Timestamp: 2025-04-19T19:18:47.550Z
Learning: UnitVisionData is a Resource class that automatically cleans up its associated nodes (fow_circle, shroud_circle, minimap_circle, shape_3d) when deleted by implementing the _notification method with NOTIFICATION_PREDELETE.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:18-21
Timestamp: 2025-04-19T19:42:33.849Z
Learning: In the VisionManager class, `texture_units_per_world_unit` is a central parameter that other nodes read from directly, rather than being updated through setter propagation. This acts as a single source of truth for pixel-to-world unit conversion.
🔇 Additional comments (1)
addons/rts_framework/features/vision/vision_manager.gd (1)

132-145: Possible wrong parent for fow_circle – verify viewport capture

_fog_viewport_container.add_sibling(fow_circle) places the circle outside the fog SubViewport hierarchy, meaning it may never be rendered into the fog texture.

If the intent is to draw both circles into the same viewport, add the second circle to _fog_viewport instead:

-	_fog_viewport_container.add_sibling(fow_circle)
+	_fog_viewport.add_child(fow_circle)

Please confirm that the current node graph still produces the desired texture; otherwise visual artefacts will appear.

Comment thread addons/rts_framework/features/vision/fog_of_war.gd
Comment thread addons/rts_framework/features/vision/fog_of_war.gd
Comment thread addons/rts_framework/features/vision/unit_vision_data.gd
Comment thread addons/rts_framework/features/vision/unit_vision_data.gd
Comment thread addons/rts_framework/features/vision/vision_manager.gd

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (2)
addons/rts_framework/features/vision/vision_manager.gd (2)

27-33: 🛠️ Refactor suggestion

Infinite recursion in map_mesh_node setter

Assigning to map_mesh_node inside its own setter re‑enters the setter and crashes with a stack‑overflow.

-var map_mesh_node : MeshInstance3D:
-	set(value):
-		map_mesh_node = value            # <- recursive
+var _map_mesh_node : MeshInstance3D
+@export var map_mesh_node : MeshInstance3D:
+	set(value):
+		_map_mesh_node = value
+		if _map_mesh_node and _map_mesh_node.mesh:
+			fog_size = _map_mesh_node.mesh.size
 	get:
-		if map_mesh_node:
-			if map_mesh_node.mesh:
-				fog_size = value.mesh.size
+		return _map_mesh_node

34-43: ⚠️ Potential issue

fog_size setter has the same recursion bug

fog_size = value inside the setter calls itself endlessly.
Introduce a backing field (e.g., _fog_size) or convert the property to a plain field if you don’t need custom logic on assignment.

♻️ Duplicate comments (1)
addons/rts_framework/features/vision/unit_vision_data.gd (1)

102-103: Remove the no‑op setter to make position truly read‑only

Leaving an empty setter silently discards assignments and can mislead future maintainers into thinking the value is writable.
Delete the set block entirely so the API clearly communicates that position is read‑only.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d96fc4 and 57f70bd.

📒 Files selected for processing (3)
  • addons/rts_framework/features/vision/fog_of_war.gd (1 hunks)
  • addons/rts_framework/features/vision/unit_vision_data.gd (1 hunks)
  • addons/rts_framework/features/vision/vision_manager.gd (6 hunks)
🧰 Additional context used
🧠 Learnings (3)
addons/rts_framework/features/vision/fog_of_war.gd (1)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/fog_of_war.gd:55-59
Timestamp: 2025-04-19T19:12:10.486Z
Learning: In Godot, `await` requires a signal or coroutine as its target. To wait for a node to be ready, use `await node_reference.ready` instead of `await node_reference`.
addons/rts_framework/features/vision/vision_manager.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:138-147
Timestamp: 2025-04-19T19:18:47.550Z
Learning: UnitVisionData is a Resource class that automatically cleans up its associated nodes (fow_circle, shroud_circle, minimap_circle, shape_3d) when deleted by implementing the _notification method with NOTIFICATION_PREDELETE.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:18-21
Timestamp: 2025-04-19T19:42:33.849Z
Learning: In the VisionManager class, `texture_units_per_world_unit` is a central parameter that other nodes read from directly, rather than being updated through setter propagation. This acts as a single source of truth for pixel-to-world unit conversion.
addons/rts_framework/features/vision/unit_vision_data.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/unit_vision_data.gd:4-9
Timestamp: 2025-04-19T19:24:21.696Z
Learning: In Godot, classes that extend Resource cannot use @export annotations for their properties, unlike classes that extend Node.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:138-147
Timestamp: 2025-04-19T19:18:47.550Z
Learning: UnitVisionData is a Resource class that automatically cleans up its associated nodes (fow_circle, shroud_circle, minimap_circle, shape_3d) when deleted by implementing the _notification method with NOTIFICATION_PREDELETE.
🔇 Additional comments (2)
addons/rts_framework/features/vision/vision_manager.gd (2)

18-24: Nice fix for the backing‑field recursion issue – the new _texture_units_per_world_unit field prevents the stack overflow that was previously reported.


132-141: Circle colours appear swapped

shroud_circle (the “what units currently see”) is given fog_circle_color, while fow_circle (the faded historical vision) is given shroud_circle_color.
If that’s not intentional, switch the assignments:

-shroud_circle.color = fog_circle_color
+shroud_circle.color = shroud_circle_color

-fow_circle.color = shroud_circle_color
+fow_circle.color = fog_circle_color

Comment thread addons/rts_framework/features/vision/unit_vision_data.gd
Comment thread addons/rts_framework/features/vision/fog_of_war.gd Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57f70bd and 0398535.

📒 Files selected for processing (1)
  • addons/rts_framework/features/vision/fog_of_war.gd (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
addons/rts_framework/features/vision/fog_of_war.gd (1)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/fog_of_war.gd:55-59
Timestamp: 2025-04-19T19:12:10.486Z
Learning: In Godot, `await` requires a signal or coroutine as its target. To wait for a node to be ready, use `await node_reference.ready` instead of `await node_reference`.
🔇 Additional comments (6)
addons/rts_framework/features/vision/fog_of_war.gd (6)

5-15: Well-implemented vision_manager property with proper backing field.

The vision_manager property is correctly implemented with a backing field and appropriate null check in the setter. This prevents the recursion issues highlighted in previous reviews and ensures that operations on the vision manager are safe.


67-76: Good implementation of fog_texture property with backing field.

The fog_texture property correctly implements the backing field pattern as recommended in previous reviews. This ensures the property maintains its value even if the material changes at runtime.


78-85: Proper null-checking in _ready method.

The _ready method now correctly checks if vision_manager is assigned before attempting to await its ready signal, and includes a helpful warning message when it's not assigned. This addresses previous issues with invalid await targets.


87-92: Safe implementation of _apply_fog_texture_from_vision_manager.

The method properly guards against a null _vision_manager reference before attempting to use it, preventing potential crashes at runtime.


19-26: Fixed recursive assignment in texture_units_per_world_unit property.

The property now correctly uses a backing field (_texture_units_per_world_unit) to store the value, preventing the infinite recursion that would occur when assigning to the property within its own setter.


20-20: 🧹 Nitpick (assertive)

Redundant default value assignment in property declaration.

The property declaration assigns the same default value (2) that's already set in the backing field. One of these assignments can be removed to avoid redundancy.

-@export_range(1, 10000, 1,"suffix:px/length") var texture_units_per_world_unit : int = 2 : # px/length
+@export_range(1, 10000, 1,"suffix:px/length") var texture_units_per_world_unit : int : # px/length

Likely an incorrect or invalid review comment.

Comment thread addons/rts_framework/features/vision/fog_of_war.gd
Comment thread addons/rts_framework/features/vision/fog_of_war.gd Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (5)
addons/rts_framework/features/vision/vision_manager.tscn (2)

48-53: Fixed viewport size hard‑codes the resolution
The 500×500 CombinedViewport repeats the configurability concern raised earlier. Expose width/height as exported variables or derive them from fog_size to support different map sizes and aspect ratios.


77-79: EditorOnlyCircle still visible in builds

Previous review suggested hiding or removing this helper outside the editor. No runtime guard was added here.
Wrap its visibility in if not Engine.is_editor_hint(): … hide() inside vision_manager.gd.

demo/game.tscn (2)

111-111: MeshInstance3D skeleton set to non‑Skeleton node – this issue was flagged before and still persists. Remove the property or point it to an actual Skeleton3D to avoid warnings and fallback to CPU skinning.


37-49: ⚠️ Potential issue

ViewportTexture path is wrong – fog will render black

CombinedViewport lives inside RTSController/VisionManager, but the ViewportTexture_fqft5 (and the mirror at lines 51‑53) points to CombinedViewport at the scene root, so the shader will sample an empty viewport.

-viewport_path = NodePath("CombinedViewport")
+viewport_path = NodePath("../RTSController/VisionManager/CombinedViewport")

Apply the same fix to ViewportTexture_ri1tv.

addons/rts_framework/features/vision/minimap.gd (1)

11-14: Initialise _vision_data to avoid null access

_vision_data is declared but uninitialised until _ready().
Any script that queries the minimap earlier will hit null.

-var _vision_data : Dictionary
+var _vision_data : Dictionary = {}      # Dictionary<BaseEntity, UnitVisionData>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a74ac1 and 13de27f.

📒 Files selected for processing (3)
  • addons/rts_framework/features/vision/minimap.gd (2 hunks)
  • addons/rts_framework/features/vision/vision_manager.tscn (3 hunks)
  • demo/game.tscn (6 hunks)
🧰 Additional context used
🧠 Learnings (1)
addons/rts_framework/features/vision/minimap.gd (1)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:11-15
Timestamp: 2025-04-19T19:15:02.215Z
Learning: In the RTS Framework, the `_vision_data` in `minimap.gd` stores direct references to `UnitVisionData` objects, not weak references. It should be initialized as an empty dictionary to prevent null access.

Comment thread addons/rts_framework/features/vision/vision_manager.tscn
Comment thread addons/rts_framework/features/vision/vision_manager.tscn
Comment thread addons/rts_framework/features/vision/minimap.gd

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (1)
addons/rts_framework/features/vision/minimap.gd (1)

85-93: 🛠️ Refactor suggestion

Gracefully handle missing CombinedViewport to avoid orphaned nodes

draw_node_on_minimap() returns false when _minimap_viewport is missing, yet the caller always proceeds to store the circle in UnitVisionData.
This leaves a live DynamicCircle2D in memory that will never be drawn and is hard to clean up.

func draw_node_on_minimap(draw_node : CanvasItem) -> bool:
    if _minimap_viewport:
        _minimap_viewport.add_child(draw_node)
        return true
-    return false
+
+    draw_node.queue_free() # Prevent leakage
+    push_error("CombinedViewport not found; minimap circle discarded for '" + name + "'.")
+    return false

(Also a tiny typo: the doc-string header says “Addes” → “Adds”.)

♻️ Duplicate comments (1)
addons/rts_framework/features/vision/minimap.gd (1)

11-14: ⚠️ Potential issue

Eagerly initialise _vision_data to prevent null-dereference races

_physics_process() assumes _vision_data is never null (for unit in _vision_data) yet the variable is only assigned in _ready().
Although Godot guarantees _ready runs before the first _physics_process, other scripts can legitimately access this class before _ready fires (e.g. via SceneTree look-ups); they would hit a fatal “attempt to iterate on a null instance” error.

-var _vision_data : Dictionary
+var _vision_data : Dictionary = {} # Dictionary<BaseEntity, UnitVisionData>

This mirrors the pattern we discussed in the last PR and provides immediate, safe default state.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 13de27f and aa9f3e3.

📒 Files selected for processing (1)
  • addons/rts_framework/features/vision/minimap.gd (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
addons/rts_framework/features/vision/minimap.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#35
File: addons/rts_framework/features/vision/minimap.gd:40-53
Timestamp: 2025-04-04T19:36:28.105Z
Learning: The minimap implementation in addons/rts_framework/features/vision/minimap.gd has been tested with over 100 units and performed well without noticeable performance issues.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:11-15
Timestamp: 2025-04-19T19:15:02.215Z
Learning: In the RTS Framework, the `_vision_data` in `minimap.gd` stores direct references to `UnitVisionData` objects, not weak references. It should be initialized as an empty dictionary to prevent null access.

Comment thread addons/rts_framework/features/vision/minimap.gd Outdated
Comment thread addons/rts_framework/features/vision/minimap.gd Outdated
@amitnos123

Copy link
Copy Markdown
Collaborator Author

@rluders I implemented both

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (2)
addons/rts_framework/features/vision/minimap.gd (2)

11-14: 🧹 Nitpick (assertive)

Initialize _vision_data eagerly and document its content

_vision_data is declared without a default value.
Because it is accessed by several helper methods before every frame, it is safer to start with an empty dictionary and document the expected key/value types.

-var _vision_data : Dictionary
+var _vision_data : Dictionary = {} # Dictionary<BaseEntity, UnitVisionData>

This prevents accidental null dereferences should another script poke the minimap before _ready() finishes loading.


81-84: 🧹 Nitpick (assertive)

Apply the same world-to-minimap scale used elsewhere

The circle radius is currently set in world units. On a typical 200-px-wide minimap a 30-metre sight range becomes a 30-pixel circle, often dwarfing the map.

Consider scaling by the engine-wide texture_units_per_world_unit (or another dedicated constant) so the minimap remains legible:

var pixels_per_unit := vision_manager.texture_units_per_world_unit
minimap_circle.radius = unit.get_sight_range() * pixels_per_unit

(or clamp to a fixed radius if that suits your UX better).

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa9f3e3 and 9f09b63.

📒 Files selected for processing (2)
  • addons/rts_framework/features/vision/minimap.gd (2 hunks)
  • addons/rts_framework/features/vision/vision_manager.gd (6 hunks)
🧰 Additional context used
🧠 Learnings (2)
addons/rts_framework/features/vision/vision_manager.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:138-147
Timestamp: 2025-04-19T19:18:47.579Z
Learning: UnitVisionData is a Resource class that automatically cleans up its associated nodes (fow_circle, shroud_circle, minimap_circle, shape_3d) when deleted by implementing the _notification method with NOTIFICATION_PREDELETE.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:18-21
Timestamp: 2025-04-19T19:42:33.892Z
Learning: In the VisionManager class, `texture_units_per_world_unit` is a central parameter that other nodes read from directly, rather than being updated through setter propagation. This acts as a single source of truth for pixel-to-world unit conversion.
addons/rts_framework/features/vision/minimap.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#35
File: addons/rts_framework/features/vision/minimap.gd:40-53
Timestamp: 2025-04-04T19:36:28.105Z
Learning: The minimap implementation in addons/rts_framework/features/vision/minimap.gd has been tested with over 100 units and performed well without noticeable performance issues.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:11-15
Timestamp: 2025-04-19T19:15:02.240Z
Learning: In the RTS Framework, the `_vision_data` in `minimap.gd` stores direct references to `UnitVisionData` objects, not weak references. It should be initialized as an empty dictionary to prevent null access.
🔇 Additional comments (1)
addons/rts_framework/features/vision/vision_manager.gd (1)

104-106: Good catch on stale‐mapping cleanup

Switching to keys() and adding the not mapped_unit.is_revealing() clause guarantees that vanished or hidden units are purged in one place, leveraging the UnitVisionData auto-cleanup.

Comment thread addons/rts_framework/features/vision/minimap.gd Outdated
Comment thread addons/rts_framework/features/vision/minimap.gd
Comment thread addons/rts_framework/features/vision/vision_manager.gd Outdated
Comment thread addons/rts_framework/features/vision/vision_manager.gd

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (3)
addons/rts_framework/features/vision/minimap.gd (2)

13-14: ⚠️ Potential issue

Initialize _vision_data to an empty dictionary to avoid null dereferences

_vision_data is declared without a default value, so it is null until _ready() succeeds.
Several code-paths (e.g. _physics_process()) access .keys() on this field and will crash if _ready() bails out early (see lines 44-47).

-var _vision_data : Dictionary
+var _vision_data : Dictionary = {} # Dictionary<BaseEntity, UnitVisionData>

82-84: 🧹 Nitpick (assertive)

Sight range is in world units – consider applying the same scale factor used elsewhere

Minimap circles are currently created with a radius equal to the unit’s real sight range (e.g. 30 m ⇒ 30 px).
If your minimap is only a few hundred pixels wide, large sight ranges dominate the view.
Scaling by vision_manager.texture_units_per_world_unit keeps visual proportions consistent with the fog-of-war and 3 D visibility logic.

-            minimap_circle.radius = unit.get_sight_range()
+            minimap_circle.radius = unit.get_sight_range() * vision_manager.texture_units_per_world_unit
addons/rts_framework/features/vision/vision_manager.gd (1)

18-24: Exported property shows “0” in the inspector even though the runtime default is 2

Because texture_units_per_world_unit lacks an initialiser, the inspector serialises a value of 0; newcomers may assume “0 px/length” is valid.
Giving the exported property the same default as the backing field avoids confusion:

-@export_range(1, 10000, 1,"suffix:px/length") var texture_units_per_world_unit : int :
+@export_range(1, 10000, 1,"suffix:px/length") var texture_units_per_world_unit : int = 2 :
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f09b63 and 2c97cf5.

📒 Files selected for processing (2)
  • addons/rts_framework/features/vision/minimap.gd (2 hunks)
  • addons/rts_framework/features/vision/vision_manager.gd (6 hunks)
🧰 Additional context used
🧠 Learnings (2)
addons/rts_framework/features/vision/minimap.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#35
File: addons/rts_framework/features/vision/minimap.gd:40-53
Timestamp: 2025-04-04T19:36:28.105Z
Learning: The minimap implementation in addons/rts_framework/features/vision/minimap.gd has been tested with over 100 units and performed well without noticeable performance issues.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:11-15
Timestamp: 2025-04-19T19:15:02.240Z
Learning: In the RTS Framework, the `_vision_data` in `minimap.gd` stores direct references to `UnitVisionData` objects, not weak references. It should be initialized as an empty dictionary to prevent null access.
addons/rts_framework/features/vision/vision_manager.gd (3)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:138-147
Timestamp: 2025-04-19T19:18:47.579Z
Learning: UnitVisionData is a Resource class that automatically cleans up its associated nodes (fow_circle, shroud_circle, minimap_circle, shape_3d) when deleted by implementing the _notification method with NOTIFICATION_PREDELETE.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:18-21
Timestamp: 2025-04-19T19:42:33.892Z
Learning: In the VisionManager class, `texture_units_per_world_unit` is a central parameter that other nodes read from directly, rather than being updated through setter propagation. This acts as a single source of truth for pixel-to-world unit conversion.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:175-187
Timestamp: 2025-05-07T18:20:17.897Z
Learning: In VisionManager, the `combined_viewport` property can be null during async loading of nodes or before _ready() completes, so fallback mechanisms should be maintained when accessing it.
🔇 Additional comments (1)
addons/rts_framework/features/vision/minimap.gd (1)

55-60: 🧹 Nitpick (assertive)

Iterate safely when the vision data may mutate during the frame

_vision_data.keys() returns a snapshot, but if VisionManager clears the dictionary between this call and the for loop, unit may no longer exist in _vision_data, causing look-ups in _unit_is_minimap_mapped() to fail.

A tiny defensive tweak:

for unit in _vision_data.keys().duplicate():

(or skip the second membership test by caching the value).

⛔ Skipped due to learnings
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:11-15
Timestamp: 2025-04-19T19:15:02.240Z
Learning: In the RTS Framework, the `_vision_data` in `minimap.gd` stores direct references to `UnitVisionData` objects, not weak references. It should be initialized as an empty dictionary to prevent null access.

Comment thread addons/rts_framework/features/vision/minimap.gd Outdated
Comment thread addons/rts_framework/features/vision/vision_manager.gd
Comment thread addons/rts_framework/features/vision/vision_manager.gd

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
addons/rts_framework/features/vision/minimap.gd (1)

11-14: Initialize _vision_data to an empty dictionary

_vision_data is declared but not initialized. Accessing it from any script that runs before _ready() (e.g. an autoload querying the minimap tree) will raise a null-reference error.

-var _vision_data : Dictionary
+var _vision_data : Dictionary = {} # Dictionary<BaseEntity, UnitVisionData>
addons/rts_framework/features/vision/vision_manager.gd (1)

18-24: Inspector shows 0 while getter returns 2 – consider explicit default

Without an initializer the editor lists texture_units_per_world_unit as 0, which is misleading even though the getter returns the backing value 2.
Setting an explicit default keeps editor & runtime in sync:

-@export_range(1, 10000, 1,"suffix:px/length") var texture_units_per_world_unit : int :
+@export_range(1, 10000, 1,"suffix:px/length") var texture_units_per_world_unit : int = 2 :
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c97cf5 and 926d363.

📒 Files selected for processing (2)
  • addons/rts_framework/features/vision/minimap.gd (2 hunks)
  • addons/rts_framework/features/vision/vision_manager.gd (6 hunks)
🧰 Additional context used
🧠 Learnings (2)
addons/rts_framework/features/vision/vision_manager.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:18-21
Timestamp: 2025-04-19T19:42:33.892Z
Learning: In the VisionManager class, `texture_units_per_world_unit` is a central parameter that other nodes read from directly, rather than being updated through setter propagation. This acts as a single source of truth for pixel-to-world unit conversion.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/vision_manager.gd:175-187
Timestamp: 2025-05-07T18:20:17.897Z
Learning: In VisionManager, the `combined_viewport` property can be null during async loading of nodes or before _ready() completes, so fallback mechanisms should be maintained when accessing it.
addons/rts_framework/features/vision/minimap.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:11-15
Timestamp: 2025-04-19T19:15:02.240Z
Learning: In the RTS Framework, the `_vision_data` in `minimap.gd` stores direct references to `UnitVisionData` objects, not weak references. It should be initialized as an empty dictionary to prevent null access.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:38-47
Timestamp: 2025-05-07T18:32:27.790Z
Learning: In the minimap implementation for the RTS framework, we should disable physics processing with `set_physics_process(false)` when initialization fails (like when vision data is null), rather than adding runtime checks in the `_physics_process()` method, to avoid affecting runtime performance.
🔇 Additional comments (3)
addons/rts_framework/features/vision/minimap.gd (1)

38-48: Graceful fallback logic looks solid

Nice job short-circuiting initialisation when vision_manager fails and disabling physics processing – this avoids per-frame null checks and keeps runtime perf unchanged. 👍

addons/rts_framework/features/vision/vision_manager.gd (2)

104-106: Dictionary-mutation race fixed – good catch

Iterating over _unit_to_vision_data.keys() prevents ERR_CHANGED when the dictionary is pruned during the same pass.
Thanks for hardening this edge-case!


130-139: Colour swap corrected

shroud_circle now uses shroud_circle_color and fow_circle uses fog_circle_color, matching their intended semantics. ✔️

Comment thread addons/rts_framework/features/vision/minimap.gd
Comment thread addons/rts_framework/features/vision/vision_manager.gd

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
addons/rts_framework/features/vision/minimap.gd (1)

11-14: 🛠️ Refactor suggestion

Initialize _vision_data eagerly to avoid null-dereference edge-cases

_vision_data is declared but not initialised until _ready().
Any code path (editor plug-ins, tool scripts, unit tests, or even another node’s _ready) that accesses the minimap before _ready() runs will still see null and crash on the first dictionary call.

-var _vision_data : Dictionary
+var _vision_data : Dictionary = {} # Dictionary<BaseEntity, UnitVisionData>

A zero-cost default removes the hazard without affecting the later assignment from vision_manager.get_vision_data().
(This was raised in earlier reviews but is still outstanding.)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 926d363 and aa66716.

📒 Files selected for processing (1)
  • addons/rts_framework/features/vision/minimap.gd (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
addons/rts_framework/features/vision/minimap.gd (3)
Learnt from: amitnos123
PR: rluders/rts-framework#35
File: addons/rts_framework/features/vision/minimap.gd:40-53
Timestamp: 2025-04-04T19:36:28.105Z
Learning: The minimap implementation in addons/rts_framework/features/vision/minimap.gd has been tested with over 100 units and performed well without noticeable performance issues.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:11-15
Timestamp: 2025-04-19T19:15:02.240Z
Learning: In the RTS Framework, the `_vision_data` in `minimap.gd` stores direct references to `UnitVisionData` objects, not weak references. It should be initialized as an empty dictionary to prevent null access.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:38-47
Timestamp: 2025-05-07T18:32:27.790Z
Learning: In the minimap implementation for the RTS framework, we should disable physics processing with `set_physics_process(false)` when initialization fails (like when vision data is null), rather than adding runtime checks in the `_physics_process()` method, to avoid affecting runtime performance.

Comment thread addons/rts_framework/features/vision/minimap.gd

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
addons/rts_framework/features/vision/minimap.gd (2)

11-14: Initialize _vision_data to an empty dictionary

_vision_data is declared but not initialised.
Any script that tries to access the minimap before _ready() finishes (e.g. an autoload querying Minimap.get_vision_data()) will hit a null reference.

A one-liner keeps the property always valid:

-var _vision_data : Dictionary
+var _vision_data : Dictionary = {} # Dictionary<BaseEntity, UnitVisionData>

85-88: 🧹 Nitpick (assertive)

Map world-space sight range to minimap pixels

Using unit.get_sight_range() as a pixel radius often produces circles larger than the minimap.
If that’s intentional, feel free to ignore; otherwise scale it with vision_manager.texture_units_per_world_unit (which you already have at hand):

-    minimap_circle.radius = unit.get_sight_range()
+    minimap_circle.radius = unit.get_sight_range() * vision_manager.texture_units_per_world_unit
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa66716 and 1e80d81.

📒 Files selected for processing (1)
  • addons/rts_framework/features/vision/minimap.gd (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
addons/rts_framework/features/vision/minimap.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:11-15
Timestamp: 2025-04-19T19:15:02.240Z
Learning: In the RTS Framework, the `_vision_data` in `minimap.gd` stores direct references to `UnitVisionData` objects, not weak references. It should be initialized as an empty dictionary to prevent null access.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:38-47
Timestamp: 2025-05-07T18:32:27.790Z
Learning: In the minimap implementation for the RTS framework, we should disable physics processing with `set_physics_process(false)` when initialization fails (like when vision data is null), rather than adding runtime checks in the `_physics_process()` method, to avoid affecting runtime performance.
🔇 Additional comments (1)
addons/rts_framework/features/vision/minimap.gd (1)

58-64: 🧹 Nitpick (assertive)

Minor micro-optimisation – cache _vision_data.keys()

_vision_data.keys() allocates a new array every frame.
For large armies this shows up in the profiler.

var units := _vision_data.keys()
for unit in units:
    ...

A tiny optimisation, but worth it in tight loops.

⛔ Skipped due to learnings
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:11-15
Timestamp: 2025-04-19T19:15:02.240Z
Learning: In the RTS Framework, the `_vision_data` in `minimap.gd` stores direct references to `UnitVisionData` objects, not weak references. It should be initialized as an empty dictionary to prevent null access.

Comment thread addons/rts_framework/features/vision/minimap.gd
Comment thread addons/rts_framework/features/vision/minimap.gd

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
addons/rts_framework/features/vision/minimap.gd (2)

13-14: Initialize _vision_data to an empty dictionary to avoid early-access null crashes

_vision_data is declared but not initialized until _ready(). Any script that queries the minimap before _ready() (e.g. via autoload, editor tool script, unit test) will still see null and can crash.
This exact concern was raised in a previous review and is still outstanding.

-var _vision_data : Dictionary
+var _vision_data : Dictionary = {} # Dictionary<BaseEntity, UnitVisionData>

86-89: Consider scaling sight-range to minimap pixels

Mapping a 30 m sight range directly to a 30-pixel radius may overflow small minimaps.
If you notice icons dominating the minimap, introduce a conversion constant:

const WORLD_TO_MINIMAP : float = 0.1
minimap_circle.radius = unit.get_sight_range() * WORLD_TO_MINIMAP

You’ve previously mentioned the current visuals are acceptable, so treat this as optional polish.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e80d81 and eb6d812.

📒 Files selected for processing (1)
  • addons/rts_framework/features/vision/minimap.gd (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
addons/rts_framework/features/vision/minimap.gd (2)
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:11-15
Timestamp: 2025-04-19T19:15:02.240Z
Learning: In the RTS Framework, the `_vision_data` in `minimap.gd` stores direct references to `UnitVisionData` objects, not weak references. It should be initialized as an empty dictionary to prevent null access.
Learnt from: amitnos123
PR: rluders/rts-framework#43
File: addons/rts_framework/features/vision/minimap.gd:38-47
Timestamp: 2025-05-07T18:32:27.790Z
Learning: In the minimap implementation for the RTS framework, we should disable physics processing with `set_physics_process(false)` when initialization fails (like when vision data is null), rather than adding runtime checks in the `_physics_process()` method, to avoid affecting runtime performance.
🔇 Additional comments (1)
addons/rts_framework/features/vision/minimap.gd (1)

37-52: Robust early-exit path looks good

Great job converting the missing-dependency guard into a hard shutdown that disables both _physics_process() and _process().
This keeps the node inert in release builds and costs zero per-frame overhead.

Comment thread addons/rts_framework/features/vision/minimap.gd
@amitnos123

Copy link
Copy Markdown
Collaborator Author

@rluders I think it's ready

@rluders rluders merged commit b366628 into rluders:main May 13, 2025
3 checks passed
@amitnos123 amitnos123 deleted the enhancement/vision branch May 13, 2025 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants