ケーススタディ
音を使わずに、手応えを作る
聴覚障害のある制作者が、音をいっさい使わない放置ゲームを作りました。何を制約として引き受け、どこで判断したかの記録です。
前提にあった3つの制約
作りはじめる前に、動かせない条件が3つありました。どれも後から足せるものではなく、最初の設計に効いてくるものです。
1. 音を使えない
私は聴覚障害があります。音で手応えを返すゲームは、私自身が楽しめません。効果音を付けて「自分には聞こえないけど、たぶんいい感じだろう」と想像しながら作るのは、作り手として誠実ではないと思いました。
だから最初から音を使わないと決めました。消極的な除外ではなく、「視覚だけで手応えを成立させる」という設計課題として引き受けました。
2. メンテナンスを最小限にしたい
私はプログラミング未経験です。作ったものが壊れたとき、自分で原因を突き止めて直せる保証がありません。加えて求職中で収入の見込みがないため、月額のかかるサーバーも借りられません。
この2つを合わせると、答えはひとつでした。そもそも壊れる箇所を作らない。
サーバーを一切使わないと決めました。ログインもなし、データベースもなし、外部APIもなし。セーブはブラウザの中だけ。読み込むものはWebフォント1つだけ。
この判断は、単に楽をするためのものではありません。技術的に何かあっても、自分の手に負える範囲に収まるようにするためです。サーバーがなければサーバーは落ちませんし、外部サービスを使っていなければ、その仕様変更に振り回されることもありません。公開したあと放っておいても、数年後に開いてたぶん同じように動きます。
3. 自分が使えるものにする
アクセシビリティを「余裕があれば足す機能」にしたくありませんでした。自分が当事者なので、後回しにすると自分が困ります。最初から組み込みました。
判断1:音の代わりに何を返すか
タップしたときの手応えは、ふつう音が担います。音を抜くと、そこに穴が空きます。何で埋めるかを考えました。
結論は「ひとつの動作に、性質の違う反応を3つ重ねる」でした。タップすると次の3つが同時に起きます。
- 結晶が一瞬ふくらむ — 押した対象そのものが反応する(触った感触の代わり)
- 粒子が弾ける — 押した位置から放射状に飛ぶ(力が加わった証拠)
- 数字が浮かび上がる — 「+120」が上に流れて消える(結果の確認)
3つとも視覚ですが、担当している意味が違います。ひとつ消しても他の2つが残るので、どこかを見落としても手応えが途切れません。
浮かぶ数字には縁取りを入れました。背景の色は鉱脈ごとに変わるので、縁取りがないと条件によって数字が読めなくなるからです。
判断2:色だけで情報を伝えない
「買える設備」を緑、「買えない設備」を灰色にする——よくある表現ですが、色覚特性によっては区別できません。
買える設備には値段の前に「▸」を付けました。枠線も変わり、明度も変わります。色が見えなくても、記号と形で分かります。
同じ考えで、選択中の設定項目にはチェックマークが入ります。一時停止中は画面全体が暗くなり、なおかつ「一時停止中」という文字が出ます。状態を色だけで示している箇所は、最終的にひとつも残りませんでした。
判断3:文字サイズは全体を動かす
文字を大きくする機能はよくありますが、本文だけが大きくなって数字やボタンが小さいまま、ということがあります。
このゲームでは、CSSのカスタムプロパティひとつで画面全体の文字が拡大します。
--fsという倍率を用意し、すべての文字サイズをcalc(14px * var(--fs))のように定義しました。4段階のボタンはこの倍率を 0.92 / 1 / 1.14 / 1.32 に切り替えるだけです。
Canvasに描いている浮かぶ数字も、同じ倍率を読んで描画サイズを変えます。HTMLとCanvasという別々の仕組みが、ひとつの値で揃います。
判断4:コントラストを後から測って直した
最初に作った配色は、見た目は良かったのですが、薄いグレーの文字が背景に溶けていました。実際に測ると、コントラスト比が2.8:1しかない箇所がありました。WCAGの基準は4.5:1です。
すべての文字色を測り直し、基準を下回っていたものを明るくしました。さらに純黒×純白の「高コントラスト」配色を2つ追加しました。見た目を優先した配色と、読みやすさを最大にした配色の両方を用意して、選べるようにするという解決です。
判断5:セーブコードを312文字から47文字へ
別の端末に移すためのセーブコードは、最初はゲームの状態をJSONにしてBase64で変換していました。これが312文字ありました。手で扱うには長すぎます。
中身を見ると、ほとんどが {"crystals": のような繰り返しのラベルでした。値の順番さえ決めておけば、ラベルは要りません。
そこで、19個の数値を36進数(0〜9とa〜z)に変換して、ハイフンでつないだだけの形式に変えました。末尾2文字はチェックサムで、打ち間違いを弾きます。
CC2-16j8-247h-qglk-c-y-2-14-p-e-6-2-0-0-8o-1-7-0-tlqv01-0i
312文字が47〜60文字になりました。約6分の1です。古い形式のコードも読めるようにしてあるので、すでに控えを取っていた人が困ることはありません。
判断6:5言語を、後から足さなかった
多言語対応を後から足すと、文章がコードのあちこちに散らばっていて、全部拾い出す作業になります。それを避けるため、表示される文字をすべて1か所の翻訳テーブルに集めました。
翻訳したのはUIだけではありません。設備の名前と説明、鉱脈の名前、イベントの名前、遊び方の全文、共有用の文章まで含みます。
数字の単位も、はじめは言語ごとに変えていました。日本語は万・億・兆、英語は K・M・B。「1万」を英語話者に見せても伝わらないからです。
ところが実際に並べてみると、別の問題が見えました。どの単位も、読む人がその約束ごとを知っていることを前提にしているのです。日本語話者が「10K」で一瞬つまずくのと同じことが、英語話者の「1万」でも起きます。数字を読み違えるゲームで、数字が読み違えられては話になりません。
最終的に単位をやめ、桁をそのまま出すことにしました。「600,000,000」は長いけれど、どの言語の読者にとっても同じ意味です。長さのほうは、桁数に応じて文字を小さくし、収まらない箇所は折り返すことで解決しました。区切り記号だけは各言語の標準に合わせています。
途中で見つけた2つのバグ
整数の末尾のゼロが消えていた
「3000億」が「3億」と表示されていました。原因は数字を整形する関数です。
小数点以下の余分なゼロを消すために replace(/\.?0+$/, '') という処理を入れていたのですが、これが整数の末尾のゼロまで消していました。「3000」が「3」に、「1200万」が「12万」になっていたのです。
初版から入っていた不具合で、小さい数字では表に出ないため気づきにくいものでした。小数点を含む場合だけ処理するよう直しました。
HTMLのタグを1文字閉じ忘れていた
鉱脈到達や再結晶の演出が出なくなっていました。調べると、> を1文字書き忘れていて、続く3行がタグの属性として吸い込まれていました。
ブラウザはエラーを出さずに解釈するので、画面上は何も壊れて見えません。JavaScriptから要素を探したときに初めて null が返り、そこで処理が止まっていました。
さらに厄介だったのは、この停止が同じ関数の後半の処理も巻き込んでいたことです。「周回数が増えない」という別のバグに見えていたものが、実は同じ原因でした。表に出た症状と原因が離れている例です。
数字で見る
| 項目 | 値 |
|---|---|
| HTMLファイル | 1個(約8,000行) |
| 外部から読み込むもの | Webフォント1つだけ |
| 対応言語 | 5 |
| 配色 | 5(うち高コントラスト2) |
| 文字サイズ | 4段階 |
| 鉱脈 | 12 |
| セーブコードの長さ | 47〜60文字 |
| サーバー費用 | 0円 |
作ってみて
音を使わないという制約は、最初は「できないこと」でした。作り終えてみると、「視覚だけで手応えを作る」という具体的な設計課題に変わっていました。制約があったから、タップの反応を3つ重ねるという解き方にたどり着けたのだと思います。
アクセシビリティも同じです。自分が当事者だったので後回しにできず、結果として最初から組み込まれました。後から足すより、ずっと安く付きました。
サーバーを使わないという判断も、維持費のためだけではありませんでした。外部に依存しないので、公開したあと放っておいても壊れません。数年後に開いても、たぶん同じように動きます。
このゲームはこのサイトのトップページでそのまま遊べます。登録は不要です。気づいたことがあればお問い合わせからお知らせください。