Create a toast component for arbitrary messages #57
Labels
No labels
assets
bug
duplicate
enhancement
help wanted
invalid
question
testing
ui
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
liamjd/UntitledColonyBuilder#57
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A label panel which appears for about 5 seconds bottom right of the screen with an arbitrary text message. Triggered by a signal.
If the message contains reference to a location or an entity, clicking on it should centre the location or entity on the screen.
The toast can be closed with a X icon, or will disappear after the specified timeout period. If the period is specified <= 0, the toast should appear permanently until manually dismissed.
Toasts will stack on top of each other, oldest toast at the bottom. Dismissing a toast (either with the X or the timeout) should fade and slide it off the screen before removing the node entirely. The toast stack should then slide down to fill the vacated space.
The message body needs to be quite flexible:
Spec (drafted with Claude)
Decisions made on 2026-09-26:
CameraRig.focus_on()), clamped to the map. There is no tween.Acceptance criteria
GameState.toast_requested(message: ToastMessage)is the one way to raise a toast from anywhere in the game.ToastMessagecarries text, plus an optional title, an optional icon, a timeout (default 5s, where<= 0means sticky) and at most one target: anEntity(Pawn or Building) or a map cell. Setting one kind of target clears the other.dismissedis emitted exactly once, even if the X is clicked during the fade.marked_for_demolition) raises a toast targeting the building's record. Cancelling a planned or under-construction building raises nothing.target_cellwhen it has one.Outline
ui/toasts/toast_message.gdToastMessage(RefCounted): data, fluentabout_entity()/about_cell()/lasting(), andfocus_point(map)ui/toasts/toast.gd+toast.tscnToast: renders one message, runs its countdown in_process, dismiss animation,dismissedandfocus_requestedsignalsui/toasts/toast_stack.gd+toast_stack.tscnToastStack(VBoxContainer, bottom right,MOUSE_FILTER_IGNORE): listens totoast_requested,push(), relaysfocus_requestedui/toasts/toast_notifier.gdToastNotifier(Node): turns gameplay signals into messages. Its builders are static so they can be tested without wiringentities/camera/camera_rig.gdfocus_on(world: Vector3)globals/GameState.gdsignal toast_requested(message: ToastMessage)common/game.tscn/game.gdfocus_requestedtocamera_rig.focus_on(message.focus_point(map))Tests:
test/unit/test_toast_message.gd,test_toast.gd,test_toast_stack.gd,test_toast_notifier.gd,test_camera_focus.gd.Out of scope / follow-ups
task_blockedcould flood the column if many tasks block together.