gohud

La legibilidad se mide

← Temas

"Bonito" es cuestión de gusto; "legible" se puede medir. Un texto gris tenue se ve bien en un buen monitor y desaparece en un teléfono a la luz del día — elegir a ojo lo garantiza tarde o temprano.

python3 addons/gohud/tools/check_contrast.py
QuéExigido
Texto del cuerpo4.5 : 1
Texto grande (24px en adelante)3 : 1
Bordes de acento e iconos3 : 1
Bordes decorativos2 : 1 — la WCAG no aplica su regla de 3:1 a la decoración
Superficies adyacentes1.12 : 1 — lo justo para que una tarjeta se distinga de su fondo

Texto de un tono sobre un tinte del mismo tono

Esta trampa apareció tres veces en este código — botones pulsados (panel de acento, etiqueta de acento), botones de peligro y chips. Se ve bien en una muestra de color y se derrumba en cuanto se mide, porque ambos comparten el tono y por tanto no tienen diferencia de luminosidad.

Por eso los colores de etiqueta no se eligen a mano. El generador de temas y GoSkin empujan cada uno la luminosidad — y solo la luminosidad — hasta superar el umbral sobre el panel en el que el texto realmente se apoya. El tono y la saturación sobreviven, así que la paleta conserva su carácter y, al cambiarla, conserva su contraste.

El color leído como texto y el color pintado como área quieren cosas opuestas

En un tema claro, un color de advertencia debe oscurecerse para seguir siendo legible como texto (#96500A). Cuando el relleno de la barra hereda ese color, la barra de experiencia se vuelve marrón. El color por sí solo no lo arregla: el amarillo es intrínsecamente brillante, así que supera el 3:1 sobre un carril gris cualquiera, y oscurecer el carril lo empeora (1.52 → 1.06).

Por eso los dos se separan. El color se mantiene vivo — la paleta lleva colores solo para relleno como warning_vivid. El borde es el que aporta el contrasteGoSkin dibuja un contorno de 1dp sobre cualquier relleno que no alcance 3:1 contra su carril, para que "cuánto queda" siga siendo legible.

MY_LIGHT = dict(
    warning=hexc("9A5407"),         # leído como texto
    warning_vivid=hexc("F2A007"),   # pintado en la barra
)
Si lo omites, se te avisa. Sin un *_vivid, un relleno que sale oscuro hace que el generador imprima the bar looks drab — add warning_vivid to the palette (en coreano: "la barra se ve apagada — añade warning_vivid a la paleta"). Un punto que antes se degradaba en silencio ahora lo dice.

Un panel flotante no puede saber qué hay detrás

Un HUD se dibuja sobre el juego — un campo nevado, o una cueva. Si su panel es translúcido, lo que haya detrás se filtra y cambia el color del panel, arrastrando el contraste del texto con él. Al 82% de opacidad, el texto atenuado de los temas oscuros caía a 3.74:1 sobre un fondo brillante — por debajo del mínimo.

Por eso los paneles translúcidos se miden con blanco puro y negro puro detrás; eso es lo peor que puede ofrecer una escena de juego. El panel de HUD de los temas incluidos es lo bastante opaco para pasar (92%) sin perder el aspecto vidrioso.

Por la misma razón, los colores de los iconos tampoco son fijos. El glifo de la ranura rápida estaba escrito a fuego en blanco y medía 1.11:1 en un tema claro — ahora sigue al panel sobre el que se apoya, exactamente igual que las etiquetas.

Dos verificadores, dos alcances. check_contrast.py lee los archivos de tema; los colores que un skin mezcla en tiempo de ejecución (chips, ranuras) los mide la sección skin contrast de la batería de pruebas dentro de Godot.