怪我システム設計

概要

キャラクタと動物が負う傷を、専用の体力値ではなく1つのオブジェクトとして表す仕組みです。何を持てば 怪我なのか(1 節)、傷の重さをどう刻むか(2 節)、手当てをどう成立させるか(3 節)、そもそも何を傷の カードにし何をプロパティに畳むか(4 節)、膿んだ傷をどう落とすか(6 節)を決めます。

怪我が意識と命をどう奪うか——気絶・死——は VitalsSystem.md が扱います。怪我を負う 場面(動物との対峙)は HuntingSystem.md、カードの見せ方は CardView.md です。実際にどんな傷を用意するかは src/assets/world-codex/injuries.yaml そのものが一覧で、本書は個々の傷を並べません。

新設した文法はありません。 怪我は普通のオブジェクトで、キャラクタと動物の injuries スロットに入り、 severity 1本と range/on_min(自然治癒と消滅)・passives の modify(宿主の痛みと荷重)・ add(宿主の血と全身の菌量)・treatment スロット(治療具を1つ当てる枠)だけで成り立ちます。

定義は src/assets/world-codex/injuries.yaml(傷)と treatments.yaml(治療具)、検証は tests/world-codex/injuriesYaml.test.ts で、本書は実装済みです(裂傷・刺し傷・捻挫・骨折と、 包帯・添え木)。5 節が挙げる口のうち在るのは大型の獣の 1 手だけです——重い罠に掛かるのは獣で、 獣は骨折を負いません(5 節)。残る治療具は止血帯だけです(3.1 節)。膿んだ傷を洗う操作(6 節)も、 膿を宿主の全身の菌量へ流し込む道(6.3 節)も入っていて、infection は皮膚が破れた傷が open_wound trait として持ちます——ただし上がる速さも押し上げる量も仮決めで、治療具が上がり方へ効く形 (3.1 節)はまだありません。未決事項は末尾に整理しています。

1. 契約

怪我は injury タグを持ち、キャラクタと動物の injuries スロットにしか入りません (Characters.md・HuntingSystem.md 3 節)。プレイヤーは 自分では出し入れできず、付けるのはワールド側の効果(アクションの pick の失敗候補など)、外すのは 怪我自身です。

内容
タグ injury(item は付けない——手持ちへ入ってしまう)
プロパティ severity(stages を持ち、on_min に destroy: self)。血が流れる傷はさらに bleeding(VitalsSystem.md 4 節)
trait treatable(治療具を1つ当てられる。3 節)
stackable false(同じ怪我を2つ負っても1つずつ並ぶ。手当ては1つずつ当てるため)
passives modify で parent(宿主)の pain を上げる。骨折はさらに load(荷重)も上げる——負うのは load を持つ人だけ(5 節)
表示 ja.yaml の表示名と説明。絵は傷そのものだけを描く(CardView.md 5 節・7 節)——誰の身体かはカードの地が言うので、人と動物で同じ絵を使える

傷そのものに目方はありませんが、weight は 0 で宣言します——当てた治療具の重さが宿主の weight へ 渡る口になるためです(ContainerSystem.md 1 節)。また bound_to_owner (GameElementDefinition.md 7.9節)なので、負った本人から剥がせません—— プレイヤーが怪我を出し入れできないのはこの帰結で、画面側の制限ではありません。

2. 値の決め方

3. 手当て

怪我は treatment スロットを1つ持ち、そこへ治療具(treatment タグ、treatments.yaml)を 1つだけ当てておけます。付け外しは怪我のカードを押して開く子ウィンドウで行います (Windows.md 1 節)。怪我のカードへ治療具を重ねても当てられます。

当てるのに30分かかり、外すのは一瞬(treatment スロットの put_in、 GameElementDefinition.md 7.10節)。値段は枠が持つので、どちらの 経路で当てても同じだけかかります。 当てる操作をドラッグ型として書くと、スロットへ直接落とす経路 だけが無料になり、同じことが経路で違う値段になります。

3.1 治療具の性格

治療具が動かせるのは、治りの速さ(severity への add)・痛み(pain への modify)・ 出血(VitalsSystem.md 4 節。当てている間だけ、傷が血を削るブロックのゲートを 閉じる)・感染(infection、4.1 節)です。それぞれの得意・不得意は次のように置きます。

得意 不得意
包帯(bandage、実装済み) 清潔を保ちやすく長く当てておける。捻挫・骨折にも多少効く 出血を止められない(早く固まるだけ)
止血帯(未実装) 出血を止める力が強い 長く当てておけない(副作用・感染)
添え木(splint、実装済み) 治りを早め(severity へ -0.6/tick)、骨折が押し上げる load を半分に緩める 出血にも痛みにも効かない

出血への効き方は分かれ、どちらも治療具の側には結果を書きません。 止血帯は hemostatic タグを 持つことで傷のゲートを閉じ(止める)、包帯は傷の bleeding を余計に引くことで固まる速さを倍にします (早める)。当てても失う量が半分にしかならないのはこの差で、「出血を抑える力は限られる」が 効き目の強弱ではなく仕組みの違いとして出ています(VitalsSystem.md 4 節)。

添え木の「行動の制限を緩める」も同じ形です。 添え木は immobilizing タグを名乗るだけで、緩んだ 後の load(18,000 → 9,000)は押し上げている骨折が書きます(3 節・5 節)。治りの速さは治療具が 持ちます——押し上げと違って、どの傷へ当てても同じだけ効くからです。

4. 何をカードにし、何をプロパティにするか

1つずつ数えて、1つずつ手当てできるものだけをカードにします。 言い換えると、それに枠を持たせたいか ——包帯は「切り傷」には当てられますが「痛み」には当てられません。痛みは合計しか意味を持たず、どの傷ぶんの 痛みかを選んで手当てすることがないからです。

カード(オブジェクト) プロパティ
判定 部位に宿る。個数がある。個別に当てるものがある 全身に及ぶ。合計しか意味を持たない
例 裂傷・骨折・噛み傷・火傷 痛み・意識・血の量・発熱・下痢・毒の回り

当てるものが無いカードは、開いても何もできません。 絵・名前・表示文字列・画面の場所というコストを 払って、ステータスエリアと同じことを二重に言うだけになります。逆に、部位ごとに手当てできるものを プロパティに畳むと、「どこが悪いのか」が合計に溶けて消えます。

4.1 感染は両側に現れる

感染は境界をまたぎます。「膿んだ傷」は傷が持つプロパティ(infection)、「全身に回った感染」は キャラクタのプロパティ(pathogen、DigestionSystem.md 6 節)です。部位ごとに 洗えるのが前者(洗う操作は 6 節)、免疫が抑え込むのを待つしかないのが後者、という対策の違いがそのまま 境界と一致します。物差しも別で、揃えません——局所は膿み具合(0〜100)、全身は菌数(log₁₀ CFU)で、 別の量だからです。前者が後者を押し上げる向きだけが繋がっています(6.3 節)。

悪化を型の差し替えで表しません。 laceration を infected_laceration へ置き換えると、spawn は 値も中身も引き継がない(GameElementDefinition.md 9.4節)ため、当てていた 治療具も経過した治りも消えます。傷が持つプロパティが上下するだけなら、洗って引き、放置して進む、が そのまま書けます。

4.2 一撃で2つの傷を作らない

同じ一撃が同じ場所に作ったものは、1枚の傷です。 尖った石は切れ味が悪いぶん打撲が強く出ますが、 それを「裂傷」と「打撲」の2枚として刺すと、4 節の判定に2つとも引っ掛かりません——部位が同じなら、 包帯を別々に当てることができないからです。攻撃1回につき傷が2枚増えれば、injuries スロットは すぐ溢れます。

分けるのは、残るものと残らないものです。

表し方
裂けた皮膚 傷のカード(laceration)。手当てでき、時間で治る
殴られた揺れ 宿主の shock(VitalsSystem.md 2.1 節)。手当てできず、自分で引く

武器の性格は、傷の枚数ではなく傷の中身で表します。 鈍い刃で裂けた傷は、切れる刃で切った傷より 出血が少なく(潰れた血管が縮むため)、痛みが強く、治りが遅い——同じ1枚の中の数値の違いです。

武器によって出る傷の型は変わります。 槍で突かれれば裂傷ではなく刺し傷(puncture_wound)が刺さり、 血の流れる速さが桁で変わります。これは pick の候補が傷の型ごとに分かれていて、どれを引くかを武器の 重み配分が決めるからです(HuntingSystem.md 1.2 節)——2枚同時に刺すのではありません。

5. 骨折は、別格の結末を 1 つだけ足す

5.1 傷の型に骨折を 1 つだけ足す【確定】

傷の型に骨折(fracture)を 1 つだけ足します。 裂傷・刺し傷に続く 3 つ目で、部位でも原因でも 分けません。

出どころ: #656(怪我に骨折を1つだけ足す)

5.2 骨折の重さと長さの置き方

5.1節の骨折を数へ落としたもので、覆すのに人間の判断は要りません。

6. 傷を洗う

膿んだ傷は、水を掛けて洗い落とします。 枠へ入れておく治療具(3 節)とは形が違い、1 回ごとに水を 使い切る操作です。治療具が効くのは infection の上がり方(3.1 節。包帯は清潔を保ち、止血帯は 逆に膿ませる)で、下げるのは洗う操作だけです。宿主の免疫も上がり方へ効くだけで、傷そのものは 引きません(6.2 節)。洗わずに放っておいた傷が何をするかは 6.3 節——削るのは宿主の全身の菌量 (pathogen)だけで、そこから先の症状と死に方は全身の側が持ちます (DigestionSystem.md 6 節・VitalsSystem.md 8 節)。

膿むのは皮膚が破れた傷だけです。 bleeding を持つ傷——裂傷・刺し傷・噛み傷・角の傷・罠の裂傷 ——が infection と洗う操作を持ち、捻挫・骨折・打ち身は持ちません。皮膚の下で起きる傷には、外から 水の届く傷口がありません。

6.1 化膿には、それを落とす手立てを持たせる【確定】

傷を洗う操作を入れます。 傷ごとに化膿の進み具合を持たせておきながら下げる手立てが 1 つも無ければ、 infection は数字が動くだけの飾りになります。

出どころ: #656(傷を洗う操作を入れる)

6.2 手間の重さは、時間ではなく水が持つ

水を 1 杯(250mL)掛けて 15 分、infection が 25 下がります。

長さは、敗血症が命を削る速さから取りました。 腐り切った傷が押し上げた菌は 6 時間で危険域へ届き、 そこからは血が -40/tick で減ります(DigestionSystem.md 6 節)。そこから安全域へ戻すのに要るのは 2 杯なので、気づいてから原因を 断つ時間はあります。間に合わない長さにすると、VitalsSystem.md 8.1 節の「傷を洗う なり膿を出すなりして原因を断たなければ死ぬ」の後半が言葉だけになります。一方で発症している間は水も 余計に減る(同 8.1 節)ので、断つために飲み水を捨てるという締め付けは残ります。

治療具を当てたままでも洗えます。 外させると 1 回ごとに付け直しの 30 分(3 節)が乗り、手間の 本体が水から時間へすり替わります。

汚すのは、開いたままの時間です。 負った瞬間は清潔(value: 0)で、傷が在るあいだ上がり続けます。 健康な体では 1 時間に 1 で上がり、放っておけば festering を経て septic へ届き、 深く残る個体なら、どの開いた傷も治りきる前に敗血症へ入ります——くくり罠の浅い裂傷だけはその前に治りきることが あります(TrapSystem.md 5.1 節)が、負った傷が浅いかは選べないので、洗わずに済ませられるとは当てにできません。1 杯が落とす量は健康な体で 1 日に膿む量を上回るので、開いた傷 1 つにつき 1 日 1 杯が清潔を 保つ値段です(tests/world-codex/injuriesYaml.test.ts が見ます)。 この速さと、治療具が上がり方へ効く形(3.1 節)は未決で、ここに置いてあるのは仮決めです (末尾の未決事項)。

宿主の免疫は、この速さを鈍らせるだけです。 傷を引かせません——引かせると「下げる手立ては洗う ことだけ」が崩れ、水の乏しさが効かなくなります。局所の免疫応答としても、傷口に入った汚れが免疫で 消えるわけではありません。鈍るのは全身で菌の増殖を抑え込めている段から上 (DigestionSystem.md 6.2 節の除去 > 増殖)で、段が 1 つ上がるごとに 0.05 です。 素の速さは 0.30/tick、健康な体(robust)がちょうど上の「1 時間に 1」で、罹って高まった体はそれより遅くなります。

弱った体では傷も速く膿む、が段の並びからそのまま出ます。vitamin の scurvy が「古傷が開く」と 書いている(DigestionSystem.md 4 節)のと同じ現象を、傷の側から見たものです。

# 皮膚が破れた傷にだけ配るtrait(bleedingを持つ傷)。
open_wound:
  props:
    # 膿み具合。局所の値で、全身へ回った菌は宿主のpathogenが持つ(6.3節)。
    infection:
      gauge: {min: good, max: bad}
      value: 0
      range:
        min: 0
        max: 100
      stages:
        - {name: clean}
        - {name: festering, alert: caution, min: 40}
        - {name: septic, alert: danger, min: 80}
      passives:
        # 素の速さは、免疫が増殖に負けている体のもの。免疫は引かせず、鈍らせるだけ。
        - add: {self: {infection: 0.30}}
        - conditions: [{subject: parent, prop: immunity, in_stage_or_above: robust}]
          add: {self: {infection: -0.05}}
        - conditions: [{subject: parent, prop: immunity, in_stage_or_above: primed}]
          add: {self: {infection: -0.05}}
  interactions:
    # 宣言は傷の側(GameElementDefinition.md 12.3節)。水は自分が何を洗えるかを知らない。
    wash:
      trigger: {drag: {tag: cleansing}}
      duration: 15
      conditions:
        - {reason: not_enough_water, subject: instrument, prop: fill, gte: 250}
        - {reason: already_clean, subject: self, prop: infection, gte: 1}
      add:
        instrument: {fill: -250}
        self: {infection: -25}

6.3 膿は、宿主の全身の菌量へ流し込む

傷が削るのは宿主の pathogen だけです。 水も血も削りません——それを削るのは全身の菌の側 (DigestionSystem.md 6 節)で、傷は「そこへどれだけ送り込むか」しか知りません。 同じ 1 つの宣言が人にも獣にも刺さります(獣は pathogen と固定の immunity を持ちます)。

open_wound:
  passives:
    - conditions: [{prop: infection, in_stage: festering}]
      add: {parent: {pathogen: 0.12}}
    - conditions: [{prop: infection, in_stage: septic}]
      add: {parent: {pathogen: 0.35}}

量は、全身の除去(免疫の段ごとの定数)と増殖(+0.15/tick)に対して読みます。

押し上げる量は仮決めです(末尾の未決事項)。洗わずに放置した開いた傷 1 つは、健康な体でも 負ってから約 3.6 日で全身が危険域へ届き、約 4.6 日で失血で死にます(tests/world-codex/injuriesYaml.test.ts)。

未決事項・今後の検討課題