Button Texture Configuration
Replace the texture of any UI button in the game with a custom mod-themed appearance.
Buttons in the game all have a default appearance. You can replace the texture of any specific button from your mod — for example, giving the crafting button a unique look themed to your mod.
Setup
1. Add your texture
Add the replacement texture to your mod’s ui.yaml under the textures section as you normally would:
textures:
- name: my_disconnect_button
Place the corresponding my_disconnect_button.png in:
mods/<your-mod>/assets/textures/ui/my_disconnect_button.png
2. Declare the override
In the same ui.yaml, add a button-overrides section. Each entry maps a button’s display label to the texture key you want to use:
button-overrides:
Disconnect: YourMod:my_disconnect_button
Craft: YourMod:my_craft_button
The texture key on the right follows the usual namespacing rule: a bare name (my_disconnect_button) resolves to your own mod, and an explicit OtherMod:name points at another mod’s texture. Both forms work.
A key that doesn’t resolve costs you the custom art, not the button. If the named texture isn’t registered, the button falls back to the default
Creation:buttonand a warning naming the key is logged once. It used to render nothing at all — no texture, no label, and no clickable area — which is how a mistake here could silently remove a button from a menu.
Example ui.yaml
textures:
- name: my_disconnect_button
- name: my_craft_button
frame-time-ms: 80
button-overrides:
Disconnect: YourMod:my_disconnect_button
Craft: YourMod:my_craft_button
Available Button Labels
These are all the buttons that exist in the base game and can be overridden:
| Context | Label |
|---|---|
| Pause menu | Resume Game |
| Pause menu | Disconnect |
| Pause menu | Quit Game |
| Pause menu — confirmation dialog | Yes |
| Pause menu — confirmation dialog | No |
| Disconnected screen | Return to Menu |
| Main menu | Single Player |
| Main menu | Multiplayer |
| Main menu | Exit |
| Single-player world select | Create New World |
| Single-player world select | Load Selected Save |
| Single-player world select | Delete Selected Save |
| Single-player / host / join menus | Back |
| Multiplayer menu | Host and Play |
| Multiplayer menu | Join Game |
| Join via IP menu | Join |
| Join game menu | Join Via IP |
| Host select save menu | Host Selected Save |
| Create world menu | Create and Play |
| Configure host menu | Play |
| In-game inventory | Open Crafting Menu |
| Crafting panel | Craft |
| Structure editor | Erase |
| Death screen | Respawn |
Note: Labels are case-sensitive and must match exactly, including spaces.
Animated Button Textures
Button textures support frame animation with per-action timing for hover, un-hover, and idle states. Each state is a horizontal row of equal-size frames; a button that defines more than one state stacks those rows into a grid — hover in row 0, unhover in row 1, idle in row 2 (rows below the last used one can be omitted, earlier unused rows must still be present).
textures:
- name: my_leave_button
frame-width: 300
frame-height: 30
hover-action:
frame-count: 5
frame-time-ms: 80
unhover-action:
frame-count: 5
frame-time-ms: 80
idle-action:
frame-count: 5
frame-time-ms: 80
Per-Frame Timing
Instead of a single uniform frame duration, you can specify a different duration for each frame within any action block using frame-durations-ms. Each entry is either a plain number (milliseconds for one frame) or a batch shorthand for a run of frames at the same duration.
Flat list:
idle-action:
frame-count: 4
frame-time-ms: 100
frame-durations-ms:
- 80
- 80
- 200
- 500
Batch shorthand:
idle-action:
frame-count: 5
frame-time-ms: 80
frame-durations-ms:
- count: 3
duration-ms: 80
- count: 2
duration-ms: 200
Flat entries and batch entries can be freely mixed in the same list.
The total number of entries produced must equal frame-count. If it doesn’t match, or if frame-durations-ms is absent, the uniform duration key (frame-time-ms) is used for all frames.
Hover Animations
You can play a separate animation when the player’s cursor is over a button. The hover animation is configured via a hover-action sub-block inside the texture entry.
The frame dimensions for the entire texture image (every row — idle, hover, and unhover frames) are set with frame-width and frame-height directly on the texture entry, not inside any action block. A multi-row (multi-state) button therefore needs an explicit frame-height so each row is sliced at the right height.
Fields
| Field | Type | Description |
|---|---|---|
frame-width | integer | Width of each frame in pixels (top-level field on the texture entry) |
frame-height | integer | Height of each frame in pixels (top-level field on the texture entry) |
frame-count | integer | Number of frames in the hover strip |
frame-time-ms | integer | Duration of each frame in milliseconds |
loop | boolean | If true, the animation loops continuously. If false (default), it plays once and holds on the last frame |
Example
textures:
- name: my_leave_button
frame-width: 300
frame-height: 30
hover-action:
frame-count: 5
frame-time-ms: 80
loop: false
button-overrides:
Disconnect: YourMod:my_leave_button
Quit Game: YourMod:my_leave_button
The texture image must be a horizontal strip containing all hover frames side by side. When the cursor is not over the button, only the first frame is shown (static). When the cursor enters the button, the animation plays from the moment of entry.
By default (loop: false) the animation plays once and freezes on the last frame until the cursor leaves. Set loop: true to cycle the animation continuously while the cursor remains over the button.
Buttons without a hover-action block always render as a single static frame.
Unhover Animations
You can play a separate animation when the player’s cursor leaves the button area. The unhover animation is configured via an unhover-action sub-block inside the texture entry.
Unhover frames occupy row 1 of the texture image, directly below the hover frames (which are row 0 — see Idle Animations for the full row assignment). The unhover animation is its own horizontal strip of frame-count frames starting at column 0 of that row, independent of how many hover frames row 0 has. This row assignment is fixed: even a button with no hover-action still reserves row 0, so its unhover frames go in row 1.
Fields
| Field | Type | Description |
|---|---|---|
frame-count | integer | Number of frames in the unhover strip |
frame-time-ms | integer | Duration of each frame in milliseconds |
The animation always plays once when the cursor leaves, then the button returns to its idle first frame.
Example
textures:
- name: my_leave_button
frame-width: 300
frame-height: 30
hover-action:
frame-count: 5
frame-time-ms: 80
loop: false
unhover-action:
frame-count: 5
frame-time-ms: 80
button-overrides:
Disconnect: YourMod:my_leave_button
Quit Game: YourMod:my_leave_button
In this example the texture image is a grid, not one long strip: row 0 holds the 5 hover frames and row 1 holds the 5 unhover frames (each frame frame-width × frame-height, so the image is 300 × 5 wide and 30 × 2 tall). Idle frames, if you add an idle-action, occupy row 2.
When the cursor leaves the button, the unhover animation plays once from the moment of departure, then the button returns to its idle first frame.
Buttons without an unhover-action block return to the static idle frame immediately when the cursor leaves.
Note: All frames in the texture image share the same
frame-widthandframe-heightdefined as top-level fields on the texture entry.
Idle Animations
You can play a looping (or one-shot) animation while the button is in its default state — not hovered and not playing an unhover animation. The idle animation is configured via an idle-action sub-block inside the texture entry.
Idle frames occupy the third row of the texture image (row index 2). Hover frames are in row 0 and unhover frames are in row 1. If you only need an idle animation without hover/unhover, those earlier rows may still be present but unused.
Fields
| Field | Type | Default | Description |
|---|---|---|---|
frame-count | integer | 0 | Number of frames in the idle strip |
frame-time-ms | integer | 0 | Duration of each frame in milliseconds |
loop | boolean | true | If true, the animation loops continuously while the button is idle. If false, it plays once and holds on the last frame |
Example
textures:
- name: my_leave_button
frame-width: 300
frame-height: 30
hover-action:
frame-count: 5
frame-time-ms: 80
unhover-action:
frame-count: 5
frame-time-ms: 80
idle-action:
frame-count: 5
frame-time-ms: 100
loop: true
button-overrides:
Disconnect: YourMod:my_leave_button
Quit Game: YourMod:my_leave_button
In this example the texture image has three rows:
- Row 0 — 5 hover frames (played when cursor is over the button)
- Row 1 — 5 unhover frames (played once when cursor leaves)
- Row 2 — 5 idle frames (looped while the button is at rest)
The loop: true default means you do not need to specify it explicitly for a looping idle. Set loop: false to play the idle animation once and freeze on the last frame.
Buttons without an idle-action block (or with frame-count: 0) display a static first frame when idle.
Overrides
An individual texture entry can take over another mod’s registered button texture at load time by adding override with that texture’s full mod-namespaced name:
textures:
- name: my_disconnect_button
override: Creation:disconnect_button
- The
namefield is still required — it locates your replacement PNG in your mod’s folder. - Your entry replaces the target’s registered texture, so redeclare any settings (such as
frame-width,frame-height, or thehover-action/unhover-action/idle-actionblocks) you want to keep.
This per-entry override replaces one specific named button texture at load time. It is distinct from the top-level button-overrides map, which remaps a button label to a texture at render time.
Multiple Mods
If more than one mod defines an override for the same label, the last mod loaded wins. Be mindful of this if your mod is intended to coexist with others that also restyle buttons.