Quick answer: Call display_set_gui_size(display_get_width(), display_get_height()) at game start so the GUI layer renders at physical pixel resolution. Create Font assets at the actual size you want to display. Do not scale text with draw_text_transformed unless you accept blurriness.

Here is how to fix GameMaker Draw GUI text blurry on high DPI displays. Your game looks sharp on a 1080p monitor. A player runs it on a 4K or retina Mac and the UI text is soft and fuzzy. The game surface scales cleanly because it is pixel art, but HUD text drawn via draw_text in Draw_GUI looks wrong. The GUI layer has its own independent resolution, set via display_set_gui_size, and the default is rarely what you want on high-DPI.

The Symptom

HUD elements (score, health bar labels, dialog boxes) look soft on retina or 4K displays. On 1080p everything is sharp. draw_set_font(fnt_main) followed by draw_text(x, y, "SCORE") produces crisp text in one environment and blurry text in another.

Variant: text is crisp on all displays at game start, then blurs after a window resize. Or text in the world is sharp but GUI is blurry, even though they use the same font.

What Causes This

GUI size smaller than window. The GUI layer is an internal surface at the size set by display_set_gui_size (default = room size). If the window is 3840x2160 and GUI size is 1920x1080, the GUI is rendered at 1080p and stretched to 4K. Text becomes blurry.

Font rendered at the wrong size. A Font asset created at size 16 produces glyph bitmaps at 16 px. Drawing with draw_text_transformed at scale 2 scales those 16 px bitmaps up, producing blur. For 32 px text, create a Font at size 32.

application_surface scaling. The application surface is another intermediate layer, scaled to window size. If the surface is 1920x1080 and window is 3840x2160, all game content (world) is scaled. GUI is drawn separately, but if you flatten to application_surface and then scale, everything blurs.

Window scaling mode. Game Options > Windows/Mac > Scaling = “Keep aspect ratio” can produce non-integer scaling. Combined with texture filtering this blurs text.

Texture interpolation on. gpu_set_tex_filter(true) enables bilinear filtering when surfaces are sampled at non-native scale. Blurs pixel art and bitmap fonts.

The Fix

Step 1: Set GUI size to match the window. In a controller object’s Create event:

// Controller object, Create event
display_set_gui_size(display_get_width(), display_get_height());

And in a window resize handler (or every step, since it is cheap):

// Controller object, Step event
var _w = window_get_width();
var _h = window_get_height();
if (display_get_gui_width() != _w || display_get_gui_height() != _h) {
    display_set_gui_size(_w, _h);
}

Now the GUI layer is exactly as large as the window. A 3840x2160 window gets a 3840x2160 GUI layer. No stretching, no blur.

Step 2: Create Font assets at the real target size. If your design calls for 32 px title text, create the Font at size 32. If you need multiple sizes, create multiple Font assets:

Pick the closest one at draw time rather than scaling:

// Draw_GUI event
draw_set_font(fnt_title);
draw_text(50, 50, "SCORE");

draw_set_font(fnt_body);
draw_text(50, 110, "Press any key");

Step 3: If the game is pixel art, scale the game surface separately. The classic pattern is: game world at 320x180, GUI at window resolution. Do this with application_surface_draw_enable(false) and manual blitting in Post Draw:

// Create event
application_surface_draw_enable(false);
surface_resize(application_surface, 320, 180);

// Post Draw event
var _w = window_get_width();
var _h = window_get_height();
draw_surface_stretched(application_surface, 0, 0, _w, _h);

// GUI event - drawn at real resolution (no scaling)
draw_set_font(fnt_title);
draw_text(50, 50, "SCORE");

The world is scaled pixel-perfect; the GUI renders at physical resolution.

Step 4: Disable texture filtering for pixel art.

// Global game start
gpu_set_tex_filter(false);

This keeps pixel art sharp. For TTF fonts you have rendered with antialiasing, filter can be left on without much effect on text (the font already has edge smoothing baked in).

Font Anti-aliasing Setting

In the Font asset editor, the Anti-aliasing slider controls glyph smoothness. Levels 1-4 are hinted anti-aliased; level 0 is pixel-perfect. For pixel-style UI, use 0. For modern UI, 3 or 4. Match this to your game’s visual style.

Testing on High DPI

In the GameMaker IDE on macOS, retina mode is automatic. On Windows, set the project’s manifest for per-monitor DPI awareness via Game Options > Windows > Allow High DPI. Without this, Windows scales the whole window post-render, bypassing your fix.

“GUI size equals window size. Font size equals intended draw size. Everything else is details.”

Related Issues

For text rendering in other engines, see Pygame Text Rendering Pixelated at Scale for the equivalent issue in pygame. For related display problems, Construct 3 Family Behavior Not Applying to All Members covers another common 2D engine pitfall.

display_set_gui_size to window size. Font assets at native size. Crisp text on every display.