Skip to content

UI Fonts and Glyphs

Dan Alexander edited this page Nov 3, 2026 · 2 revisions

UI, fonts and glyphs

Bitmap UI definitions, private-use characters, glyph positioning, menu overlays and Bedrock font conversion.

Documentation for VoxelCore v1.0.0. Home · Installation · Compatibility

Java UI font content

VoxelCore compiles shared spacing glyphs and namespaced bitmap UI definitions into every compatible generated Java pack. Textures can be tightly cropped: transparent padding is neither required nor used for positioning.

Use the compact ItemsAdder-style authoring shape:

ui:
  warps_menu:
    path: ui/npc/warps_menu.png
    scale_ratio: 18
    y_position: 8
    gui: true

path is relative to assets/<pack namespace>/textures/. scale_ratio becomes the bitmap provider height and defaults to the PNG height. y_position becomes its ascent, defaults to min(8, scale_ratio), may be negative, and cannot exceed scale_ratio. gui defaults to false; when true, the placeholder automatically appends the exact negative rendered advance so following title text returns to its original horizontal position. PNG dimensions and the scale ratio are limited to 256. An optional symbol may assign one private-use Unicode character; otherwise VoxelCore allocates a stable character and preserves the allocation in glyph-allocations.yml.

The Bedrock font atlas automatically preserves the native-resolution size of large bitmap glyphs (such as a 16px help-box question mark) while retaining the existing shared pixel-density calibration for normal-height rank, tag and HUD icons. The converter derives this from the Java bitmap provider's height and source PNG dimensions, including before transparent cropping. No separate Bedrock configuration or hand-editing of generated glyph pages is required. Regenerate the Bedrock pack normally after updating VoxelCore.

Logos and banners taller than 32 Java pixels do not fit a Bedrock text glyph at their Java size, because Bedrock draws a glyph-page pixel at a fixed size and every cell on a page grows to its widest glyph. They are reduced with their proportions kept: by default the longest side becomes at most bedrock.oversized_glyph_size pixels (128, i.e. a 2048px glyph page; lower it to keep pages small, up to 256). To control one glyph, add either optional key to its definition:

ui:
  branding_logo:
    path: ui/branding/logo.png
    scale_ratio: 128
    bedrock_height: 96   # exact height in pixels baked into the Bedrock page (1-256), overrides bedrock_scale
    # bedrock_scale: 0.5 # or: multiplier on scale_ratio (greater than 0, at most 8)

Glyphs that set either key may use up to 256 pixels on their longest side whatever oversized_glyph_size says. Both keys affect Bedrock only.

Bitmap providers in custom font files such as assets/<namespace>/font/branding.json are converted too, because Bedrock has one font and shows their private-use characters from the same glyph pages. A custom-font provider taller than 32 pixels is reduced as above; one with a negative ascent is a Java screen overlay and is not converted.

On Bedrock (Geyser), every gui: true definition is also exported as a chest-screen background: the Bedrock pack's ui/chest_screen.json shows the image whenever an inventory title contains that glyph, sized by scale_ratio, aligned for the conventional :offset_-8: prefix and placed vertically by y_position, and hides the default Bedrock title text for that menu. On those menus Bedrock's grey chest frame and close button are replaced by the Java container texture (assets/minecraft/textures/gui/container/generic_54.png from your packs, else vanilla), so a partly transparent retexture looks the same as on Java. This applies to Bedrock's Classic UI chest screen; the Pocket UI layout is unchanged. No server-side change is needed; a content pack that supplies its own ui/chest_screen.json keeps it and the generated backgrounds are skipped (listed in unsupported-items.txt).

Menu rows are deliberately not configuration data. The same cropped overlay can cover any subset of slots in a 1–6 row inventory; its vertical placement is controlled only by scale_ratio and y_position.

VoxelCore generates the final assets/minecraft/font/default.json, including positive/negative spacing providers and all bitmap providers. If a content pack supplies its own assets/minecraft/font/default.json, VoxelCore preserves its providers in their authored order and appends the generated providers. Custom font files such as assets/voxel/font/branding.json, language overrides such as assets/minecraft/lang/en_nz.json, and their referenced textures are copied unchanged. Authored bitmap/space characters reserve their Unicode values globally, so automatic allocations skip them and an explicit symbol collision fails validation instead of silently replacing branding glyphs. Missing textures, unsafe paths, invalid dimensions, duplicate explicit symbols, and incompatible targets fail validation. Minecraft 1.12.2 is rejected because it predates resource-pack bitmap fonts.

Each definition has a readable alias such as :warps_menu: and an unambiguous full alias such as :voxel/warps_menu:. Runtime replacement prefixes every UI glyph with Minecraft white (§f, conventionally authored as &f) so gray inventory-title formatting does not tint the bitmap. Definitions marked gui: true then append their calculated negative advance; ordinary emoji, rank, and inline font images leave the cursor after the image. Initial pixel positioning uses :offset_<pixels>:, for example:

:offset_-16::warps_menu:§rWarps

Offsets from -1024 through 1024 are supported. Non-power-of-two values are composed from multiple generated spacing glyphs, so :offset_-17: also resolves exactly.

VoxelCore resolves inline definitions (gui: false, including the default) in player chat only for senders with voxelcore.placeholders.chat. Definitions marked gui: true and :offset_<pixels>: controls require the separate voxelcore.placeholders.chat.gui permission. The permissions are independent: premium players can receive the inline permission for emojis or ranks, while staff can receive only the GUI permission when appropriate. Both default to operators and can be granted through the server permission manager. Unauthorized placeholders remain unchanged.

VoxelCore-owned UI and integrations should call VoxelCore.getInstance().getTextPlaceholderService().resolve(text) before sending titles or other text. A resource pack cannot mutate a title already created by an unrelated plugin; therefore DeluxeMenus cannot receive transparent :name: replacement from VoxelCore without a dedicated integration. Until that integration exists, use the literal allocated character returned by:

/voxelcore admin ui copy voxel:warps_menu
/voxelcore admin ui copy :warps_menu:

Both forms have tab completion. ui list and ui info <content-id-or-alias> expose definitions and resolved metadata. ui copy sends a clickable clipboard component, supports Shift-click insertion, and prints the literal character and codepoint. On clients without direct clipboard support, clicking puts the character into the chat input so it can be selected and copied.

VoxelCore automatically resolves UI placeholders in player chat, inventory titles, and Bukkit player-list display names, headers, and footers. The player-list synchronizer runs after server ticks so values supplied by ordinary tab-list plugins are processed without a plugin-specific dependency. Integrations writing packet-only or Adventure-only components should call VoxelCore#getTextPlaceholderService() before sending their text.

VoxelCore also compiles a built-in three-line popup-tooltip font set and border slices for every resource-pack target that supports bitmap fonts. The renderer maps ordinary ASCII onto three private-use rows with ascents 4, -1, and -6, then overlays them on a dynamically sized background using the same generated spacing glyphs as :offset_<pixels>:. Because the row variants are also appended to minecraft:default, runtime popups work through Bukkit's cross-version title/subtitle API without requiring Adventure font components. The generated pack additionally exposes voxelcore:tooltip_line1, voxelcore:tooltip_line2, and voxelcore:tooltip_line3 for integrations that want the named fonts directly.

For live testing, use three text sections separated with |:

/voxelcore admin ui tooltip 3 &fTiki Coffee Table | &7Price: 250 | &6(Click to purchase)

The first argument is the display duration in seconds, from greater than zero through 300 seconds. The tooltip appears to the right of the crosshair using the built-in default horizontal offset. The current generated resource pack must be built and applied to the client before the compiler-owned glyphs can render.

On first startup, VoxelCore also extracts editable tooltip artwork to:

plugins/VoxelCore/assets/tooltip/
├── left.png
├── center.png
└── right.png

These files are the default tooltip border templates bundled with the plugin. Edit the pixels in place and the next pack validate / pack build uses those files instead of the embedded fallback artwork. The three templates must remain exactly 2x38 pixels so their font advances remain stable. Existing files are never overwritten during startup, so plugin updates preserve local artwork changes. An optional right_offset.png may also be supplied at 4x38; otherwise VoxelCore keeps its built-in offset variant.

Physical container titles can use normal VoxelCore UI glyph and offset placeholders. Define any background artwork through the ordinary ui: content system and reference its glyph in config.yml. Only physical block-backed inventories are modified; virtual/plugin-created GUIs, entity inventories and vehicle inventories keep their own titles.

ui:
  container_titles:
    enabled: true
    chest:
      single: '&f:offset_-8::generic_27_top::offset_8:Chest'
      double: '&f:offset_-8::generic_54_top::offset_8:Large Chest'
    barrel: '&f:offset_-8::barrel_background::offset_8:Barrel'

The barrel_background glyph is an example, not a bundled image: supply it in your content. Other physical block containers can use their lower-case material name (for example hopper, dispenser, furnace, blast_furnace, smoker and brewing_stand). The shulker_box key applies to all colours; an individual colour, such as red_shulker_box, can override it.

The original ui.chest_titles configuration remains supported. When ui.container_titles.enabled is true, non-empty container_titles.chest.single and container_titles.chest.double values override the corresponding legacy chest values. Unconfigured containers retain their normal names. Title resolution uses the existing modern Paper initial-open override with the older Bukkit fallback. The Bedrock generated chest-screen background artwork remains a separate, Classic UI-only feature.

Optional plugin integrations

PlaceholderAPI and ShopGUI+ integration is documented separately in Integrations. Both are optional.

Clone this wiki locally