Quick answer: Use a pixel font at its design size with AA off. For variable sizes, render at integer multiples of the target.

A roguelike renders HUD text at 8pt. Anti-aliasing turns crisp glyphs into smudges. The font wasn’t designed for that size.

Pixel Fonts

Source a pixel-friendly font (Pixel Operator, NicoBold). Use at its native size (often 8, 16, 32). Disable AA:

font = pygame.font.Font("pixel.ttf", 8)
surf = font.render("HP: 100", False, (255, 255, 255))   # AA off

Crisp; designed to render exactly at this size without sub-pixel spread.

Integer Scaling

To display larger, render at 8pt then scale by integer factor:

scaled = pygame.transform.scale(surf, (surf.get_width() * 2, surf.get_height() * 2))

Nearest-neighbor preserves pixel edges. Smooth scale (smoothscale) softens; only use for non-pixel-art look.

For Vector Fonts at Small Size

If you must use a TTF at small size, consider:

Freetype Module

import pygame.freetype

face = pygame.freetype.Font("font.ttf", 8)
surf, rect = face.render("HP: 100", (255, 255, 255))

Freetype has hinting support; better small-size legibility than pygame.font for vector fonts.

Verifying

HUD readable at design size. Compare side-by-side: AA on vs off. Pixel font with AA off wins for retro aesthetic.

“Pixel fonts + AA off, or vector + freetype. Two paths to crisp small text in Pygame.”

For multi-language games, find a pixel font with extended glyph coverage (Cyrillic, accents) — not all retro pixel fonts include them.