Skip to main content

Overview

The Screen system in Minecraft Community Edition provides the foundation for all user interface screens, including menus, dialogs, and in-game overlays. All screens inherit from the Screen base class, which itself extends GuiComponent.

Screen Base Class

The Screen class (Screen.h/Screen.cpp) provides the core functionality for all UI screens:

Class Hierarchy

GuiComponent
  └── Screen
      ├── TitleScreen
      ├── PauseScreen
      ├── ChatScreen
      ├── AbstractContainerScreen
      │   ├── InventoryScreen
      │   ├── CraftingScreen
      │   └── FurnaceScreen
      ├── AchievementScreen
      ├── OptionsScreen
      ├── DeathScreen
      └── [Other Screens]

Core Properties

class Screen : public GuiComponent
{
protected:
    Minecraft *minecraft;           // Reference to main game instance
    Font *font;                     // Font renderer
    vector<Button *> buttons;       // Screen's interactive buttons
    
public:
    int width, height;              // Screen dimensions
    bool passEvents;                // Whether to pass input events through
    GuiParticles *particles;        // Particle system for visual effects
};
Key Source Files:
  • Minecraft.Client/Screen.h:8 - Screen class definition
  • Minecraft.Client/Screen.cpp:11 - Screen constructor

Screen Lifecycle

Initialization

Screens are initialized through a two-stage process: 1. Base Initialization (Screen::init())
void Screen::init(Minecraft *minecraft, int width, int height)
{
    particles = new GuiParticles(minecraft);
    this->minecraft = minecraft;
    this->font = minecraft->font;
    this->width = width;
    this->height = height;
    buttons.clear();
    init();  // Call derived class init
}
Source: Minecraft.Client/Screen.cpp:83 2. Derived Class Setup (virtual void init()) Each screen type implements its own init() method to:
  • Add buttons to the screen
  • Initialize screen-specific state
  • Set up UI layout

Update Loop

tick() - Called every game tick (20 times per second)
virtual void tick();
Used for:
  • Updating animations
  • Processing time-based logic
  • Managing screen state
Source: Minecraft.Client/Screen.cpp:146

Rendering

render() - Called every frame to draw the screen
virtual void render(int xm, int ym, float a)
{
    // Render all buttons
    for (auto it = buttons.begin(); it != buttons.end(); it++) {
        Button *button = *it;
        button->render(minecraft, xm, ym);
    }
}
Parameters:
  • xm - Mouse X coordinate
  • ym - Mouse Y coordinate
  • a - Alpha/interpolation value for smooth rendering
Source: Minecraft.Client/Screen.cpp:22

Cleanup

removed() - Called when screen is closed
virtual void removed();
Use for cleanup tasks when transitioning away from the screen. Source: Minecraft.Client/Screen.cpp:150

Input Handling

Mouse Input

mouseClicked() - Handles mouse button press
virtual void mouseClicked(int x, int y, int buttonNum)
{
    if (buttonNum == 0) {  // Left click
        for (auto it = buttons.begin(); it != buttons.end(); it++) {
            Button *button = *it;
            if (button->clicked(minecraft, x, y)) {
                clickedButton = button;
                minecraft->soundEngine->playUI(eSoundType_RANDOM_CLICK, 1, 1);
                buttonClicked(button);
            }
        }
    }
}
Source: Minecraft.Client/Screen.cpp:52 mouseReleased() - Handles mouse button release
virtual void mouseReleased(int x, int y, int buttonNum);
Source: Minecraft.Client/Screen.cpp:70

Keyboard Input

keyPressed() - Handles keyboard input
virtual void keyPressed(wchar_t eventCharacter, int eventKey)
{
    if (eventKey == Keyboard::KEY_ESCAPE) {
        minecraft->setScreen(NULL);  // Close screen
    }
}
Source: Minecraft.Client/Screen.cpp:32 tabPressed() - Handles tab key for chat auto-complete
virtual void tabPressed();
Source: Minecraft.Client/Screen.cpp:200

Button Callbacks

buttonClicked() - Override to handle button presses
virtual void buttonClicked(Button *button);
Implementations check the button ID to determine action:
void TitleScreen::buttonClicked(Button *button) {
    switch (button->id) {
        case 0: // Play game
            minecraft->setScreen(new SelectWorldScreen());
            break;
        case 1: // Options
            minecraft->setScreen(new OptionsScreen(this, minecraft->options));
            break;
    }
}
Source: Minecraft.Client/Screen.cpp:79

Screen Transitions

Screens are transitioned using Minecraft::setScreen():
// Close current screen
minecraft->setScreen(NULL);

// Open new screen
minecraft->setScreen(new PauseScreen());

// Return to previous screen (pass in reference)
minecraft->setScreen(lastScreen);

Background Rendering

Screens provide methods to render common backgrounds:

Semi-transparent Overlay

void Screen::renderBackground(int vo)
{
    if (minecraft->level != NULL) {
        // In-game: dark gradient overlay
        fillGradient(0, 0, width, height, 0xc0101010, 0xd0101010);
    } else {
        // Menu: dirt background
        renderDirtBackground(vo);
    }
}
Source: Minecraft.Client/Screen.cpp:159

Dirt Background

The classic Minecraft dirt background for main menus:
virtual void renderDirtBackground(int vo);
Source: Minecraft.Client/Screen.cpp:171

Common Screen Types

TitleScreen - Main menu
  • File: Minecraft.Client/TitleScreen.h:7
  • Features: Logo animation, splash text, main menu buttons
  • Key Method: render() for animated logo
PauseScreen - In-game pause menu
  • File: Minecraft.Client/PauseScreen.h:4
  • Features: Resume, options, save, quit
  • Property: isPauseScreen() returns true
OptionsScreen - Settings and configuration
  • File: Minecraft.Client/OptionsScreen.h:6
  • Features: Controls, video settings, game options
  • Uses Options class for settings management

Dialog Screens

ChatScreen - In-game chat interface
  • File: Minecraft.Client/ChatScreen.h:5
  • Features: Text input, message history
  • Special handling for character filtering
ConfirmScreen - Yes/No dialog
  • File: Minecraft.Client/ConfirmScreen.h
  • Features: Confirmation dialogs with callbacks
  • Method: confirmResult(bool result, int id)
DeathScreen - Death/respawn screen
  • File: Minecraft.Client/DeathScreen.h:4
  • Features: Respawn button, score display
  • Method: isPauseScreen() returns true

Container Screens

AbstractContainerScreen - Base for inventory UIs
  • File: Minecraft.Client/AbstractContainerScreen.h:8
  • Features: Slot rendering, item dragging
  • Abstract method: renderBg(float a)
Derived screens:
  • InventoryScreen - Player inventory (InventoryScreen.h:6)
  • CraftingScreen - Crafting table interface
  • FurnaceScreen - Furnace interface
  • ContainerScreen - Generic chest/container

Information Screens

AchievementScreen - Achievement viewer
  • File: Minecraft.Client/AchievementScreen.h:6
  • Features: Scrollable achievement tree, progress tracking
  • Properties: xScrollP, yScrollP for panning
  • Special rendering with zoom and scroll
StatsScreen - Statistics viewer
  • File: Minecraft.Client/StatsScreen.h
  • Features: Block/item statistics display

Connection Screens

ConnectScreen - Connecting to server
  • File: Minecraft.Client/ConnectScreen.h
  • Features: Connection status, cancel button
ReceivingLevelScreen - Loading level data
  • File: Minecraft.Client/ReceivingLevelScreen.h
  • Features: Progress bar for level download
DisconnectedScreen - Disconnection message
  • File: Minecraft.Client/DisconnectedScreen.h
  • Features: Reason display, return to menu
ErrorScreen - Critical error display
  • File: Minecraft.Client/ErrorScreen.h
  • Features: Error message, stacktrace display

Pause Behavior

Screens can control whether they pause the game:
virtual bool isPauseScreen()
{
    return true;  // Default: pause game
}
Source: Minecraft.Client/Screen.cpp:191 Set to false for screens that should allow game to continue (like chat).

Particle Effects

Screens have access to a particle system for visual effects:
GuiParticles *particles;  // Created in init()
Used by achievement notifications and other animated UI elements. See: GUI Components for details on GuiParticles.

Best Practices

Creating a New Screen

  1. Inherit from Screen (or appropriate base class)
  2. Override init() to set up UI
  3. Override render() to draw custom elements
  4. Override buttonClicked() to handle interactions
  5. Call parent methods when appropriate

Example Implementation

class MyCustomScreen : public Screen {
public:
    void init() override {
        buttons.clear();
        buttons.push_back(new Button(0, width/2 - 100, height/2, L"Click Me"));
        buttons.push_back(new Button(1, width/2 - 100, height/2 + 24, L"Close"));
    }
    
    void buttonClicked(Button *button) override {
        if (button->id == 0) {
            // Handle button 0
        } else if (button->id == 1) {
            minecraft->setScreen(NULL);
        }
    }
    
    void render(int xm, int ym, float a) override {
        renderBackground();  // Draw background
        drawCenteredString(font, L"My Custom Screen", width/2, 40, 0xFFFFFF);
        Screen::render(xm, ym, a);  // Draw buttons
    }
};

Size Calculation

Screens use ScreenSizeCalculator to handle different resolutions and GUI scales:
ScreenSizeCalculator ssc(minecraft->options, minecraft->width, 
                         minecraft->height, guiScale);
int screenWidth = ssc.getWidth();
int screenHeight = ssc.getHeight();
Source: Minecraft.Client/ScreenSizeCalculator.h

Build docs developers (and LLMs) love