Skip to content

Drawing Text

SpiDrone edited this page Jul 22, 2026 · 5 revisions

Drawing Text

Everything here assumes you've already registered a font per the Adding Fonts page. All examples use a ResourceLocation font ID like mymod:myfont, but every method also has a String-based overload ("mymod:myfont") and a no-font overload that falls back to Minecraft's own vanilla font.

Basics

UIGraphicsHelper.drawCustomFont(graphics, myFont, "Hello World", x, y, 0xFFFFFFFF, false);
Param Meaning
graphics The GuiGraphics from your render/draw call
myFont The font's registered ID
x, y Anchor position — meaning depends on align (see below)
color ARGB int, e.g. 0xFFFFFFFF = opaque white
dropShadow Whether to render vanilla's text drop shadow
# Drawing Text

Everything here assumes you've already registered a font per the [Adding Fonts](Adding-Fonts) page. All examples use a ResourceLocation font ID like mymod:myfont, but every method also has a String-based overload ("mymod:myfont") and a no-font overload that falls back to Minecraft's own vanilla font.

Basics

UIGraphicsHelper.drawCustomFont(graphics, myFont, "Hello World", x, y, 0xFFFFFFFF, false);
Param Meaning
graphics The GuiGraphics from your render/draw call
myFont The font's registered ID
x, y Anchor position — meaning depends on align (see below)
color ARGB int, e.g. 0xFFFFFFFF = opaque white
dropShadow Whether to render vanilla's text drop shadow

Shorter overloads drop trailing params with sensible defaults:

UIGraphicsHelper.drawCustomFont(graphics, myFont, "Hello", x, y, color);      // no drop shadow
UIGraphicsHelper.drawCustomFont(graphics, myFont, "Hello", x, y);             // + white text
UIGraphicsHelper.drawCustomFont(graphics, "Hello", x, y);                     // + vanilla font

Alignment

public enum TextAlign { LEFT, CENTER, RIGHT }

Add align as the last argument. It changes what x means:

  • LEFT (default) — x is the left edge of the text
  • CENTERx is the horizontal center point
  • RIGHTx is the right edge of the text
// Title, centered on screen
UIGraphicsHelper.drawCustomFont(graphics, myFont, "Title", w / 2, 20, 0xFFFFFFFF, false, TextAlign.CENTER);

// Numbers pinned to the right edge
UIGraphicsHelper.drawCustomFont(graphics, myFont, "42", w - 10, 40, 0xFFFFFFFF, false, TextAlign.RIGHT);

// Names pinned to the left edge — same as omitting align entirely
UIGraphicsHelper.drawCustomFont(graphics, myFont, "Player Name", 10, 40, 0xFFFFFFFF, false, TextAlign.LEFT);

This is handy for laying out a HUD row where numbers and labels need to stay aligned on opposite edges no matter how long the text is.

Color Effects

Instead of a flat int color, you can pass a ComponentEffects.TextEffect for per-character coloring. See ComponentEffects for the full list — currently:

ComponentEffects.solid(int color)                     // flat color (same as passing color directly)
ComponentEffects.gradient(int colorStart, int colorEnd) // smooth blend across the string
ComponentEffects.rainbow()                             // animated hue cycle
ComponentEffects.rainbow(float speed)                  // faster/slower cycle
ComponentEffects.holographic(int color1, int color2)   // animated shimmer between two colors
UIGraphicsHelper.drawCustomFont(graphics, myFont, "Legendary", x, y,
    ComponentEffects.gradient(0xFFFFD700, 0xFFFF4500), false);

UIGraphicsHelper.drawCustomFont(graphics, myFont, "Rainbow Title", x, y,
    ComponentEffects.rainbow(), false, TextAlign.CENTER);

Combining color effects

ComponentEffects.combine(...) blends multiple color effects together (averaged per character):

TextEffect blended = ComponentEffects.combine(
    ComponentEffects.rainbow(),
    ComponentEffects.gradient(0xFFFFFFFF, 0xFF000000)
);
UIGraphicsHelper.drawCustomFont(graphics, myFont, "Blended", x, y, blended, false);

Motion Effects

Motion effects move each character individually and are passed as a second effect, ComponentEffects.TextOffset, alongside a color effect:

ComponentEffects.wave()                                 // gentle up/down bob per character
ComponentEffects.wave(float amplitude, float speed)      // custom height/speed
ComponentEffects.typewriterBounce()                      // one letter bounces up at a time, left to right
ComponentEffects.typewriterBounce(float amplitude, long msPerChar) // custom height/timing
// Plain white text with a wave
UIGraphicsHelper.drawCustomFont(graphics, myFont, "Wavy Text", x, y,
    ComponentEffects.solid(0xFFFFFFFF), ComponentEffects.wave(), false);

// Rainbow color + wave motion together
UIGraphicsHelper.drawCustomFont(graphics, myFont, "Rainbow Wave", x, y,
    ComponentEffects.rainbow(), ComponentEffects.wave(), false);

// Typewriter-style bounce, one letter rising at a time
UIGraphicsHelper.drawCustomFont(graphics, myFont, "Typewriter", x, y,
    ComponentEffects.solid(0xFFFFFFFF), ComponentEffects.typewriterBounce(), false);

Combining motion effects

ComponentEffects.combine(...) also works for offset effects (summed per character):

TextOffset busy = ComponentEffects.combine(ComponentEffects.wave(), ComponentEffects.typewriterBounce());

Stacking multiple motion effects can get visually noisy — try lower amplitudes first.

Note: motion effects draw one character at a time instead of the whole string in a single call, since each glyph needs its own position. This is fine for titles and short labels; avoid it for long paragraphs.

Wrapped Text in a Bounding Box

drawCustomFontBound auto-wraps text to fit inside a box, with an optional manual split character for forced line breaks. Text that would overflow the box is clipped rather than drawn outside it.

int linesDrawn = UIGraphicsHelper.drawCustomFontBound(
    graphics, myFont, "Some long description$New paragraph here",
    '$',                    // manual split character — forces a break wherever it appears
    x1, y1, x2, y2,          // box bounds
    0xFFFFFFFF, false,       // color, drop shadow
    TextAlign.LEFT           // aligns each wrapped line within the box width
);

The $ splits the string into segments first; each segment is then automatically word-wrapped to fit the box width. Useful for translations where a translator needs some control over line breaks that automatic wrapping alone can't guarantee.

Returns the number of lines actually drawn — handy for sizing a panel around the text afterward.

Measuring Text

Before drawing into a layout, you can measure how wide text will render in a given font:

int width = UIGraphicsHelper.measureCustomFontWidth(myFont, "Hello World");

Quick Reference

Goal Method
Single line, flat color drawCustomFont(graphics, font, text, x, y, color, dropShadow, align)
Single line, color effect drawCustomFont(graphics, font, text, x, y, TextEffect, dropShadow, align)
Single line, color + motion drawCustomFont(graphics, font, text, x, y, TextEffect, TextOffset, dropShadow, align)
Wrapped in a box drawCustomFontBound(graphics, font, text, splitChar, x1, y1, x2, y2, color, dropShadow, align)
Measure width measureCustomFontWidth(font, text)

Clone this wiki locally