# Combat UI Unit Panel Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Replace the exit-button CombatUI with a bottom-left panel that shows the selected unit's name and HP. **Architecture:** CombatUI listens to the `unit_selected_changed` signal from units in the `"units"` group. On selection, it populates a name label and HP progress bar and shows the panel. On deselection, it hides the panel. **Tech Stack:** Godot 4.6, GDScript, `.tscn` scene files --- ## File Structure | File | Action | Responsibility | |------|--------|----------------| | `prefabs/unit.tscn` | Modify | Add Unit node to `"units"` group | | `scripts/combat_ui.gd` | Create | Script that connects to unit signals, shows/hides panel, populates data | | `prefabs/combat_ui.tscn` | Modify | Remove exit button, add UnitPanel with NameLabel and HPBar, attach new script | --- ### Task 1: Add Unit to the "units" group **Files:** - Modify: `prefabs/unit.tscn` - [ ] **Step 1: Add the group to the Unit scene** In `prefabs/unit.tscn`, add a `groups` property to the root `Unit` node so every instantiated unit is automatically in the `"units"` group. Add this line to the root `[node name="Unit" ...]` block: ``` groups=["units"] ``` The full node line becomes: ``` [node name="Unit" type="Node2D" unique_id=1893234933 groups=["units"]] ``` - [ ] **Step 2: Verify in editor** Open `scenes/combat_test.tscn` in Godot, run the scene (F5), and use the Remote scene tree to confirm the spawned unit node appears under the `"units"` group. - [ ] **Step 3: Commit** ```bash git add prefabs/unit.tscn git commit -m "feat: add Unit to 'units' group for discovery" ``` --- ### Task 2: Create combat_ui.gd script **Files:** - Create: `scripts/combat_ui.gd` - [ ] **Step 1: Write the script** Create `scripts/combat_ui.gd` with the following content: ```gdscript class_name CombatUI extends CanvasLayer @onready var unit_panel: PanelContainer = %UnitPanel @onready var name_label: Label = %NameLabel @onready var hp_bar: ProgressBar = %HPBar func _ready() -> void: unit_panel.visible = false for unit: Unit in get_tree().get_nodes_in_group("units"): unit.unit_selected_changed.connect(_on_unit_selected_changed) func _on_unit_selected_changed(unit: Unit, selected: bool) -> void: if selected: name_label.text = unit.current_info.name hp_bar.max_value = unit.current_stats.max_hp hp_bar.value = unit.current_stats.current_hp unit_panel.visible = true else: unit_panel.visible = false ``` - [ ] **Step 2: Commit** ```bash git add scripts/combat_ui.gd git commit -m "feat: add CombatUI script for unit info panel" ``` --- ### Task 3: Rebuild combat_ui.tscn **Files:** - Modify: `prefabs/combat_ui.tscn` - [ ] **Step 1: Replace the scene file contents** Replace the entire contents of `prefabs/combat_ui.tscn` with: ``` [gd_scene format=3 uid="uid://cy7r0udfcsqbn"] [ext_resource type="Theme" uid="uid://dx26d6py3n8xi" path="res://resources/main_ui_theme.tres" id="1_2ro41"] [ext_resource type="Script" path="res://scripts/combat_ui.gd" id="2_ui_script"] [node name="CombatUI" type="CanvasLayer" unique_id=1093388037] script = ExtResource("2_ui_script") [node name="UnitPanel" type="PanelContainer" parent="." unique_id=2000000001] unique_name_in_owner = true visible = false anchors_preset = 2 anchor_top = 1.0 anchor_bottom = 1.0 offset_left = 8.0 offset_top = -78.0 offset_right = 208.0 offset_bottom = -8.0 grow_vertical = 0 theme = ExtResource("1_2ro41") [node name="MarginContainer" type="MarginContainer" parent="UnitPanel"] layout_mode = 2 theme_override_constants/margin_left = 8 theme_override_constants/margin_top = 8 theme_override_constants/margin_right = 8 theme_override_constants/margin_bottom = 8 [node name="VBoxContainer" type="VBoxContainer" parent="UnitPanel/MarginContainer"] layout_mode = 2 [node name="NameLabel" type="Label" parent="UnitPanel/MarginContainer/VBoxContainer" unique_id=2000000002] unique_name_in_owner = true layout_mode = 2 text = "Unit" [node name="HPBar" type="ProgressBar" parent="UnitPanel/MarginContainer/VBoxContainer" unique_id=2000000003] unique_name_in_owner = true layout_mode = 2 max_value = 100.0 value = 100.0 show_percentage = false ``` Key changes from the old file: - Removed the exit button, its inline GDScript, the VBoxContainer, and the `[connection]` block. - Added the `combat_ui.gd` script as an ext_resource and attached it to the root node. - Added `UnitPanel` (PanelContainer) anchored to bottom-left with 8px margin from edges, 200px wide, ~70px tall. - `NameLabel` and `HPBar` are marked with `unique_name_in_owner = true` so the script can reference them via `%NameLabel` and `%HPBar`. - `UnitPanel` is also unique-named for `%UnitPanel` access. - `show_percentage = false` on HPBar since we just want the bar visual. - [ ] **Step 2: Open in Godot and verify scene tree** Open `prefabs/combat_ui.tscn` in the Godot editor. Confirm: 1. No errors in the Scene dock. 2. The node tree shows: `CombatUI > UnitPanel > MarginContainer > VBoxContainer > NameLabel + HPBar`. 3. The UnitPanel is positioned at the bottom-left of the viewport. - [ ] **Step 3: Commit** ```bash git add prefabs/combat_ui.tscn git commit -m "feat: replace exit button with unit info panel in CombatUI" ``` --- ### Task 4: Integration test — verify end-to-end behavior **Files:** - None (manual verification) - [ ] **Step 1: Run the combat test scene** Run `scenes/combat_test.tscn` (F5 or F6 from the scene). The test map generator spawns a unit named "Putit" with 50 HP. - [ ] **Step 2: Verify panel is hidden on start** Confirm the bottom-left corner is empty — no panel visible. - [ ] **Step 3: Click the unit to select it** Click the "Putit" unit on the map. Confirm: 1. The panel appears in the bottom-left corner. 2. The name label shows "Putit". 3. The HP bar is full (50/50). - [ ] **Step 4: Click an empty tile to deselect** Click an empty floor tile (this moves the unit, but the unit stays selected). Currently, clicking a different unit would deselect the first — since there's only one test unit, verify that selecting the same unit again keeps the panel visible and data correct. - [ ] **Step 5: Verify exit button is gone** Confirm there is no "Exit" button anywhere in the UI. - [ ] **Step 6: Commit (if any tweaks were needed)** ```bash git add -A git commit -m "fix: adjustments from integration testing" ```