Question about HUD, autoloads, and UI communication in Godot

Godot Version

4.4

Question

I’m trying to understand the recommended architecture for HUD and UI in Godot, especially regarding autoloads and logic responsibility.

Since HUD elements (subtitles, choices, pause menu, etc.) exist in every gameplay scene, is it reasonable to add the HUD as an autoload, or are autoloads generally meant only for non-visual logic systems?

If HUD is an autoload:

  • Should it perform any logic, or should it be presentation-only?

  • Should UI elements like Subtitles be children of the HUD by default, or instantiated only when needed?

For example, if I have a Subtitles scene:

  • When a player interacts with an object, how should that object trigger subtitles?

  • Should the object call something like HUD.show_subtitles(text)?

  • Or should it talk directly to the Subtitles scene?

  • Or should there be a separate logic/system layer in between?

Another concern is UI layout:
If I keep UI elements (subtitles, choices, notifications, etc.) as separate scenes under one HUD, but they are not aware of each other, they can overlap when one grows (e.g., long subtitles + choices).
Is it acceptable for HUD elements to be independent and overlap, or is it expected to have some kind of composition/layout layer that coordinates related UI (like subtitles and dialogue choices)?

I’d appreciate insight into how this is typically handled in real projects and what trade-offs people usually accept.

For me it should be a scene, not an autoload. And he shouldn’t have any logic (excepting display logic of course) and focus presentation only. Well, that’s how I see things and do it on my project. The HUD’s job is just to “display” datas on the screen, and he listens to them from other scenes or autoloads.

I would define a “zone” on my HUD where I can display the subtitles, visible = false by default.

When the player interact with an object, just emit a signal with the text to display as a parameter to the signal. Catch that signal on the HUD, add it to the subtitle zone on the HUD while setting visible to true. That’s how I would do it

I see what you mean, that makes sense from a separation point of view. I’m just a bit unsure about one thing though. Since HUD, pause menu, subtitles, etc. are needed in basically every gameplay scene, wouldn’t it be more practical to keep HUD as an autoload so it always exists, instead of recreating it per scene each time?

Also for interactions — if an object wants to show subtitles, what would you consider the cleanest way for it to pass that text? Through a global signal bus or manager? Calling into a global class? If it talks directly to HUD, that feels tightly coupled, but if every object needs its own resource setup, that feels heavy too.

I use a Game Template that I created (and is open source). It’s main node contains a state machine, and that state machine contains the main UI in one of the states. I use a number of small, atomic Autoloads to handle things. However UI in an Autoload would not make a lot of sense once you got your game going.

As for subtitles, I’d consider that part of the HUD. And the HUD is something I always attach to the player. It just makes a lot of sense because there are so many things about the player that the HUD needs access to.

I also think you are falling into the trap of future-proofing with some of your questions. You are trying to architect out an entire system before building anything, and the fact of the matter is that if you don’t have experience using Godot it’s really hard to plan those things out. I know. I have UML diagrams covering my walls that literally had to be reworked multiple times as I started understanding more about how Godot works. Which is why I do what I do now.

In Godot 4, a common and scalable approach is to treat the HUD as a visual layer while keeping logic elsewhere.

Using an autoload for non-visual systems (dialogue manager, subtitle manager, UI state) usually works better than autoloading the HUD itself. The HUD scene can then be instantiated per gameplay scene, while it listens to signals from those global systems.

For example:

  • Gameplay objects emit events like request_subtitles(text)

  • A global UI or Dialogue Manager (autoload) receives that

  • The HUD (or Subtitles scene) reacts and displays content

This avoids tight coupling like calling HUD.show_subtitles() directly from gameplay logic.

For layout concerns (overlapping subtitles, choices, notifications), many projects solve this with a simple UI coordinator or container-based layout system that manages spacing and priority. This keeps UI elements independent but still prevents clashes as content grows.

If you’re interested in how mature tools handle centralized processing with clean separation between logic and presentation, projects like Equalizer APO are a good example of keeping core systems decoupled from the UI layer while still reacting in real time.

Overall trade-off:

  • Autoloads → logic & state

  • HUD → presentation & signals
    This keeps things flexible as the project grows.