A player downloads your game, double-clicks the icon, and within forty-five seconds they have decided whether they like you. They have not seen your combat system. They have not met your boss. They have not heard your soundtrack at the moment it is...
In This Chapter
- UI vs. UX — A Designer's Distinction
- Diegetic vs. Non-Diegetic UI
- HUD Hierarchy
- Menus
- UI for Controllers vs. Keyboard/Mouse vs. Touch
- Readability and Typography
- Color and Iconography
- Feedback and Confirmation
- Accessibility — Not Optional
- Tutorialization Through UI
- Information Density and Attention
- UI Animation (Micro-Interactions)
- Designing for the "Slow Look"
- GDScript Implementation
- Progressive Project Update — Ch 29: Full UI Suite
- Common Pitfalls
- Summary
Chapter 29: User Interface and User Experience — The Invisible Layer
A player downloads your game, double-clicks the icon, and within forty-five seconds they have decided whether they like you. They have not seen your combat system. They have not met your boss. They have not heard your soundtrack at the moment it is supposed to land. What they have seen is your splash screen, your main menu, the way the cursor responds to their mouse, the font you chose, the sound a button makes when they hover over it, and how long it takes the "Continue" prompt to appear after they hit "New Game." That is your first impression, and it is entirely UI.
Most designers do not want to talk about this. UI is not what got them into games. They got into games because of Dark Souls combat or Breath of the Wild exploration or that moment in Celeste when the music swells on the summit. Nobody wakes up at twenty-four years old saying, "I want to design a settings menu." So UI gets handed off — to the engineer with the most patience, to the artist who has the least to do this sprint, to the lead designer's "I'll fix it before launch" pile. And then the game ships and the reviews say things like "feels rough," "hard to navigate," "obviously a port," and the designer is genuinely confused, because the combat is great. The combat is great. Nobody is arguing about the combat. They cannot get to the combat without sitting through forty seconds of unskippable splash logos and a controller-rebind menu that has no D-pad navigation.
This chapter is the one that retroactively makes your last six chapters matter. Combat (Ch 26) does not feel good if the health bar is in the wrong place. Progression (Ch 25) does not feel rewarding if the upgrade menu has thirteen tabs. The dialogue system you built in Ch 21 does not deliver its emotional beat if the subtitles are eighteen-pixel white text on a sky background. UI is the layer through which every other system speaks to the player. When it is invisible — when the player does not notice it, does not think about it, does not even remember it — your other systems get to do their jobs. When it is visible, it is in the way.
That is the design goal for almost all UI in almost all games: be invisible. Get out of the way. Let the player do the thing. We are going to spend this chapter talking about how, exactly, you accomplish invisibility — and how you handle the cases where invisibility is wrong, where the UI is the experience and you need it to be loud and proud (looking at you, Persona 5).
UI vs. UX — A Designer's Distinction
Before anything else, a vocabulary fight you need to win.
User Interface (UI) is the surface. It is the buttons, the bars, the icons, the menus, the typefaces, the colors. It is the visual and interactive scaffolding the player touches. UI is what a screenshot shows you.
User Experience (UX) is the whole ride. It includes the UI, but it also includes the moment-to-moment feel of using your game — how long things take, how predictable they are, how often the player is surprised in good ways and in bad ways, how the experience of "I want to do X" leads (or fails to lead) to "X happened." UX is what a screenshot cannot show you.
A game can have beautiful UI and bad UX. Destiny 2 has stunning art on every menu screen and is famously frustrating to navigate; the inventory management UX is its own meme. A game can have ugly UI and great UX. Dwarf Fortress (the classic ASCII version) is hostile-looking by any reasonable standard, and players who learn it report flow states that AAA games rarely match. The UI is the gate; the UX is the garden.
The overlap is where you actually work. Your UI choices determine UX outcomes. Choosing a smaller font (UI) creates a readability problem at four feet from a TV (UX). Hiding the map behind a menu (UI) creates an exploration friction (UX). Adding a confirmation dialog before selling an item (UI) trades fewer regretted sales (UX win) for slower commerce (UX cost). Every UI decision casts a UX shadow. The job is to make the shadow useful.
A note on roles: in larger studios, UI and UX are different specializations. UI artists make the visual elements; UX designers make the wireframes, the flows, the interaction logic. In small teams, you do both, often without knowing which hat you have on. Get used to switching. When you are choosing a font, you are doing UI. When you are deciding whether the map should be a hold-button or a toggle, you are doing UX. Both are design.
💡 Intuition: UI is what the player sees. UX is what the player feels. You can fix UI in a sprint. You cannot fix UX without fixing the underlying assumptions about how the player moves through your game.
Diegetic vs. Non-Diegetic UI
The single most influential UI distinction in modern game design comes from film theory, oddly enough. Diegetic elements exist in the story world — the characters can see and interact with them. Non-diegetic elements exist outside the story world — only the audience (or in our case, the player) can see them.
A health bar floating in the top-left corner is non-diegetic. Isaac Clarke's spine glowing red in Dead Space is diegetic. Both communicate "you are losing health." One stands outside the world; one lives inside it.
The choice between diegetic and non-diegetic is the most important UI architectural decision you will make. It cascades through every other choice. It determines tone. It determines the camera. It determines what your menus can be. And — a thing that does not get said often enough — it determines how much money you spend on UI engineering, because diegetic UI is expensive.
Diegetic UI: The Immersion Trade
Dead Space (2008) is the canonical example, and we will spend a whole case study on it (Case Study 29.1). The key insight: Visceral Games removed every floating element from Isaac's screen. No health bar. No ammo counter. No mini-map. Instead, the spine of his suit glows blue and decreases as he takes damage. His weapons display ammo as small holographic counters embedded in the gun model. The map is a holographic projection that Isaac himself summons in front of his face — and crucially, the game does not pause while he is reading it. Enemies can attack him while he checks his bearings.
The result is an immersive horror experience few games have matched. There is no "screen" between the player and Isaac's situation. When Isaac panics, the player panics, because the player cannot retreat to a comfortable abstraction layer.
Metro 2033 and its sequels do something similar with Artyom's wristwatch, which displays gas-mask filter time. Far Cry 2 (2008, the original — not the later iterations) had a paper map the character physically pulled out and held in front of his face; the camera dropped to first-person and you watched him orient himself by sun and landmarks. Alien: Isolation puts the motion tracker in Ripley's hands; she literally raises it, and the camera shifts focus between the tracker and the corridor ahead, never both in focus at once.
Diegetic UI's pros are real and powerful: presence, immersion, narrative cohesion, visual cleanliness. There is no clutter on screen because the information lives in the world. When done well, the player forgets they are looking at UI at all.
The cons are equally real and frequently underestimated:
- Speed. Diegetic UI is slower to read. Glancing at a corner-of-screen number takes a fraction of a second; reading a holographic counter on a moving gun takes longer. In games where speed of decision matters (action, competitive), this cost can be lethal.
- Discoverability. New players do not always know that Isaac's spine is the health bar. Tutorialization burden is higher.
- Flexibility. A non-diegetic UI element can be moved, resized, or hidden trivially. A diegetic element is welded to a model and an animation; changing it costs art, code, and probably new motion capture.
- Camera dependence. If your camera ever cannot show the diegetic element clearly, your UI breaks. Third-person games that go to first-person for cinematic moments suddenly lose access to a back-mounted health bar.
- Genre fit. Diegetic UI works best in slow-paced, atmospheric, single-character experiences. It does not work in 12-player tactical shooters. It does not work in JRPGs with party menus. Forcing it on the wrong genre creates a museum exhibit, not a game.
🎮 Case Study: Dead Space's spine-health worked because the camera was over-the-shoulder, the pace was slow enough for glances, and the horror genre rewarded the friction of "I cannot easily check my status" with tension. Try the same trick in a fast first-person shooter and your players will rebind the health display in the first patch.
Non-Diegetic UI: The Default for a Reason
Most games use non-diegetic UI because most games need it. The corner-of-screen health bar, the ammo counter, the minimap, the objective marker — these are functional decisions made in service of clarity. Doom (1993) had a face in the bottom of the screen showing damage state; Doom Eternal (2020) has a HUD with health, armor, ammo, and ability cooldowns visible at all times. Both games are about speed of decision. Both correctly use non-diegetic UI.
The mistake is to assume non-diegetic equals lazy or immersion-breaking. It does not. A well-designed non-diegetic HUD vanishes into the player's peripheral vision. They glance at it; they read what they need; they return to the world. Within thirty minutes of play, the HUD disappears from conscious awareness. That is the goal: not the absence of UI, but the absence of friction in reading it.
Spatial and Meta UI
Two intermediate categories are worth knowing because they show up constantly.
Spatial UI lives in the 3D space of the world but is not perceived by characters. Objective markers floating over destinations (Skyrim's quest arrows, Far Cry's waypoints, Spider-Man's glowing collectible markers) are spatial. The character cannot see them; the player can. Spatial UI is a compromise — more world-integrated than non-diegetic but with the player-only logic of a HUD element.
Meta UI is non-diegetic UI that responds to in-world events as if they were affecting the screen itself. Blood splatters on the camera when the character is hit. Cracks across the screen when health is low. The whole-screen film grain that ramps up when the character is hallucinating. Resident Evil 4's low-health red border. Meta UI smuggles narrative state into UI without requiring full diegesis.
A practical tip: most successful games are mixed. The Last of Us is mostly non-diegetic with meta-UI flourishes (blood splatter, screen-edge red when injured) and one genuinely diegetic touch (the listen-mode visualization, which is presented as Joel's perception). Resident Evil 4 (2023 remake) uses diegetic inventory (the briefcase) and non-diegetic everything else. Pure diegesis is rare and expensive. Mixed approaches are the practical norm.
HUD Hierarchy
The Heads-Up Display is the persistent, in-game UI layer. Health, ammo, abilities, minimap, objective text, currency, status effects, party state, weapon selection — anything the player needs to glance at without leaving gameplay. Designing the HUD is an exercise in priority. Everything cannot be on screen always; the HUD's job is to negotiate what stays, what comes and goes, and what hides until summoned.
The honest framing: a HUD has three tiers.
Tier 1 — Always Visible. The information the player needs every second to make moment-to-moment decisions. In a shooter: health, ammo. In an RPG: health, mana, hotbar. In a strategy game: resources, current selection. This is your most precious screen real estate. Be ruthless. If something is on Tier 1, ask: would the game break if it disappeared for ten seconds? If no, it does not belong on Tier 1.
Tier 2 — Contextual. Information that appears when relevant and disappears when not. The "press E to interact" prompt that surfaces when the player is near a door. The damage numbers that flash and fade. The combo counter that appears mid-fight and vanishes after three seconds of inaction. The boss health bar that only appears during boss fights. Contextual UI lets you defer cost — most of the time the screen is clean; only when the moment demands it does the UI surface.
Tier 3 — Hidden. Information accessible through deliberate input — the inventory, the map, the skill tree, the quest log. Hidden UI is the cheapest from a screen-real-estate perspective and the most expensive from an interaction-cost perspective. Every "open the menu" is an interruption to play.
The decision tree for placing a piece of information:
- Does the player need this every second? → Tier 1.
- Does the player need this when something specific happens? → Tier 2.
- Does the player look this up occasionally? → Tier 3.
- Does the player never need this? → Cut it.
Run that tree on every UI element. Most teams over-promote — putting Tier 2 or Tier 3 information on Tier 1 because the designer was worried the player would miss it. The player will be more annoyed by clutter than by occasionally pressing a button to check something.
The Two Poles: Dark Souls vs. Borderlands
Two HUD philosophies define the spectrum.
Dark Souls (2011) shows: a thin health bar in the top-left, a thin stamina bar beneath it, an item-slot bar in the bottom-left, a soul counter and runes in the bottom-right. That is the entire combat HUD. No minimap. No quest arrow. No damage numbers. No combo counter. No ability cooldowns shown — you feel the cooldown by trying the ability. The player's screen is mostly the world: the snowy ridge, the cathedral, the bonfire glow, the giant about to kill you. The HUD is a quiet whisper of necessary state, and nothing else.
Borderlands 2 (2012) shows: health bar, shield bar, gun image, ammo counter, ammo type, current grenade, action skill cooldown, mission objective, mini-map with marker, currency, badass rank, equipped artifact, and — during combat — damage numbers in giant orange text flying off every enemy. The screen is covered in numbers. The game is about loot and stats; the HUD reflects that.
Both are correct for their games. Dark Souls is about presence and atmosphere; clutter would destroy the dread. Borderlands is about a Skinner box of numerical reward; the numbers are the dopamine. Each game's HUD is a thesis statement about what the experience is supposed to deliver.
The mistake is to copy one without the other. A horror game with Borderlands's HUD would not be scary. A loot shooter with Dark Souls's HUD would feel like a stat sheet was missing.
🛠️ Practitioner Tip: Build your HUD twice. Once with everything you think you need. Then strip every element that is not Tier 1 — make it contextual or hidden. Playtest the stripped version. You will be amazed how much was decoration and how little was essential.
Reading Order
In any moment of gameplay, the player's eye traces a reading order across the screen. They look at the center (the action), the corners (status), the bottom (objectives), and back to the center. A HUD that respects reading order places the most critical state where the eye will already be — in fast-paced games, that is near the crosshair, not in the corners. Doom Eternal keeps health and ammo in the bottom-corners but adds a small armor display directly under the crosshair, because in a fight the player is looking at the crosshair and a quick down-glance is faster than a corner-glance. Small choice, large impact. Watch where your players' eyes go (literally, with eye-tracking, if you can; otherwise, by playtesting and asking) and put the critical information where they are already looking.
Menus
The menu is where UX, more than UI, decides the experience.
A menu has a job. It might be: present the start of the game (main menu), let the player adjust settings (settings menu), let the player manage equipment (inventory), let the player pause and decide what to do next (pause menu). Each job has different requirements, and pretending one design solves them all is the source of most menu-related misery.
Main Menu — First Impression
The main menu is the first three seconds of your relationship with the player. It does four things, in order:
- Identifies the game. Title, art, music. The player should immediately know what game they are in. Hollow Knight's main menu is a single melancholy piano line over a watercolor of Hallownest. The player is in the world from the first beat.
- Offers continuation. "Continue" should be the default-highlighted option if a save exists. The player who plays for an hour every evening should be able to launch the game and press one button to resume. Three is too many.
- Offers entry. "New Game," "Load Game," and (if applicable) "Multiplayer" are the secondary options.
- Offers escape hatches. Settings, Credits, Quit. These do not need prominence. The player who wants to quit will look for "Quit"; do not put it second.
A surprising number of AAA main menus violate point 2. The player launches, presses "Continue," and is taken to a save-slot select screen with five empty slots and one full one — and they have to navigate to the full one and press the button again. That is two extra inputs on every single launch. Over a year of play, it is hours of friction.
The main menu is also where you make your settings visible. A player who needs to adjust subtitles or rebind controls or enable colorblind mode should be able to find Settings before hitting "New Game." Hiding settings inside an in-game pause menu means the player has to start the game, get to a safe pause point, and then dig — an absurd amount of friction for a basic accessibility need.
Pause Menu — Workflow
The pause menu is the player's workshop. They open it to: change a setting mid-game, check an objective, look at the inventory, save (if save-on-demand exists), maybe quit.
The pause menu's design should anticipate the most common reason a player pauses. If players mostly pause to check inventory, the pause menu should open near the inventory. If they mostly pause to step away from the game, "Resume" should be the default highlight so they can dismiss with one button. Few teams do this analysis. Most pause menus are arranged by what feels orderly to the designer (Resume, Inventory, Map, Quests, Settings, Save, Quit) rather than by frequency of use.
Inventory — Tool vs. Gameplay
There are two philosophies of inventory design.
Inventory as tool says: the inventory exists to let the player manage what they have. It should be fast, clear, sortable, searchable. It should not be in the way. Examples: Skyrim's list-based inventory (dated but functional), World of Warcraft's grid bags, Final Fantasy XIV's interface.
Inventory as gameplay says: managing what you have is itself a puzzle. The constrained space is the design. Examples: Resident Evil 4's briefcase (every item is a Tetris-shaped object you have to fit, in real time, in a fixed grid), Diablo II's grid (a pelt is 2x2, a sword is 1x3, you cannot fit your loot without thinking about packing), Pathologic 2's bag (you carry less than you need; you have to choose).
Neither philosophy is right. The choice depends on whether you want inventory friction to be the experience or interfere with the experience. Resident Evil 4's briefcase is iconic because the puzzle is fun and the constraint creates strategic decisions about what to bring on missions. Skyrim's inventory is the most-mocked menu in modern AAA because the game does not want you to puzzle over packing — you carry hundreds of items and you just want to find the iron dagger.
Decide which one your game is. Build for it. Do not split the difference.
Settings — Respect for the Player
A settings menu is where you communicate, more than anywhere else, your respect for the people playing your game. A good settings menu offers:
- Display: resolution, fullscreen/windowed/borderless, vsync, frame rate cap, FOV (field of view, in 3D games), HDR toggle, brightness/gamma calibration.
- Audio: master volume, music volume, SFX volume, dialogue volume, separate sliders for each — and ideally a "test" button for each.
- Controls: rebindable keys for keyboard, rebindable buttons for controller, mouse sensitivity, controller sensitivity, invert-Y option (still essential in 2026).
- Gameplay: difficulty, aim assist toggle (separate from difficulty), tutorial hint frequency.
- Accessibility: see the dedicated section below.
- Language: with previewable text.
The settings menu is also where you signal trust. Do not hide options behind tabs the player has to discover. Do not require a restart for settings that should be live. Do not silently revert settings on update. Do not display settings as percentages when sliders are clearer. If the player turns master volume to zero, do not pop up a confirmation dialog. Treat them as adults who know what they want.
⚠️ Pitfall: A surprising number of games treat the settings menu as an afterthought because "no one looks at it during demos." Settings are not for demos. They are for the millions of hours of play after launch, and they are the difference between a player who sticks with your game and a player who refunds it because the brightness was wrong on their TV and they could not figure out how to fix it.
UI for Controllers vs. Keyboard/Mouse vs. Touch
You will be tempted, especially if your game is built for one platform first, to think of porting as "just adding controller support." This is the four-month-project lie that has destroyed countless development schedules.
Each input method demands a different UI architecture. They are not skins of one another.
Keyboard and Mouse
Mouse-driven UI assumes free, fast pointing. Cursors hover over arbitrary screen positions. Buttons can be small because the mouse can land on them precisely. Lists can be long because scroll wheels exist. Drag-and-drop is natural. Right-click context menus are natural. Hover tooltips work because the cursor is always somewhere specific.
Mouse UIs let you have many options visible at once. A Civilization tech tree on a monitor is dense, navigable, and clear. The same tree on a controller is a nightmare.
Controller
Controller UI is focus-driven, not pointer-driven. The player does not have a free cursor; they have a current selection (a "focus") that they move with the d-pad or stick. Each press of d-pad-down moves focus to the next element below, where "next element below" is a designer's choice, not an obvious geometric fact.
This means controller UI has constraints mouse UI does not:
- Limited options per screen. With focus-cycling, you cannot have hundreds of elements; navigation becomes painful past ~20 elements.
- Explicit navigation logic. You must define neighbor relationships — what gets focus when the player presses up, down, left, right, from each element. Godot calls these
focus_neighbor_*properties. Unity calls them Selectable navigation. They are a lot of work and almost always wrong on the first pass. - Modal shifts. Holding a button to switch UI modes (in Persona 5, holding a face button switches the whole menu's behavior) is natural on controller and awkward on mouse.
- Radial menus. A controller's analog stick can quickly select among 4-8 options arranged in a circle; this is the controller's superpower for inventory or weapon select. Mass Effect's radial power wheel, Borderlands's weapon wheel, Returnal's artifact wheel. Mouse can do radial menus too but loses much of the feel.
- Tooltips need triggers. With no hover, you need a button to show details. Often this is the same button that should select the item, creating ambiguity unless you design carefully (one short press selects, hold for tooltip — common pattern).
A controller UI built well is fast: muscle memory takes over and the player navigates without looking. A controller UI built poorly is the most common reason console reviews say a game "feels like a port."
Touch
Touch UI is the most demanding. Targets must be at least 44x44 pixels (iOS guideline) or 48x48 dp (Material Design) — large enough for a finger pad. There is no hover, no right-click, no precise pointing. There is gesture: tap, double-tap, long-press, swipe, pinch.
Touch also has the fat finger problem — the finger occludes what it is touching. A target the player is dragging is hidden by their hand. Critical UI (health, ammo) cannot be in the bottom corners on phones because the thumbs are there.
Touch UI requires designs that other input methods do not need: tap-and-hold to confirm destructive actions, large button regions with smaller visual icons, drag handles for scrolling, swipe-from-edge for menus.
The honest framing: if your game is mouse-first, designing for controller is a real second design pass. If your game is controller-first, designing for mouse is a different second pass. If your game ships on touch, you almost have to build the UI a third time. Anyone who tells you "we will just remap the inputs" is wrong, and they will be embarrassed three months from launch. Plan accordingly.
Readability and Typography
Type is design's quietest decision. Players never compliment a font; they only resent one that fails them.
The functional requirements for game type:
- Readable at distance. A console game is played from 6-10 feet from a TV. Text that is comfortable on your monitor at desk-distance is illegible from the couch. Test on a real TV at real distance, not just on your dev monitor.
- Readable at low contrast scenes. A subtitle over a snowy mountain or a beach scene loses contrast. Provide a text background option (a translucent box behind subtitles) for accessibility.
- Color-contrast compliant. WCAG (Web Content Accessibility Guidelines) recommends a contrast ratio of at least 4.5:1 for normal text, 3:1 for large text. White text on a yellow background fails this test, as does dark gray on black.
- Readable at all resolutions. A UI designed for 1080p and naively scaled to 4K becomes tiny. A UI designed for 4K and scaled down to 1080p becomes blurry. Build resolution-independent UI from the start (using anchored rects and font scales, not pixel-fixed positions).
- Readable in translation. German is famously about 30% longer than English. Russian and Polish run long. Japanese and Chinese can be denser per character but require larger fonts. If your UI text fits its boxes only in English, your localization team will hate you.
The font choice itself: most games should use a sans-serif for UI (sans-serifs are more readable at small sizes on screens). Fancy faces — gothic blackletter, distressed grunge fonts, custom calligraphic fonts — should be reserved for titles, headers, and one-off thematic elements. Body text and HUD elements need clarity. A common pattern: one display face (used for the title, chapter names, and 2-3 hero moments) and one workhorse face (used for everything else). Hollow Knight uses a custom calligraphic title face and Trajan-like display, with a clean sans for everything else. Hades uses the same dual-font approach.
Font size matters as much as choice. The minimum readable size on a TV-played console game is roughly 28-32px (at 1080p). On PC, you can go smaller — 16-20px is fine — because the player is closer. Mobile sits in the middle. When in doubt, larger.
🎮 Case Study: Dead Rising 1 (2006) shipped with body text so small on a standard-definition TV that whole groups of players literally could not read the mission text. Capcom never properly patched this; the game became infamous for it. The lesson: readability must be tested on the worst expected setup, not the best.
Color and Iconography
Color carries information in UI. Red signals danger. Green signals health. Blue signals mana or interactable. Yellow signals warning or quest objective. These conventions are strong but not universal — and they are exclusionary if used badly.
The first rule: never code information by color alone. Roughly 1 in 12 men and 1 in 200 women have some form of color vision deficiency. The most common (deuteranopia and protanopia) make red and green difficult to distinguish. A game that signals "enemy = red, friend = green" with no other distinguishing feature is unplayable for these players.
The fix is redundant coding — color plus shape, plus icon, plus label, plus position. Hearthstone shows enemy minions on the opponent's side and friendly minions on yours; the spatial position is unambiguous. Among Us uses both color and a distinctive hat/symbol. Overwatch uses color (red enemy outline, blue ally) but also icons (different character silhouettes) and positional information.
Iconography is the visual shorthand for actions and objects. A heart for health, a star for special, a gear for settings, a magnifying glass for search. Conventions exist for a reason — players already know them. Reinventing iconography in pursuit of style usually fails. Use familiar icons and reserve novelty for the few items that genuinely have no convention.
When using icons, consider:
- Pair with text the first time. Show the gear icon labeled "Settings" the first time the player encounters it. After they have learned the icon, drop the text in subsequent appearances.
- Maintain consistent style. Mixing flat icons with skeuomorphic ones, or line icons with filled ones, fragments the visual language.
- Test recognition. Show your icons to playtesters out of context and ask "what does this represent?" If you get more than two interpretations, redesign.
Feedback and Confirmation
A button that does not respond when pressed is broken, even if the underlying logic worked. The player needs to know — within milliseconds — that the input was registered. This is the lesson from Chapter 8 (Feedback Systems) translated into UI.
Hover state. When a mouse cursor is over a button, the button should change. Brighter, slightly enlarged, an outline, a subtle glow. The change tells the player "this is what would activate if you clicked."
Press state. When the button is pressed, it should change again. Inset look, slight color shift, sound effect. The change confirms the input was registered.
Activated result. When the action completes, communicate completion. A button labeled "Save" that flashes green and shows "Saved!" for 2 seconds is much better than a button that goes back to its idle state silently. The player needs to know the save happened.
Sound. Every button should make a sound when activated. Different sounds for different actions: a soft click for navigation, a heavier click for confirmation, a tone for error. Without sound, the UI feels lifeless. With sound, the UI feels responsive even before the player consciously registers why.
Tooltips. When the player rests their cursor on something for ~500ms, a tooltip should appear with details. Don't show tooltips immediately (jittery), don't require a click (interruption). 500ms is the sweet spot for "I want to know" without being noisy.
Undo and confirmation. This is where most games get it wrong. The principle: confirm destructive, undoable actions; do not confirm trivial actions.
| Action | Confirm? |
|---|---|
| Quit to main menu (loses progress?) | Yes |
| Delete save | Yes (and ideally type a word) |
| Sell 99 of an item | Yes |
| Sell 1 of an item | No |
| Equip an item | No |
| Open inventory | No |
| Drink potion | No |
| Sell legendary item worth 8 hours of grind | YES |
A confirmation on every trivial action trains the player to dismiss confirmations without reading them, which means when the important confirmation appears, they dismiss it too and lose the legendary item anyway. The dialog box is a boy who cried wolf problem.
Better than confirmation, where possible, is undo. A "you sold an item — Undo (10s)" notification at the bottom of the screen catches mis-sales without nagging on every trade. Email's "Unsend" works because it does not require pre-confirmation; it just gives a brief grace period. Apply the same pattern in games where you can.
⚠️ Pitfall: "Are you sure?" dialogs proliferate when designers are afraid of complaints about lost progress. The solution is not more dialogs; it is better save systems and undo affordances. The dialog is admitting your save system is fragile.
Accessibility — Not Optional
Accessibility used to be a feature. It is now baseline. As of the mid-2020s, a major game shipped without subtitles, remappable controls, colorblind options, and at least basic motion-reduction settings will be reviewed harshly and deserve to be. The financial argument for accessibility is real (15-20% of players have some accessibility need), but the moral argument is simpler: people who want to play your game should be allowed to play your game.
The minimum responsible accessibility set:
- Subtitles. On by default, with options for size (small/medium/large), background opacity (none/translucent/opaque), and speaker labels (so the player knows who is talking when off-screen). The Last of Us Part II allows up to four customization sliders per subtitle setting. The minimum acceptable in 2026 is the basics.
- Remappable controls. Every input, both keyboard and controller, fully remappable. No "we let you remap most things but the dodge button is hardcoded."
- Colorblind modes. At least three: deuteranopia, protanopia, tritanopia. Plus a high-contrast mode for cases color codes need to be replaced.
- Reduce motion. Toggles to reduce screen shake (which can cause vestibular symptoms), camera motion, and animation flourishes. Critical for players with motion sensitivity, vestibular disorders, or photosensitive epilepsy.
- Audio cues. Visual indicators for off-screen audio events (a directional indicator showing where a footstep came from, a screen-edge flash for an off-camera explosion). Fortnite added this for deaf players and many hearing players also turned it on; it improved the experience for everyone.
- Aim assist. Toggleable, with intensity options. Aim assist is not "easy mode" — it is a different curve mapping input to aim that helps players with motor impairments, low-precision controllers, or older hands play the game competently.
- Difficulty options separate from challenge. Recall Chapter 11's discussion of Celeste's assist mode: separate sliders for game speed, infinite stamina, invincibility, dash count, and air-dash. Each addresses a different access need without conflating them as one "difficulty" choice.
The Last of Us Part II is the contemporary gold standard, with over 60 accessibility options across vision, hearing, motor, and cognitive needs. Naughty Dog worked with disabled gamers throughout development as paid consultants. The result is a game that won multiple accessibility awards and reportedly opened the AAA experience to thousands of players who could not previously play games of that genre. We will examine TLOU2's process in detail in Case Study 29.2.
The point worth absorbing: accessibility done well is not a sacrifice of design vision. The Last of Us Part II is also one of the most cinematically and mechanically refined AAA games of its generation. The accessibility did not dilute the design; it deepened it, because designing for varied bodies forces you to think more carefully about what your design fundamentally requires versus what it incidentally requires.
🛠️ Practitioner Tip: Accessibility cannot be added in the last sprint. Subtitle systems require scene-by-scene work; remap systems require input architecture decisions made at the engine layer; colorblind modes require palette decisions during art passes. Build accessibility into your earliest UI architecture and your art bible. Retrofitting always produces worse results at higher cost.
Tutorialization Through UI
UI does most of the in-game teaching, often badly. The goal: teach without interrupting.
Good: Half-Life 2 (2004) teaches the gravity gun by giving the player an empty room with cans and a wastebasket. A quiet on-screen prompt says "Press Mouse1 to launch, Mouse2 to grab." The player tries it, throws cans into the wastebasket, gets a reward sound, and now knows the mechanic forever — taught through play, with the UI as a quiet hint, not a lecture.
Bad: BioShock 2 (2010) introduces every plasmid, every weapon, and every enemy type with a full-screen modal popup that pauses the game and forces the player to read 4-6 lines of text. Players who play through the game describe the experience as a slog of being interrupted every minute by a tutorial box. The teaching system is a wall between the player and the game.
The principles:
- Just-in-time, not in advance. Teach a mechanic at the moment the player needs to use it. Do not teach all the wall-jump techniques in a tutorial level if the player will not encounter wall-jumps for another two hours.
- Briefly, on-screen. A small prompt in a corner ("Press Z to dash") that fades after the player has used the action 3-5 times is better than a modal popup.
- Visual when possible. A glowing outline on the interactable object is faster to parse than a text instruction telling the player to press E.
- Skippable. Players who already know how to play (returning players, sequel players, genre veterans) should be able to skip tutorials without dying because they did not see a critical hint.
- Progressive disclosure. Show only the hint relevant to the current moment. If three abilities are available, do not list all three on screen; show the one the moment requires.
The "tutorial hint frequency" setting in your settings menu (Off / Reduced / Full) is a good way to give all of these populations what they need.
Information Density and Attention
Three psychological principles govern UI information design.
Miller's 7±2. Short-term memory holds about 7 items. UI lists, hotbars, and option panels are best limited to ~7 items per visible group. Past 9, the player loses track without scanning. Diablo II's 8 belt slots respect Miller. The 30-icon belt of a poorly designed RPG inventory does not.
Hick's Law. Decision time scales logarithmically with the number of options. A menu with 5 options is decided faster than one with 50. Splitting many options into sub-menus (with 5-7 options each) is faster overall than presenting all options at once, even though it requires more clicks. The grand-old-radio-set look of "every option visible at once" is satisfying to designers and torture to users.
Fitts's Law. Time to acquire a target is proportional to the distance to it and inversely proportional to its size. Big, close buttons are fast; small, far buttons are slow. The corners of the screen are infinite-sized targets (you cannot overshoot a corner with a mouse) and are therefore the fastest places to put high-frequency UI. The center of the screen is also fast (the cursor often sits there). The farthest, smallest places — small buttons in the middle of the screen — are the slowest.
These three principles apply to game UI as cleanly as to enterprise software, and most games ignore them.
UI Animation (Micro-Interactions)
UI without animation feels cheap. Static elements that snap on and off look like 1990s software. Modern UI has micro-interactions — small, intentional animations that communicate state and add personality.
Examples:
- A button that subtly scales to 1.05x when hovered.
- A menu that slides in from the side rather than popping into existence.
- A "save" icon that briefly spins, glows, then resolves to a checkmark.
- A health bar that eases from 100 to 60 over 200ms rather than jumping instantly.
- A coin pickup that physically arcs into the corner UI counter (juice we covered in Ch 8).
The principle is easing. A linear motion (constant velocity start to end) feels mechanical. An eased motion (slow start, fast middle, slow end — a "cubic" or "quad" easing curve) feels organic. Godot's Tween class supports a dozen easing types; experiment.
Two warnings about UI animation. First, do not animate everything. A menu where every element animates in sequence over 2 seconds becomes laggy and frustrating after the tenth time the player opens it. Reserve animation for the moments where the personality serves; make repeated interactions snappy. Second, respect the reduce motion accessibility setting. When the player has motion reduction enabled, your slick animations should resolve to instant transitions or much shorter ones.
Designing for the "Slow Look"
Players come in two types when it comes to UI: the ones who pause to read and the ones who skip past. Your UI must serve both.
The slow looker reads tooltips, examines maps, opens menus to study options. They want depth — long descriptions, ability comparisons, lore on items. Give it to them.
The fast skipper hits "next" past every dialog and never reads tooltips. They want the critical information to be in the primary visual layer — the always-visible HUD, the stat icons, the immediate consequences of actions. Give it to them too.
The way to serve both is layered information. The icon in the inventory shows the item's silhouette and color (instantly readable to the skipper). The hover tooltip shows the name, basic stats, and a one-line description (readable in 2 seconds for the medium-paced player). The expanded "details" panel shows lore, comparison to currently equipped item, drop history, and acquisition info (rewarding for the slow looker who reads).
Most games default to a single information layer. The skipper is overwhelmed; the slow looker is underwhelmed. Layered design serves both.
GDScript Implementation
Time to build. This is Godot 4.x, using Control nodes and the theme system. Three scripts: UIManager, InventoryUI, SettingsMenu.
UIManager.gd
The UIManager is an autoload singleton that controls scene-level UI: pause menu, main menu transitions, modal dialogs, focus handling for controller users.
# UIManager.gd - Autoload singleton
extends Node
signal menu_opened(menu_name)
signal menu_closed(menu_name)
var current_menu: Control = null
var menu_stack: Array[Control] = []
var is_paused: bool = false
@onready var pause_menu_scene = preload("res://ui/PauseMenu.tscn")
func _ready() -> void:
# We always want UI input to work even when game is paused
process_mode = Node.PROCESS_MODE_ALWAYS
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("pause") and current_menu == null:
toggle_pause_menu()
elif event.is_action_pressed("ui_cancel") and current_menu != null:
close_top_menu()
func toggle_pause_menu() -> void:
if is_paused:
resume_game()
else:
var pause_menu = pause_menu_scene.instantiate()
push_menu(pause_menu)
get_tree().paused = true
is_paused = true
func push_menu(menu: Control) -> void:
if current_menu != null:
current_menu.visible = false
menu_stack.push_back(current_menu)
get_tree().root.add_child(menu)
current_menu = menu
# Critical for controller users - grab focus on the first focusable child
_grab_first_focus(menu)
menu_opened.emit(menu.name)
func close_top_menu() -> void:
if current_menu == null:
return
var closing = current_menu
menu_closed.emit(closing.name)
closing.queue_free()
if menu_stack.is_empty():
current_menu = null
resume_game()
else:
current_menu = menu_stack.pop_back()
current_menu.visible = true
_grab_first_focus(current_menu)
func resume_game() -> void:
get_tree().paused = false
is_paused = false
func _grab_first_focus(menu: Control) -> void:
# Find the first focusable Control and grab focus.
# Critical for controller-driven UI - without this, the player
# cannot navigate the menu at all on a controller.
var focusable = _find_first_focusable(menu)
if focusable:
focusable.grab_focus()
func _find_first_focusable(node: Node) -> Control:
if node is Control and node.focus_mode != Control.FOCUS_NONE:
return node
for child in node.get_children():
var found = _find_first_focusable(child)
if found:
return found
return null
A few production-relevant details. First, process_mode = PROCESS_MODE_ALWAYS ensures the manager keeps running when the game is paused — without it, the pause menu cannot be unpaused. Second, _grab_first_focus is the line that matters most for controller users: a menu that loads without grabbing focus on a controller is a menu the player cannot interact with at all. Third, the menu stack supports submenus: opening Settings from Pause keeps Pause underneath; closing Settings returns to Pause cleanly.
InventoryUI.gd
A grid-based inventory with drag-drop, tooltip on hover, and controller-focusable slots.
# InventoryUI.gd - Inventory display with grid slots
extends Control
signal item_used(item: Item)
signal item_dropped(item: Item)
const GRID_COLS: int = 8
const GRID_ROWS: int = 5
const SLOT_SCENE = preload("res://ui/InventorySlot.tscn")
@onready var grid: GridContainer = $Margin/VBox/GridContainer
@onready var tooltip_panel: Panel = $TooltipPanel
@onready var tooltip_label: RichTextLabel = $TooltipPanel/Label
@onready var item_name_label: Label = $Margin/VBox/HeaderHBox/ItemNameLabel
var inventory: Inventory # Reference to the Inventory data object from Ch 24
var slots: Array[InventorySlot] = []
var hovered_slot: InventorySlot = null
var tooltip_timer: float = 0.0
const TOOLTIP_DELAY: float = 0.5 # 500ms - the sweet spot
func _ready() -> void:
grid.columns = GRID_COLS
_build_grid()
inventory = GameManager.player_inventory
inventory.changed.connect(refresh)
refresh()
tooltip_panel.visible = false
func _build_grid() -> void:
for i in range(GRID_COLS * GRID_ROWS):
var slot = SLOT_SCENE.instantiate() as InventorySlot
slot.slot_index = i
slot.mouse_entered.connect(_on_slot_hover.bind(slot))
slot.mouse_exited.connect(_on_slot_unhover.bind(slot))
slot.focus_entered.connect(_on_slot_hover.bind(slot)) # Controller focus = hover
slot.focus_exited.connect(_on_slot_unhover.bind(slot))
slot.gui_input.connect(_on_slot_input.bind(slot))
# Set up controller navigation neighbors
if i % GRID_COLS != 0:
slot.focus_neighbor_left = NodePath("../Slot%d" % (i - 1))
if i >= GRID_COLS:
slot.focus_neighbor_top = NodePath("../Slot%d" % (i - GRID_COLS))
slot.name = "Slot%d" % i
grid.add_child(slot)
slots.append(slot)
func refresh() -> void:
for i in range(slots.size()):
var item = inventory.get_item_at(i)
slots[i].set_item(item)
func _on_slot_hover(slot: InventorySlot) -> void:
hovered_slot = slot
tooltip_timer = 0.0 # Reset; show tooltip after delay
func _on_slot_unhover(slot: InventorySlot) -> void:
if hovered_slot == slot:
hovered_slot = null
tooltip_panel.visible = false
func _process(delta: float) -> void:
if hovered_slot and not tooltip_panel.visible:
tooltip_timer += delta
if tooltip_timer >= TOOLTIP_DELAY:
_show_tooltip(hovered_slot)
func _show_tooltip(slot: InventorySlot) -> void:
var item = inventory.get_item_at(slot.slot_index)
if item == null:
return
tooltip_label.text = "[b]%s[/b]\n%s\n[color=gray]%s[/color]" % [
item.display_name, item.description, item.rarity_text()
]
tooltip_panel.visible = true
# Position tooltip near slot, but clamp to screen
var pos = slot.global_position + Vector2(slot.size.x + 8, 0)
if pos.x + tooltip_panel.size.x > get_viewport_rect().size.x:
pos.x = slot.global_position.x - tooltip_panel.size.x - 8
tooltip_panel.global_position = pos
func _on_slot_input(event: InputEvent, slot: InventorySlot) -> void:
if event.is_action_pressed("ui_accept") or (event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT):
var item = inventory.get_item_at(slot.slot_index)
if item != null:
item_used.emit(item)
The InventoryUI integrates with the Inventory.gd model introduced in Ch 24 — note the call to GameManager.player_inventory and the connection to inventory.changed. The grid creates focus neighbors for controller navigation; the same _on_slot_hover handler fires for both mouse hover and controller focus, which keeps the tooltip behavior identical across input methods. Drag-drop and a context menu for "Drop / Use / Examine" would extend this; left as exercise.
SettingsMenu.gd
Settings with sliders, dropdowns, and a key remap section. The remap uses Godot's InputMap API to listen for the next input event and assign it.
# SettingsMenu.gd - Settings panel with audio, video, controls, accessibility
extends Control
@onready var master_slider: HSlider = $Tabs/Audio/MasterSlider
@onready var music_slider: HSlider = $Tabs/Audio/MusicSlider
@onready var sfx_slider: HSlider = $Tabs/Audio/SFXSlider
@onready var resolution_option: OptionButton = $Tabs/Video/ResolutionOption
@onready var fullscreen_check: CheckBox = $Tabs/Video/FullscreenCheck
@onready var colorblind_option: OptionButton = $Tabs/Accessibility/ColorblindOption
@onready var subtitles_check: CheckBox = $Tabs/Accessibility/SubtitlesCheck
@onready var subtitle_size_option: OptionButton = $Tabs/Accessibility/SubtitleSizeOption
@onready var reduce_motion_check: CheckBox = $Tabs/Accessibility/ReduceMotionCheck
@onready var key_remap_list: VBoxContainer = $Tabs/Controls/KeyRemapList
var awaiting_remap_for: String = ""
var awaiting_remap_button: Button = null
const RESOLUTIONS = [
Vector2i(1280, 720), Vector2i(1920, 1080), Vector2i(2560, 1440), Vector2i(3840, 2160)
]
const REMAPPABLE_ACTIONS = ["move_up", "move_down", "move_left", "move_right",
"attack", "dodge", "interact", "pause"]
func _ready() -> void:
_load_settings()
_populate_resolutions()
_populate_colorblind_modes()
_build_key_remap_list()
_connect_signals()
func _populate_resolutions() -> void:
for res in RESOLUTIONS:
resolution_option.add_item("%d x %d" % [res.x, res.y])
func _populate_colorblind_modes() -> void:
colorblind_option.add_item("Off")
colorblind_option.add_item("Deuteranopia")
colorblind_option.add_item("Protanopia")
colorblind_option.add_item("Tritanopia")
func _build_key_remap_list() -> void:
for action in REMAPPABLE_ACTIONS:
var hbox = HBoxContainer.new()
var label = Label.new()
label.text = action.capitalize().replace("_", " ")
label.custom_minimum_size.x = 200
var button = Button.new()
button.text = _get_action_key_name(action)
button.custom_minimum_size.x = 160
button.pressed.connect(_on_remap_button_pressed.bind(action, button))
hbox.add_child(label)
hbox.add_child(button)
key_remap_list.add_child(hbox)
func _get_action_key_name(action: String) -> String:
var events = InputMap.action_get_events(action)
for event in events:
if event is InputEventKey:
return OS.get_keycode_string(event.physical_keycode)
return "[Unbound]"
func _on_remap_button_pressed(action: String, button: Button) -> void:
awaiting_remap_for = action
awaiting_remap_button = button
button.text = "Press any key..."
set_process_input(true)
func _input(event: InputEvent) -> void:
if awaiting_remap_for == "":
return
if event is InputEventKey and event.pressed and not event.echo:
# Clear existing keyboard binding for this action
for existing in InputMap.action_get_events(awaiting_remap_for):
if existing is InputEventKey:
InputMap.action_erase_event(awaiting_remap_for, existing)
InputMap.action_add_event(awaiting_remap_for, event)
awaiting_remap_button.text = OS.get_keycode_string(event.physical_keycode)
awaiting_remap_for = ""
awaiting_remap_button = null
_save_settings()
get_viewport().set_input_as_handled()
func _connect_signals() -> void:
master_slider.value_changed.connect(_on_master_volume_changed)
music_slider.value_changed.connect(_on_music_volume_changed)
sfx_slider.value_changed.connect(_on_sfx_volume_changed)
fullscreen_check.toggled.connect(_on_fullscreen_toggled)
colorblind_option.item_selected.connect(_on_colorblind_changed)
reduce_motion_check.toggled.connect(_on_reduce_motion_toggled)
func _on_master_volume_changed(value: float) -> void:
AudioServer.set_bus_volume_db(0, linear_to_db(value))
_save_settings()
func _on_music_volume_changed(value: float) -> void:
var bus = AudioServer.get_bus_index("Music")
AudioServer.set_bus_volume_db(bus, linear_to_db(value))
_save_settings()
func _on_sfx_volume_changed(value: float) -> void:
var bus = AudioServer.get_bus_index("SFX")
AudioServer.set_bus_volume_db(bus, linear_to_db(value))
_save_settings()
func _on_fullscreen_toggled(on: bool) -> void:
DisplayServer.window_set_mode(
DisplayServer.WINDOW_MODE_FULLSCREEN if on else DisplayServer.WINDOW_MODE_WINDOWED
)
_save_settings()
func _on_colorblind_changed(index: int) -> void:
# The actual shader swap happens in a global ColorblindManager, not shown.
GameManager.set_colorblind_mode(index)
_save_settings()
func _on_reduce_motion_toggled(on: bool) -> void:
GameManager.reduce_motion = on
_save_settings()
func _save_settings() -> void:
var config = ConfigFile.new()
config.set_value("audio", "master", master_slider.value)
config.set_value("audio", "music", music_slider.value)
config.set_value("audio", "sfx", sfx_slider.value)
config.set_value("video", "fullscreen", fullscreen_check.button_pressed)
config.set_value("accessibility", "colorblind", colorblind_option.selected)
config.set_value("accessibility", "reduce_motion", reduce_motion_check.button_pressed)
# Persist key bindings
for action in REMAPPABLE_ACTIONS:
for event in InputMap.action_get_events(action):
if event is InputEventKey:
config.set_value("input", action, event.physical_keycode)
break
config.save("user://settings.cfg")
func _load_settings() -> void:
var config = ConfigFile.new()
if config.load("user://settings.cfg") != OK:
return
master_slider.value = config.get_value("audio", "master", 1.0)
music_slider.value = config.get_value("audio", "music", 1.0)
sfx_slider.value = config.get_value("audio", "sfx", 1.0)
# ... and so on for the rest
The remap system is the bit most worth studying. The _input callback only fires when awaiting_remap_for is set, and it captures the next keypress, clears the previous binding, installs the new one, and persists the change. A production version would handle controller buttons separately, conflict detection (warning if you bind two actions to the same key), and a "reset to defaults" button. Build that as the exercise.
The colorblind mode is implementation-light here intentionally: the actual screen-color filter would be a post-processing shader applied via a CanvasLayer-attached ColorRect with a custom filter material. Godot's documentation has examples; the practical pattern is that GameManager.set_colorblind_mode(index) updates a shader uniform that the screen filter reads.
Progressive Project Update — Ch 29: Full UI Suite
This chapter's project deliverable is the complete UI layer for your action-adventure prototype. By chapter end you should have:
- Main Menu with Continue/New Game/Settings/Quit, working save detection (Continue only enabled if a save exists), and the title screen art and music landing within 3 seconds of launch.
- Pause Menu opened by Esc/Start, with Resume/Settings/Save/Quit to Main Menu, default focus on Resume so a single button dismisses, and proper
get_tree().pausedintegration. - HUD with Tier 1 (health, currency, currently equipped weapon icon), Tier 2 (interaction prompts, damage numbers if your style supports them, boss health bar when in boss fight), and Tier 3 (inventory, map, quest log accessed via dedicated buttons).
- Inventory as a grid (start with 8x5 = 40 slots), with hover/focus tooltips, controller navigation working (focus_neighbor wiring), and at least basic "Use" action.
- Settings with audio sliders (master/music/sfx), video toggles (fullscreen, vsync), accessibility (colorblind dropdown, reduce-motion checkbox, subtitle on/off and size), and key remapping for at least 6 actions, persisted to
user://settings.cfg. - Accessibility baseline: subtitles for any voiced lines (re-using the dialogue system from Ch 21), colorblind shader (even if minimal), and remappable controls.
This is the largest single Project Checkpoint so far in the book. Budget two to three weeks for a competent first pass; another two for polish. Most of the surprises will be controller focus issues — every menu should be navigable end-to-end with no mouse. Test that on every screen.
Common Pitfalls
A short list of mistakes you will make and recognize after the fact:
-
Submenus within submenus. Players want flat menus. Each level of nesting is friction. If your settings has Tabs > Subcategories > Slider, that is one level too many. Most game settings should be one level deep with maybe a tab structure.
-
Tiny text. Designers work close to monitors. Players sit on couches. Your text is too small. The default body size for console games is
28-32px at 1080pminimum, period. -
No controller UX. You built it on a mouse, "added controller support" in a sprint, and shipped. The controller version is unusable. Honest playtest with a controller-only player tells you immediately.
-
Accessibility as afterthought. You added subtitles in the last sprint, with no size options, on a transparent background. Color codes everywhere with no alternative. A reduced-motion option that does nothing because animations were never built around the toggle. Users notice within minutes; reviewers notice within hours.
-
Confirmation dialog for trivial actions. "Are you sure you want to equip this sword?" The player learns to dismiss without reading. When the real confirmation appears (delete save), it dies the same death.
-
Pausing the game during the inventory. Common in JRPG-influenced design. Sometimes correct (turn-based, deliberate inventory). Often wrong (action games where the inventory pause becomes a strategic crutch — the Bethesda inventory problem, where players pause-eat 30 cheese wheels mid-fight).
Summary
UI is the layer through which every other system in your game speaks to the player. When invisible, your design lands. When friction-laden, the player blames the design. The choice between diegetic and non-diegetic UI is the most consequential architectural decision; choose with eyes open about the tradeoffs in speed, discoverability, and engineering cost. The HUD is a hierarchy: Tier 1 always visible, Tier 2 contextual, Tier 3 hidden — and most teams over-promote. Menus should respect the player's most common need (Continue should be one button; Resume should be the default highlight). Each input method (mouse, controller, touch) demands its own UI architecture, not a skin. Type, color, and iconography all have measurable accessibility floors that should not be optional. Confirm destructive, undoable actions; do not confirm trivial actions; prefer undo to confirmation where possible. Accessibility is baseline now — The Last of Us Part II set a standard the industry has begun to meet, and the financial and moral arguments are aligned. Build accessibility into the architecture, not the polish phase.
This is the chapter that makes your other chapters feel professional. Spend the time. The combat is great, but the player has to find the combat first.
Next up: Sound. The other invisible layer.