Skip to content
Abhinav Pradeep edited this page Sep 17, 2026 · 2 revisions

Overview

The hotbar is intended to allow players to maange their weapons and spells, and is independent of the inventory. Opening, closing, or changing inventory pages does not remove it. Inventory page handling remains the responsibility of InventoryDisplay and InventoryActions.

Player controls

Key Weapon Existing weapon type
1 Sword WeaponType.SWORD
2 Knife WeaponType.DAGGER
3 Bow WeaponType.BOW

The sword is selected initially. All three weapons are available immediately; this feature does not add unlocking, pickups, or persistence.

The existing terminal commands use the same selection state:

weapon sword
weapon knife
weapon bow

Number-key presses are consumed by the player input handler, with no corresponding key-release action. The terminal retains input priority, so typing numbers while it is open does not switch weapons. Selection can occur while the inventory book is open.

Component responsibilities

WeaponSelectionComponent

This player component is the shared source of truth for the selected weapon. PlayerFactory attaches it alongside the existing sword, knife, and bow components.

  • equip(WeaponType) enables the requested weapon component and disables the other available weapon components.
  • getSelectedWeapon() returns the selected weapon type.
  • getWeapons() returns a read-only list of item descriptors in hotbar order: sword, knife, bow.
  • Selecting the current weapon is a successful no-op.
  • Null selections or missing weapon components are rejected without changing the current selection.

Switching does not reset the shared weapon cooldown or change combat statistics. The existing weapon components continue to implement attacks.

Input and events

KeyboardPlayerInputComponent maps number keys to weapon types. Both events below are dispatched through the player's existing event handler.

Event Payload Producer Listener
equipWeapon WeaponType Keyboard input WeaponSelectionComponent.equip
weaponSelected WeaponType WeaponSelectionComponent HotbarDisplay

The event handler invokes registered listeners when an event is triggered. The terminal command calls equip directly, so keyboard and terminal selection both follow the same validation and notification path.

weaponSelected is emitted when selection changes, including successful initial sword selection. The hotbar also reads the current selection when it is created, so it does not depend on receiving that initial event.

HotbarDisplay

MainGameScreen creates HotbarDisplay(player) as a separate component on the UI entity. It displays two groups of three circular slots:

  • The left group contains weapon icons and labels 1, 2, and 3.
  • The right group contains empty placeholders for future spells; no spell behaviour is implemented.
  • The selected weapon frame stays at full brightness; unselected weapon frames are grey.
  • Icons, labels, and the right-hand frames are not tinted by selection changes.

Content creation is separate from layout. createWeaponGroup() and createSpellGroup() supply their slot actors to createHotbarGroup(List<Actor>), which applies common sizing and spacing. createCircleFrame() supplies the shared frame artwork.

The hotbar does not intercept mouse or touch input. Actor names such as weapon-icon-1 and weapon-key-1 let tests locate UI elements; they do not implement input bindings.

Layout and textures

The hotbar sits 48 UI stage units above the bottom edge. Slots have a maximum diameter of 96 units, with 6-unit gaps within each group. The left margin is 340 units; the right margin can shrink from 340 to 96 units on narrower windows.

slotSize(width) subtracts the margins, a 24-unit group gap, and four internal slot gaps, then divides the remaining width between six circles. The result is clamped between 1 and 96 units. Layout is recalculated when the stage size changes. This is responsive hotbar sizing, not whole-game scaling; extremely narrow windows can still overflow the fixed margins.

Each weapon icon fits inside a centred square measuring 55% of its slot diameter. Icon paths come from WeaponItem.getTexture(), and textures are retrieved through ResourceService. The bow currently uses its existing throwing-knife artwork.

The circular frame is taken from images/ui/ui_big_pieces.png. HotbarDisplay owns and disposes this sprite-sheet texture. Weapon textures belong to WeaponAssetsComponent and are only borrowed by the UI; disposing the hotbar does not unload them.

The inventory book retains its centred layout and does not use hotbar geometry to calculate its position.

Tests and verification

  • WeaponSelectionComponentTest: default selection, switching, invalid and repeated selections, exclusive enabling, terminal synchronisation, and cooldown preservation.
  • KeyboardPlayerInputComponentTest: exact number-key mappings, event consumption, and terminal input priority.
  • HotbarDisplayTest: item icons and labels, selection highlights, resizing, persistence across inventory page changes, and resource ownership.

Follow-up work

Spells/status affects were not added in time/communicated clearly. So they are not included in the hotbar. It is intended that the right three slots would be for the spells.

LLM delcaration

Content for this page was generated with the help of LLMs, namely GPT-6 Astra

Table of Contents

Home

Test Plan

Team 2

Features

Components
Player
Items and Inventory
Enemies
Interactable NPCs
Cutscenes and Dialogue
Music
Bosses
Rooms
Weapons
Abilities & Spells
Game Screens and Areas
Dungeons

Game Engine

Getting Started

Entities and Components

Service Locator

Loading Resources

Logging

Unit Testing

Debug Terminal

Input Handling

UI

Animations

Audio

AI

Physics

Terrain

Concurrency & Threading

Settings

Troubleshooting

MacOS Setup Guide

Clone this wiki locally