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:button and 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:

ContextLabel
Pause menuResume Game
Pause menuDisconnect
Pause menuQuit Game
Pause menu — confirmation dialogYes
Pause menu — confirmation dialogNo
Disconnected screenReturn to Menu
Main menuSingle Player
Main menuMultiplayer
Main menuExit
Single-player world selectCreate New World
Single-player world selectLoad Selected Save
Single-player world selectDelete Selected Save
Single-player / host / join menusBack
Multiplayer menuHost and Play
Multiplayer menuJoin Game
Join via IP menuJoin
Join game menuJoin Via IP
Host select save menuHost Selected Save
Create world menuCreate and Play
Configure host menuPlay
In-game inventoryOpen Crafting Menu
Crafting panelCraft
Structure editorErase
Death screenRespawn

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

FieldTypeDescription
frame-widthintegerWidth of each frame in pixels (top-level field on the texture entry)
frame-heightintegerHeight of each frame in pixels (top-level field on the texture entry)
frame-countintegerNumber of frames in the hover strip
frame-time-msintegerDuration of each frame in milliseconds
loopbooleanIf 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

FieldTypeDescription
frame-countintegerNumber of frames in the unhover strip
frame-time-msintegerDuration 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-width and frame-height defined 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

FieldTypeDefaultDescription
frame-countinteger0Number of frames in the idle strip
frame-time-msinteger0Duration of each frame in milliseconds
loopbooleantrueIf 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 name field 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 the hover-action/unhover-action/idle-action blocks) 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.