> For the complete documentation index, see [llms.txt](https://edseries-plugins.gitbook.io/p/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://edseries-plugins.gitbook.io/p/pinnablockselector/reference/custom-textures.md).

# Custom Textures & Resource-Pack Menus

The selector and the purchase menu are PinnaPrison GUI files (`plugins/PinnaPrison/guis/pinnablockselector/`), so they can look like anything your resource pack can draw: a full picture as the background, your own icons on every button, custom tooltip frames and values drawn with your own art. This page shows how. You only edit the menu files and your pack; PinnaBlockSelector needs no extra setting.

## How it fits together

A resource-pack menu is still a normal chest menu, built from three layers that you set in the menu file:

1. **The background**: a picture from your pack, placed in the menu **title**.
2. **The buttons**: menu items that wear your pack's models and tooltip frames.
3. **Live values**: text, glyphs or models that change with the player's data.

The server only sends the title and the items. The pack on the player's game does the drawing, so every player needs your pack loaded. Players without it see vanilla items and unreadable characters in the title.

## 1. The background picture

A menu title is text, and text can show font images ("glyphs") from your pack. A glyph as large as the chest window covers the vanilla texture and becomes the background.

```yaml
# plugins/PinnaPrison/guis/pinnablockselector/blockselector.yml
title: '&f:offset_-18::block_selector:'
rows: 6
```

| Part               | What it does                                                                                                                                                                                                                                                                                              |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `&f`               | Makes the title white. Title text is dark grey by default and glyphs take the colour of the text, so without `&f` the picture looks dark.                                                                                                                                                                 |
| `:offset_-18:`     | Moves the text cursor 18 pixels to the left. The title starts 8 pixels in from the left edge of the window, so the picture needs a negative offset to start at the edge. The right number depends on how your picture was drawn: change it one pixel at a time until the picture lines up with the slots. |
| `:block_selector:` | The picture itself (here an ItemsAdder font image called `block_selector`).                                                                                                                                                                                                                               |

Set `rows` to the menu height your picture was made for. Draw the frames of the 28 block slots, the 4 choice slots and the buttons into the picture, so the items sit inside them.

### Writing glyphs for your pack plugin

| Pack made with | Picture                                                                                                                         | Offset                                                     |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| ItemsAdder     | `:name:`, or `%img_name%` through PlaceholderAPI                                                                                | `:offset_-18:` (or `%img_offset_-18%`)                     |
| Nexo or Oraxen | the glyph's PlaceholderAPI placeholder (for example `%nexo_<glyph-id>%` or `%oraxen_<glyph-id>%`), or the glyph's own character | the plugin's shift placeholder or character (see its docs) |
| Your own pack  | the character you gave the picture in your font file                                                                            | a character of a `space` provider with a negative width    |

Menu titles use `&` colour codes, not MiniMessage, so tags such as `<glyph:...>` or `<shift:...>` are shown as plain text. Use the PlaceholderAPI form or the raw character instead (PlaceholderAPI must be installed for `%...%`).

### Using your own font

If you make the pack yourself, add the picture and a few negative spaces to a font, for example `assets/minecraft/font/default.json`. Use characters from Unicode's private use area, which no language uses: here U+E000 for the picture and U+F801, U+F808 and U+F810 for spaces of -1, -8 and -16 pixels.

In the examples below, `<U+E000>` stands for that one character. In the JSON file write it as a JSON escape (a backslash, the letter `u` and the four hex digits `E000`), or paste the character itself.

```json
{
  "providers": [
    { "type": "space", "advances": { "<U+F801>": -1, "<U+F808>": -8, "<U+F810>": -16 } },
    { "type": "bitmap", "file": "mypack:gui/block_selector.png", "ascent": 13, "height": 222, "chars": ["<U+E000>"] }
  ]
}
```

The picture goes in `assets/mypack/textures/gui/block_selector.png`. `height` is the height the picture is drawn at (222 = a 6-row chest window) and `ascent` how far it reaches above the title line (13 puts its top at the top of the window). `ascent` must never be larger than `height`, or the game ignores the whole font.

In the menu file, write the same escapes inside a double-quoted YAML string (YAML only reads escapes between double quotes), or paste the characters. -16, -1 and -1 make the same 18 pixel offset as `:offset_-18:`:

```yaml
title: "&f<U+F810><U+F801><U+F801><U+E000>"
```

### Text on top of the picture

After the picture the cursor stands at its right edge, and anything written after it is drawn over the picture. Move back with another negative offset first, then write your text with a normal colour:

```yaml
title: '&f:offset_-18::block_selector::offset_-160:&8{category-name} &7{page-number}/{total-pages}'
```

The title takes the window tokens (`{category}`, `{category-name}`, `{page-number}`, `{total-pages}`, `{player}`) and PlaceholderAPI placeholders, and it is redrawn when the page changes.

## 2. Button textures

Menu items use PinnaPrison's item format. These are the keys that matter for a pack:

| Key                 | Use                                                                                                                                                                                                                                                                                                                                            |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `material`          | A vanilla material (`PAPER`...) or an item of your pack plugin: `itemsadder:<namespace>:<id>`, `nexo:<id>`, `oraxen:<id>`. Pack plugin items bring their own model, so they need no `custom-model-data`. `texture-<base64>` makes a custom head and `head-<player>` / `head-{player}` a player's head. An unknown material shows as a barrier. |
| `custom-model-data` | The model number your pack gives that material, e.g. `20010`. Tokens and placeholders work here too. `-1` or empty means none.                                                                                                                                                                                                                 |
| `tooltip-style`     | A tooltip frame from your pack, `namespace:id` (Minecraft 1.21.2+).                                                                                                                                                                                                                                                                            |
| `hide-tooltip`      | `true` shows no tooltip at all on hover (1.20.5+). The item can still be clicked.                                                                                                                                                                                                                                                              |
| `glow`              | The enchant shimmer, without a visible enchant.                                                                                                                                                                                                                                                                                                |
| `color`             | Tint for leather armour and potions: `'#RRGGBB'` or `'R,G,B'`.                                                                                                                                                                                                                                                                                 |

PinnaPrison menus have no `item-model` key: choose the model with `custom-model-data`, or use an item of your pack plugin as `material`. These keys work everywhere an item is written: the menu items, their state sections (`empty`, `changed`, `cooldown`, `selected`, `cannot-afford`, `locked`), the block entries and the page arrows of `pagination`.

### Custom model data

The number is read by the material's model in your pack. On Minecraft 1.21.4+ that is the item definition (for paper: `assets/minecraft/items/paper.json`, usually a `range_dispatch` on `custom_model_data`); older versions use `overrides` in `assets/minecraft/models/item/paper.json`. ItemsAdder, Nexo and Oraxen write these files for you: look up the number they gave your item, or use the item's id as `material`.

### Tooltip frames

`tooltip-style: 'mypack:gold'` uses `assets/mypack/textures/gui/sprites/tooltip/gold_background.png` and `gold_frame.png` from your pack (with `.png.mcmeta` files that set nine-slice scaling, like the vanilla tooltip). Placeholders work here too.

### Invisible items

A common trick is to draw the buttons into the background picture and put an invisible item on each button slot. Give those items a model with a fully transparent texture (a `custom-model-data` number your pack maps to an empty model). Add `hide-tooltip: true` to slots that should show nothing on hover, and leave it out on buttons so players can still read their name and lore.

### The block entries

The block entries use `material: '{material}'`, so they show the real block. Keep it that way and only give each state its own frame, so players see at a glance which blocks are chosen:

```yaml
pagination:
  source: 'pinnablockselector-blocks'
  slots: '10-16,19-25,28-34,37-43'
  entry:
    material: '{material}'
    tooltip-style: 'mypack:common'
    lore: ['&7Click to add it']
  selected-entry:
    material: '{material}'
    glow: true
    tooltip-style: 'mypack:rare'
    lore: ['&a#{position} &7of your blocks', '&7Click to remove it']
  full-entry:
    material: '{material}'
    tooltip-style: 'mypack:locked'
    lore: ['&cYour choice is full ({selected}/{max})']
  previous-page:
    slot: '48'
    material: PAPER
    custom-model-data: 20020
    tooltip-style: 'mypack:common'
    name: '&7Previous page'
  next-page:
    slot: '50'
    material: PAPER
    custom-model-data: 20021
    tooltip-style: 'mypack:common'
    name: '&7Next page'
```

Leave `name` out of the entries so every player sees the block's name in their own game language.

### A full button

The Apply button with its own icon and frame for each state: nothing to apply, changes ready, and changes waiting for the cooldown.

```yaml
  apply:
    custom-item:
      type: 'pinnablockselector-apply'
      cooldown-ready: '&aReady'
      block-line: '&7 #{position} &f{name}'
      no-blocks-line: '&7 Your mine tier''s blocks'
      # there are changes and they can be applied now
      changed:
        material: PAPER
        custom-model-data: 20011
        glow: true
        tooltip-style: 'mypack:gold'
        name: '&a&lApply'
        lore:
          - '&7Your mine will be made of:'
          - '{blocks}'
          - ''
          - '&aClick to apply'
      # there are changes, but the cooldown is still running
      cooldown:
        material: PAPER
        custom-model-data: 20012
        tooltip-style: 'mypack:locked'
        name: '&c&lApply'
        lore:
          - '&7You can apply again in &c{cooldown}'
    slot: '49'
    update-interval: 20
    # nothing changed
    material: PAPER
    custom-model-data: 20010
    tooltip-style: 'mypack:common'
    click-sound: 'UI_BUTTON_CLICK'
    name: '&7Apply'
    lore:
      - '&7No changes to apply.'
```

The choice slots work the same way: the item of `pinnablockselector-selected` shows the chosen block, and its `empty` section can be a pack icon (`material: PAPER` + `custom-model-data`) for a free slot. For an item of your pack plugin, replace `material` and `custom-model-data` with one line, for example `material: 'nexo:apply_button'`.

## 3. Numbers drawn with textures

PinnaBlockSelector has no option that turns its numbers into pictures by itself: its tokens (`{selected}`, `{max}`, `{position}`, `{cooldown}`...) are plain text in the menu's font. You can still get a fully textured look with what is there.

### A model per value

`custom-model-data` accepts tokens and PlaceholderAPI placeholders, so an item can change its model with a number:

```yaml
  info:
    custom-item:
      type: 'pinnablockselector-info'
    slot: '4'
    material: KNOWLEDGE_BOOK
    custom-model-data: '{selected}'
```

The item then has model data 0 to 4 by the number of chosen blocks, and your pack can show a different icon for each value, for example a counter with "2/4" painted on it. Use a material that no other item of your menus uses, because these low numbers would clash with your other models, and map the values in that material's item definition, here `assets/minecraft/items/knowledge_book.json` (Minecraft 1.21.4+):

```json
{
  "model": {
    "type": "minecraft:range_dispatch",
    "property": "minecraft:custom_model_data",
    "index": 0,
    "entries": [
      { "threshold": 1, "model": { "type": "minecraft:model", "model": "mypack:item/chosen_1" } },
      { "threshold": 2, "model": { "type": "minecraft:model", "model": "mypack:item/chosen_2" } },
      { "threshold": 3, "model": { "type": "minecraft:model", "model": "mypack:item/chosen_3" } },
      { "threshold": 4, "model": { "type": "minecraft:model", "model": "mypack:item/chosen_4" } }
    ],
    "fallback": { "type": "minecraft:model", "model": "mypack:item/chosen_0" }
  }
}
```

Each entry is used from its threshold up to the next one, and 0 uses the fallback. A PlaceholderAPI number works the same way, e.g. `custom-model-data: '%pinnablockselector_blocks%'` for the blocks on the mine right now.

### Glyphs from PlaceholderAPI

Titles, names and lore parse PlaceholderAPI, so a placeholder of another plugin that returns glyphs (for example a number written with your pack's digits) can be used anywhere in these menus. PinnaBlockSelector's own placeholders return plain text.

## Checklist

* Every player has your pack loaded (the server resource pack, or the hosting of your pack plugin), and it loads without errors.
* `&f` is the first thing in the title, and the offset lines the picture up with the slots.
* `tooltip-style` needs Minecraft 1.21.2+ and `hide-tooltip` 1.20.5+, on the server and on the player's game. Item definitions in `assets/<namespace>/items/` (such as `range_dispatch`) need 1.21.4+.
* A barrier instead of your item means the `material` is misspelled, or its pack plugin isn't installed or doesn't know that id.
* After editing the menu files run `/pinnaprison reload`. After changing the pack, rebuild it with your pack plugin and rejoin so the game loads the new version.
