出来を決めるのは小さなところだ
大きなパネルをいくら磨いても、目に留まるのはいつも小さなものだ — 途中で切れた単語、欠けた発光、 窮屈なスロット。2026-09-13 にそうした4つが指摘され、デモ画面ではなくウィジェットとテーマの側で直した。 だから、どの画面でも同じ結果になる。
| 何が起きたか | 原因 | 直し方 |
|---|---|---|
コーチマークの Done が Don/e になった |
折り返しを有効にしたボタンは文字幅を最小幅から差し引く — 狭められると単語の途中で割れる | GoStyle.fit_words(): 1単語なら決して折り返さず、複数語なら折り返すがいちばん長い単語は必ず収まる。判定は翻訳キーではなく実際に表示される文字で行い、言語が変わればフォームが付け直す |
| 全幅ボタンの発光が、左側だけ縦に切れた | スクロールコンテナは例外なく自分の端で切り取る。右だけはレールの余白のおかげで残っていた | GoScroll が親の余白を借りて端を 12dp 外へ押し出し、内側で返す — 中身の位置は動かない |
| スロットの中で、時間・アイコン・個数が縦に積み上がった | 48dp の中に3行あった | アイコンは中央に大きく、ショートカットは左上、個数は右下のバッジ、残り時間はアイコンに重ねたバッジへ — バッジのパネルはスキンの badge_box() から来る |
| ドロップダウンが平坦で、どれを選んでいるか見えない | 項目のホバーにボタンのパネルを使い、ラジオの印はエンジンの薄い既定のままだった | 専用のホバーパネル(淡いアクセント)、チェックボックスと同じラジオの絵、タッチに合わせた項目の高さ |
アイコンだけのボタンには GoStyle.icon_button(icon, action, -1, tooltip_key) で説明を与える —
マウス利用者へのツールチップも、スクリーンリーダー向けのアクセシビリティ名も、この1つの値から取る。
ツールチップは gohud が自分で描く。エンジンの既定は、幅の計算が狂うと文字を1文字ずつ改行してしまう
(幅 1dp と実測された)。
コーチマークのカードは固定物を避ける
横持ちでは、カードが画面のいちばん上か下の端へ送られていた — ヘッダーや HUD がちょうど居座る場所だ。
デモではヘッダーの → × の上に重なっていた。いまは対象と同じ高さにとどまり、場所を確保している
GoHudAnchor を回り込み、そのほか避けたいものは keep_clear で受け取る。
対象を覆わずに障害物から外れる最短の距離だけ動き、画面が狭くてすべてを避けきれないときはその場にとどまる —
重なるほうが、消えるよりましだ。ページより上にあると読めるだけの立体感は、スキンのダイヤルから来る
(float_shadow_size、float_shadow_lift、float_shadow_alpha。面取り系のスキンは float_glow_size)。
tour.keep_clear = [header_bar, toolbar] # アンカーではない固定物
マウスとキーボードのある画面
指にはホバー状態がない。 モバイルだけを見て作ると、デスクトップにしかない2つの状態が未確認のまま残る —
そして実際、片方は壊れていた。gohud のフォーカスリングが主ボタンの上で見えなかったのだ。パネルが
アクセント色で、リングも同じ色。1.00:1、同じ色を同じ色の上に描いていた。キーボードで移動すると、
自分がどこにいるのか分からなかった。
塗りつぶしのボタン(GoPrimaryButton、GoDangerSolidButton)は
自分のパネルと対比するリングを使う — ダークテーマでは暗く、ライトテーマでは白く、SF では暗い照準
ブラケットになる。コントラスト検査はフォーカスリングを、それが載っているパネルに対して測るので、
パレットを変えてもこの規則は生き残る(WCAG 2.4.11 はフォーカス表示に 3:1 を求めている)。
HUD ウィジェット
GoHudAnchor — 9か所
セーフエリアと画面端の余白を尊重する。landscape_spot を与えれば横持ちで移動する —
縦持ちで下中央にあるコントロールを、横持ちでは右下へ回せる。
本文を HUD の下に潜り込ませない
スクロールする画面が HUD と同じ表示面を分け合うと、本文はその下へ滑り込み、2組の文字が重なって どちらも読めなくなる。このアドオンでも2度起きた。入力欄のプレースホルダーがクイックスロットの間から はみ出し、設定のトグルのつまみが体力バーの上に載った。
form.avoid_hud = true # 表示中の GoHudAnchor をすべて避ける
joystick_anchor.reserve_space = false # …指が触れたときだけ現れるものは除く
それぞれの矩形は失う面積がいちばん小さい方向へ避ける。右上のバーは、縦持ちのスマートフォンでは下へ 回り込み(高さの 13%)、横持ちでは横へ回り込む(幅の 21%) — 横持ちで縦に避ければ画面の 27% を失う。 すでに明け渡した領域は、次の矩形を測る前に差し引かれる。
HUD どうしもぶつかる
9か所は画面を分割するだけで、部品どうしがぶつからないことまでは保証しない。上中央の幅広い スナックバーが、右上の体力バーの真上に着地して値を隠した — 残り体力が読めなかったのだ。
notice_anchor.avoid_peers = true # 固定 HUD の下へ落ち着く
notice_anchor.reserve_space = false # 出ている間にページを押しのけたりはしない
よけるのは縦方向だけだ — 横にも動かすと、中央揃えのトーストが出るたびに違う場所に現れてしまう。 しかも、避けるのは自分からはよけない部品に対してだけだ。両方が譲ると、2つは永遠に場所を入れ替え続ける。
GoBar — 体力・マナ・経験値
var hp := GoBar.new()
hp.label_text = "HP"
hp.ink = GoUi.color(GoTheme.DANGER_FILL) # 塗り専用のトークン
hp.set_values(320, 500) # "320 / 500"
変化は 0.18 秒かけてなめらかに動く — 跳ねる体力バーは、どれだけ強く殴られたのかを伝えない。
reduce_motion にすれば即座に反映する。大きな数は 12.3k のように略記するので、
桁が増減してもバーの幅が揺れない。
GoSlot — クイックスロット1つ
アイコン、個数、クールダウン、ショートカットを1つの面に収める。小さな円にバッジをぶら下げると、 スロットごとに幅が変わって列が揺れてしまう。
touch_peers で互いの存在を教えておく。
keyboard_focus は既定で無効だ。8個並んだスロットが、キーボード利用者と設定項目すべての間に
Tab 順で割り込まないようにするためである。キーボードやゲームパッドが唯一の入力手段なら有効にする。
GoJoystick — バーチャルスティック
| モード | ふるまい |
|---|---|
FIXED | 常に同じ場所 — 見なくても指が届く |
FOLLOW | 親指を置いた場所に現れる |
RELATIVE | 現れたあとも親指を追い続ける — 長く動かすときに楽だ |
moved が渡す Vector2 は長さ 0〜1 なので、そのまま速度に掛けられる。
画面サイズや DPI で変わることもない。
GoIconButton — 小さく見えて大きく押せる
touch_peers が要る。