プレイヤーキャラクタ
新規ゲーム作成時に選ぶ主人公。1キャラクタ=1つの object_def で、src/assets/world-codex/characters/ に
1ファイルずつ置く(共通の骨組みだけが player_character trait)。
character タグはプレイヤーが操作するキャラクタだけに付く。操作できない生物は、持ち運べるなら
アイテム(item)、持ち運べないなら設置物(fixture)で表す。したがって「選べるキャラクタの一覧」は
character タグを引くだけで得られる(WorldCodex.objectDefNamesWithTag)。
定義を分けたうえで齟齬を防ぐ方法
キャラクタごとに数値は違ってよいが、あるキャラクタだけ満腹度の定義が無い、最大値だけ変えて
stages を直し忘れたといった食い違いは許容できない。これを防ぐのは trait ではなくテスト
(tests/world-codex/charactersYaml.test.ts)である。
trait は「何を持つべきか」ではなく「省略したらこの値」しか表現できない。props のマージはフィールド
単位の上書き(RawObjectDef.resolve)なので、trait に既定値を置くと「range.max だけ上書きして
stages は trait のまま」が素通りする。stages のしきい値は max から導いた値なので、この瞬間に
下記の不変条件が壊れるうえ、キャラクタのファイルを読んでも stages が見えないため気づけない。
そこでテストは character タグを持つ全 object_def を走査する。キャラクタを1つ足せば自動的に検査
対象になり、登録漏れが起きない。
契約
持たなければならないもの
| 内容 | |
|---|---|
singleton |
true(同時に存在するプレイヤーキャラクタは1体) |
| タグ | character |
| スロット | hand(item を受け入れる枠。数は人物ごとに定義する)、equipment、injuries |
| プロパティ | weight / travel_delay / pain / blood / warmth / chill_point / satiety / carbohydrate / protein / lipid / vitamin / loneliness / homesickness / comfort / company / happiness / pathogen / immunity / hydration / body_fat / wakefulness / stamina / load と、腕前(Skills.md 2 節)、その段が押し上げる上乗せ ignition_ease / quarry_sense / hunting_aim(同 5 節。重みの base の土台になる)(いずれも個体差を持たず player_character trait が配る) |
| アクション | 休息(wait / rest / nap。下の休息節。睡眠は寝床が配る)と、限界(collapse / fall_asleep / despair。下の限界節)。どちらも player_character trait が配る |
| 表示 | ja.yaml の表示名、代替アイコン(characterCard.ts。絵が入るまでの繋ぎ) |
status タグが付くのは pain / blood / warmth / satiety / vitamin / homesickness / happiness / pathogen /
hydration / wakefulness / stamina / load で、宣言順もこの順に揃える(propertiesWithTag の戻り順がそのままステータスエリアの
並びになる、StatusArea.md)。trait 由来のものが先頭に並ぶのは、trait の props が
キャラクタ自身の props より前に並ぶため(RawObjectDef.resolve)。chill_point は status を持たない
——見せるのは残っている熱だけで、境目そのものは衣服・寝床が押し下げる裏の値。loneliness と comfort と
company も持たない——常時見せるのは間の homesickness だけで、どれもその詳細から辿って読む
(下のホームシック節)。栄養素の在庫(carbohydrate ほか)は
status を持たない——常に見せるのは腹が満ちているかどうかだけで、在庫は開いて見るもの
(DigestionSystem.md 3 節)。ビタミンだけが在庫と別扱いなのは、
尽きた先の弊害を段が持つため(同 4 節)。immunity も status を持たない——常時見せるのは症状
(pathogen の段)のほうで、免疫そのものは体脂肪と同じく開いて見る値(同 6.2 節)。
気絶を決める consciousness は、pain と同じくキャラクタ間で共通の値としてここへ加わる予定である
(押し下げる側は VitalsSystem.md 2 節。手番を飛ばす側は入ったが、
倒れている間の画面がまだ無いため、まだ実装しておらず上の契約にも含めない。同 7 節)。
値の刻み方(キャラクタ間で共通の規約)
数値のスケールは GameElementDefinition.md 6.0節に従い、
range.min は常に0——唯一の例外が immunity で、そこだけは押し下げが重なっても残る守りの底(20)を置く
(DigestionSystem.md 6.2 節)。1 tick(15分)。
尽きると死ぬのは hydration / body_fat / blood / warmth
(VitalsSystem.md 8 節・8.3 節)。
いずれも range.min(=0)へ達した時点で on_min が自分を destroy する、同じ形で書く。
死因を名乗るのはその destroy で、添えた reason(dehydrated / starved / exsanguinated /
frozen)が消された側に残る(WorldObject.destroyedReason、
VitalsSystem.md 6 節)。
同じ名前の段を一番下に置くのは、尽きる前に警告を出すため。
satiety(満腹感): 単位は mL——胃に入っている物のかさで、エネルギーではない (DigestionSystem.md2 節)。maxが胃の容量なので、下の 「安全域を外れるのはmaxの80%」も「初期値は75%」も当てはまらない。maxの6割に置いた段fullをeatが読んで「もう食べられない」を見る。餓死はbody_fatが受け持つため 致命的域は持たない。個体差は無くplayer_charactertrait が配る。- 栄養素の在庫(
carbohydrate/protein/lipid): 単位は tick(体脂肪と同じ物差し)。 在庫がある間はbody_fatへ流れ続け、速さは栄養素ごとに違う(同 3 節)。個体差は持たず trait が配る。 段を持つのはlipidだけで、一番下のfat_starved(脂が尽きた域)がhydrationとproteinを削り、painを押し上げる(同 7 節)。statusタグは持たないので画面に行は増えない。 vitamin(ビタミン): 単位は mg(ビタミンC相当)。エネルギーにならないので、ほかの在庫とは 物差しが違う(同 4 節)。同じく trait が配る。一番下の段scurvy(壊血病)がpainを押し上げる ——体調不良を怪我のカードにせず、原因となる値の段に持たせる (DesignPrinciples.md)。happiness(幸福度): メンタルの不調を代表する1本で、単位を持たない 0〜100。自分では動かず、 食べた物が上げ、painとhomesicknessの段が下げる(下の幸福度節)。0 まで落ちると 打ちひしがれ、その強制の時間の間だけ戻る(下の限界節)。個体差は持たせず trait が配る。loneliness(孤独、日)/homesickness(ホームシック)/comfort(居心地)/company(連れ): 時間の経過そのものから生える圧(下のホームシック節)。溜める側と抑える側は自分では 動かずbaseで継ぐだけで、間のhomesickness(0〜120、増える側が悪い)だけが溜まってhappinessを 削る。個体差は持たせず trait が配る。pathogen(全身の菌)/immunity(免疫): 菌は log₁₀ CFU(0〜9)で持ち、菌が居ることになる段 (latent以上)に居る間だけ定数で増える。免疫は段ごとの定数でそれを引き、除去と増殖の大小 1 つで 着地するか暴走するかが決まる(DigestionSystem.md6 節)。菌の上2段がhydrationとbloodを 削るので死に方は増えない。免疫を押し下げるのは生活の側で、ビタミンが最も重く、しかも2段で 押す(壊血病と、その手前の不足)。宣言はそれぞれの段の側が持ち、何がどれだけ押すかの一覧はDigestionSystem.md6.2 節。どちらも個体差は持たせず trait が配る。hydration(水分):-1/tick固定で、maxが「満水から何 tick 保つか」。減り方に個体差を 持たせない——キャラクタが違っても、飲んだ水1mLの意味が変わってはならないため。持ちの差はmax(=体が抱える水の量)で表す。液体の mL からの換算は飲用側の宣言が持つ(transferのto_amount、LiquidContainerSystem.md5節)。 脱水はそのまま死に至るため、致命的域(fatal)を持つ。尽きた段の名前はdehydrated。min: maxの段full(満水ちょうど)を持ち、名前を固定する——液体のdrinkがこの名前で 「もう飲めない」を見る(LiquidContainerSystem.md5節)。body_fat(体脂肪): 3本のエネルギーから届いた分が積み上がり、尽きると餓死する。初期値はmaxの 1/4(標準体格)。減る速さは自分の段で決まり(太っている ほど速い)、これが食べ過ぎても際限なく太らない平衡点になる。尽きる域の名前がstarved。 1日に要る量の個体差(標準体格でnourished段のレート)はここに出る (DigestionSystem.md5 節)。statusタグを持たないため ステータスエリアには出ない——画面に見える飢えの兆しは満腹感が受け持つ。wakefulness(覚醒度): 0で強制的に眠りに入る(下の限界節。致死性は無い)。-1/tick。 戻すのは眠る休息(仮眠・睡眠)と、その眠り込み(休息節)、それに飲むとwakefulnessを 配る液体(茶。LiquidContainerSystem.md)。maxは「満タンから、 意識を保てなくなって眠り込むまでの時間」で、普通の人間の48時間(192 tick)を基準に置く。外から起こし続ける実験の記録 (数日〜十日)は採らない——あれは自力で起きていられる長さではないため。眠らずにいられる長さの 個人差はここに出る。stamina(体力): 疲労の逆。戻すのは休息(同節)と、倒れ込み・眠り込み(下の限界節)。 tickで減るのは荷を担いでいる間だけで、減らすのはloadの段(下の荷重の効き方節)。空身なら 1 も減らない。0で倒れ込む。pain(痛み): 負っている怪我(InjurySystem.md)がmodifyで押し上げる値。自分では 動かないのでvalueは 0 のまま、maxは「これ以上は耐えられない」点。痛みの感じ方は食の好みではなく 身体の仕組みなので、栄養バランスと同じく個体差を持たせずplayer_charactertrait が配る。weight(体重、g): 65,000(下のbloodが体重のおよそ1/13という関係に合わせてある)。担ぐ側も担がれる側になる——筏に乗れば自分と手持ちが積載として効く (ContainerSystem.md1.1 節)。個体差はまだ持たせず trait が配る。travel_delay(歩みの遅れ、分): 素は 0 で、自分では動かずloadの段がmodifyで押し上げる (下の荷重の効き方節)。道のtravel_minutesがbaseでここを土台にする。statusタグは持たない ——見せるのは荷重そのもので、遅れはその段から読める。個体差は持たせず trait が配る。blood(血液量、mL):maxが体格そのもの(体重のおよそ1/13)で、満タンから始まる。体が 自分で作り直すステータス(+2/tick、赤血球が作られる実際の速さ)。削るのは出血する 怪我だけなので、削られるのは一瞬でも戻るのは桁違いに遅い——牙の傷1つが奪う600mLに3.1日かかる (VitalsSystem.md3.3 節)。尽きた段の 名前はexsanguinated。刻み方はVitalsSystem.md3 節、これも個体差を 持たせず trait が配る。戻るのは水分と体脂肪がともに安全域にある間だけで(同 3.1 節)、 水も食べ物も切らしたまま養生することはできない。warmth(熱、kcal)/chill_point(寒さの入口、℃):bloodと同じくmaxが体格そのもの (700 = 深部体温 37℃ から 25℃ までに失える熱)で、満タンから始まる。寒いかどうかは、居る場所のambient_temperatureとchill_point(素は16℃)の比較1つで決まる——下回る間は-2/tick、 屋根も蓋も無い所で雨に打たれている間は-6/tickで削られ、上回る間は+8/tickで戻る。尽きた段の 名前はfrozen。段の境目は深部体温で置く(刻み方はVitalsSystem.md8.4 節)。個体差は持たせず trait が配る。chill_pointは、防ぐ側(衣服・寝床)がmodifyで押し下げるための境目で、火だけは境目ではなく 気温の側を上げる。load(荷重): 持ち物と装備の重さ(g)。自分では動かず、中身から導出される (ContainerSystem.md2節)のでvalueは 0 のまま。maxが 「担げる量」そのもので、担ぎ慣れの個人差はここに出る。段が駆動するのは移動の可否だけではない ——歩みの遅れとstaminaの削りも段が持つ(下の荷重の効き方節)。
域の区分(stages の不変条件)
GameElementDefinition.md 6.4節の alert。max が違っても
プレイヤーの読み取り方が変わらないよう、しきい値は次の形で揃える。
- 安全域から外れるのは
maxの80%(=ステータスエリアに出始める位置)。この境界だけは 全ステータス・全キャラクタで共通でなければ「まだ大丈夫」の感覚が崩れる。端数は丸める——段のしきい値は 人が読む数字なので、小数が書けても整数に留める。 hydrationとhappinessの初期値はmaxの75%(安全域のやや下)。満腹感も同じ狙いで留意域(300mL)から 始める(DigestionSystem.md2 節)。満タンで始めると alert がsafeでステータスバーに出ず(StatusArea.md)、 飲食の操作も最初は試せないため。荷が無ければ減らないstaminaと、序盤に眠らせたくないwakefulnessは満タンで始める。- 減る速さが一定のものは、80%より下を残り時間で切る。
wakefulnessは残り12時間未満でcaution、残り3時間未満でdanger。 hydrationも残り時間で切る: 残り2日未満でcaution、残り1日未満でdanger、 残り6時間未満でfatal。staminaは割合で切る:maxの60%未満でcaution、20%未満でdanger。減る速さが担いでいる 荷で変わる(下の荷重の効き方節)ので、残り時間で切ると荷を持ち替えるたびに段の意味が変わります。 割合なら、境目は常に「体力があと何割か」を指したままです。happinessも割合で切る:maxの80%で安全域を外れ、50%未満でcaution、20%未満でdanger(下の幸福度節)。減る速さが今の痛みで変わるので、staminaと同じ理由で残り時間では 切れない。vitaminの80%より下は現実の量で切る: 300mg 未満が壊血病(danger)で、その上のcautionの 境目は 600mg。発症の境目だけは残り時間ではなく実際の血中量で、外から検算できる (DesignPrinciples.md「現実に単位があるものは、その単位で持つ」)。bloodは失った割合で切る(臨床の出血性ショックの分類、VitalsSystem.md3 節)。2割失って安全域を外れるので、上の80%の境界と ちょうど一致する。以降 3割でcaution、4割でdanger、6割でfatal。warmthの境目は深部体温で切る(VitalsSystem.md8.4 節)ので、 上の80%は安全域の境目ではなくcautionの境目になる(560 = 34.6℃ = 軽度低体温症の入口)。 安全域はmaxちょうど(37℃)で、満タンから始まり、そこから 560 までがwatch——体温は満タンが 常態なので、失った熱はそれだけで留意に値する。loadとpainとhomesicknessは増える側が悪いので、上の「80%で安全域を外れる」は当てはまらない。maxからの 割合で刻む: 1/4 でwatch、1/2 でcaution、5/6 でdanger。0 から始まって荷造り・怪我の最中に 現れるよう、最初の境目は低めに置く。loadの危険域の段の名前はtoo_heavyで固定する——道のtravelがこの名前で移動可否を見る(ContainerSystem.md5節)。
荷重の効き方
効かせ方は 1 箇所——load の段(ContainerSystem.md 5 節)で、
閾値を別に持つ量は 1 つも足しません。 荷が何に効くかは「荷は、歩みの遅れと疲れにも効く」節が
決めます。
| 段 | 移動 | 歩みの遅れ | stamina |
|---|---|---|---|
light |
通る | 遅れない | 減らない |
laden |
通る | +15 分 |
-0.3/tick |
heavy |
通る | +30 分 |
-1/tick |
too_heavy |
通れない | — | -2/tick |
- 疲れる側は、今の文法でそのまま書けます。 段の
passivesがaddでstaminaを削るだけです (GameElementDefinition.md6.4 節)。削るのが時間なので、 往復の回数そのものが重みを持ちます——重い荷で長い道を歩くほど、削られる tick が増えます。staminaが空身では減らない、という既定が破れるのは、ここだけです。 - 桁は「1 日で使い切れる」位置に取ります。 起きている間を
heavyのまま担ぎ通すと、max100 のほとんどを使い切ります(captain.yaml)。荷を下ろして骨組みを差した寝台で 眠れば、その 1 日ぶんがちょうど戻るので、重い荷の 1 日ぶんと、睡眠1回の回復がちょうど釣り合う位置です (tests/world-codex/beddingYaml.test.tsが見ます)。これより 1 桁 小さいと、何往復しても睡眠1回で必ず取り返せてしまい、削っているのに何も決まりません。 - 借金が積み上がるかは、寝床の段で決まります。 釣り合うのは骨組みを差した寝台の上だけで、敷物だけ
では睡眠1回で返し切れません(
Bedding.md4節)——重い荷の日を毎日続けられるか どうかが、寝床を仕上げたかどうかで分かれます。 - 担いだまま眠れば、そのぶん戻りません。 回復は経過の間ずっと効く宣言なので、削りと同じ足し算に
入ります(下の休息節)——
heavyのまま眠れば削りのぶん戻りが減り、釣り合いは崩れます。 荷を下ろす理由がここから出ます(そりを作る理由と同じ向きで、下ろす手間そのものは要りません)。 - 遅くなる側は、道が担ぎ手の遅れを土台に継ぎます。 道の所要時間は道自身が持つので、そこへ
base: {subject: agent, prop: travel_delay}(GameElementDefinition.md6.5 節)を書き、durationは{prop: travel_minutes}の 1 つを読むだけにします。travel_delayは素が 0 で、loadの段がmodifyで押し上げる分です。 道が知っているのは「自分の所要時間は歩く人の遅れで伸びる」ことだけで、遅れの内訳(荷・怪我)は 知りません——遅くするものが増えても押す先は人のtravel_delayなので、道の宣言は変わりません。 - 遅れは tick の刻みで刻みます(
ActionSystem.md6.2 節)。道の所要時間も 1 tick(15 分)の倍数なので(生成が刻みへ丸める)、荷を担いでも行動の長さは格子に乗ったままです。 - 一律の加算なので、短い道ほど割合として重く効きます。 同じ遅れが、道が短いほど所要に対して
大きな割合になります。式(積)を書ける場所を作らないことを優先した結果として承知のうえなので
(
GameElementDefinition.md10.2 節)、この点は積へ戻す理由に なりません。釣り合いを動かすなら、動かすのは段ごとの分数です。 - 軽くする道具の値打ちは損なわれません。 そりのような率を下げる道具は
loadそのものを下げるので、 移動の可否・遅れ・疲れに同時に効きます(ContainerSystem.md2 節)。移動が重くなる方向の変更ですが、DesignPrinciples.mdの 「コストは、それを軽くする道具の値打ちそのもの」に沿って、重くなった分がそのまま、そりを作る理由と 前線を近づける理由になります。 - 怪我もここへ合流します。 骨折は宿主の
loadを押し上げる(InjurySystem.md5 節)ので、傷の側に移動の規則を 1 行も書かずに「折れた脚では遅く、余計に疲れる」が出ます。 - 画面は変わりません。
loadは既にステータスエリアへ「増えると悪い」バーとして並んでいます (StatusArea.md6 節)。段が増えたわけでも、新しい行が増えたわけでもありません。
上の表の数値は目安です。 段ごとの遅れと削りをどこに置くかは、1 日にどれだけ往復するのが普通かが
決まって初めて釣り合いが見えます(未決事項は
ContainerSystem.md 8 節)。動かないのは、削るのが時間であることと、
1 日ぶんと、荷を下ろした睡眠1回の回復が同じ桁であることだけです。
荷は、歩みの遅れと疲れにも効く【確定】
荷は、担げるかどうかだけでなく、歩みの遅れと疲れにも効きます。
出どころ: #656(重いほど移動が遅くなる/重いほど疲れる)
幸福度
happiness は、メンタルの不調を代表する1本です。 ストレス・退屈・里心が行き着く先を分けず、心の不調は
すべてここへ集めます(DesignPrinciples.md)。分かれるのは原因の側
だけで、pain と homesickness がそれぞれ値を持ってここを削ります。
押し引きはすべて add で、modify は1本も刺しません。 刺すと実効値が実体値とずれて on_min が
書けなくなります(WorldCodex.requireRangeEventsOnUnmodifiedProperties)——尽きたことへ反応する道を
add だけの値のまま開けておきます。意味の面でも、効くのは「快適な寝床で寝た今夜」であって、寝床を
所有していること自体ではありません。
現実の単位を持ちません(pain・stamina と同じ抽象の 0〜100)。値そのものは外から検算できず、
確かめられるのは大小の関係だけです。初期値は水分と同じ 75(安全域のやや下)——漂着した直後から
ステータスエリアに出ていて、食べれば戻ることが最初の1食で分かります。
| 段 | 下限 | 域 |
|---|---|---|
miserable |
0 | 危険 |
dejected |
20 | 要注意 |
glum |
50 | 留意 |
content |
80 | 安全 |
致命的域は持ちません。 尽きても死なず、0 に達すると打ちひしがれて時間が過ぎ、その間に少し戻ります (下の限界節)。
上げるのは、食べた物のベース値
食べ物は eat の add に定数を1つ持ちます。量ではなく質で決まります——かさは satiety が、
身になる量は栄養素が既に持っているので、ここが数えるのは食べた喜びだけです。同じ「火の通った1食」
なら、丸焼きのネズミも焼いた肉と同じだけ戻します。
持つのは eat だけで、飲む操作は1つも持ちません——food を名乗る青い実(刃で穴を開けてその場で
水を飲む)も同じです。飲んで上がるかどうかは決めていません。
| 値 | 何を食べたか |
|---|---|
| 6 | 火を通した食事(焼いた肉・ヤシガニ・タロイモ・ネズミ) |
| 4 | 生でうまい果実(バナナ・ベリー・ヤシの果肉・青い実のゼリー) |
| 2 | 生で食べられるだけの物(空心菜・海藻・海鳥の卵) |
| 1 | 本来は火を通すもの(生肉) |
| 0 | 炭(腹の嵩しか残っていない) |
焼いた肉は生肉より多く戻します。 DigestionSystem.md 6節の菌と併せて、生で食べない理由が1本増えます。
値そのものは検算できません(幸福度に現実の単位が無いため)。動かないのは、火を通した物が最も戻す
ことと、量が効かないことだけです。書き忘れると、その食べ物だけが心に何も残さない食事になるので、
eat を持つ型がすべてベース値を宣言していることを tests/world-codex/foodsYaml.test.ts が全数で
見張ります。
下げるのは、痛みとホームシックの段
pain の段が add で削ります——sore で −0.125/tick、hurting で −0.25/tick、unbearable で
−0.5/tick。怪我も壊血病も脂の欠乏も痛みへ合流しているので、削る宣言を
1箇所に置くだけで、内側の不調が残らず心へ届きます。疼く程度なら食事で取り返せ、激痛のまま1日を
過ごすと最良の食事3食でも追いつきません。
内側の不調が痛みへ合流するのに対し、外から時間が掛ける圧は homesickness が受け持ちます(下の
ホームシック節)。削る量は痛みと同じ目盛りで、削る側はこれで全部です。
寒さと雨はここへ引きません。 どちらも熱(warmth)が受け持っていて、対抗手段(火・屋根)もそちらに
付いています。両方へ効かせると、火を焚くことがうまい物を食べることの代わりになります。
時間そのものから生える圧は、下のホームシック節が持ちます。 寝床からの寄与は未実装で、
Bedding.md 8節がこの節を待っています。
ホームシック
サバイバルは知識と設備が積み上がるぶん、後半ほど易しくなります。 危機が最初の数日だけになって残りが
作業になるのを埋める圧を、時間の経過そのものから生やします
(DesignPrinciples.md 「後半には、時間の経過そのものから生える圧を置く」)。
経過日数 ──▶ loneliness ──▶ homesickness ──▶ happiness を削る
▲抑える
comfort(住居の設え) / company(世話をしている獣)
常時のバーに出るのは homesickness だけです。 溜める側の loneliness も、抑える側の comfort・
company も status タグを持たないので、増減の理由は「里心が募っている」の1本に集まります。
どれも、そのホームシックの詳細から辿れば読めます——影響の枠として並んでいるので、押せばその段が
出ます(下の抑えるのは、今いる場所節)。
孤独は、経過日数そのもの
loneliness は独立した値としては溜めません。base: {subject: ancestor, prop: day} で world の日数を
場所ごしに継ぐだけです(ambient_brightness・sheltered と同じ形)。時間の単調増加関数でしかないものを
別に持つと、同じ数が2箇所に立ちます。base にしてあるので、将来「他の生存者に会う」で modify して
下げる余地は追加のコストなしに残ります。
段の境目は日数で置きます——30・60・90日目で、初回の季節がちょうど各30日(calm→wet→dry、
ClimateSystem.md 2.3 節)なので雨季と乾季の入口に重なります。漂着した
最初のひと月は溜まりません——生き延びるだけで手一杯のあいだに里心は付きません。
季節そのものではなく日数で切るのは、プレイヤーが読めるのが日付のほうだからです。開始時刻は 8:00〜
12:00 から選ばれる(SaveDataManagement.md)ので、季節の切り替わりは境目の日の途中に来ます。日数で
切っておけば、その半日ぶんのずれが「どちらの季節に数えるか」の問題にならずに済みます。
| 段 | 日 | homesickness を溜める速さ(/tick) |
|---|---|---|
occupied |
〜29 | — |
restless |
30〜 | +0.01 |
lonely |
60〜 | +0.02 |
forsaken |
90〜 | +0.04 |
ホームシックが幸福度を削る
homesickness は 0〜120 で、増える側が悪いので段は max からの割合で刻みます(pain・load と同じ
1/4・1/2・5/6、上の域の区分節)。削り方も pain と同じ形で、1段上がるごとに倍です。
| 段 | 下限 | 域 | happiness(/tick) |
|---|---|---|---|
settled |
0 | 安全 | — |
wistful |
30 | 留意 | -0.125 |
yearning |
60 | 要注意 | -0.25 |
despondent |
100 | 危険 | -0.5 |
max が 120 なのは、表へ出る日のほうが先に決まっているからです。 この目盛りに現実の単位は無く、
決まっているのは「60日目に顕在化する」ほうで、30日目から溜まり始めた分が60日目のうちに留意域
(max の1/4)を越える max の範囲のうち、いちばん読みやすい数が 120 です(60日目に表へ出ることは
tests/world-codex/homesickness.test.ts が見ます)。
何も打たなければ、60日目に留意域へ入って削られ始め、91日目に初めて打ちひしがれます(火を通した3食
を通した場合。tests/world-codex/homesickness.test.ts)。初回の雨季が明けるころに表へ出て、
1周回(ContentSkeleton.md 8.3 節)の終盤で手が止まり始める位置です。
追いつくのは最初の段まで——yearning からの削りは最良の食事でも埋まりません。
0 は終点ではありません。 幸福度が尽きると打ちひしがれ、120分が強制的に過ぎて happiness が
+2.5/tick 戻り(下の限界節)、削りが続く限りそれを繰り返します。
繰り返す速さを決めるのは、削りと戻しの差——despondent の削りに何を食べたかを差し引いた正味で
持ち出せた量を割った時間が、次に打ちひしがれるまでの間隔です。強制の時間にも削りは走るので、
持ち出せる量もその正味で決まります。口にした物がそのまま手元に残る時間になります(食べたかどうかで
1日に奪われる時間が変わることは tests/world-codex/homesickness.test.ts が見ます)。
打ちひしがれている間も日が進むので、里心そのものはそこでは止まりません——止められるのは、下の設えと連れだけです。
抑えるのは、今いる場所
抑える手はどちらも場所が持つ値(location trait)です。キャラクタは
base: {subject: ancestor} で継ぐだけなので、遠征に出れば、どちらも効きません。
場所は入れ子になるので、どちらも ambient_temperature と同じく囲っている場所から継ぎます
(洞窟と住居は土地の fixtures に据わる場所で、筏は海へ出れば海区の fixtures に浮かぶ場所です)。継がないと、浜に建てた囲いのすぐ隣の
洞窟へ入った瞬間に慰めが消えます。継ぐのは下向きだけなので、外に立っている間、住居の中の設えは
効きません。
comfort(居心地)は、その場に据えた設えが押し上げます(家具・娯楽、furnishings.yaml。据えれば
効き続け、手入れは要りません)。住居の部品も同じ形で押しますが、そちらはまだ実装がありません
(Dwellings.md 2 節)。
設えは、据えること以外に何の役にも立ちません——生きるのに要る物が居心地を兼ねると、対策が
どうせ作る物になって圧が素通りします(ContentSkeleton.md 3 節の系統12)。
住居だけは例外で、雨風のために建てた家も押します——ただし部品の合計は homely 止まりに抑えて
あるので(Dwellings.md 2.1 節)、snug へ届くには設えを積むことになります。
| 段 | 下限 | homesickness(/tick) |
|---|---|---|
bare |
0 | — |
homely |
20 | -0.02 |
snug |
50 | -0.04 |
company(連れ)は、飼葉の残っている囲いが1つにつき 1 だけ押し上げます(farming.yaml。数えるのは
囲いの数で、頭数ではありません——囲いは中に何頭居るかを知らないためです)。囲いの中に生きた獣が
居ることが飼いならしたことそのもので、世話をやめれば慰めも切れます。
| 段 | 下限 | homesickness(/tick) |
|---|---|---|
alone |
0 | — |
kept |
1 | -0.02 |
分けているのは、積み上がってよいかどうかが違うからです。 据えた設えは積むほど効いてよい
——それが家具・娯楽を作る値打ちそのものなので、comfort は段を重ねます。連れは積み上がってはいけません
——囲いは同じ土地へいくつでも据えられる(土地の fixtures に枠数の上限はありません)ので、頭数や囲いの
数で慰めが増える形にすると、囲いを3つ並べるだけで最後の段まで打ち消せます。company の段が1つ
だけなのはそのためで、頭数でも囲いの数でも効き目は増えません。
囲い1つでも、homely まで積んだ設えでも、60日目からの増えはちょうど止まります。
90日目からの増えを止めるには snug まで積むか、homely(家でも設えでも)と家畜の
両方が要るので、家畜だけでは最後まで持ちません。逆に、家を建てただけでも homely 止まりです——「どうせ建てる家」を
1つ置けば済む圧にはしていません。
90日目からを止める snug へは、設えを積んで届きます。 単体で届く物は1つも無いので必ず積むことに
なり、何をいくつ並べるかは自由で、要るのは合計の手間のほうです(点数を掛かる手間に比例させてある
ので点あたりの手間はおおむね揃いますが、払う総手間は並べ方で上へ振れます——点あたりの手間の差と、
線を越える手前で行き過ぎる量の差が、どちらも乗るためです。いちばん安い積み方は
stats/terrain.yaml の work_piles に出ます)。
刃物1つで届く道もあるので、斧も狩りも通らずに snug まで積めます——里心の対策は、ほかの系統の
進み具合に縛られません。
どちらもプロパティのタブには出ません(タグを1つも持たないため、Windows.md 6 節)。
読む場所はホームシックの詳細で、そこに並ぶ影響の枠を押すと、今どの段に居るかが名札で出ます
(同 8.1 節・8.2 節)。出すのは段の名前だけで、点数は出しません——要るのは「今どれに届いているか」で、
あと何点かではないためです(腕前と同じ、Skills.md 5.1 節)。
専用の場所を作らないのは、押し上げているのが場所の側だからです。 周りの事情を身の値と同じ並びへ
混ぜると、homesickness が動いた理由を確かめる先が割れます
(DesignPrinciples.md「周りの事情と、身に起きていることは、別の
場所に出す」)。結果から原因へ降りる道だけを開けておけば、問いを持った人にだけ答えが出ます。
気にし続けたい人は、その詳細から固定表示にすれば常時のバーへ出せます
(StatusArea.md 3 節)。
遠征は心を削るものとして割り切ります。 持ち運べる慰めの席は開けません(開ければ、拠点を離れない選択と
離れる選択の差が消えます)。設えのある場所へ帰れば homesickness は減るので、遠出で増やしたぶんは
帰ってから戻す、が押し引きの形になります。
長い遠征ほど、帰るまでが遠くなります。 里心が深いまま出ると、道中で打ちひしがれて強制の時間が過ぎ (下の限界節)、そのぶんも日は進みます——遠征に出た日数がそのまま余計に溜まる形です。 拠点へ帰るまでは止める手が1つも無いので、帰りの余裕をどれだけ残すかが終盤の遠出の判断になります。
休息
時間を進める操作は、キャラクタ自身のアクションです。 どれも同じ形(duration と passives)で
player_character trait に並び、ActionSystem.md 2 節の実行パイプラインを
そのまま通ります。違うのは長さと回復量だけ——このうち wakefulness も戻すのは眠るものです。
時間を進める専用の仕組みは持ちません——プレイヤーが押せない限界の操作も同じ形です。
睡眠(sleep)はここにありません。配るのは寝床のほうです(Bedding.md 4 節)。
まったく同じ形の操作を寝床が自分で持ち、その回復量は寝床の段で変わります。地面の上で取れるのは
仮眠までなので、下の表はそのまま「寝床の無いところで取れるもの」の一覧でもあります。
戻すのは tick 毎です(passives、GameElementDefinition.md
11.7 節)。経過中の減り(荷・痛み・里心)と同じ足し算に入るので、受け取る量は「宣言 − その間の減り」
になります。休んでいる間も荷は担いだままで、その重さのぶんだけ戻りが薄くなります。
入口は日時のフリップカードで、押すとキャラクタ自身の子ウィンドウが開きます
(Windows.md 4 節)。
| 長さ | stamina |
wakefulness |
|
|---|---|---|---|
wait(待機) |
15分 | +0.75/tick | — |
rest(休憩) |
60分 | +1/tick | — |
nap(仮眠) |
180分 | +1.25/tick | +3/tick |
- 通しで眠れるのは寝床の上だけです。 地面の上で取れるのは仮眠までなので、釣り合う点がずれます
——仮眠だけで回すと寝床の上より眠る時間が長くなり、1日に起きていられる時間が短くなります
(
Bedding.md4.1節)。地面でも通しで眠れるようにする ことが決まっていて(同 4.1.1節)、入ればこの行と上の表は書き直しになります。 - まとめて休むほど1時間あたりの回復が大きい。 同じ長さを休むなら、空身で休憩を重ねるより 仮眠のほうが多く戻ります。細切れに休むより通しで休むほうが得、が数値だけで出ます。 この割増しが効くのは地面の上だけです(同 4節)。
- 体力の割は、荷が削る量から逆算しています(下の荷重の効き方節)。地面の上の1日を
仮眠で回すと、
heavyを起きている間担ぎ通した1日ぶんを仮眠では返し切れません。地面の上では重い荷の日を 続けられない、というのが 寝床を敷き骨組みを差す理由で、返せる位置に在るのは骨組みを差した寝台だけです (Bedding.md4節)。too_heavyを担いだままなら、地面のどの休息でも体力は減ります。 - 眠っている間も覚醒度は減り続けます(
-1/tick)。寝床の上で睡眠1回を取る1日は、覚醒度がちょうど元へ戻ります——普通の1日を回すぶんには 釣り合い、それより長く起きた日だけが翌日へ持ち越されます。睡眠1回では満タンに届かないので、 寝溜めはできません(2つともtests/world-codex/charactersYaml.test.tsが見ます)。 - 回復量は個体差を持ちません(痛み・血と同じく trait が配ります)。
staminaのmaxが大きい キャラクタほど1回で戻る割合は小さく、休息の重みは体格の側に出ます。 - 休んでいる間も水分と体脂肪は減ります。 眠っている間も水分は起きているときと同じ割で減ります——眠ること自体に
値段があり、渇いたまま眠れば眠っている間に死にます(
VitalsSystem.md6 節)。
限界
尽きた値は、強制的に時間を進めます。 0 に達すると何も手につかなくなり、一定の時間が過ぎ、その間に
少し戻ります。対象は stamina(体力)・wakefulness(覚醒度)・happiness(幸福度)で、
尽きても死にません——死ぬのは hydration / body_fat / blood / warmth だけ
(VitalsSystem.md 8 節)で、これらは動きを止めるだけです。
どれも同じ1つの形で書きます。 押す機会の無い操作(trigger: tick、
GameElementDefinition.md 11.1 節)が、下限に居ることを
conditions で見て、duration ぶん時間を進め、passives が tick 毎に戻す——上の休息と
同じ形で、player_character trait が並べて配ります。違うのは見る値・長さ・戻る量だけです。
| 手番 | 見る値 | 長さ | 戻るもの |
|---|---|---|---|
collapse(倒れ込む) |
stamina |
120分 | stamina +1/tick |
fall_asleep(眠り込む) |
wakefulness |
360分 | wakefulness +3/tick・stamina +1/tick |
despair(打ちひしがれる) |
happiness |
120分 | happiness +2.5/tick |
- 戻る割に、まとめて休んだ割増し(上の休息節)は付けません——どの値についても。 どれも
休み方を選んだことにならないためで、体力は
restと同じ割です。幸福度には自発の休息が無い ので割の比べようがなく、120分で危険域をちょうど抜ける量を置きます(tests/world-codex/charactersYaml.test.tsが見ます)。 眠気を戻せる休息は 眠る休息で、どれも割増しを持っているので、そちらはいちばん薄いnapの割を使います。 - 眠り込みが戻すのは眠気だけではないので、体力もこの割に従います。 寝床の上の
sleepと同じ割に すると、寝床の無い場所で体力を戻す最良の手が眠り込みになります——寝床を要らない休息のうち最も 割のよいnapを上回ってしまうためです。 - 戻る量は個体差を持ちません(休息と同じく trait が配ります)。
staminaのmaxが大きい キャラクタほど1回で戻る割合は小さく、倒れる回数の重みは体格の側に出ます。ただし空身で倒れても、 どのキャラクタも危険域(exhausted)からは出られません——戻る量が、maxがいちばん薄い 技師(90)の境目 18 にすら届かないためです(tests/world-codex/charactersYaml.test.tsが見ます)。倒れ込みは逃げ場であって、戻す手ではありません ——戻すのは自発の休息の仕事です。荷を担いだままならさらに薄くなります。 - 眠気を
sleepの割で戻すと、寝床を敷く理由が消えます。 倒れるまで起きているほうが、寝床で眠るより 1日に長く起きていられることになるためです。napの割なら、倒れるまで起きているほうが損になります。 - 戻すのが tick 毎なのは、限界だけが下限から始まるからです。 経過し終えてから足す形だと、下限に 張り付いた値の減りを既定のクランプが吸い、宣言した量がまるごと残ります——自発の休息は経過ぶんを 引かれるので、同じ長さなら限界のほうが多く戻ることになります。tick 毎なら減りと同じ足し算に 入るので、荷を担いだままの倒れ込みは担いだぶんだけ薄くなります。限界は罰であって、選ばなかった ことへの褒美にはしません。
- どれも寝床を要りません(見るのは尽きた値だけです)。自発の
sleepを配るのは寝床ですが (上の休息節)、眠り込みまでそちらへ移すと、寝床の無い場所で眠気が尽きた時点で覚醒度を 戻す手が世界から消えます——限界は逃げ場であって線ではありません。
起きるのは操作の切れ目で、進行中の操作は中断しません——歩き終わってから倒れます
(GameElementDefinition.md 11.5 節)。
見るのは「下限に居る間」で、達した瞬間ではありません。 一度で限界を抜けられなければ、次に時間が 動いたときにまた起きます。ただし限界の手番が起きている最中に尽きた値は、同じ値でも別の値でも、その 切れ目では続きません(倒れ込んでいる最中に眠気が尽きても、眠り込むのは次に時間が動いたときです) ——戻り切らない値があると、手が戻らないまま時間だけが進み続けることになるためです。同時に尽きていた値は、 どれもその切れ目で順に引き直されます——先に起きた手番の間に戻り切っていれば、そちらは起きません。
どれも、強制の時間が過ぎる前に自分から告げます(announce、
GameElementDefinition.md 11.6 節。何を告げるかは
player_character.yaml の各手番が持ちます)。1時間の道を選んで押したプレイヤーには、ボタンが言った
60 分ではなく 180 分が過ぎたことしか見えないので、告げなければ時計が飛んだ理由が画面のどこにも
出ません。告げるのを結果の側(signal)に置けないのはここで、眠り込みの 360 分では理由を聞くのが
6 時間後になります。出す場所と見え方は札の上の文字で、他の出来事と同じです
(../ui/CardView.md 14 節)。
選択とセーブ
SaveData.characterId は選ばれた object_def の識別子そのもの。読み込み時に未知の識別子だった場合
(識別子の改名・旧セーブ)は先頭のキャラクタで代替して開ける(resolveCharacterDefName)。
キャラクタの絵は src/assets/objects/<識別子>.png に置けば、コード側の登録なしにカードとポートレイトへ
出る(objectArt.ts)。用意されるまでは代替の絵文字を出す。