gohud

読みやすさは測って決める

← テーマ

「きれい」は好みだが、「読める」は測れる。 薄い灰色の文字は良いモニタでは平気に見えて、 日中の屋外ではスマートフォンから消える — 目で選んでいれば、いつか必ずそうなる。

python3 addons/gohud/tools/check_contrast.py
対象必要な比
本文の文字4.5 : 1
大きな文字(24px 以上)3 : 1
アクセントの枠とアイコン3 : 1
装飾の枠2 : 1 — WCAG は装飾に 3:1 の規則を課していない
隣り合う面1.12 : 1 — カードが背景と別物だと分かる程度

同系色の文字を同系色の淡い面に載せる

この落とし穴は、このコードベースで3度現れた — 押されたボタン(アクセントのパネルにアクセントの文字)、 危険ボタン、そしてチップだ。色見本の上ではよく見えるのに、測った瞬間に崩れる。 2つが同じ色相を共有していて、明度の差がないからだ。

だからラベルの色は手で選ばない。テーマのビルダーと GoSkin はそれぞれ、文字が実際に載る パネルの上でしきい値を超えるまで明度だけを押し上げる。色相と彩度は残るので、パレットは持ち味を保ち、 変更してもコントラストは保たれる。

文字として読む色と、面として塗る色は求めるものが逆だ

ライトテーマでは、警告色は文字として読めるよう暗くしなければならない(#96500A)。 バーの塗りがそれを受け継ぐと、経験値バーは茶色になる。色だけでは直せない。黄色はそもそも明るく、 灰色の溝に対して 3:1 をまったく満たさないし、溝を暗くするともっと悪くなる(1.52 → 1.06)。

そこで両者を切り離した。色は鮮やかなまま — パレットは warning_vivid のような 塗り専用の色を持つ。コントラストは縁が担うGoSkin は、溝に対して 3:1 に届かない塗りに 1dp の輪郭を描く。こうして「どれだけ溜まっているか」は読めるままになる。

MY_LIGHT = dict(
    warning=hexc("9A5407"),         # 文字として読む色
    warning_vivid=hexc("F2A007"),   # バーに塗る色
)
書き忘れは報告される。 *_vivid がないまま塗りが暗くなると、ビルダーは the bar looks drab — add warning_vivid to the palette と出力する(ビルダーが実際に出す文言)。 黙って劣化していた場所が、いまは声を上げる。

浮かぶパネルは、背後に何があるか知りようがない

HUD はゲームのに描かれる — 雪原かもしれないし、洞窟かもしれない。パネルが半透明なら背後のものが 透けてパネルの色そのものを変え、文字のコントラストまで道連れにする。不透明度 82% では、明るい背景の上で ダークテーマの控えめな文字が 3.74:1 まで落ちた — 最低基準を下回っている。

そこで半透明のパネルは純白と純黒を背後に置いて測る。ゲームの場面が出しうる最悪がその2つだからだ。 同梱テーマの HUD パネルは、ガラスのような見え方を保ったまま基準を通る不透明度 (92%) にしてある。

同じ理由でアイコンの色も固定していない。クイックスロットのグリフは白で決め打ちされていて、 ライトテーマで 1.11:1 と測れた — いまはラベルとまったく同じように、載っているパネルに従う。

2つの検査、2つの守備範囲。 check_contrast.py はテーマファイルを読む。 スキンが実行中に混ぜる色(チップ、スロット)は、Godot の中で走るテストスイートの skin contrast の節が測る。