画面レイアウト
概要
ゲーム画面全体の骨格——エリアの分割・寸法・縦横対応——を決めるドキュメントです。個別の表示要素は
別の文書が扱います: ステータスの表示は StatusArea.md、カードと枠の見た目は
CardView.md、子ウィンドウは Windows.md、カードの操作と
時間経過の見せ方は CardInteraction.md です。
画面を等分するのではなく、カード寸法(205×320u)を基準に各エリアの寸法を積み上げます(1 節)。
単位は u(画面短辺 ÷ 1080)で、オプションバー・ダッシュボード・フィールド・フィルターバーの
各領域を、縦型・横型で同じ要素のままグリッドの配置換えだけで組み直します。
実装は src/game/PlayScene.ts(寸法計算は src/game/looks/PlayScreenLayout.ts)で、本書の寸法
トークンをそのまま使います(12 節)。レイアウトは HTML モック(13 節)で検証済みで、Phaser 側も
実装済みです。本書に未実装の節はありません。
1. 設計原則
- カード基準レイアウト: 画面を等分して領域を作るのではなく、カード寸法を基準に各エリアの
寸法を積み上げて決める。カードのアスペクト比はブリッジ版のトランプ(57:89)に合わせ、205×320u
(= 41:64、比率 0.6406)とする。枠の画像(
src/assets/ui/card_frame.png、410×640)も同じ比率で、 引き伸ばしによる歪みが出ないようカードのちょうど 2 倍の解像度で作ってある。 - 絵は u の 2 倍で描く:
uは短辺 ÷ 1080 なので、短辺 2160px の端末で 2 になる。それより大きい 端末は現実的に無いため、2 倍より大きく描いても縮小されるだけ。u 上の寸法が決まっている絵 (カードの枠・日時の桁・区切りの帯・ボタンのアイコン)はすべてこの倍率で作る。 - 短辺基準の単位: 寸法は
u(= 画面短辺 ÷ 1080、CSS ではvminベース)で定義する。 縦型・横型どちらも短辺を基準にするため、同一端末ならカードの実寸が画面の向きによらず一致する。 ただし設計の基準は縦型が 9:16(1080×1920u)・横型が 16:9(1920×1080u)で、それより正方形に 近い画面では基準の寸法が入り切らない——縦型は高さ(積み上がるエリア)、横型は幅(3 列)が足りなく なる。uは向きごとの設計寸法が縦横とも収まる最大値とし、入り切らない画面では全体を縮める (3.1 節)。 - フィールドエリア最優先: ゲームの中心エリアであるフィールドエリアのカードサイズを最大化する。 カード 205×320u・レーン高 352u はフィールドエリア 3 レーンが横型の画面高(1080u)に ちょうど収まる最大値。ただし幅には上限がある——カード 6 枚を超えた分を使う相手が フィールドエリアに居ないので、超えた分の幅はサイドバーへ回す(10.1 節)。
- 画面全体を1つのグリッドで組む: オプションバー・ダッシュボード・フィールド・フィルターバーの
各領域を、向きによらず同じ要素のまま
grid-template-areasの違いだけで配置し直す。 縦型は 1 列の縦積み(オプション→ダッシュボード→フィールド→フィルター)、横型は ダッシュボード|フィールド|右列(オプション/フィルター)の 3 列(右列だけ上下 2 段)。 これにより、フィールドエリアが横型より狭くなる縦型で、他のエリア(特にキャラクターエリア)が 間延びしないよう、フィルターバー分の高さをキャラクターエリアから差し引ける。 - 画面を無理に使い切らない: 縦型でエリアを積んだ余りは、引き伸ばして埋めるのではなく、 オプションバーの上に余白として残す。スマートフォンでは画面上端に指が届きにくく、そこまで 使い切る価値が薄いため(3.2 節)。
- キャラクターカードはフィールドカード基準: ポートレイトカードはあくまで補助的な表示なので、 フィールドカードと同じサイズ(205×320u)とし、縦型・横型で共通にする。
- 親指到達圏: 縦型では頻繁に操作するフィールドエリアを画面下部に置く。低頻度のオプション ボタンをまとめるオプションバーは、通常のフロー内で他のエリアと重ならないよう配置する。縦型では 画面最上部に固定し、横型ではフィールドエリア右のサイドバー上段に置く。押す頻度が高い日時が 最上部に来るのは承知のうえで、時間経過の選択自体は画面下部から開くボトムシートで行うため、 親指圏から外れるのは入口だけに留まる。
- レーンは横スクロール: フィールドエリアはスクロール可能なので、レーンに収まらないカードは 横スクロールで送ればよく、視界に何枚入るかを画面比ごとに揃える必要はない。ただしカード 5 枚は どの画面比でも見えるようにする(3.1 節)。9:16 の縦型でちょうど 5 枚、16:9 の横型では 6 枚が 視界に入り、それより横長ならさらに増える。
- 現在地カードのピン留め: 現在地カードは設置物レーン左端に固定表示し、区切り線を挟んで 右に設置物を並べる。ピン留めはレーンの中身ではなくレーンの見出しで、区切り線がその境目。 現在地は常にフィールドカードと同サイズでフィールドエリア内に表示される。
- 空は本の外: 状況エリア(=空の帯)を、オプションバーと同じく背景のページの外側に置く。 外の様子は見上げるものなので、画面でも一番上に来るのが自然で、向きによる例外も要らない。 本の中に窓として貼るのはやめた——空は手元の記録ではなく外の眺めで、本の中に収めると 他のページの項目と同列に見えるため。本の外に置くぶん、角は丸めず、周囲に余白も残さない。
- 日時は空の中に吊り下げる: 経過日数(3 桁)と時刻は、卓球のスコアボードのように
一桁ずつ独立したフリップカードで表示し、空の窓の中に置く。各カードは上部の留具のみで
吊り下げられ、台紙のような外枠は持たない。経過日数と時刻は上下ではなく左右に並べ、
背の低い時刻の桁は日数の桁と下端で揃える(中央で揃えると小さい桁が宙に浮いて見える)。
縦型・横型でサイズは共通。タップすると休憩・仮眠などキャラクタ自身が持つ時間経過アクションを
選ぶボトムシートが画面下部から開く(睡眠を配るのは寝床の札。
Bedding.md4.1節)。入口の位置によらず、選択操作自体は親指圏で行える。 経過日数の側に単位のラベルは置かない。日数の桁(64×88u)は時刻の桁(44×60u)より大きく、 時刻の側だけが「:」を持つので、大小と区切りだけで読み分けられる。文字を持たなければ翻訳も要らず、 表示幅も設計値だけで決まる(唯一の文字である「:」も、字幅がフォントで変わらないよう 10u 固定で 場所を取り、はみ出しは前後の桁間 8u が吸収する)。 - ボタンはポートレイトの右へ縦積み: 地図・装備・怪我・レシピのボタンが、ポートレイト カード(320u)と状況アイコンの行を合わせた高さを使い切る。下へ積むより 1 つあたりを 大きく取れるうえ、余った高さが残らない。状況アイコンはポートレイトの下だけに 1 行。縦型・横型で 同じ組み方になるので、向きによる分岐を持たない。状況アイコン・地図・装備・怪我・レシピはいずれも ポートレイトカードに重ねず、通常のフロー内に配置する。
- 押す頻度と大きさを対応させる: 地図・装備・怪我・レシピはよく使うので、状況アイコン(48×48u)より 大きなボタン(168×72u)にする。アイテム名は表示せず、タップ先の子ウィンドウで確認する。 列の高さを等分はしない——文字を持たないボタンなので、絵より広い面を取ると、絵ではなく 面の方が目に入る。列の上下には 16u の余白を空け、残りをボタン同士の間隔に回す(4.2 節)。 並びは持ち物の近さの順で、地図と装備は身につけているもの、 装備と怪我は開く子ウィンドウの形が同じ。押す頻度が最も低い地図が端に来る。持ち物ではない レシピは反対の端。 キャラクター表示エリア自体にも内側の余白(16u)を確保し、要素が端に張り付かないようにする。
- これらは絵だけで表す(4.2 節)。文字を持たせないのは、言語ごとに変わる 文字数をボタンの内側へ収める必要が出るため。日時のフリップカードと同じ理由で、文字を持たなければ 翻訳も要らず、表示幅も設計値だけで決まる。役割が固定されているので、絵だけで区別が付く。
- ステータスエリアのバーは上寄せ: 表示するステータスは常に全種類ではなく、
statusタグが 付いたもののうち安全域を外れたもの(と固定表示にしたもの)だけを並べる可変長リスト (StatusArea.md)。中央寄せにすると表示件数が変わるたびにバー群の位置が 上下に動いてしまうため、上端に揃えて件数が変わっても位置が安定するようにする。
2. 寸法トークン
| 要素 | 寸法 (u) |
|---|---|
| カード | 205 × 320(ブリッジ版 57:89 に相当) |
| レーン高 | 352(カード + 上下 15) |
| カード間ギャップ | 12 |
| レーン間・外周マージン | 6 |
| エリアの区切りの帯 | 高さ 12(レーン間マージンの 2 倍。中央半分が区切り、上下 3 ずつは隣へかぶる) |
| スクロールバー | 高さ 8、送られるカードの下端との間隔 3(カードの下の余白 16 の中に置く)、つまみの最小長 48 |
| 情報エリアの余白 | フィールドエリア側 32、それ以外の辺 24(背景のページの縁を避ける) |
| フィールドエリアの最小幅 | 縦型 1079・横型 1085(カード 5 枚 1073 + 外周マージン。3.1 節) |
| オプション・フィルターボタンの間隔 | 20(カード間ギャップより広めに確保し、隣接ボタンの誤タップを防ぐ) |
| 状況エリア高 | 縦型 128、横型 184(横型は幅が日時 1 つ分しかなく、天候名を別の段へ分けるため高い) |
| 状況エリアの内側の余白 | 縦型 24×16・横型 20×16(空は四辺いっぱいに敷き、載せ物だけがこの内側) |
| 縦型のページの上辺 | 24(状況エリアを外へ出して上端が画面の途中に来たので、左右と同じ縁を見せる) |
| ダッシュボード列幅(横型) | 478(日時のフリップカード 406 + 左右パディング 20×2 + 紙の余白 32) |
| 日時フリップカード | 日数の桁(3 桁)64×88、時刻の桁 44×60、「:」の確保幅 10、桁間 2、日数と時刻の間 14(縦型・横型共通) |
| オプションバー高・フィルターバー高(縦型、内容量に応じた自動、共通) | 約 120(アイコンボタン 88 + 上下パディング 16×2) |
| 右サイドバー幅(横型、オプション/フィルター共有) | 120(バー厚みと同じ。アイコンボタン 88 + 左右パディング 16×2)。フィールドエリアに余剰があるときだけ 2 列の 240(10.1 節) |
| ポートレイトカード | 205 × 320(フィールドカードと同サイズ、縦型・横型共通) |
| キャラクター表示エリア高 | 余白 16 + ポートレイト 320 + ギャップ 12 + 状況アイコンの行 48 + 下の余白。縦型 444(下 48)、横型 412(下 16) |
| キャラクター表示エリアの内側余白 | 16(縦型の下だけ 48。この辺が背景のページの下端=表紙の縁に当たるため) |
| アイコンボタン | 88 × 88(最小タップ領域。オプションボタン・フィルターボタンも共用) |
| 地図・装備・怪我・レシピボタン | 168 × 72(列の上下に 16 の余白。間隔は残りから決まる) |
| 地図・装備・怪我・レシピボタンのアイコン | 145 × 64(どれも同じ。物の大小は絵の側が持つ) |
| 状況アイコン | 48 × 48(1 行に 4 つまで。4.1.1 節) |
| 探索ウィンドウのプログレスバー | 高さ 72、幅はウィンドウ幅(フィールドエリアと同程度)から内側余白 32×2 を引いた残り |
3. 情報エリア (Information Area)
フィールドエリアの左(横型)・上(縦型)にまとまっている、キャラクターエリアです。 オプションバーと状況エリアは含みません(どちらも本の外側に置きます)。
背景は 1 枚の本のページ(src/assets/ui/information_background.png)で、内訳の各エリアは自前の
背景色を持たず、このページの上に直接載ります。
- 絵は9patch(Phaser の NineSlice)として敷きます。四隅と縁はそのまま、中央の紙だけが引き伸ばされる ので、1 枚で任意の大きさを賄えます。縦型は同じ絵を 90 度回して、表紙の縁を下へ向けます。
- 絵は1px = 1u(短辺 1080u のときの原寸)で描かれています。9patch の縁は絵から原寸で切り出される ため、絵全体を u 倍して敷き、縁の太さを画面の大きさによらず一定の u に保ちます。
- 反対側(横型の左・縦型の上)は画面外へはみ出す前提です。極端な画面比で絵が届かない場合に備え、
下地に紙の色(
COLOR.informationPaper)の背景板を敷きます。 - フィールドエリア側の縁 48u のうち、外側の 16u は透過のグラデーションで、ページがフィールドエリアへ
落とす影です。この 16u 分だけフィールドエリアへ食い込ませて置き、影が全部フィールドエリアの上に
落ちるようにします。縁 48u・影 16u は絵が従うべき寸法で、絵はこれに合わせて切り出します
(
tools/comfyui/recipes/information_background.json)。 - レーンの区切りの帯より後(=手前)に置きます。ページの縁が帯に途切れさせられないようにするため です。背景板はレーンからはみ出したカードを隠す役目も兼ねます。
中身は紙の内側に収めます(informationContent)。内訳の各エリアはこの範囲へ配置し、エリア自身の
パディングはその内側でさらに効きます。余白は辺によって決め方が違います。
| 辺 | 余白 | 決め方 |
|---|---|---|
| フィールドエリア側(横型は右・縦型は下) | 32u | 縁の幅(48u)から食い込ませる幅(16u)を引いた残り |
| それ以外(横型は上下・縦型は左右) | 24u | 縁が角でカーブしていて幅が一定でないため、絵から導かず見た目の余白として置く |
この制約が次の寸法を決めています。
- 横型のダッシュボード列幅 478u: 日時のフリップカード(406u)+左右パディング 20u×2 +紙の余白 32u。
- 縦型のキャラクター表示エリアの下パディング 48u: このエリアの下端は背景のページの下端 (表紙の縁)に接しているので、紙の余白をここが受け持ちます。紙の余白(32u)より広く取るのは、 縁ぎりぎりに置くと中身が縁に載って見えるためです。状況エリア(128u)とページの上辺(24u)との 和が 596u で、9:16 の端末でフィールドエリアが 1080u を割らない(=3 レーンが収まる)範囲です。 横型の縁は右辺にあり、情報エリアの中身の幅が既に引いているので、下は通常のパディング(16u)で 足ります。
3.1 3 レーンとカード 5 枚は必ず確保する
フィールドエリアの 3 レーン(1080u)と、レーンに見えるカード 5 枚は、どの画面比でも必ず確保 します。 3 レーンが無いと手持ち・足元・現在地のどれかが見えず、プレイ自体が成り立ちません。 カードが 5 枚見えていないと、場に何があるかを見比べるより先に送る操作が要ります。
u は向きごとの設計寸法が縦横とも収まる最大値(= 短辺 ÷ 1080 を上限に、足りない軸のぶんだけ
縮めた値)にします(ScreenMetrics)。カードは小さくなりますが、レーンが欠けたりカードが 5 枚
見えなかったりするよりは読めます。
| 向き | 幅 (u) | 高さ (u) |
|---|---|---|
| 縦型 | 1080(9:16 の基準。フィールドエリアが画面幅そのもの) | 1920(オプションバー 120 + 情報エリア 600 + フィールドエリア 1080 + フィルターバー 120) |
| 横型 | 1683(ダッシュボード列 478 + フィールドエリア 1085 + 右サイドバー 120) | 1080(3 レーンぶん) |
先に足りなくなる軸は向きで逆です。 縦型は短辺が幅なので高さが、横型は短辺が高さなので幅が
足りなくなります。9:16 より正方形に近い縦型では u が長辺 ÷ 1920 まで、16:9 より正方形に近い横型
では短辺 ÷ 1080 から長辺 ÷ 1683 まで縮みます。
カード 5 枚に要る幅は、レーンの外周マージンの内側の 1073u(カード 205×5 + ギャップ 12×4)です。 横型のフィールドエリアが 1085u なのは、左右の辺に区切りの帯がかぶる(本と右サイドバーとの境目、 7.6 節)ぶんの外周マージン 6u×2 を足すためです。縦型は右端が画面の端そのもので、レーンからはみ出した カードもそのまま見えるので、外周マージン 1 つぶん(1079u)で足り、基準の 1080u が既にこれを満たして います。
縦型と違い、横型は縮めたぶんの高さが余ります(4:3 なら 1262u)。余りは 3 レーンが背を伸ばして 吸収し、カードはレーンの中央に並びます。外に残すと、区切りの帯で囲った枠が画面の端から離れて 見えるためです。
3.2 縦長の画面の余り
キャラクターエリアは内容量ぶん(444u)だけ確保し、引き伸ばしません。 9:16 より縦長の端末で
余った高さは、オプションバーの上に余白として残し、画面外の色(COLOR.outsideScreen、Phaser の
キャンバスの地の色と同じ)で塗り潰します。
スマートフォンでは画面上端に指が届きにくく、そこまで使い切る価値が薄いためです。余白は情報エリアの 外側なので、はみ出した背景のページごと塗り潰します。
3.3 情報エリアの区切り線
背景が 1 枚の紙になり、エリアごとの塗り分けが無くなったため、意味のまとまりの境目だけを線で示します。 見た目は現在地カードの右の区切り線と同じ(太さ 4u・黒 35%)です。
状況エリアとの境目には引きません。状況エリアは本の外にあり、境目は本の外側の区切りの帯 (7.6 節)が受け持つためです。
| 向き | 位置 |
|---|---|
| 横型 | ステータスエリアの上(キャラクター表示エリアとの境目) |
| 縦型 | ステータスエリアの左(同上) |
4. キャラクターエリア (Character Area)
キャラクター表示エリアとステータスエリアで構成します。
両者は縦型では左右、横型では上下に隣接します。ステータスエリアに何をどう出すかは
StatusArea.md が扱います。
4.1 キャラクター表示エリア (Character Display Area)
縦型・横型で同じ組み方です(横型は幅だけが列いっぱいに広がります)。いずれもポートレイト カードに重ねず、通常のフロー内に配置します(ボタンの仕様は 1 節の設計原則を参照)。
- 1 行目: 左にポートレイトカード(205×320u)、右に地図・装備・怪我・レシピのボタンを縦積み。
ボタンの列は上下に 16u の余白を空け、残りをボタン同士の間隔に回します(1 つあたり 20u)。
ポートレイトは上端から 10.5u(
PAPER_INSET+FRAME_SIDE_WIDTH)を枠に使うので、人はカードの上端では なく枠の内側を上端として読みます。余白が無いとボタンだけが先に始まり、列が高くはみ出して 見えました。枠と同じ 10.5u では揃うだけなので、内側へ入る量まで空けます。 - 2 行目: 状況アイコンを左詰めで 1 行。ポートレイトの下だけに置き、ボタンの列はこの行の下端まで 伸ばします。こうすると、1 行目に挙げたボタンがどれも同じ大きさで入ります。何を出すかは 4.1.1 節です。
4.1.1 状況アイコンに何を出すか
出すのは、キャラクタの周りが今どうなっているかのうち、操作の可否を変えているものだけです。 画面を見ただけでは分からない環境の事情を、それが効いている間だけ目に見せる場所です。
- キャラクタ自身の状態は出しません。 減っていく量(水分・満腹度)はステータスエリアが
(
StatusArea.md)、気絶のような状態はポートレイトカードへの覆いが出します (CardView.md9.1 節)。線は値の持ち主ではなく、その値が何についての事実かで 引きます——手元の明るさ(hand_brightness)はキャラクタが持つプロパティですが、表しているのは 本人ではなく手元へ届いている光の量なので、ここに出します。 - 出すのは値ではなく段です。 バーが「どれだけか」を出すのに対し、状況アイコンは「線の向こう側に
居る」ことだけを出します。環境の悪条件は速さではなく可否として効かせる
(
DesignPrinciples.mdの「悪条件は、効率を下げるのではなく、 できる/できないの線で効かせる」節)ので、環境の側に、連続量として見せるべきものがありません。 - 何も妨げていない間は出しません。 出しても読み取るものが無いためです(ステータスエリアが
安全域を出さないのと同じ、
StatusArea.md2 節)。晴れた日中は 1 つも出ず、 行は空になります。 - 画面の演出で見えているものでも、線は出します。 明るさは翳りと輝きが画面全体へ映しますが (7.5 節)、映しているのは量なので、もう採りに出られないことは色の濃さからは読めません。 演出が量を、アイコンが線を出す、と役割を分けます。
- 既に名前で出ているものは出しません。 天気は状況エリアが絵と名前で出しているので(5 節)、
アイコンを添えると同じことを二度言うことになります。出すのは天気そのものではなく、身に
当たっている側の値です——雨なら雨ざらしかどうか(
sheltered)、嵐なら風雨(wind_speed)で、 どちらも天気の名前が変わらないまま、屋根の下へ入れば裏返ります。 - アイコンは値ごとで、原因ごとではありません。 暗さは手元(
hand_brightness)と視界 (looking_brightness)の 2 つの値に効き、対抗手段も違います——地面に据えた明かりは手元だけを 取り戻し、視界は持ち歩く明かりでしか戻りません (IlluminationSystem.md3 節)。1 つに畳むと、松明を地面へ 刺したのにアイコンが消えない理由が読めなくなります。
どの段でどの絵を出すかは、世界の側の宣言が決めます。 段
(GameElementDefinition.md 6.4 節の stages)へ絵の識別子を
1 つ書けるようにし(situation)、その段に居る間だけ、その識別子の絵を出します。書かない段では
出ません。UI はプロパティの意味も段の意味も知らないので、出すものが増えても画面の側に足すものは
ありません——ステータスエリアが status タグと alert から出し分けているのと同じ形です
(StatusArea.md 1 節・2 節)。
looking_brightness:
stages:
- name: pitch_dark
situation: no_road # この段に居る間だけ、no_road の絵を出す
- name: dim
min: -5
situation: too_dark_outside
- name: bright
min: 3 # 書かない段では出ない
- 「出すか」と「どの絵か」を 1 つの宣言に畳みます。 2 つに分けると、片方だけ書いた宣言が黙って 出なくなります。
- 既にある宣言では足りません。
alert(同 2 節)は良し悪しの軸なので、屋根の下に居るような 悪くない段を名乗れません。段の名前をそのまま識別子にすることもできません——段の名前は プロパティごとの名前空間で、dimはhand_brightnessにもlooking_brightnessにもあり、 意味が違うためです。 - 絵は
src/assets/icons/<識別子>.pngで、置き場所も規約も 4.2 節と同じです。絵がまだ無い識別子は 絵文字で代用し、絵と絵文字が混ざった状態を正常とします。代役の絵文字を持つのは画面の側です (PlaySceneのSITUATION_ICONS)——絵が届くまでの繋ぎなので、ボタンの代役と同じ扱いにします。 代役すら無い識別子でも落とさず❔を出します:出すと決めたのは世界の側で、画面の都合で 黙って消えるほうが悪いためです。 - 並び順は宣言順(プロパティの宣言順、同じプロパティなら段の宣言順)です。出る件数が変わるので、 深刻さのような可変の順に並べると、同じ絵が毎回違う場所に来ます。
- 押しても何も起きません。 出しているのは場所と世界の事実で、そこから操作する対象がないためです。
どの絵が何かは、そのプロパティに
property_tags(GameElementDefinition.md6.7 節)を付ければプロパティのタブ (Windows.md6 節)へ名前付きで並ぶので、覚える場はそこになります。 - 1 行に入るのは 4 つまでです。48u の絵を 8u の間隔で並べるので 4 つで 216u になり、ポートレイトの 幅(205u)は超えますが、ボタンの列が始まる手前(205u + 列との間隔 12u)には収まります。同時に 5 つ以上が点く組み合わせが現れたら、そのときに行の側を見直します。
4.1.2 今の宣言で出せるもの
出しているのは、手元と視界の明るさ、身に当たっている風雨、そして屋根の下です。 明るさと風雨は
段が既にあり、sheltered は 0/1 の値へ段を足すだけで届きました。
| 出すもの | 見る値 | 段(名乗る識別子) | 何が変わるか |
|---|---|---|---|
| 手元が暗い | hand_brightness(キャラクタ) |
pitch_dark・dim(どちらも too_dark_for_handwork) |
レシピの工程と、暗いと形を損なう手作業が通らない(IlluminationSystem.md 5 節) |
| 外が暗い | looking_brightness(キャラクタ) |
dim(too_dark_outside) |
探索と屋外の採取が通らない(同 5 節) |
| 道が見えない | looking_brightness |
pitch_dark(no_road) |
上に加えて、陸の道を歩けない(同 5 節) |
| 屋根の下 | sheltered(キャラクタが場所から継ぐ) |
1 の側(sheltered) |
雨が当たらない。雨の日でも火を起こせ、雨に打たれて体温を失わない——何が変わるかを決めるのは読む側それぞれなので、ここに挙げるのは代表だけ(ContainerSystem.md 6 節) |
| 風雨に晒されている | wind_speed(キャラクタが場所から継ぐ) |
gale(too_stormy) |
嵐の日、屋外の採取も探索も道の移動も手元の作業も通らない(ContentSkeleton.md 8.1.4 節) |
- 手元の 2 段が同じ絵なのは、線が 1 本しかないからです。 手元の作業に要るのは
brightで、dimとpitch_darkはどちらも「作れない」の一言に尽きます。視界の側は 2 本 (dimで採れなくなり、pitch_darkで歩けなくなる)なので、そちらだけ絵が分かれます。 - 屋根の下は、悪くない側の段です。 世界が
sheltered: 0を宣言し、守る側だけが 1 を宣言する (core.yaml)ので、既定と違うのは 1 のほうです。雨水を溜めたい日には不利にもなるため、 良し悪しではなく「今そうである」ことだけを出します。 - 段を持つのはキャラクタの側だけです。 場所の側にも
shelteredはありますが、ancestorは 同名を宣言している最初の祖先で止まるので、そちらへ段を置くと守る側を足すたびに段の宣言も 足すことになります。キャラクタがbaseで継いで自分の段を持てば(player_character.yaml、 明るさ 2 つと同じ形)、守る側は今までどおりsheltered: 1を宣言するだけで済みます。 - 風雨と屋根の下は同時には点きません。 屋根の下ではキャラクタの
shelteredの段が風雨を 0 まで 落とす(player_character.yaml)ので、同じ嵐の日でもgaleの段ごと外れます。一度に点きうるのはsituationを名乗る段を持つプロパティの数まで——1 つのプロパティが居る段は 1 つだからです——で、 1 行に入る数(4.1.1 節)に収まっていることは自動テストが見張ります (tests/integration/situationIcons.test.ts)。 - 絵はまだ 1 枚もなく、どれも絵文字が代役です(4.1.1 節)。
4.1.3 まだ出せないものと、何が入れば出せるか
足りないのは絵ではなく、世界の側の値です。 どれも「出す形」は 4.1.1 節のまま使えます。
| 出したいもの | 何が足りないか |
|---|---|
| 暑さ・寒さ | 寒い側は体が受け取る形を持ちました(キャラクタの warmth、VitalsSystem.md 8.3 節)が、寒い場所に居ることを引ける段がありません——寒さは気温と chill_point の比較で決まり、段は 1 つのプロパティの値域でしか引けないためです(下の「雨に打たれている」と同じ形の不足)。暑い側は受け取る形からありません——熱中症にあたるプロパティが無く、今の気温が動かしているのは画面の陽炎(7.5.4 節)だけで、操作の可否を何も変えていません。度合いはステータスエリアが(StatusArea.md 8 節)、暑い/寒い場所に居ることは状況アイコンが出す分担です |
| 周囲の蚊 | 世界に蚊がありません。虫刺されも病気も無いので、値も段もありません。入るときは場所の側のプロパティ(core.yaml の location trait)として持つのが素直で、そのとき出すのは 4.1.1 節の 1 行の宣言だけで済みます |
| 雨に打たれている | 「守られているか」(sheltered)と「降っているか」(weather)を 2 つのプロパティが別々に持っており、段は 1 つのプロパティの値域でしか引けません。出すなら、両方から押される濡れ具合のプロパティを場所かキャラクタへ足す必要があります |
4.2 ボタンの絵
地図・装備・怪我・レシピのボタンの絵は src/assets/icons/<アイコンの識別子>.png に置きます。
識別子は map・equipment・injury・recipe で、コード側への登録は要りません
(src/art/iconArt.ts)。
- 識別子はドメインではなく UI が決めます。 カードの絵と違い、これらは特定の
object_defでは なく画面に固定で置かれるボタンだからです。 - 絵は物 1 つを中央に置いたアイコンで、背景は透過です。 ボタンの地の色はボタン自身が持ちます。 全面を覆う絵にすると、絵がボタンの大きさに対して大きすぎ、何のボタンかより絵の方が目に入ります。
- どれも同じ寸法(336×144px)で持ち、UI は同じ大きさ(145×64u)で敷きます。 寸法そのものを 物の大きさにすると、絵を差し替えるたびに画面上の大きさが暗黙に変わってしまいます。変わるのは 中の画素だけにします。
- 物の大小は絵の側が持ちます——開いた地図(104×58u)> 開いた本(96×44u)> T シャツ (65×62u)> 巻いた包帯(61×38u)。UI が物を測って一律に揃えると、この差が消えます。 厳密な比にはしません(包帯が見えなくなるため)。順序が読める程度に詰めます。
- キャンバスを正方形にしてはいけません。 正方形だと平たい物ほど小さくしか描けません(開いた 地図が高さの半分しか使えず、巻いた包帯より小さく見えました)。ボタンと同じ横長にします。
- ボタンの地は、紙を敷いたうえにボタンの色を乗算で載せます(染めた紙)。平らな塗りに
淡い色を置くとパステルに見え、汚れと滲みのある他の絵から浮きます。色は染みが見える程度に
くすませます(
COLOR.mapButtonなど)。紙が読めなければ、この色の平らな塗りが地になります。 - 敷く紙はボタン専用の絵(
slot_button_paper.png)で、ボタン 1 つぶんが 1 枚です。 カードの枠と 同じ紙から切り出してありますが(recipes/slot_button_paper.json)、それは生成の話で、実行時に カードのテクスチャを共有はしません(DesignNotes.md)。角丸は絵に焼いてあり、 枠線はその上へ引き直します。1 枚はボタンと同じ縦横比で切り出します——ボタンの矩形へ引き伸ばして 敷くので、比が違うと紙の粒が一方向へ伸びます。1 枚ずつ別の場所から取るのは、同じ場所だと同じ染みが 並んで模様として目に付くためです。 - ボタンは影を落とします(ずらし 1.5u と 3u の 2 枚重ね、
drawBoxのshadow)。カードは絵に影が 焼いてあり(recipes/card_frame.json)、影を持たないボタンだけが本のページに貼り付いて見えて いました。立体的な縁は足しません——枠を与えるとカードと同じ格に見え、画面のメリハリが かえって失われます。 - 枠線は黒ではなく暖色です(
COLOR.paperButtonBorder)。染めた紙の上に黒い細線を引くと、絵の中に 画面部品の線が 1 本混じって見えます。カードの縁の線が種別ごとの暗い色であるのと同じ扱いです。 - 絵がまだ無いものは絵文字で代用し、同じ場所へキャンバスの高さで置きます。絵は少しずつ増える前提 なので、両者が混ざった状態を正常とします。
- 一覧はビルド時に作ります(
import.meta.glob)。ファイル名がコードの引く識別子と食い違うと絵は 黙って使われないままになるので、自動テスト(tests/art/iconArt.test.ts)が検査します。理由は カードの絵と同じです。 - 血のような小さな印は、絵文字の形を借りて重ねます(怪我の赤い滴)。生成にも編集にも 描かせられず、描かせると生々しい塊になるか布の汚れに紛れるかのどちらかになるためです。
- 絵は
tools/comfyui/recipes/icon_<識別子>.jsonから作り直せます。物の大きさはcardArt.size、 キャンバスはcardArt.canvas(どれも同じ値)です。 - オプション・フィルターバーのアイコンも同じ置き場所と規約です(6 節)。作り方だけが違い、 あちらは絵文字を下絵にします。
状況アイコンも同じ置き場所と規約です(4.1.1 節)。違うのは識別子を誰が決めるかで、あちらは出るものが 世界の宣言とともに増えるため、UI ではなく段の側が名乗ります。
5. 状況エリア (Situation Area)
空を敷いた 1 本の帯で、日時と天候の名前をその上に載せます(WeatherPanel)。本の外側の
最上部——縦型はオプションバーの直下に画面幅いっぱい、横型はダッシュボード列の上端に列幅いっぱい——に
置きます。オプションバーと同じ扱いなので、角は丸めず、四辺に余白も残しません。空は四辺いっぱいに
敷き、内側の余白(縦型 24×16・横型 20×16)は載せ物だけに効きます。
高さは載せ物の分しか取りません。 空は絵として見せるものですが、日時の上に広く余らせても 情報は増えないためです。縦型は日時 1 段ぶん、横型は天候名と日時の 2 段ぶんです。
天候はアイコンではなく絵と名前で表します。 絵だけでは晴天どうしを区別できないので名前は
必ず出しますが、アイコンを添えると名前と同じことを二度言うことになるため、絵に語らせて
アイコンは持ちません。名前は言語ごとの対応表の symbol_texts 節から引きます
(Localization.md)。
載せ物は絵の主題(太陽・雲)を置く右上を必ず空けます。
| 向き | 日時 | 天候名 |
|---|---|---|
| 縦型 | 窓の左下 | 窓の右下(下端は日時と揃える) |
| 横型 | 窓の下端(左右中央) | 窓の左上 |
横型が上下に分かれるのは、ダッシュボード列の幅(446u)が日時のフリップカード(406u)で ほぼ埋まり、名前を横に並べる余地が無いためです。そのぶん状況エリアは縦型より高くなります。
日時は押しボタンです。 押すとキャラクタ自身の子ウィンドウが開き、休息を選べます
(Windows.md 4 節)。時間を進める操作の入口をここに置くのは、選んだ結果が現れるのが
この時計だからです。
日時の各桁は白い紙の画像(flip_digit.png)に黒い数字を載せたもの。画像はカードの枠と同じ
生成テクスチャから組み立て、留具の穴・リング・落ち影まで描き込んである
(tools/comfyui/recipes/flip_digit.json)。窓の下端に付けるので、桁の紙は絵の下側に重なります。
空の絵はここを白く抜かない約束なので(5.1 節)、明るい空でも白い紙が沈みません。
5.1 空の絵
置き場所は src/assets/weather/<天気の識別子>.png のみで、コード側への登録は要りません
(src/art/weatherArt.ts)。天気の識別子は light_rain などのプロパティの値
(ClimateSystem.md 4.2 節)です。
- 1 枚の絵を縦型・横型それぞれの窓へ cover で敷きます。 切り出される範囲は向きによって 大きく違う(縦型は横長、横型は正方形に近い)ので、絵は横長のパノラマ 1 枚で描き、 主題は右上へ寄せます。
- 右上の角を合わせて、はみ出す側(左・下)を切り落とします。 中央で合わせると、向きが 変わって切り出しの比率が変わったときに主題ごと落ちてしまうためです。
- 絵は空だけで、海も陸も入れません。 土地の眺めはレーンの背景が受け持っているので、ここに海や 岸が映ると、土地が変わっても空だけ別の場所に見えます。
- 日時と天候名が載る場所を、白く抜かないようにします。 桁の紙も天候名も白いので、そこが白いと 沈みます。太陽を大きく描く天気ほどここが危うくなるので、光は右上へ寄せて逃がします。
- 絵がまだ無い天気は単色の板になります(
COLOR.weatherPanel)。絵は少しずつ増える前提なので、 絵のある天気と無い天気が混ざった状態を正常とします。板は天気そのものを表しませんが、白い天候名と 白い桁の紙がどちらも読める暗さにしてあります。 - 一覧はビルド時に作ります(
import.meta.glob)。ファイル名が実在の天気かどうかは自動テスト (tests/art/weatherArt.test.ts)が検査します。理由はカードの絵と 同じです。天気は土地と違って移動を待たずに変わるため、遅延ロードはせず起動時に読み切ります。 - 絵は
tools/comfyui/recipes/weather_<識別子>.jsonから作り直せます。
6. オプションバー (Options Bar)
設定・図鑑・日記・メニューのアイコンボタンを置くバーです。低頻度の操作なので、 通常のフロー内で他のエリアと重ならない位置に固定します。縦型では画面最上部 (キャラクターエリアの直上)に横長バーとして置きます。高さはフィルターバーと同じ 上下パディング 16u を確保した自動サイズ(約 120u)にし、ボタンの上下の余白がフィルター バーより狭く見えないようにしています。横型ではフィールドエリア右のサイドバー上段に置き、 アイコンボタンを縦に並べます(下段はフィルターバー、サイドバーの詳細は 10 節)。ボタンの 間隔はカード間ギャップ(12u)より広い 20u とし、隣接ボタンを誤タップしにくくしています。
アイコンボタンもスロットボタンと同じ紙として扱います(4.2 節)。落ち影を持たせ、枠線は黒では
なく地に合う暗い色にします(オプションバーは COLOR.paperButtonBorder、フィルターバーは藤色の地に
合わせた COLOR.filterButtonBorder)。
アイコンの絵は 4.2 節と同じ置き場所・同じ規約です(src/assets/icons/<識別子>.png)。識別子は
settings・codex・diaryと、フィルターのfilter_allとワールドが名乗るもの(card_filtersの
id、8.1.3 節)。どれも同じ寸法(160×160px)で持ち、UI は同じ大きさ(80×80u)で敷きます。
ボタンが正方形なので、キャンバスも正方形にします(スロットボタンの横長キャンバスと
違い、縦横で使える量が変わりません)。役割に大小は無いので、物の大小も付けません——
スロットボタンで地図と包帯の大きさを描き分けたのとは、そこだけ扱いが違います。
敷く大きさは画面によっても変えません。 ボタンが並び切らない画面でも 88u のまま並べ、はみ出した 分は送って見せます(8 節)。縮めれば全部が同時に見えますが、88u はアイコンボタンの最小タップ領域 (2 節)なので、見えることと引き換えに押せなくなります。
絵は絵文字を下絵にして作ります(tools/comfyui/emoji_page.py)。設定・料理・水のような役割は、
生成に任せると毎回ちがう物が出てきて、押す前に何のボタンか読めません。形と配置は絵文字から借り、
質感だけを Qwen Image Edit で描き直します。絵がまだ無いものは絵文字のまま(88u のボタンに対して
58u)で、絵と絵文字が混ざった状態を正常とします。
メニュー(☰)だけは絵にしません。物ではなく記号なので、質感を与える対象がありません。
7. フィールドエリア (Field Area)
カードを配置する主要な描画領域です。上から設置物レーン・アイテムレーン・
ハンドレーンの 3 レーン(各 352u 高。正方形に近い横型では、余った高さを 3 つで分け合って
高くなります——3.1 節)で構成し、各レーンは独立に横スクロールできます。
レーンに並ぶカードと枠の見た目は CardView.md、カードの操作は
CardInteraction.md が扱います。
7.1 設置物レーン (Fixture Lane)
現在地の設置物(fixtures スロット)を表示します。道・木・建物・家具など、持ち歩けないものが
すべてここに入ります。道も設置物の一種なので、木や建物と同じ並びに置かれます。
左端には現在地カードをピン留めし、区切り線を挟んで右に設置物を並べます。ピン留めはレーンの中身では
レーンの見出しで、タップすると現在地そのものの子ウィンドウが開きます。探索はそのタブ
(Windows.md 5 節)で、「探索する」は他のアクションと同じ最下段のボタンです。
横型では画面の横幅を活かし、カード 5 枚(ピン留め含む)強が視界に入ります。
道のカードは、道そのものではなく行き先の土地の名前と絵を出します。 道は「どこへ繋がっているか」 だけが意味を持ちますし、土地の景色と別々に描いた道の絵は、どの景色に載せても人の目には不自然に 映るためです。地に敷く景色は他の設置物と同じで、今いる土地のものです。
そのぶん、道であることは枠の色と、桟の中央の右向き矢印が 示します。 名前も絵も行き先のものなので、これが無いと現在地のカードや他の設置物と見分けが 付きません。先に読めるのは色のほうで、矢印は色を確かめる側です。
矢印は 22×11u で、紙の色の塗りに枠の色の縁にします。桟の色は種別で変わるので、塗り一色では 沈む組み合わせが出ます。絵文字(➡)ではなく図形で描きます——字を持たないフォントでは豆腐に なりますし、絵文字として描かれると環境ごとに色も形も変わってしまうためです。線ではなく塗り潰した 矢羽根にするのは、細い線だとカードを縮めて並べたときに何の形か読み取れなくなるからです。
持ち歩けない設置物(ヤシの木)はどのレーンへも送れないので端の操作を持ちませんが、同じレーンの 中でなら並べ替えられます。地形をどう捉えているかはプレイヤーごとに違うので、並び順はプレイヤーが 決めます。
7.1.1 外側の場所へ切り替える
現在地がそれ自体さらに別の場所の中にあるとき——海に出た筏の上、住居や避難所の中——設置物レーンは 外側の場所の設置物へ切り替えられます。切り替えなければ外側は画面から丸ごと消え、外側に置かれるもの (海区で見つけた航路・漂流物)に手が届きません。
条件は入れ子になっていることだけで、乗り物かどうかは見ません。 「場所である」ことの証は
fixtures スロットを持つことなので、筏も住居も同じ1つの仕組みに乗ります。
- 切り替えはピン留めした場所の札の端で行います。上端を押すと1段外側へ、下端を押すと内側へ戻り、 外側を持たない土地では端が出ません(陸に居る間の見た目と操作は今までどおり)。
- 既定は内側です。入れ物へ乗り込んだ瞬間に見えるものが変わらないようにするためで、外側が 無くなれば(筏から降りれば)自動的に現在地へ戻ります。
- ピン留めの札も、そこから開く子ウィンドウも、レーンが映している場所のものになります。そうしないと
どちらを見ているのか読めません(
DesignPrinciples.md「見分けの付かない場所を作らない」)。探索も映している場所に効きます。 - 切り替わるのは設置物レーンだけです。アイテムレーンとハンドレーンは現在地とプレイヤーのものから
動きません。外側の場所(海区)は
itemsスロットを持たない方針なので、切り替える相手がありません。 作り直すのもそのレーンだけです——ピン留めの札も敷く絵も映している場所のものなので設置物レーンは 建て直しますが、他の 2 レーンに出ている札はその場に残ります(3 レーンとも建て直すと、切り替えの たびに手持ちの札まで一度消えて出直します)。 - 見える範囲は切り替えても変わりません。 内側も外側も「今いる場所から見える」ことに変わりはなく、
レーンがどちらを映しているかは見え方の話です。開いている子ウィンドウを畳むかどうかもこの範囲で
決まるので(
Windows.md1.1 節)、切り替えでウィンドウが閉じることはありません。
これはつなぎです。 最終形は、1つの設置物レーンに内側と外側の設置物が一緒に並ぶことで、切り替えは そこまでの間に合わせにすぎません。
7.2 アイテムレーン (Item Lane)
現在地に落ちているアイテム(items スロット)を表示します。持ち歩けるものだけがここに入り、
下端 1/6 を押すと手持ちへ移ります(CardInteraction.md 1 節)。横型では
設置物レーンと同様にカード 5 枚分強が視界に入ります。
同種のアイテムは手持ちと同じく 1 枚のカード(スタック)にまとまり、右上の丸数字が個数を出します
(CardView.md 6 節)。
レーンの中身は items スロットそのもので、どの隙間へでも落とせます。
7.3 ハンドレーン (Hand Lane)
プレイヤーの手持ち(character の hand スロット)を表示します。レーンの幅はカード 6 枚分で
頭打ちにするため、横型でレーン幅が広がってもカードは引き伸ばしません。枠の数は人物ごとに違い
(characters/*.yaml の hand)、レーンに収まらない枠は隠れます。hand は固定枠スロット
(SlotSystem.md 3 節)で枠の位置が動かないため、空いている枠は
破線の枠だけのカードをプレースホルダーとして常に並べます。カードは上端 1/6 を押すと
アイテムレーンへ戻ります。
枠の位置が動かないこと自体に用途があります。 ハンドレーンは「持って移動できるスロット」で あると同時にワーキングスペースでもあり、かごを右端に置いたまま左側を作業用に空けておく、と いった使い方を想定しています。持ち替えのたびに札が寄ると、この置き場所の取り決めが毎回崩れます。
ただし、レーンに入り切らない札があるときだけは左へ詰めます(PlayScreenView の
packToFrontIfHidden)。縦型と、幅で決まる横型(縦横比 1.0〜1.558)のレーンはカード 5 枚ぶんの
横幅しか無く(3.1 節)、一度に見えるのは 5 枠までなので、6 枠目に居るカードは送らないと見えない
ためです。詰めるのは次のすべてが揃うときだけで、揃わなければ枠の位置は動きません。
- レーンに枠が全部は表示できていない
- 入り切らない枠に札が在る
- その札より左に空き枠が在る
これは画面の都合による場当たりの割り切りで、スロットの規定ではありません。 詰めるのは表示では なくスロットの中身そのもので、画面の都合でワールドの側を変えています——手持ちの並びが端末の幅で 変わることになりますが、承知のうえです。見た目の層だけを詰めると、枠の位置とスロットの添字がずれ、 空き枠へ落としたカードが別の枠へ入ります。レーンの幅が足りるようになれば、この処理ごと消えます。
7.4 スクロールバー
各レーンの下端に、送り具合を示す半透明のスクロールバー(src/ui/ScrollIndicator.ts)を重ねます。
どのレーンのどこへ置くかを決めるのは src/game/ui/CardLane.ts です。
端のカードを見切らせるだけでは「まだ右にカードがある」ことに気付きにくく、視界に入る枚数が少ない
縦型のハンドレーンで特に見落とされるためです。
- 中身が可視域に収まるレーンには出しません。 送れないレーンにバーを出しても意味を持たないためです。
- つまみの長さは中身に対する可視域の割合、位置は送り具合そのものです。中身が長いとつまみが 見えない細さまで痩せるので、最小の長さ(48u)で下限を切ります。
- 置き場所は送られるカードの真下(下端から 3u)で、横は送られる範囲だけです。ピン留めのある 設置物レーンでは、ピン留めは送られないので区切り線より右だけに置きます。
- カードの下には常に 16u の余白(レーン高 352u とカード高 320u の差の半分)を置き、バーはその中の 上寄せに入れます。バーが出るかどうかでカードの位置が動かないよう、余白は送る必要が無いときも 空けたままにします。レーンではこの余白に区切りの帯がかぶる 3u も収まるので、バーはカードにも帯にも 重なりません。
- 暗いトラックに明るいつまみを重ねます。レーンの背景の絵は明るいものも暗いものもあり、どちらの 上でもつまみが読める必要があるためです。
- 送っている間だけ濃くし、止まれば控えめな濃さへ戻りますが、消えはしません。 「まだ先がある」ことは 操作していない間こそ伝わる必要があるためです。
同じバーを、送れる他の場所——スロットの子ウィンドウ(レーンそのもの)、探索ウィンドウの
発見物の枠(Windows.md)、オプションバーとフィルターバー(8 節)——にも同じ規約で
置きます。発見物の枠にはレーンのような余白が無いので、カードの下に同じ 16u を足します(そのぶん
ウィンドウが縦に伸びます)。縦に送る場所には同じバーを 90 度回して立てます——縦の区切りに横の帯の
絵を回して敷くのと同じで(7.6 節)、縦向きのバーを別に持ちません。置き場所は送られる範囲の終わりの
辺から 3u で、横型の右サイドバーではサイドバーの右端がそれに当たります。
7.5 空の演出
外の様子をフィールドエリアそのものへ映します。状況エリアの窓は情報エリアの端にある小さな絵なので、 カードの並ぶ場所が映す方が早く伝わるためです。演出はそれぞれ別のものを見ています。
| 演出 | 見ているもの | 映す範囲 | 実装 |
|---|---|---|---|
| 翳り・輝き | ambient_brightness(明るさ) |
画面全体 | src/game/looks/skyTint.ts |
| 雨 | weather(天気) |
フィールドエリア | src/game/looks/rainStyle.ts |
| 陽炎 | 居る土地の ambient_temperature(気温) |
フィールドエリアの3レーン | src/game/looks/heatHaze.ts |
| 日の出・日の入り | 太陽高度が ambient_brightness へ与える寄与 |
フィールドエリア | src/game/view/daylight.ts |
日の出・日の入りだけが境目をまたいだ瞬間に一度だけ出て、ほかは今の外の様子を映し続けます (7.5.6節)。
7.5.1 明るさは世界の環境光が決める
天気ではなく ambient_brightness を見ます。 これは太陽高度と天気の寄与を1つに畳んだ実効値で、
夜は天気によらず底へ均される(IlluminationSystem.md 9節)ので、
真夜中の快晴が明るくなるような取り違えが起きません。雨が暗いのも同じ仕組みで表せます——雨雲が陽を
遮ることは、天気から明るさへの寄与として既に書かれているので、雨の側に暗さを持たせる必要がありません。
翳りも輝きも足さない基準は曇りの正午(+11)です。そこから暗いほど青みのある翳りが濃くなり、 明るいほど暖色の輝きが強くなります。輝きは加算合成にします——普通に重ねると白く濁って、明るくならずに 褪せて見えるためです。
暗さは、光が少し減っただけで大きく効かせます。 明るさはEVスケール(同1節)なので、正午の嵐と 曇りの差は5段——底から基準までの17段の3割ほど——ですが、目にはそれ以上に暗く映るため、翳りは明るさが 下がり始めた側で速く濃くなります。
7.5.2 翳り・輝きだけは画面全体にかぶせる
外の明るさは画面の一部の性質ではありません。 フィールドエリアだけが翳っていると、暗くなったと いうより、そこだけモーダルウィンドウで操作を止められているように見えます。情報エリアもバーも 子ウィンドウも、同じ明るさで同じだけ翳らせます。雨と陽炎がフィールドエリアに留まるのとは、ここが 違います——降る雨や地面の陽炎は外の景色そのもので、映すべき場所が決まっているためです。
- ドーナツグラフと致命的域の枠だけは翳りより手前に残します。 どちらも夜でも変わらず読めている 必要があるためです。
- 入力は遮りません。 翳っている間も、下のカード・ボタンの操作は変わりません。
- 色の板を1枚重ねるだけで、フィルタは使いません。 画面全体へ広げても板は1枚のままなので、 描画バッファ(DesignNotes.md)は要らず、持つものも増えません。
7.5.3 雨
雨が強いほど、多く・長く・速く・斜めになります。小雨は鉛直に近く数も少なく、大雨は少し斜めで量が 増え、嵐は更に斜めで、雨粒より長く薄い風の筋が混じります。傾きは向きだけでなく落ちる向きでも あり、筋の向きと落ちる向きは常に一致させます——斜めに降る雨が縦に伸びていると、風の向きが読めない ためです。
- 雨はカードより手前、隣接エリアより奥に降ります。 カードの上に降っていないと、雨が背景の絵の 一部に見えてしまいます。一方でフィールドエリアの外へは出さないので、情報エリアやバーには掛かりません。
- 入力は遮りません。 降っている間もカードの操作は変わりません。
- 雨は敷き詰めた1枚の絵(TileSprite)で描き、フィルタは使いません。 敷き詰めた絵は自分の矩形の 外へ描かないので、はみ出しを切り抜く必要がそもそもありません。フィルタで切り抜くと画面サイズの 描画バッファを使ってしまいます(DesignNotes.md)。絵は上下左右で 繋がるように描き、縦横それぞれ1周ぶん送っては戻すので、継ぎ目も折り返しも見えません。
7.5.4 陽炎
居る土地が暑いときだけ、レーンを1枚の熱い空気ごしに見せます(Phaserの変位フィルタ)。
- フィールドエリアの3レーンすべてに立てます。 暑いのは画面の一部ではないので、外の地面(設置物・ アイテム)だけを揺らして手持ちのレーンを止めておくと、そこだけ熱が届いていないように見えます。
- 1つのレーンに見えているものは、すべて歪ませます。 地面の絵だけでなく、その上のカード、現在地 カードとその背景、区切り線まで含みます。一部だけを止めると、そこに境目が見えます。
- ゆらぎはレーンの上の位置で決めます。 表示物ごとに別々のフィルタを掛けることになりますが、 どれもレーンの矩形を1枚の空気として見るので、同じ位置なら同じだけ揺れます。設置物レーンで背景が 固定と可動に分かれていても、境目に段差は出ません。カードを送っても空気は動かず、カードがその中を 通っていきます。
- 砂だけでは足りません。 まっすぐな輪郭が無く、ゆらいでいることが読み取れないためです。カードの 縁という直線が一緒に波打って、初めて陽炎に見えます。
- ここだけはフィルタを使うので、立っている間は描画バッファを使います(DesignNotes.md)。 歪ませる以上は避けられないコストです。掛ける対象は多いものの、 どれもレーンの矩形を写すためバッファは使い回され、レーンを増やしても消費は増えません。
- カードの名前が読める範囲に留めます。 大きく歪むと、陽炎ではなく描画の壊れに見えます。
- 天気ではなく気温を見ます。 陽炎が立つのは地面が焼けているからで、灼熱という天気の名前そのもの ではないためです。そのため乾季後半の晴天でも立ちます。
- 見ているのは、空ではなく居る土地の気温です。 歪ませているのは今居る土地の地面なので、読む先も
足元です。土地の気温は空の気温に海抜ぶんの差
(
../engine/ClimateSystem.md1.1 節)を足したものなので、同じ日でも 高い土地ほど弱くなります。 - 据えた炉の暖も、同じ気温へ積まれます(
../engine/FireSystem.md9.2 節)。熱の出どころは問わないので、火を焚いている土地では、暑い季節でなくても立ちます ——涼しくない季節の、日射が気温を押し上げている時間 (../engine/IlluminationSystem.md9 節)なら、炉の暖だけで 最も強いところまで届きます。日射が気温を動かさない朝夕や雨天の昼は、立ちはしても上端までは 届きません。
7.5.5 対応表はUI側が持つ
今の空を映し続ける演出は、強さの対応表がUI側にあります。WorldCodexは表示に関わる値を持たない方針 (Localization.md)で、液体の色 (LiquidContainerSystem.md 4.1節)のようにドメインが意味を持つ値でも ないためです。表に無い天気では降らせません。天気が増えても画面は壊れず、表へ足すまで降らないだけです。
7.5.6 日の出・日の入り
日が昇った・日が沈んだ瞬間に、フィールドエリアの中央で太陽と月が入れ替わります。 空が染まり、
地平線の向こうから昇る側が現れ、替わりに沈む側が沈みます。日の出のときだけ、その上に DAY 10 と
日数が出ます。 数秒で醒め、跡は残りません。
出すのは「太陽の光だけで手元の細かい作業ができるか」が切り替わった瞬間です (IlluminationSystem.md 5節)。明るさが大きく動くのは日の出と日の入り ですが、その境目のどこで演出を出すかは、遊びの側で線が引かれているところ——手元の作業ができなく なる時刻——に合わせます。刻々と変わる明るさそのもの(翳り・輝き)とは別に、「今、できることが 変わった」を一度だけ告げるのがこの演出です。
- 天気も樹冠も反射も見ません。 見るのは太陽高度が世界の
ambient_brightnessへ与える寄与だけです。 出しているのは太陽の位置なので、嵐が来ただけで日が沈んではなりません。同じ理由で、暗い密林に 居ても日の出は日の出です。 - 境目の数字も太陽高度の寄与も、UI側は持ちません。 しきい値はキャラクタの
hand_brightnessの段が (同 8節)、寄与はhourの段のmodifyが持っているので、どちらも宣言から読みます。 結果として日の出は6時、日の入りは18時になりますが、その数字をUIは書き写しません。 - またいだかを答えるのは映しの層です(
src/game/view/daylight.ts)。前後の時刻を渡せば境目を 答えるので、画面を作らずに検査できます(tests/game/daylight.test.ts)。画面の側は演出を出すだけです。 - 経過の途中のtickで出ます。 経過の再生は控えを1つずつ画面へ通す(
PlayScene.showRecorded)ので、 半日眠れば日の入りと日の出が順に出ます。前のが醒め切らないうちに次が来たら、差し替えます。 - 絵は持たず、図形で描きます(
src/game/ui/DaybreakOverlay.ts)。一度きり数秒だけ出るものなので、 素材を1組増やす価値がありません。月の満ち欠けも描きません——満ち欠けを表す値をワールドが持たない ためです(同 9節、月あかりは半月固定)。 - 入力は遮りません。 出ている間もカードの操作は変わりません。翳り・輝きより手前 (夜をまたぐ演出なので、翳りの下では出した意味がありません)、ドーナツグラフより奥 (経過時間を隠しません)に置きます。
日数は左上のカレンダーと同じ数(生存日数)です。 カレンダーは0時に次の日へ繰り上がるので、 日の出のときには既にその数を出しています——それでよいものとして、揃えに行きません。日が変わったこと そのものは時計が言っていて、この演出が言うのは「その日が始まった」ことだからです。
7.6 エリアの区切り
エリアの境目には木の梁の帯(src/assets/ui/separator.png)を敷きます。敷く場所は次のとおりです。
-
レーンの区切り: 設置物レーンの上・レーンの間・ハンドレーンの下。フィールド エリアを枠で囲う見え方になります。
-
本の外に並ぶ帯の境目(縦型のみ): オプションバーと状況エリアの間、状況エリアと本の間。 横型はオプションバーが右サイドバーにあり、状況エリアと本も上下に並ばないため、置きません。
-
フィールドエリアの左右の辺(横型のみ): 左は状況エリアと本、右は右サイドバーと接します。 ここだけ縦向きなので、同じ絵を反時計回りに 90 度回して敷きます(回した別ファイルは持ちません)。 縦型はこれらが上下に並ぶため、置きません。
左の帯は状況エリアの右辺ではなくフィールドエリアの左辺に置きます。 右サイドバーとの境目と 同じくフィールドエリアの辺として一貫させるためで、こうすると高さも両辺で揃います。本のページは この帯より手前に置かれるので、帯は本の縁で自然に終わります——状況エリアの右辺として置くと、 帯が本の影の途中で切れて不自然に見えました。
帯は中央半分だけが区切りそのもので、上下 1/4 ずつは隣のエリアへかぶせます。 そのため帯の高さは レーン間マージン(6u)の 2 倍の 12u を取り、境目の線に対して上下対称に置きます。レーンの区切りで かぶる 3u ぶんはレーン内側のカード上下の余白(15u)に収まるので、カードには重なりません。
- 絵は帯の高さへ合わせて縦横同率で拡大縮小し、横方向は繰り返して並べます(左右の端が繋がるように 描きます)。
- 原寸は 192×24px(高さ 12u の 2 倍)です。
- 入力は遮りません。 隣のエリアへかぶせて置くため、下のエリアのタップやドラッグを奪わないように しています。
- レーンの区切りは、隣接エリア(状況エリア・フィルターバー)の背景板を描き終えた後に敷きます。 上端・下端の帯はフィールドエリアの外へ 3u はみ出すので、先に敷くと隣接エリアに覆われてしまうため です。本の外に並ぶ帯の境目も同じ理由で、オプションバーと状況エリアを描き終えた後に敷きます。 一方、フィールドエリアの左の帯は本のページより先に敷きます(上記のとおり、ページに覆わせて 終端させるため)。
8. フィルターバー (Filter Bar)
フィールドエリアに表示するカードをタグで絞り込むボタン列です。ボタンはオプションボタンと同じ アイコンのみの正方形ボタン(アイコンボタン、88×88u)を再利用し、ラベルは付けません。選択中の ボタンは背景色を反転させて強調します。縦型ではフィールドエリア直下に置き、ボタンを 1 行に 並べます。横型ではオプションバーと同じ右サイドバーに同居し、サイドバー 下段でボタンを縦に並べます。ボタンの間隔はオプションバーと同じ 20u です。
ボタンは先頭が「すべて」で、残りはワールドの card_filters が並べる順に出ます(8.1 節)。
バーに収まらない分は送って見せます(レーンと同じ扱い、1 節「レーンは横スクロール」)。並ぶ向き (縦型は横、横型は縦)へドラッグとホイールで送り、送れるときだけレーンと同じスクロールバーが出ます (7.4 節)。ボタンの寸法は画面によって変えません——88u はアイコンボタンの最小タップ領域(2 節) なので、収まらないことを縮めて解決すると、押せる大きさのほうが失われます。オプションバーも同じ 仕組みに乗り、どちらのバーも数が増減したときの扱いは変わりません。
- 1 列を上下で分け合う横型は、初めから収まりません。 右サイドバーの下段は設計の基準(16:9)でも 636u で、前後の余白 16u×2 を引くと収まるのは 5 個まで(88u のボタンと 20u の間隔)——今のボタンは これを超えます。
- サイドバーが 2 列に広がる横型では、今のボタンが収まります(10.1 節)。フィルターが画面の高さ いっぱいの列(1080u)を持ち、前後の余白 16u 込みで 9 個までが並び、10 個目から送りが要ります。
- 縦型も今のボタンが収まります。 幅 1080u に対して、前後の余白 20u 込みで 9 個までが並び、 10 個目から送りが要ります。
- 収まらないときは、寄せ方によらずバーの先頭から並べます。 中央寄せ・末尾寄せのまま溢れさせると、 送り切っても先頭のボタンがバーの外に残ります。
8.1 絞り込みは、今の仕事に使う札だけを残す
ボタンを選んでいる間、そのボタンが指すタグをどれも持たない札をレーンから隠します。 選んで いない間は何も隠しません。以下の子節はすべてこのラベルの下にあります。
8.1.1 ボタンは、繰り返し払う支出の系統に対応させる
フィルターの一覧は ContentSkeleton.md 3 節の系統から作り、
同じ札の集まりを指す系統は 1 つのボタンへ畳みます。 画面の側で「よく使いそうなもの」を選ぶと、
なぜその顔ぶれなのかを誰も説明できず、世界に系統が増えても追随できません。
| ボタン | 系統 | 指すタグ |
|---|---|---|
| 食 | 2 食の調達・3 保存 | food・roastable・hearth・preservative |
| 水 | 1 水 | water・hot_water・liquid_container・container_lid |
| 火 | 5 火 | fuel・tinder・hearth |
| 道具 | 4 刃物・打撃、6 狩りの道具 | tool・weapon・trap・meat_bait・plant_bait・strike_target |
| 入れ物 | 7 運ぶ入れ物 | container・liquid_container・container_lid |
| 身につける | 8 衣類 | equippable |
| 住まい | 9 寝床・10 住居・12 家具・娯楽 | bed・shelter・furnishing |
| 遠出 | 11 船と海図 | path・sea_route・boat・sail |
- 「すべて」はこの一覧に入れません。 絞り込みを解除するボタンであってフィルターではないため、 UI が常に先頭へ置きます。ワールド側のデータに置くと、アセットパックが解除の手段を消せてしまいます。
- 1 枚の札が複数のボタンに出てかまいません。 炉は食と火の両方に、生の芋は食(焼ける)と道具
(罠の餌)の両方に出ます。レシピ一覧の棚(
Windows.md9.2 節)と違って札は 取り合いにならないので、「最初に一致した 1 つ」に決める理由がありません。 - 食のボタンが残すのは、食べられる物だけではありません。 焼ける物(
roastable)は生では 食べられなくても残り——生の芋とヤシガニはfoodを持ちません——炉(hearth)も残ります。 料理は札を並べてする仕事なので、材料と器具が同時に見えている必要があります。 - 娯楽の札は、住まいのボタンに出ます。 娯楽は里心を抑える設え(
furnishing)として系統12に なったので(ContentSkeleton.md3 節)、モックの並び(すべて・料理・ 水・クラフティング・娯楽)のうち娯楽だけは、独立したボタンではなく住まいへ畳まれて残ります ——寝床も住居も設えも「そこを我が家にする物」で、同じ仕事のときに同時に見えていてほしい札です。 - 道(
path)を指す系統はありません。 移動の距離は支出ですが、それを安くしていく段の連なりが 無いので系統から落ちました(ContentSkeleton.md3.1 節)。それでも 指す札はあるので、遠出のボタンに残します——落とすと道の札を絞り込む手が1つも無くなり、 移動の手段が隠れたままになります(8.1.6 節)。
8.1.2 足りないタグは、フィルターの名前ではなく物の名前で足す
指したい集まりを既存のタグで言い表せないときは、「その物が何であるか」を言うタグを足します。
足したのは、雨風をしのげる住まいであることを言う shelter(浅い洞窟)、そこで眠れることを言う
bed(敷物)、得た食を保たせる
物であることを言う preservative(塩)、海を渡る乗り物であることを言う boat(筏)、里心を抑える
ために据える物であることを言う furnishing(家具・娯楽)、打ちかかる相手であることを言う
strike_target(的)です。いずれも
ContentSkeleton.md 3 節の系統に 1 対 1 で対応します。帆(sail)と
航路(sea_route)は在っても船そのものを指す語は無く、無いままでは遠出のボタンから筏が消えます。
タグは物に付いて初めて在るもので、付ける先が無いまま名前だけを置くと、誰も正しさを確かめないまま
残ります。 寝床であることを名乗るのは寝床そのものだけで、そこへ差し込む骨組みと詰め物
(Bedding.md 1 節)は名乗りません。
こうして足したタグは、フィルターが無くても正しい宣言です(GameElementDefinition.md
4.1 節)。filter_food のようにボタンの名前を持つタグは作りません(8.1.5 節)。
8.1.3 どのボタンがどのタグを指すかは、ワールド側の card_filters が持つ
ルートキー card_filters(GameElementDefinition.md
3.1 節)に、ボタンを並べる順に書きます。recipe_categories と同じく、分類のために別の語彙を
持ち込まず、既にあるタグを指すだけにします。
card_filters:
- id: filter_food
icon: 🍖
tags: [food, roastable, hearth, preservative]
- id: filter_water
icon: 💧
tags: [water, hot_water, liquid_container, water_source, container_lid]
idがそのままアイコンの名前です(src/assets/icons/<id>.png)。型が自分の絵の名前を名乗る のと同じ形で(同 4.3 節)、UI 側に「このフィルターはこの絵」の対応表を置きません。- 絵がまだ無い間に置く絵文字も、同じ宣言が名乗ります(
icon)。代用の絵文字は 4.2 節のとおり 正常な状態なので、UI 側にその表を置くと、結局「このフィルターはこの絵」を画面が持つことになります。 - 文言は持ちません。 ボタンはアイコンだけでラベルを出さないので、
tag_texts(Localization.md)に相当するものを置いても読み手が居ません。iconは言語で変わらない絵の代用であって、文言ではありません。 - 綴りの誤りは、世界を丸ごと読む自動テストが見張ります(
tests/world-codex/cardFiltersYaml.test.ts)。 黙って何も残さないボタンを作らないためですが、ロード時には落とせません——指すタグはファイルを またいで付くので、どのファイルまで読んだ時点で「実在しない」と言えるかが決まらないためです (recipe_categoriesと同じ扱い)。見張るのは名前が在ることではなく、そのタグを名乗る型が 1 つ以上在ることです。
8.1.4 中身が該当する札は、自分が該当しなくても残る
入れ物は、外から開いて中を見られるスロット(GameElementDefinition.md
7.11 節の visible_slots)に該当する物が入っていれば残ります。 入れ子は辿ります——袋の中の籠の
中の干し肉でも、袋が残ります。
-
辿る深さに上限は設けません。 開いていけば必ず行き着く物なので、「何段目までなら探す」を決めると、 同じ干し肉が入れ方によって見つかったり見つからなかったりします。世界の入れ子は木なので、辿る先は いつか尽きます。
-
visible_slotsに挙がっていないスロットは数えません。 筏の積荷のように外から覗けない中身は、 そこに在ることを画面が言っていないので、札を残す理由にもなりません。「見える」と「入れられる」が 別であること(同 7.11 節)が、そのまま「探して見つかる」と「入っている」の別になります。 -
中身で残った札に、それと分かる印は付けません。 枠の色とバーは、その物が何であるかと今どう なっているかを言う場所です(
CardView.md2 節・8 節)。一時的な見え方のために 印を足すと、その分担が崩れます。中に何が入っているかは開けば分かります。 -
判定は表示のたびに行います。 中身を出し入れすれば、フィルターを掛けたまま札が現れたり 消えたりします。
8.1.5 フィルター専用のタグは作らない
採るのは 8.1.3 節の「ボタン 1 つが既存のタグを複数指す」ほうです。 採らなかった
のは、物の側へ filter_food のようなタグを足してボタンとタグを 1:1 にする案で、理由は次のとおりです。
- タグが言うのは「その物が何であるか」です(
GameElementDefinition.md4.2 節)。filter_foodが言うのは「食のボタンで出す」——画面の都合であって、物の事実ではありません。 - 暗黙に一致すべき宣言が 2 箇所に増えます。
foodを名乗る物はfilter_foodも名乗るはずですが、 それを保証するものがありません。片方だけ書かれた物はエラーにならず、ただ画面から消えます。 - 結局 1:1 になりません。 炉は食にも火にも出るので
filter_foodとfilter_fireの両方が要り、 ボタンを 1 つ足すたびに既存の型を全部見直すことになります。 - ボタンの入れ替えが、物の側の書き換えになります。 指すタグを変えるだけなら
card_filtersの 1 行ですが、専用タグでは対象の型すべてを書き直すことになります。
採る側の弱点は、指したい集まりを既存のタグで言い表せないと成り立たないことです。そのときに 足すのは 8.1.2 節のタグで、これはフィルターが無くても正しい宣言なので、増えても負債になりません。
8.1.6 絞り込むのは設置物レーンとアイテムレーンだけ
ハンドレーンは絞り込みません。 手持ちは固定枠で枠の位置が動かないこと自体に意味があり (7.3 節)、枠の数がレーンに収まる人物なら送らずに全部見えます——隠しても短くなりません。
- ピン留めした現在地の札は残ります。 レーンの中身ではなくレーンの見出しだからです(7.1 節)。
- 道の札は他の設置物と同じに扱い、遠出のボタンでだけ残します。 移動の手段が隠れることは ありますが、「すべて」を押せば戻るので行き止まりにはなりません。道だけを例外にすると、 何が隠れるかの規則が札の種類ごとに増えます。
- ボタンは 1 つだけ選べます。 複数選べると、選んだ 2 つが「かつ」なのか「または」なのかを 画面が言えません。同じボタンを押し直すか「すべて」を押すと解除します。
- 選んだフィルターは、場所を移っても時間が経っても続きます。 仕事は場所をまたいで続くためです。
- 落とす位置は、隠れている札を跨いで数えません。 絞り込んでいる間にレーンへ落とした札は、
指した位置に見えている札の数だけ前から数えた位置へ入ります——設置物・アイテムはどちらも前詰めの
スロットなので(
SlotSystem.md3 節)、ずれるのは隠れた札との前後だけで、 どの枠に入るかは変わりません。
8.1.7 絞り込みが隠している枚数は、そのレーンに出す【確定】
そうしないと、見えている札がそのレーンの全部なのかが読めません。空になったレーンでは物を置き 忘れたのかどうかが、札が残っているレーンでは残りが何枚あるのかが、レーンを見ても分かりません。
絞り込みが 1 枚以上隠しているレーンは、隠れている枚数を出します。
枚数を言います。 「絞り込み中」とだけ言う書き方は採りません。絞り込みを選んでいること自体は ボタンの強調が言っているので、レーンが足せるのは何枚隠れているかだけです。
出どころ: #656(枚数を言う規則だけ)
8.1.8 隠れている枚数は、先頭の空き枠に重ねる
重ねるのは先頭の空き枠 1 つだけです。 空き枠は札の後ろに出るので、「この先に隠れているものが N 枚ある」と読める並びになり、札の絵にもかぶりません。空き枠が複数あっても、隠れているという事実は 1 度言えば足ります。
空き枠が 1 つも無い並び(枠数の決まったスロットが埋まっている)では、末尾の枠に重ねます。 そこが並びの終わりで、続きがあることを言う場所として最も近いためです。
8.1.9 何を1枚と数え、どのレーンに出すか
8.1.7 節から導いたもので、覆すのに人間の判断は要りません。
- 出す文字列は
隠れ3枚。 数えるのは札で、束は何個入っていても 1 枚です——レーンに並ぶ単位が それだからです。 - 残っている札の有無によらず出します。 見えている札がレーンの全部かどうかは、そのレーンを見ないと 分かりません。
- 絞り込みの効かない場所には出ません(ハンドレーン・子ウィンドウ、8.1.6 節)。隠れている枚数を 答えるのは並びを持つ側なので、効かない場所では 0 枚になります。
9. 縦型レイアウト(1080×1920u)
| エリア | サイズ (u) |
|---|---|
| オプションバー | 1080 × 約 120(本の外、幅いっぱい) |
| 状況エリア | 1080 × 128(本の外、幅いっぱい) |
| キャラクターエリア | 1032 × 444 |
| フィールドエリア | 1080 × 1080(レーンに使えるのは外周マージンの内側 1074u で、カード 5 枚分と余り 1u) |
| フィルターバー | 1080 × 約 120(最下部) |
画面が 9:16 より縦長の端末では、余剰の高さはオプションバーの上に余白として残します (3.2 節)。左右が 1080u ではなく 1032u なのは、背景のページの縁を避けるためです(3 節)。
10. 横型レイアウト(1920×1080u)
左にダッシュボード列、中央にフィールドエリア、右に幅 120u のサイドバー(オプション/ フィルター)を置きます。オプションバーをダッシュボード列からサイドバーへ移した分で、 フィールドエリアにカード 6 枚分の横幅(1322u)を確保できます。サイドバー幅はバー自体の厚み(アイコンボタン 88 + 左右 パディング 16×2)と同じ 120u にし、ボタン左右の余白が広くなりすぎないようにしています。
サイドバーはボタンの数では太らせません。 フィルターは下段(636u)に並び切りませんが、 列を増やして幅を広げると、その分はフィールドエリアのカードの枚数から引かれます(1 節「フィールド エリア最優先」)。並び切らない分は送って見せます(8 節)。上段のオプションバーだけは高さを内容量 (アイコンボタン 4 個で 444u)ぶん取り、残りを下段が使います。太らせる理由になるのはフィールドエリアの余剰だけ で、その規則が 10.1 節です。
| エリア | サイズ (u) |
|---|---|
| 状況エリア | 478 × 184(本の外、ダッシュボード列の幅いっぱい) |
| ダッシュボード列 | 478 × 896(状況エリアの下。上からキャラクター表示・ステータス) |
| ダッシュボード列の中身 | 446 × 848(背景のページの縁を避けた範囲) |
| フィールドエリア | 1322 × 1080(カード 6 枚分の横幅) |
| 右サイドバー | 120 × 1080(上段: オプションバー、下段: フィルターバー) |
この表は余剰が無い画面のものです。フィールドエリアがカード 6 枚より多く表示できる画面では、 サイドバーが 240u の 2 列になります(10.1 節)。
画面が 16:9 より正方形に近い端末では、この 3 列が短辺基準の u では並びません。その場合は u を
縮めて幅 1683u を確保し(3.1 節)、フィールドエリアはカード 5 枚ぶん(1085u)まで狭まります。
この帯(縦横比 1.0〜1.558)は、どの寸法でも余りがちょうど 0 です——1085u は 3.1 節の最小幅
そのもので、6 枚目は 1u も入りません。1920×1080 の 1322u が 6 枚分なのは、16:9 が最小幅より
広いぶんをフィールドエリアが吸収した結果です。
キャラクター表示エリア(412u)は固定の高さで、残りを
ステータスエリアが吸収します(オプションバーがサイドバーへ移ったことで空いたスペースも
この吸収分に含まれる。表示件数が可変なため、余白が見えても問題ない)。.dashboard-column は
min-width: 0 を指定し、キャラクター
表示エリアなどの内容量で横幅が突っ張らないようにしている点に注意(flex: 1 な列が中身の
最小幅で止まってしまう既知の挙動の回避)。ダッシュボード列の幅は固定なので、画面が 16:9 より
横長の端末では、余剰の幅をフィールドエリアが吸収します(1 節の設計原則「フィールドエリア最優先」の
とおり、広がった分はカードの表示枚数に回る)。カード 6 枚を超えた分だけは、フィールドエリアでは
なくサイドバーが取ります(10.1 節)。
10.1 フィールドエリアが余らせた幅は、サイドバーへ回す【確定】
フィールドエリアがハンドレーンの枠の上限(7.3 節)より多くのカードを表示できるときに限り、超えた 分の幅をサイドバーへ回します。
上限を超えた幅は、使う相手が居ません。設置物・アイテムのレーンは送れば読めますが、手持ちは 広げても空き枠すら伸びません。1 節「フィールドエリア最優先」が効くのはここまでです。
出どころ: #656(余った幅はサイドバーへ)
10.2 回すのは 1 列(120u)で、フィルターを高さいっぱいの列にする
確定しているのは 10.1 節の 1 文だけで、回す幅と組み方は仮決めです。
- 回すのは 1 列ぶん(120u) で、サイドバーは 240u になります。120u はカード 1 枚のピッチ (217u)より狭いので、回してもカード 6 枚を割りません。
- 2 列とも画面の高さいっぱいの列にし、フィールドエリア寄りの左をフィルター、右端をオプションに します。オプションを上段(444u)だけに留めると、その下の 636u×120u が地の色の穴になります。 ボタンの並べ方は 1 列のときと同じで、フィルターは先頭から、オプションは列の中央へ寄せます。
- 判定は広げる前の幅で行います。 サイドバーが 120u のときのフィールドエリア幅で枚数を数え、 7 枚以上のときだけ広げます。広げた後の幅で測ると、広げる→6 枚になる→余剰が無くなる→戻す、を 繰り返します。
uの決め方(3.1 節)が使うサイドバー幅は 120u のままです。 ここを 240u にすると、余剰の無い 狭い横型まで全体が縮みます。
| 画面 | 幅 (u) | フィールドエリア (u) | 枚数 | 広げた後 (u) | 広げた後の枚数 |
|---|---|---|---|---|---|
| 16:9 | 1920 | 1322 | 6 | — | 広げない |
| 約 1.96:1 | 2117 | 1519 | 7 | 1399 | 6 |
| 19.5:9 | 2340 | 1742 | 8 | 1622 | 7 |
19.5:9 では広げた後も 1 枚余りますが、そこから先へ回す相手がいません——フィルターは 1 列で 足りています。送る仕組み(8 節)はどちらの組み方でも残ります。 余剰の無い画面と、ボタンが 10 個を 超える世界では、これまでどおり送って見せます。
11. エリア構成まとめ
画面([縦型] 上から)
├── オプションバー(アイコンボタン×4)
├── 状況エリア(空の帯: 左下に日時フリップカード、右下に天候名)
├── キャラクターエリア
│ ├── キャラクター表示エリア
│ │ ├── 1行目: ポートレイトカード|地図・装備・怪我・レシピのボタン(縦積み)
│ │ └── 2行目: 状況アイコン(1行・左詰め)
│ └── ステータスエリア(バー×7)
├── フィールドエリア(カード 5 枚分)
│ ├── 設置物レーン(現在地ピン + 道・木・建物…)
│ ├── アイテムレーン
│ └── ハンドレーン
└── フィルターバー(アイコンボタン×9、1行)
画面([横型] 上から。左の列・フィールドエリア・右サイドバーは左右並び)
├── 左の列
│ ├── 状況エリア(空の帯: 左上に天候名、下端に日時フリップカード)
│ └── ダッシュボード列(=キャラクターエリア)
│ ├── キャラクター表示エリア(縦型と同じ組み方。幅だけが列いっぱい)
│ └── ステータスエリア(バー×7)
├── フィールドエリア(カード 5 枚分強。ハンドレーンのみ 6 枚分で頭打ちにして余白を残す)
│ ├── 設置物レーン(現在地ピン + 道・木・建物…)
│ ├── アイテムレーン
│ └── ハンドレーン
└── 右サイドバー(120u の 1 列。フィールドエリアに余剰があれば 240u の 2 列)
├── オプションバー(アイコンボタン×4、上段。2 列なら右の列)
└── フィルターバー(アイコンボタン×9、下段。収まらない分は送る。2 列なら左の列で全部出る)
12. 実装
Phaser 側の実装は src/game/PlayScene.ts(エリアの寸法計算は src/game/looks/PlayScreenLayout.ts、
探索のタブは src/game/ui/ExplorationPane.ts)。本ドキュメントの u 単位の寸法トークンをそのまま
用い、向きの変更時は画面を作り直して配置し直します(開いている子ウィンドウは組み立て直されます)。
アクションで表示内容が変わったときは画面を作り直さず、レーンの中身を差し替えます。移動で現在地が
変わったときだけは、フィールドエリアだけを作り直します
(移動の場面転換)。
表示する内容は src/game/view/PlayScreenView.ts が供給します。3 レーンと日時は実際のワールド状態
(現在地とそのスロットの中身・キャラクターの手持ちスロット・world の日時)から作ります。
アイテムの画像がまだ無いため、カードのアイコンは種別ごとの絵文字を仮に使っています。名前は
言語ごとの対応表(Localization.md)から引きます。状況アイコンは
4.1.1 節の宣言がまだ入っていないため、モックと同じ固定の絵文字を返すプレースホルダーのままです
(PlayScreenView.conditions)。
ワールド状態そのものの保存はまだ無いため、プレイ画面はセーブデータのシードから世界を作り直して 表示します(SaveDataManagement.md)。
13. HTML モックとスクリーンショット
表示方法:スマートフォンブラウザで開くと、縦向き・横向きの切り替えに追従してレイアウトが変化します。
デスクトップブラウザでは、ウィンドウ比率を変更するか、DevTools のデバイスシミュレーターでご確認ください。
モックは領域分割と寸法の検証を目的とし、装飾はカードの角丸程度に留めています。各エリアとレーンには
position:absolute のラベルを重ね、背景色を変えて境界を視認しやすくしています。
縦型 1080×1920

横型 1920×1080
