Skip to main content

Overview

Minecraft Community Edition’s GUI system consists of reusable components for building user interfaces. The system is built around the GuiComponent base class, with specialized components for buttons, HUD elements, and visual effects.

GuiComponent Base Class

The GuiComponent class (GuiComponent.h) provides fundamental rendering utilities used by all GUI elements:
class GuiComponent
{
protected:
    float blitOffset;  // Z-offset for layered rendering
    
    // Drawing primitives
    void hLine(int x0, int x1, int y, int col);
    void vLine(int x, int y0, int y1, int col);
    void fill(int x0, int y0, int x1, int y1, int col);
    void fillGradient(int x0, int y0, int x1, int y1, int col1, int col2);
    
public:
    void drawCenteredString(Font *font, const wstring& str, int x, int y, int color);
    void drawString(Font *font, const wstring& str, int x, int y, int color);
    void blit(int x, int y, int sx, int sy, int w, int h);
};
Source: Minecraft.Client/GuiComponent.h:5

Drawing Methods

Line Drawing
// Horizontal line from x0 to x1 at y
hLine(int x0, int x1, int y, int color);

// Vertical line from y0 to y1 at x
vLine(int x, int y0, int y1, int color);
Filled Rectangles
// Solid color rectangle
fill(int x0, int y0, int x1, int y1, int color);

// Gradient rectangle (top to bottom)
fillGradient(int x0, int y0, int x1, int y1, int topColor, int bottomColor);
Text Rendering
// Draw text centered at position
drawCenteredString(Font *font, const wstring& str, int x, int y, int color);

// Draw text left-aligned at position
drawString(Font *font, const wstring& str, int x, int y, int color);
Texture Blitting
// Copy texture region to screen
blit(int x, int y, int sourceX, int sourceY, int width, int height);
Copies a rectangular region from the currently bound texture to screen coordinates.

Button Component

The Button class provides interactive button elements for screens.

Button Properties

class Button : public GuiComponent
{
protected:
    int w, h;           // Button dimensions
    
public:
    int x, y;           // Button position
    wstring msg;        // Button label text
    int id;             // Button identifier
    bool active;        // Can be clicked
    bool visible;       // Should be rendered
};
Source: Minecraft.Client/Button.h:5

Creating Buttons

Constructor with default size (200x20):
Button(int id, int x, int y, const wstring& msg);
Constructor with custom size:
Button(int id, int x, int y, int w, int h, const wstring& msg);
Example:
// Standard button
buttons.push_back(new Button(0, width/2 - 100, height/2, L"Play Game"));

// Custom sized button
buttons.push_back(new Button(1, 10, 10, 80, 20, L"Small"));
Source: Minecraft.Client/Button.cpp:5

Button States

Buttons have three visual states:
int Button::getYImage(bool hovered)
{
    int res = 1;              // Normal state
    if (!active) res = 0;     // Disabled state
    else if (hovered) res = 2; // Hovered state
    return res;
}
Source: Minecraft.Client/Button.cpp:30
  • State 0 (Disabled): Gray, non-interactive
  • State 1 (Normal): Default appearance
  • State 2 (Hovered): Highlighted when mouse over

Button Rendering

Buttons render using the gui.png texture:
void Button::render(Minecraft *minecraft, int xm, int ym)
{
    if (!visible) return;
    
    Font *font = minecraft->font;
    glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture(TN_GUI_GUI));
    glColor4f(1, 1, 1, 1);
    
    bool hovered = xm >= x && ym >= y && xm < x + w && ym < y + h;
    int yImage = getYImage(hovered);
    
    // Render left half
    blit(x, y, 0, 46 + yImage * 20, w / 2, h);
    // Render right half
    blit(x + w / 2, y, 200 - w / 2, 46 + yImage * 20, w / 2, h);
    
    renderBg(minecraft, xm, ym);  // Custom background rendering
    
    // Render text with state-based color
    int textColor = !active ? 0xffa0a0a0 : (hovered ? 0xffffa0 : 0xe0e0e0);
    drawCenteredString(font, msg, x + w / 2, y + (h - 8) / 2, textColor);
}
Source: Minecraft.Client/Button.cpp:38

Button Interaction

Click Detection:
bool Button::clicked(Minecraft *minecraft, int mx, int my)
{
    return active && mx >= x && my >= y && mx < x + w && my < y + h;
}
Source: Minecraft.Client/Button.cpp:82 Release Handling:
virtual void released(int mx, int my);  // Override for custom behavior
Source: Minecraft.Client/Button.cpp:78

Button Customization

renderBg() - Override for custom button appearance:
virtual void renderBg(Minecraft *minecraft, int xm, int ym);
Used by specialized button types to add custom rendering. Source: Minecraft.Client/Button.cpp:74

Gui (HUD) Class

The Gui class manages the in-game heads-up display (HUD), including health, hunger, hotbar, and messages.

Gui Overview

class Gui : public GuiComponent
{
private:
    static const int m_iMaxMessageWidth = 280;
    static ItemRenderer *itemRenderer;
    vector<GuiMessage> guiMessages[XUSER_MAX_COUNT];  // Per-player messages
    Random *random;
    Minecraft *minecraft;
    
public:
    wstring selectedName;              // Selected block/entity name
    wstring overlayMessageString;      // Jukebox/achievement message
    int overlayMessageTime;            // Message display timer
    bool animateOverlayMessageColor;   // Rainbow text effect
    
    static float currentGuiBlendFactor;   // For blending effects
    static float currentGuiScaleFactor;   // Current GUI scale
    
    float progress;  // Loading/progress bar value
};
Source: Minecraft.Client/Gui.h:8

HUD Rendering

The main render method handles all HUD elements:
void Gui::render(float a, bool mouseFree, int xMouse, int yMouse);
Parameters:
  • a - Alpha/interpolation value
  • mouseFree - Whether cursor is visible
  • xMouse, yMouse - Cursor position
Source: Minecraft.Client/Gui.cpp:57

GUI Scaling

The HUD adapts to different screen configurations:
// Calculate GUI scale based on settings
if (minecraft->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_FULLSCREEN) {
    guiScale = app.GetGameSettings(iPad, eGameSetting_UISize) + 2;
} else {
    guiScale = app.GetGameSettings(iPad, eGameSetting_UISizeSplitscreen) + 2;
}

ScreenSizeCalculator ssc(minecraft->options, minecraft->width, 
                         minecraft->height, guiScale);
int screenWidth = ssc.getWidth();
int screenHeight = ssc.getHeight();

currentGuiScaleFactor = (float) guiScale;
Source: Minecraft.Client/Gui.cpp:68 Supports:
  • Fullscreen GUI scaling (scale 2-4)
  • Split-screen adjustments
  • Safe zones for different viewports
  • Dynamic scaling for up to 4 players

Chat Messages

Adding Messages:
void Gui::addMessage(const wstring& string, int iPad, bool bIsDeathMessage=false);
Adds a message to the chat overlay for a specific player. Clearing Messages:
void Gui::clearMessages(int iPad=-1);
Clears messages for a player (or all players if iPad=-1). Message Access:
DWORD getMessagesCount(int iPad);
wstring getMessage(int iPad, DWORD index);
float getOpacity(int iPad, DWORD index);  // Fade-out calculation
Source: Minecraft.Client/Gui.h:52

GuiMessage Structure

class GuiMessage
{
public:
    wstring string;  // Message text
    int ticks;       // Time remaining to display
    
    GuiMessage(const wstring& string);
};
Source: Minecraft.Client/GuiMessage.h:4 Messages automatically fade out over time based on their tick count.

Overlay Messages

Setting Overlay Text:
void Gui::setNowPlaying(const wstring& string);
Displays a large centered message (used for jukebox “Now Playing” text). Getting Overlay State:
wstring getJukeboxMessage(int iPad);
float getJukeboxOpacity(int iPad);
Source: Minecraft.Client/Gui.h:54

HUD Elements

The Gui class renders various HUD components: Hotbar - Item quick-select bar
  • 9 slots for quick access
  • Selected slot highlighting
  • Item icons and counts
Health Bar - Player health display
  • Heart icons
  • Damage flash animation
  • Regeneration effect
Hunger Bar - Food level display
  • Food icons (drumsticks)
  • Saturation overlay
Armor Bar - Armor protection display
  • Armor icons
  • Durability indication
Experience Bar - XP progress display
  • Progress bar
  • Level number
Vignette - Screen darkening effect
  • Damage indication
  • Low health warning
  • Portal overlay
Crosshair - Center-screen targeting reticle Debug Overlay - F3 debug information
  • FPS counter
  • Position/rotation
  • Chunk information
  • Memory usage

Specialized Rendering

renderSlot() - Renders a single inventory slot:
void renderSlot(int slot, int x, int y, float a);
renderPumpkin() - Renders pumpkin head overlay:
void renderPumpkin(int w, int h);
renderVignette() - Renders screen vignette effect:
void renderVignette(float br, int w, int h);
Source: Minecraft.Client/Gui.h:44

Debug Graphs

For performance monitoring:
void renderGraph(int dataLength, int dataPos, __int64 *dataA, 
                 float dataAScale, int dataAWarning, 
                 __int64 *dataB, float dataBScale, int dataBWarning);

void renderStackedGraph(int dataPos, int dataLength, int dataSources, 
                        __int64 (*func)(unsigned int dataPos, unsigned int dataSource));
Source: Minecraft.Client/Gui.h:66

Update Loop

void Gui::tick();
Called every game tick to:
  • Update message timers
  • Fade out old messages
  • Animate HUD elements
  • Update overlay message timer

GuiParticles System

The GuiParticles class manages particle effects for UI elements, primarily used in achievement notifications.

GuiParticles Class

class GuiParticles : public GuiComponent
{
private:
    vector<GuiParticle *> particles;
    Minecraft *mc;
    
public:
    GuiParticles(Minecraft *mc);
    void tick();                           // Update all particles
    void add(GuiParticle *guiParticle);    // Add new particle
    void render(float a);                  // Render all particles
};
Source: Minecraft.Client/GuiParticles.h:8

GuiParticle

Individual particle in the UI:
class GuiParticle
{
public:
    double x, y;              // Current position
    double xo, yo;            // Old position (for interpolation)
    double xa, ya;            // Velocity
    double friction;          // Movement damping
    bool removed;             // Marked for deletion
    int life, lifeTime;       // Current/max lifetime
    double r, g, b, a;        // Current color
    double oR, oG, oB, oA;    // Old color (for interpolation)
    
    GuiParticle(double x, double y, double xa, double ya);
    void tick(GuiParticles *guiParticles);
    void preTick();
    void remove();
};
Source: Minecraft.Client/GuiParticle.h:5

Using Particles

// In Screen class
particles->add(new GuiParticle(x, y, velocityX, velocityY));

// Update particles
particles->tick();

// Render particles
particles->render(partialTick);
Particles automatically:
  • Apply velocity and friction
  • Fade out over lifetime
  • Remove themselves when expired
  • Interpolate position and color for smooth rendering

Achievement Popup System

While not in a dedicated class, achievement notifications use the GUI system: Components:
  • Toast-style popup in corner
  • Achievement icon and title
  • Slide-in animation
  • GuiParticles for celebratory effect
  • Auto-dismiss timer
Implementation: Typically handled through the HUD rendering system with special overlay logic.

Item Rendering

The ItemRenderer class handles rendering items in GUI contexts:
static ItemRenderer *itemRenderer;  // Shared instance in Gui
Used for:
  • Hotbar item icons
  • Inventory slot items
  • Achievement icons
  • Item tooltips

Color Format

Colors in the GUI system use 32-bit ARGB format:
// Format: 0xAARRGGBB
0xFFFFFFFF  // White, fully opaque
0xFF000000  // Black, fully opaque
0x80FFFFFF  // White, 50% transparent
0xFFFF0000  // Red, fully opaque
0xFF00FF00  // Green, fully opaque
0xFF0000FF  // Blue, fully opaque

// Common text colors
0xFFFFFF    // White
0xe0e0e0    // Light gray (normal button text)
0xffffa0    // Yellow (hovered button text)
0xffa0a0a0  // Gray (disabled button text)

Best Practices

Creating Custom GUI Components

  1. Extend GuiComponent for rendering utilities
  2. Use blit() for texture-based rendering
  3. Use fill() for solid color rectangles
  4. Cache Font references for text rendering
  5. Handle visibility with visible flags
  6. Support scaling using currentGuiScaleFactor

Button Usage

  1. Use unique IDs for each button
  2. Set active=false to disable buttons
  3. Set visible=false to hide buttons
  4. Position relative to screen width/height
  5. Standard spacing: 24 pixels between buttons vertically

HUD Rendering

  1. Respect safe zones for console rendering
  2. Scale appropriately for split-screen
  3. Use blitOffset for layered rendering
  4. Interpolate animations using alpha parameter
  5. Optimize rendering - avoid overdraw

Build docs developers (and LLMs) love