# ステータスエリア

## 概要

キャラクターのプロパティをバーで並べるステータスエリア（[`ScreenLayout.md`](./ScreenLayout.md)
4 節）に、**何を・どう出すか**を決めるドキュメントです。エリアの位置と寸法は
`ScreenLayout.md`、バーを持つ他の場所（カードの状態バー）は [`CardView.md`](./CardView.md) 8 節が
扱います。

**UI はステータスの意味を一切知らず、すべて YAML 側の宣言から導きます**——出すものは `status` タグ
（プロパティのタグ）、見せ方の切り替えは域（`stages` の `alert`）、悪化の向きは域の並び
（`alertDirection`）、行の左に出す絵は対応表の `icon`
（[`Localization.md`](../engine/Localization.md)）が決めます。UI 専用の新しい宣言はありません。

実装は `src/game/ui/StatusBar.ts`・`ProgressBar`（バーの部品）と `src/game/looks/theme.ts`（色）、
どの行を出すかは `src/game/view/ShownStatuses.ts`、1 行が何を映すかは `src/game/view/statusBarLook.ts`
（どちらも画面を持たない層）で、実装済みです。
どのプロパティが対象かは `characters/` の YAML が持ちます。

## 1. 出すもの: `status` タグ

キャラクターのプロパティのうち、**`status` タグ**（プロパティのタグ、
[GameElementDefinition.md](../engine/GameElementDefinition.md) 6.7 節）が付いたものだけをバーで表示
します。何を常時見せるかは YAML 側の宣言で決まり、UI は種別を一切知りません。`status` は健康・栄養と
いったカテゴリと**重ねて**付けます（満腹度は `status` であり `nutrition` でもある）。

件数は可変です。上端に揃えて表示し、件数が変わってもバー群の位置が動かないようにします。
残りのプロパティはポートレイトカードから開く子ウィンドウのプロパティのタブ
（[`Windows.md`](./Windows.md) 6 節）で見ます。**タグを 1 つも持たないものはどちらにも並びませんが、
それが効いている相手の詳細に影響の枠として現れるなら、そこから開けます**（同 8.2 節）。**どの相手の
詳細にも現れないものは、今は読む場所がありません**——読ませたくなったら、タグを付けて並べます。
**枠として現れるかどうかは持続効果の宣言が決めること**なので、見せたいからといって足せるものでは
ありません。

**バーの値は、アクション・combination・探索のたびに書き換えます。** 中身だけを差し替えるのは、バーを
作り直すと、後から置かれた子ウィンドウの覆いより手前へ出てしまうためです。同じ理由で
**バーは全プロパティ分を画面の組み立て時に作っておき**、以後は見せ方と位置だけを変えます（出す行は
行動のたびに変わるため、あとから作るとその瞬間に開いている子ウィンドウを突き抜けます）。

## 2. 域による出し分け

各ステータスがどの域にあるかは、YAML 側の `stages.alert`
（[GameElementDefinition.md](../engine/GameElementDefinition.md) 6.4 節）が宣言します。UI は域ごとに
見せ方を変えるだけで、どのステータスがいつ危ないのかは一切知りません。

| 域 | 見せ方 |
|----|--------|
| 安全域 (`safe`) | 出さない（余裕があるものを並べても読み取る情報が無いため）。ただし安全域へ戻った行は、良くなった分の帯（4 節）を見せ終わってから消えます |
| 留意域 (`watch`) | 出す |
| 要注意域 (`caution`) | 出す（留意域と同じ） |
| 危険域 (`danger`) | 出したうえで、バーの枠を黄色く明滅させる |
| 致命的域 (`fatal`) | 出したうえで、バーの枠を赤く明滅させ、**画面全体の内周も赤く明滅**させる |

**留意域と要注意域は今のところ同じ見せ方**です。留意域は「すぐどうこうはならないが、まったく見なくて
よくはない」程度で、要注意域はもう少し差し迫った状態を表します。今は区別して見せていませんが、深刻さの
違いを YAML 側の宣言として持っておくことで、後から見せ方を分けられます。

致命的域は、放置すると死に至るステータス（水分など）だけが持ちます。画面全体の枠まで使うのは、
ステータスエリアを見ていなくても手が止まるようにするためです。

**安全域から外れる（＝ステータスエリアに出る）のは、おおむね最大値の 80%** です（実際の値は
プロパティごとに `stages` が持ちます、`characters/`）。開始直後はどのステータスも満タン＝安全域
なので、ステータスエリアは空から始まり、値が減るにつれて行が現れます。

## 3. 行の左はアイコン、固定表示と並び順

**行の左に出すのは名前ではなくアイコン**（44u の欄）です。ステータスエリアに並ぶのは常に同じ数件で、
プレイヤーは毎回読み直すのではなく位置と絵で見分けるため、名前に取っていた幅（140u）はバーへ回します。
絵は対応表の `icon`（[`Localization.md`](../engine/Localization.md)）が宣言し、**宣言が無いプロパティは
表示名で代用します**——どのプロパティも固定表示にすればここへ出せるので、絵が揃っているとは限りません。
代用しても欄の幅は変えません。バーの左端が行ごとにずれると、長さを見比べられなくなるためです。

**プロパティウィンドウは、同じアイコンに表示名を添えて並べます**（[`Windows.md`](./Windows.md) 6 節）。
ここが絵と名前の対応を覚える場になるので、ステータスエリアは名前を出さずに済みます。

**行はどこをタップしても、そのステータスの詳細**（[`Windows.md`](./Windows.md) 8 節）**が開きます**
（ステータスエリアでもプロパティウィンドウでも同じ）。1 本の行の中で押した場所によって別の操作になると、
印や絵を狙ったつもりの指が別の操作に当たります。**固定表示の付け外しは、開いた詳細の見出しの行にある
ボタン**（[`Windows.md`](./Windows.md) 8 節）が引き受けます。固定表示にしたものは安全域でも出続けるので、
気にしている値を自分で残せます。固定表示にするとアイコンの左に 📌 が付き、印の欄（34u）は印が無い間も空けておきます
（付け外しで位置が動かないようにするため）。**詳細を開けたプロパティは、どれも固定表示にすれば
ステータスエリアへ出せます**——プロパティウィンドウにしか出ないものも、どこにも並ばず影響の枠からしか
開けないもの（[`Windows.md`](./Windows.md) 8.2 節）も同じです。どれを固定表示にしたかはセーブデータが
持ち（[SaveDataManagement.md](../engine/SaveDataManagement.md) セーブデータのスキーマ節）、切り替える
たびにそのスロットへ書き戻すので、開き直しても残ります。

並び順は次のとおりで、同じまとまりの中はプロパティの宣言順のままです。

1. 固定表示にしたもの
2. 危険域・致命的域のもの
3. 留意域・要注意域のもの
4. 安全域へ戻り、変化を見せ終わるのを待っているもの

**行の位置が変わるときは、その位置まで動かして見せます**（0.25 秒）。出す行が入れ替わると並び順も
変わるため、いきなり別の値が現れたように見えないようにするためです。固定表示を外した行はその場で
消えます（動かす先が無いため）。

**安全域へ戻った行は、その場では消さず、良くなった分の帯（4 節）が追いつき切ってから消します。**
値が安全域に入った瞬間に落とすと、行が消えるのと帯が動き出すのが同時になり、**何がどれだけ良く
なったのかが見えないまま**バーごと消えます。待つ間は最後尾（4）へ置きます——もう注意すべき値では
ないものを、まだ注意すべき行より上に出さないためです。既に出ていない行は動かさずに現れる決まりなので
（4 節）、安全域のまま値が動いても現れることはありません。

## 4. 変わった分の帯

**バーの値が変わるときは、変わる前の位置に帯を残し、少し遅れて（0.25 秒後から 0.7 秒かけて）追いつかせます。**
格闘ゲームの体力バーと同じで、塗りが一瞬で動くと「どれだけ変わったか」が見えないためです。追いつき切る前に
また変わった場合は、そのとき見えていた位置から続きます。

**動くのは変わる前の値の側だけで、今の値の側はすぐそこへ移ります。** 値そのものは待たせず、変化の量だけを
目で追わせるためです。帯と塗りのうち広い方が帯・狭い方が塗りになるので、向きで見え方が変わります。

| | 帯 | 塗り |
|---|---|---|
| 減ったとき | 減る前の位置に残り、遅れて縮む | すぐ今の値まで縮む |
| 増えたとき | すぐ今の値まで伸びる | 遅れて帯を満たしていく |

**良し悪しを表すのは帯の色だけです**（形は増減だけで決まります）。悪化した分は赤、好転した分は塗りを
薄めた色になるので、増えると悪いステータス（荷重）では**増えた分の帯が赤く**なります。

好転の帯を固定の 1 色にせず塗りから引く（`fadedFill`）のは、**これから満ちる分**を表すためです。
塗りの色はバーごとに違う（水は青、油は黄色）ので、固定色だと何が満ちる途中なのかが読めなくなります。
悪化の赤が塗りの色によらず同じなのは対照的ですが、失われたものはもう塗りではないので色を共有しません。

**1 回の行動の途中では帯を動かしません。** 長い行動は tick ごとに値が動きますが（時間経過の再生、
[`CardInteraction.md`](./CardInteraction.md) 8 節）、そのつど追いつかせると 1 tick 分ずつの帯にしか
見えません。**行動が終わってから動き始める**ことで、帯はその行動で変わった合計を示します。

この動きはバーの部品（`ProgressBar`）が持つので、増えるだけのバー（探索率）でも進んだ分が帯として出ます。

**出ていなかった行が現れるときは、その行動を始める前の値から見せ始めます。** 帯は「今この行動でどれだけ
変わったか」を見せるものなので、現れた行にもその行動での増減ぶんは帯で出ます。出ていない間（安全域だった間）
に変わった分まで足すと、現れた瞬間に満タンから大きく減ったように見えてしまうため、そこは含めません。

**段が上がった行だけは、帯を出しません。** 段の中の進みを見せるバー（9 節）は、段が上がると次の段へ
軸ごと移って 0 から始まるので、またいだ前後の差は変わった分ではありません。帯にすると、腕が上がったのに
「減った分」の赤い帯が出ます。**満たされ具合のバーは軸が `range` そのもの**で、値が段をまたいでも動かない
ため、これまでどおり帯が出ます（水分が渇きの段へ落ちた行も同じです）。増減の記号（5 節）は値そのものの
増減なので、段をまたいでも出ます。

## 5. 増減の記号

**バーの右に、直前の行動での増減を三角で出します**（増えたら明るい緑の ▲、減ったら赤の ▼）。行動を
始める前と終わったときの値を比べたもので、変わらなかった項目には出しません。次の行動まで出したままに
するので、移動のようにフィールドエリアを作り直す行動でも記号は残ります。

**記号が消えるのは、時間が経過してなお値が動かなかったときだけです。** 時間を消費しない操作（箱へ
入れる、並べ替える）は行動の区切りではないので、そこで値が動かなくても直前の行動の記号を残します
——ステータスが動きようのない操作をしただけで記号が消えると、その操作が何かを変えたように見えるためです。
荷重のように時間を消費せずに動く項目もあるので、**動いた項目だけは上書き**します。

記号の欄（40u）は**記号が無い間も空けておきます**。出たり消えたりするたびにバーの長さが変わると、値が
動いたのか幅が変わったのかを取り違えるためです。

## 6. 増えると悪いステータス

負荷（`load`、[ContainerSystem.md](../engine/ContainerSystem.md) 2 節）のように**増えるほど悪い**プロパティも、
`status` タグを付けるだけで同じ行として並びます。**専用のバーをキャラクター表示エリアには置きません**——
空身の間も 0 のバーが出続けて「安全域は出さない」と食い違いますし、常に見ていたいプレイヤーは固定表示（📌）で
自分で残せます。荷造りの最中から見えている必要はあるので、それは留意域の閾値を低く取ることで満たします。

ただしバーの語彙は「満タンが良い」に寄っているため、向きだけが逆になります。**どちら向きが悪化かは
定義の側が述べます**（`PropertyDef.worsensUpward`、
[`GameElementDefinition.md`](../engine/GameElementDefinition.md) 6.8 節）——荷重のように段の `alert` が
下から上へ深刻になっていく量は、それだけで増える側が悪いと言えているので、二度書かせません。
UI が切り替えるのは次の 2 点だけです。

| | 減ると悪い（満腹度など） | 増えると悪い（荷重） |
|---|---|---|
| 遅れて出る帯 | 塗りが先に縮み、帯が後から縮む | 帯が先に伸び、塗りが後から伸びる |
| 増減の記号 | ▲ 緑・▼ 赤 | ▲ 赤・▼ 緑（向きは値の増減のまま） |

帯の規約を「**悪化した分を遅れて見せる**」に一般化したもので、溜めと動きの時間（0.25 秒後から 0.7 秒）も、
1 回の行動の途中では動かさないことも、向きによらず同じです。並び順・明滅・固定表示も既存のままです。

## 7. 塗りの色は域が決める

**塗りの色は、域（`alert`）の深刻さで安全域の緑から致命的域の茶へ寄せます。** 満タンが良いバーと悪いバーが
同じ画面に並ぶ以上、塗りの**長さ**だけでは良し悪しが読めないためです。長さは「どれだけか」を、色は
「まずいのか」を表す、と役割を分けます。

- 引くのは値の位置ではなく**域**なので、まだ安全域なら満タンでなくても緑のままです。
- 域を持たないバー（探索率）は常に安全域で、緑のまま変わりません。
- **危険域・致命的域の明滅する枠は、暗い線を敷いた上に載せます。** 深刻な域ほど塗りが濃くなるので、
  明るい枠の色をそのまま置くと沈んで読めなくなるためです。

## 8. 両端が悪い量は、バーにしない

体温のように**高すぎても低すぎても悪い**量は、`range` を持つプロパティ（＝バーになるもの）としては
宣言できません（`alert` の深刻さが下から上へ単調でないため、ロード時エラー）。塗りの向きを
「良い方へ伸びる」とも「悪い方へ伸びる」とも決められないからです。

この種の量は、**片側だけを別のプロパティとして見せます**。高いほど良いのか低いほど良いのかが読み取れない
バーを作らずに済み、プレイヤーが対処すべき事柄（冷やす／温める）とも一対一で対応します。

**寒い側は `warmth`（体に残っている熱）で、「減ると悪い」ふつうのバーです**
（[`VitalsSystem.md`](../engine/VitalsSystem.md) 8.3 節）。**向きを「増えるほど悪い」に揃える必要は
ありません**——体温を 2 本に割るのが要点で、割った先の向きは、残量として数えられるかどうかで決まります。
熱は残量として数えられる（尽きれば凍死する現実の量）ので、水・血と同じ向きに置きます。暑い側を後から
足すなら、そちらは残量ではないので「増えるほど悪い」量（熱中症の度合い）になります。**同じ体温から
出た 2 本のバーが逆を向く**のは矛盾ではなく、片方だけが実在の在庫だからです。

## 9. 割合を持たない量は、レベルと段内進捗で見せる

`range` を持たないプロパティ（腕前、[`SkillSystem.md`](../engine/SkillSystem.md) 5 節）には満たされ具合が
無いので、バーの代わりに実効値そのものを出します。ただし**段を持つものは、値ではなく今いる段の名前
（レベル）と、次の段までの進み**を出します。腕前の値は指数的に増えるため、生の値も最大値に対する割合も、
序盤が常にほぼ 0 % に見えるからです。

- **バーが映すのは「今いる段の中でどこまで来たか」**（`(現在値 − 今の段の min) ÷ (次の段の min − 今の段の
  min)`）で、段が上がるたび 0 に戻ります。上の段ほど幅が広いので、同じ 1 回の行動で進む量が目に見えて
  減り、鈍化がそのまま体感になります。
- **バーの左端に今いる段、右端に次の段の名前**を重ねます。長さが同じでも「あと少しで満タン」ではなく
  「あと少しで次の段」と読め、満ちたら 0 へ戻る量であることが両端の名前から分かります。**満たされ具合の
  バー（`range` を持つもの）には名前を載せません**——長さそのものが答えなので、文字は要りません。今いる
  段はステータス詳細（[`Windows.md`](./Windows.md) 8.1 節）が名札で出します。
- **進みを言えない段では、段の名前だけを出してバーを出しません。** 次の段が無い最上段と、下端を名乗らない
  最下段（受け皿、[GameElementDefinition.md](../engine/GameElementDefinition.md) 6.4 節。`range` も無ければ
  区間が定まりません）がこれにあたります。0 のバーを出すと、値が動いても止まったままに見えます。
- **段が上がった行では、変わった分の帯（4 節）を出しません。** バーの軸が次の段へ移るので、またいだ前後の
  差は変化量ではありません。
