From ab0debd0b47d82cae8fa08ba854e3f7157c5b163 Mon Sep 17 00:00:00 2001 From: VinPropane Date: Fri, 29 May 2026 21:32:18 -0400 Subject: [PATCH] NEO-97: fix HUD overlap with vertical stack and larger fonts Replace fixed-height absolute labels with HudRoot VBoxContainer so text expands without overlapping; apply 22/20px theme via prototype_hud_theme. --- client/scenes/main.tscn | 210 ++++++++---------- client/scripts/craft_recipe_panel.gd | 4 + client/scripts/main.gd | 33 ++- client/scripts/prototype_hud_theme.gd | 48 ++++ client/scripts/prototype_hud_theme.gd.uid | 1 + .../scripts/prototype_hud_theme_constants.gd | 15 ++ .../prototype_hud_theme_constants.gd.uid | 1 + 7 files changed, 180 insertions(+), 132 deletions(-) create mode 100644 client/scripts/prototype_hud_theme.gd create mode 100644 client/scripts/prototype_hud_theme.gd.uid create mode 100644 client/scripts/prototype_hud_theme_constants.gd create mode 100644 client/scripts/prototype_hud_theme_constants.gd.uid diff --git a/client/scenes/main.tscn b/client/scenes/main.tscn index 12ca05e..7237929 100644 --- a/client/scenes/main.tscn +++ b/client/scenes/main.tscn @@ -1128,225 +1128,195 @@ anchor_top = 1.0 anchor_right = 1.0 anchor_bottom = 1.0 offset_left = 12.0 -offset_top = -44.0 +offset_top = -56.0 offset_right = -12.0 offset_bottom = -8.0 grow_horizontal = 2 theme_override_colors/font_color = Color(0.95, 0.75, 0.75, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 18 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 22 autowrap_mode = 3 -[node name="PlayerPositionLabel" type="Label" parent="UICanvas" unique_id=9000003] +[node name="HudRoot" type="VBoxContainer" parent="UICanvas" unique_id=9000022] offset_left = 8.0 offset_top = 8.0 -offset_right = 360.0 -offset_bottom = 118.0 -grow_horizontal = 0 -grow_vertical = 0 +offset_right = 664.0 +theme_override_constants/separation = 12 + +[node name="PlayerPositionLabel" type="Label" parent="UICanvas/HudRoot" unique_id=9000003] +layout_mode = 2 +size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.92, 0.95, 0.98, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 18 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 22 +autowrap_mode = 3 text = "x: — y: — z: — srv: —" -[node name="TargetLockLabel" type="Label" parent="UICanvas" unique_id=9000004] -offset_left = 8.0 -offset_top = 122.0 -offset_right = 360.0 -offset_bottom = 306.0 -grow_horizontal = 0 -grow_vertical = 0 +[node name="TargetLockLabel" type="Label" parent="UICanvas/HudRoot" unique_id=9000004] +layout_mode = 2 +size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.86, 0.94, 1, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 18 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 22 +autowrap_mode = 3 text = "Target: — Validity: — Seq: —" -[node name="CastFeedbackLabel" type="Label" parent="UICanvas" unique_id=9000005] -offset_left = 8.0 -offset_top = 318.0 -offset_right = 520.0 -offset_bottom = 372.0 -grow_horizontal = 0 -grow_vertical = 0 +[node name="CastFeedbackLabel" type="Label" parent="UICanvas/HudRoot" unique_id=9000005] +layout_mode = 2 +size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.95, 0.88, 0.72, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 18 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 22 autowrap_mode = 3 text = "Cast: —" -[node name="CombatTargetHpLabel" type="Label" parent="UICanvas" unique_id=9000018] -offset_left = 8.0 -offset_top = 374.0 -offset_right = 520.0 -offset_bottom = 402.0 -grow_horizontal = 0 -grow_vertical = 0 +[node name="CombatTargetHpLabel" type="Label" parent="UICanvas/HudRoot" unique_id=9000018] +layout_mode = 2 +size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.92, 0.78, 0.82, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 18 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 22 autowrap_mode = 3 text = "Target HP: — (Tab → dummy)" -[node name="PlayerCombatHpLabel" type="Label" parent="UICanvas" unique_id=9000019] -offset_left = 8.0 -offset_top = 404.0 -offset_right = 520.0 -offset_bottom = 432.0 -grow_horizontal = 0 -grow_vertical = 0 +[node name="PlayerCombatHpLabel" type="Label" parent="UICanvas/HudRoot" unique_id=9000019] +layout_mode = 2 +size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.82, 0.92, 0.98, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 18 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 22 autowrap_mode = 3 text = "Player HP: —" -[node name="NpcStateLabel" type="Label" parent="UICanvas" unique_id=9000020] -offset_left = 8.0 -offset_top = 434.0 -offset_right = 520.0 -offset_bottom = 472.0 -grow_horizontal = 0 -grow_vertical = 0 +[node name="NpcStateLabel" type="Label" parent="UICanvas/HudRoot" unique_id=9000020] +layout_mode = 2 +size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.88, 0.82, 0.98, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 18 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 22 autowrap_mode = 3 text = "NPC state: —" -[node name="TelegraphLabel" type="Label" parent="UICanvas" unique_id=9000021] -offset_left = 8.0 -offset_top = 474.0 -offset_right = 520.0 -offset_bottom = 502.0 -grow_horizontal = 0 -grow_vertical = 0 +[node name="TelegraphLabel" type="Label" parent="UICanvas/HudRoot" unique_id=9000021] +layout_mode = 2 +size_flags_horizontal = 3 theme_override_colors/font_color = Color(1, 0.72, 0.55, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 18 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 22 autowrap_mode = 3 text = "Telegraph: —" -[node name="GatherFeedbackLabel" type="Label" parent="UICanvas" unique_id=9000008] -offset_left = 8.0 -offset_top = 504.0 -offset_right = 520.0 -offset_bottom = 532.0 -grow_horizontal = 0 -grow_vertical = 0 +[node name="GatherFeedbackLabel" type="Label" parent="UICanvas/HudRoot" unique_id=9000008] +layout_mode = 2 +size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.88, 0.95, 0.72, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 17 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 20 autowrap_mode = 3 text = "Gather: —" -[node name="CraftFeedbackLabel" type="Label" parent="UICanvas" unique_id=9000010] -offset_left = 8.0 -offset_top = 534.0 -offset_right = 520.0 -offset_bottom = 562.0 -grow_horizontal = 0 -grow_vertical = 0 +[node name="CraftFeedbackLabel" type="Label" parent="UICanvas/HudRoot" unique_id=9000010] +layout_mode = 2 +size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.95, 0.82, 0.72, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 17 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 20 autowrap_mode = 3 text = "Craft: —" -[node name="CooldownSlotsLabel" type="Label" parent="UICanvas" unique_id=9000006] -offset_left = 8.0 -offset_top = 564.0 -offset_right = 520.0 -offset_bottom = 642.0 -grow_horizontal = 0 -grow_vertical = 0 +[node name="CooldownSlotsLabel" type="Label" parent="UICanvas/HudRoot" unique_id=9000006] +layout_mode = 2 +size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.78, 0.92, 0.86, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 17 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 20 autowrap_mode = 3 text = "Cooldowns: —" -[node name="EconomyHudSection" type="VBoxContainer" parent="UICanvas" unique_id=9000014] -offset_left = 8.0 -offset_top = 648.0 -offset_right = 520.0 -offset_bottom = 1164.0 -grow_horizontal = 0 -grow_vertical = 0 +[node name="EconomyHudSection" type="VBoxContainer" parent="UICanvas/HudRoot" unique_id=9000014] +layout_mode = 2 +size_flags_horizontal = 3 script = ExtResource("20_economy_hud") -[node name="HeaderRow" type="HBoxContainer" parent="UICanvas/EconomyHudSection" unique_id=9000015] +[node name="HeaderRow" type="HBoxContainer" parent="UICanvas/HudRoot/EconomyHudSection" unique_id=9000015] layout_mode = 2 -[node name="ToggleButton" type="CheckButton" parent="UICanvas/EconomyHudSection/HeaderRow" unique_id=9000016] +[node name="ToggleButton" type="CheckButton" parent="UICanvas/HudRoot/EconomyHudSection/HeaderRow" unique_id=9000016] layout_mode = 2 +theme_override_font_sizes/font_size = 20 text = "Economy HUD" -[node name="Body" type="VBoxContainer" parent="UICanvas/EconomyHudSection" unique_id=9000017] +[node name="Body" type="VBoxContainer" parent="UICanvas/HudRoot/EconomyHudSection" unique_id=9000017] layout_mode = 2 +theme_override_constants/separation = 8 -[node name="InventoryLabel" type="Label" parent="UICanvas/EconomyHudSection/Body" unique_id=9000007] -custom_minimum_size = Vector2(512, 148) +[node name="InventoryLabel" type="Label" parent="UICanvas/HudRoot/EconomyHudSection/Body" unique_id=9000007] +custom_minimum_size = Vector2(656, 0) layout_mode = 2 size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.9, 0.86, 0.98, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 17 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 20 autowrap_mode = 3 text = "Inventory: (refresh: I) Loading…" -[node name="SkillProgressionLabel" type="Label" parent="UICanvas/EconomyHudSection/Body" unique_id=9000009] -custom_minimum_size = Vector2(512, 84) +[node name="SkillProgressionLabel" type="Label" parent="UICanvas/HudRoot/EconomyHudSection/Body" unique_id=9000009] +custom_minimum_size = Vector2(656, 0) layout_mode = 2 size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.82, 0.9, 1, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 17 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 20 autowrap_mode = 3 text = "Skills: Loading…" -[node name="GigXpLabel" type="Label" parent="UICanvas/EconomyHudSection/Body" unique_id=9000018] -custom_minimum_size = Vector2(512, 48) +[node name="GigXpLabel" type="Label" parent="UICanvas/HudRoot/EconomyHudSection/Body" unique_id=9000018] +custom_minimum_size = Vector2(656, 0) layout_mode = 2 size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.88, 0.78, 1, 1) theme_override_colors/font_outline_color = Color(0.08, 0.08, 0.1, 1) -theme_override_constants/outline_size = 6 -theme_override_font_sizes/font_size = 17 +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 20 autowrap_mode = 3 text = "Gig XP: Loading…" -[node name="CraftRecipePanel" type="Control" parent="UICanvas/EconomyHudSection/Body" unique_id=9000011] -custom_minimum_size = Vector2(512, 280) +[node name="CraftRecipePanel" type="Control" parent="UICanvas/HudRoot/EconomyHudSection/Body" unique_id=9000011] +custom_minimum_size = Vector2(656, 320) layout_mode = 2 size_flags_horizontal = 3 script = ExtResource("19_craft_panel") -[node name="ScrollContainer" type="ScrollContainer" parent="UICanvas/EconomyHudSection/Body/CraftRecipePanel" unique_id=9000012] -layout_mode = 0 -offset_right = 512.0 -offset_bottom = 280.0 +[node name="ScrollContainer" type="ScrollContainer" parent="UICanvas/HudRoot/EconomyHudSection/Body/CraftRecipePanel" unique_id=9000012] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 -[node name="VBoxContainer" type="VBoxContainer" parent="UICanvas/EconomyHudSection/Body/CraftRecipePanel/ScrollContainer" unique_id=9000013] +[node name="VBoxContainer" type="VBoxContainer" parent="UICanvas/HudRoot/EconomyHudSection/Body/CraftRecipePanel/ScrollContainer" unique_id=9000013] layout_mode = 2 size_flags_horizontal = 3 +theme_override_constants/separation = 8 diff --git a/client/scripts/craft_recipe_panel.gd b/client/scripts/craft_recipe_panel.gd index 8780163..8c6f36e 100644 --- a/client/scripts/craft_recipe_panel.gd +++ b/client/scripts/craft_recipe_panel.gd @@ -2,6 +2,8 @@ extends Control ## NEO-74: scrollable prototype recipe list with per-row Craft buttons. +const PrototypeHudTheme := preload("res://scripts/prototype_hud_theme.gd") + signal craft_requested(recipe_id: String) var _item_defs_client: Node = null @@ -33,9 +35,11 @@ func populate(recipes: Array) -> void: info.size_flags_horizontal = Control.SIZE_EXPAND_FILL info.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART info.text = _format_recipe_line(recipe) + PrototypeHudTheme.apply_to_label(info, false) row.add_child(info) var craft_btn := Button.new() craft_btn.text = "Craft" + PrototypeHudTheme.apply_to_button(craft_btn, false) craft_btn.pressed.connect(_on_craft_pressed.bind(recipe_id)) row.add_child(craft_btn) _vbox.add_child(row) diff --git a/client/scripts/main.gd b/client/scripts/main.gd index c7da57f..4354777 100644 --- a/client/scripts/main.gd +++ b/client/scripts/main.gd @@ -17,7 +17,7 @@ extends Node3D ## Steep ramp: **2 m / 1.5 m** rise/run (~53°) so slope exceeds `Player` `floor_max_angle` (~50°) ## and is not walkable; gentle ramp stays shallower than `NavigationMesh.agent_max_climb`. Steep is ## under `World` only (not nav source geometry). -## Prototype HUD: world `CharacterBody3D` position in `UICanvas/PlayerPositionLabel` +## Prototype HUD: world `CharacterBody3D` position in `UICanvas/HudRoot/PlayerPositionLabel` ## (updated in `_physics_process` so it matches physics ticks). const MOVE_REJECT_MSG_SECONDS: float = 4.0 @@ -46,6 +46,7 @@ const NpcRuntimeClientScript := preload("res://scripts/npc_runtime_client.gd") const PlayerCombatHealthClientScript := preload("res://scripts/player_combat_health_client.gd") const NpcRuntimeHudStateScript := preload("res://scripts/npc_runtime_hud_state.gd") const NpcCombatHudHelpers := preload("res://scripts/npc_combat_hud_helpers.gd") +const PrototypeHudTheme := preload("res://scripts/prototype_hud_theme.gd") const COMBAT_POLL_INTERVAL_SEC: float = 1.0 const COOLDOWN_REASON_ON_CD := "on_cooldown" const DEV_BOOTSTRAP_CAST_ABILITY_ID := "prototype_pulse" @@ -119,18 +120,19 @@ var _dev_pulse_bootstrap_attempted: bool = false @onready var _interactables_root: Node3D = $World/NavigationRegion3D/InteractablesRoot @onready var _radius_preview: Node3D = $World/InteractionMarkers @onready var _move_reject_label: Label = $UICanvas/MoveRejectLabel -@onready var _player_pos_label: Label = $UICanvas/PlayerPositionLabel -@onready var _target_lock_label: Label = $UICanvas/TargetLockLabel -@onready var _cast_feedback_label: Label = $UICanvas/CastFeedbackLabel -@onready var _combat_target_hp_label: Label = $UICanvas/CombatTargetHpLabel -@onready var _player_combat_hp_label: Label = $UICanvas/PlayerCombatHpLabel -@onready var _npc_state_label: Label = $UICanvas/NpcStateLabel -@onready var _telegraph_label: Label = $UICanvas/TelegraphLabel -@onready var _cooldown_slots_label: Label = $UICanvas/CooldownSlotsLabel -@onready var _economy_hud_section: VBoxContainer = $UICanvas/EconomyHudSection +@onready var _hud_root: VBoxContainer = $UICanvas/HudRoot +@onready var _player_pos_label: Label = $UICanvas/HudRoot/PlayerPositionLabel +@onready var _target_lock_label: Label = $UICanvas/HudRoot/TargetLockLabel +@onready var _cast_feedback_label: Label = $UICanvas/HudRoot/CastFeedbackLabel +@onready var _combat_target_hp_label: Label = $UICanvas/HudRoot/CombatTargetHpLabel +@onready var _player_combat_hp_label: Label = $UICanvas/HudRoot/PlayerCombatHpLabel +@onready var _npc_state_label: Label = $UICanvas/HudRoot/NpcStateLabel +@onready var _telegraph_label: Label = $UICanvas/HudRoot/TelegraphLabel +@onready var _cooldown_slots_label: Label = $UICanvas/HudRoot/CooldownSlotsLabel +@onready var _economy_hud_section: VBoxContainer = $UICanvas/HudRoot/EconomyHudSection @onready var _inventory_label: Label = _economy_hud_section.get_node("Body/InventoryLabel") -@onready var _gather_feedback_label: Label = $UICanvas/GatherFeedbackLabel -@onready var _craft_feedback_label: Label = $UICanvas/CraftFeedbackLabel +@onready var _gather_feedback_label: Label = $UICanvas/HudRoot/GatherFeedbackLabel +@onready var _craft_feedback_label: Label = $UICanvas/HudRoot/CraftFeedbackLabel @onready var _skill_progression_label: Label = _economy_hud_section.get_node("Body/SkillProgressionLabel") @onready var _gig_xp_label: Label = _economy_hud_section.get_node("Body/GigXpLabel") @@ -150,6 +152,7 @@ var _skill_progression_label: Label = _economy_hud_section.get_node("Body/SkillP func _ready() -> void: set_physics_process(true) set_process_unhandled_key_input(true) + _apply_prototype_hud_theme() await get_tree().process_frame _dev_obstacle_smoke = get_node_or_null("World/NavigationRegion3D/Obstacle") as Node3D # Runtime load + .call avoids class_name / preload static resolution issues across Godot parses. @@ -285,6 +288,12 @@ func _on_authoritative_position(world: Vector3, apply_as_snap: bool) -> void: ## [code]push_warning[/code] in [code]ability_cast_client.gd[/code]. ## HUD [member _cast_feedback_label] (NEO-28). Deny branches in [code]AbilityCastApi.cs[/code]. ## TODO(E9.M1): catalog + ingest. +func _apply_prototype_hud_theme() -> void: + PrototypeHudTheme.apply_to_label(_move_reject_label, true) + if is_instance_valid(_hud_root): + PrototypeHudTheme.apply_to_hud_root(_hud_root) + + func _on_authoritative_ack_for_hud(world: Vector3) -> void: _last_ack_world = world _have_last_ack = true diff --git a/client/scripts/prototype_hud_theme.gd b/client/scripts/prototype_hud_theme.gd new file mode 100644 index 0000000..38086c1 --- /dev/null +++ b/client/scripts/prototype_hud_theme.gd @@ -0,0 +1,48 @@ +extends RefCounted + +## Applies shared prototype HUD font sizing to scene labels and dynamic craft rows. + +const Constants := preload("res://scripts/prototype_hud_theme_constants.gd") + + +static func apply_to_label(label: Label, primary: bool = true) -> void: + if not is_instance_valid(label): + return + var font_size: int = ( + Constants.FONT_SIZE_PRIMARY if primary else Constants.FONT_SIZE_SECONDARY + ) + label.add_theme_font_size_override("font_size", font_size) + label.add_theme_constant_override("outline_size", Constants.OUTLINE_SIZE) + label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART + label.custom_minimum_size.x = Constants.HUD_STACK_WIDTH + + +static func apply_to_button(button: BaseButton, primary: bool = true) -> void: + if not is_instance_valid(button): + return + var font_size: int = ( + Constants.FONT_SIZE_PRIMARY if primary else Constants.FONT_SIZE_SECONDARY + ) + button.add_theme_font_size_override("font_size", font_size) + + +static func apply_to_hud_root(root: VBoxContainer) -> void: + if not is_instance_valid(root): + return + root.add_theme_constant_override("separation", Constants.STACK_SEPARATION) + for child in root.get_children(): + if child is Label: + var label: Label = child as Label + apply_to_label(label, not Constants.SECONDARY_LABEL_NAMES.has(label.name)) + elif child.name == "EconomyHudSection": + apply_to_economy_section(child) + + +static func apply_to_economy_section(section: Node) -> void: + if not is_instance_valid(section): + return + for label in section.find_children("*", "Label", true, false): + apply_to_label(label as Label, false) + var toggle: Node = section.get_node_or_null("HeaderRow/ToggleButton") + if toggle is BaseButton: + apply_to_button(toggle as BaseButton, false) diff --git a/client/scripts/prototype_hud_theme.gd.uid b/client/scripts/prototype_hud_theme.gd.uid new file mode 100644 index 0000000..2939f47 --- /dev/null +++ b/client/scripts/prototype_hud_theme.gd.uid @@ -0,0 +1 @@ +uid://c8hudthemeapply01 diff --git a/client/scripts/prototype_hud_theme_constants.gd b/client/scripts/prototype_hud_theme_constants.gd new file mode 100644 index 0000000..e0e9912 --- /dev/null +++ b/client/scripts/prototype_hud_theme_constants.gd @@ -0,0 +1,15 @@ +extends RefCounted + +## Prototype HUD typography + stack spacing (NEO-97 readability pass). + +const FONT_SIZE_PRIMARY: int = 22 +const FONT_SIZE_SECONDARY: int = 20 +const OUTLINE_SIZE: int = 8 +const STACK_SEPARATION: int = 12 +const HUD_STACK_WIDTH: float = 656.0 + +const SECONDARY_LABEL_NAMES: Array[StringName] = [ + &"GatherFeedbackLabel", + &"CraftFeedbackLabel", + &"CooldownSlotsLabel", +] diff --git a/client/scripts/prototype_hud_theme_constants.gd.uid b/client/scripts/prototype_hud_theme_constants.gd.uid new file mode 100644 index 0000000..edcf812 --- /dev/null +++ b/client/scripts/prototype_hud_theme_constants.gd.uid @@ -0,0 +1 @@ +uid://c8hudthemeconst01