狩猟システム設計
概要
本ドキュメントは、動物を狩る(あるいは狩られる)局面の設計をまとめたものです。「どんな動物が島のどこに
どれだけ居るか」は TerrainGeneration.md・ExplorationSystem.md
の関心事、「その動物と出会ったプレイヤーが何をできるか」が本書の関心事です。
戦闘がゲームの主眼ではないため、狩猟専用の数値を1つも作らないことを設計の芯にしています。敵の体力・
ダメージ・命中率といった専用の語彙を新設すると、GameConcept.md が全体の原則
として掲げる「派手な専用ロジックを足すのではなく、単純な加減算の積分が複雑な挙動を立ち上げる」に対して、
そこだけが例外になります。代わりに怪我・耐久・荷重・腐敗・探索・時間という既存の仕組みへ載せます。
専用の画面もモーダルな状態も持ちません。 動物は普通のカードとしてアイテムレーンに並び、攻撃は既存の ドラッグ操作、逃走は既存の移動アクションです。同時に2頭以上と対峙できるのは、この設計がモーダルな状態を 1つも持たないことの帰結です。
本ドキュメントは検討結果であり、確定仕様書ではありません。1 節・3 節は実装済みです
(src/assets/world-codex/animals.yaml の動物と injuries.yaml・tools.yaml の武器、検証は
tests/world-codex/animalsYaml.test.ts)。6 節の変化の観測と 6.3 節の告知も実装済みです
(WorldSession.observeChanges・observeSignals)。6.1 節の突進も実装済みで、観測した変化から
組み立てています(changedInstances.lungeTargetsByInstance・cardMotionPlan、検証は
tests/game/changedInstances.test.ts・tests/game/cardMotionPlan.test.ts・tests/world-codex/animalTurn.test.ts)。5 節の動物の1手も実装済みで、時間が経てば
2 節が述べる「動物の 6 手」がそのまま現れます(WorldObject.runTickActions、検証は
tests/world-codex/animalTurn.test.ts)。4 節の resists も実装済みで、どれも beast trait で宣言しているため、警戒している間は手にも
入れ物にも入りません(GameElementDefinition.md 7.13 節、検証は
tests/domain/resists.test.ts)。狩猟を支えるエンジンの拡張は 7 節、未決事項は 8 節にまとめています。
数値の裏取りは、遭遇を実際に通して数えます(stats/hunt.yaml、読み方は
HuntStats.md)。何手で逃げに転じるか・槍と斧で結末がどう違うか・
深手を負わせた獲物が何手残るかは、静的な集計では出ません。
1. 既存の操作に載せる
1.1 動物は items スロットのカード
動物は item タグを持ち、土地の items スロット(ExplorationSystem.md 1.1 節)に
並びます。items/fixtures の区別は「持ち運べるか」ではなく動かせるかなので、動物は前者です。持ち上げ
られるかどうかは 4 節の resists が別に決めます。
1.2 攻撃はドラッグ型の操作
武器として使える道具を動物のカードへ重ねる操作です。ヤシの実を割る・怪我に治療具を当てるのと同じ、既存の
中核動詞(GameElementDefinition.md 12 節)そのままで、新しい操作の語彙を
持ち込みません。
beast:
interactions:
strike:
trigger: {drag: {tag: weapon}}
duration: 15
狙い所は武器の性格に畳みます。 「急所/胴/脚」を選ばせる専用のUIは持たず、槍は急所寄り(当たりにくく
決まりやすい)、棍棒は脚寄り(当たるが倒せない)のように、武器ごとの pick の重み配分で表します。選択は
「どのカードを重ねるか」に宿るため、画面に何も足さずに判断が残ります。
候補は「一撃がどう入ったか」の型で、当たり所について武器が宣言するのはその配分だけです(武器はほかに
間合いを名乗ります。この節の末尾)。動物の側(beast trait)が
候補を1組だけ持ち、weight が {subject: instrument, prop: ...} で武器のプロパティを読みます
(GameElementDefinition.md 10.2 節)。動物はどんな武器が在るかを知らず、
武器はどんな獲物が居るかを知りません。
| 候補 | 与える衝撃 | 残る傷 |
|---|---|---|
強打(heavy_blow) |
250 | 裂傷 |
浅打(light_blow) |
30 | 裂傷 |
刺突(thrust) |
30 | 刺し傷(血が桁違いに速く流れる) |
外し(whiff) |
— | — |
| 仕留め | — | —(1.4 節) |
威力の側を武器から読むことはできません。 add の値はリテラルだけで、{subject, prop} 参照を持たない
(同 9.2 節)ためです。だから武器が動かせるのは重みだけで、衝撃の量は候補が持ちます——武器を増やしても
候補は増えません(棍棒は強打だけ、ナイフは浅打と刺突、のように既存の候補へ配るだけ)。
配分の合計は武器によらず100に揃えます。仕留めの重み(無防備さ、1.4 節)と並ぶ目盛りが武器ごとに変わると、 同じ無防備さが武器によって別の意味を持ってしまうためです。
殴る人の腕は、どの武器の卓も同じだけ伸ばします。 積むのはその武器が最も太く名乗る当たり方 1 つ
だけで、狩猟の腕(hunting_aim)を base の土台にします(../world/Skills.md 5 節)。
当たり方の数だけ積まないのは、上の目盛りを実効値でも保つためです——2 つ名乗る石斧だけが倍受け取ると、
仕留めの重みと並ぶ目盛りが武器ごとに変わります。1 つに限れば、expert(+40)でも卓の合計はどの武器も
同じだけ伸び、仕留めの割合は武器によらず同じままです。
- 外し(
whiff)には積みません。 卓の合計が増えるぶんで外れの割合が落ちます。 - 0 を宣言した当たり方(尖った石の強打)にも積みません。 積むと、腕が上がるだけでその武器に無い 一撃が出ます。
- 腕は、その武器の性格を強めます。 石斧の強打対浅打は 60 対 15 から、強打の側だけが伸びて開きます——腕が 上がるほど、その武器が得意な当たり方へ寄ります。
同じ一撃が、体格で意味を変えます。 衝撃の max は体重の1/50(VitalsSystem.md
2.1 節)なので、浅打(30)はネズミ・ヤケイを一撃で沈め、サル(気絶は70)には3撃を要し、イノシシ(同840)
には何撃当てても届きません。上位の武器の存在価値は、この壁が作ります——衝撃の引きも体格に比例するので、
弱い武器で殴り続けても大型の衝撃は溜まりません。
道具の durability(DurabilitySystem.md)が減るので、作るのに手間のかかった武器を
賭けるという重みが自然に付きます。
武器は当たり所のほかに、間合い(reach、cm)を名乗ります。 手に持っている間、その土地に
「間合いが構えられている」ことが立ち(../../src/assets/world-codex/core.yaml の
braced_reach)、獣はそれを読んで踏み込む手を細らせます(5.5 節)。当たり外れの配分と傷の種類しか
無かった槍と斧の違いが、立ち位置にも出ます。
- 武器はどんな獣が居るかを知らず、獣はどんな武器が在るかを知りません。 条件は入れ子のスロットを
見られない(
GameElementDefinition.md14.3 節)ので、場所が1つ挟まります ——据えた設えが土地の居心地を押し、キャラクタがそこから継ぐのと同じ形(同 8.6 節)です。 - 線は150cm。 獣が踏み込む一歩の外へ穂先を置けるのはここからで、70cmの柄(石斧)は牙の届く 間合いの内側に入ります。この島で間合いを取れるのは槍(200cm)だけです。
- 構えていなければ効きません(
in_slot: handのゲート)。地面に置いた槍も、背負った槍も同じです。 - 盾ではありません。 押し引きなので牙は通り、追い詰めたイノシシからでも1回の遭遇で平均 0.71枚の 傷を負います(石斧なら2.69枚)。
1.3 逃走は travel
専用の逃走コマンドは持ちません。道を渡って隣の土地へ移る、既存の移動アクションがそれです。
置いていったアイテムはその土地に残るため、取りに戻るにはまだ動物が居る土地へ戻ることになります。逃走の ペナルティを別に書く必要がありません(大型の動物ほど長く居座る、が被害の大きさになります)。
1.4 仕留めは、無防備さが重みを押し上げる
即死は怪我として表しません。 首や後頭部への一撃で中枢が止まるのは、残らない出来事——手当ての
しようがなく、次の瞬間には死体になっている——なので、pick の候補が直接 destroy と死体の spawn を
行います。カードにするのは1つずつ数えて手当てできるものだけ、という境界
(InjurySystem.md 4 節)がそのまま「これはカードにしない」と答えます。
仕留められるかは、相手の無防備さ(vulnerability)がそのまま候補の重みになります。
- weight: {prop: vulnerability}
set: {self: {blood: 0}}
signal: killed
仕留めは、血を空にすることで表します。 死体へ置き換えるのは blood の on_min
(VitalsSystem.md 3 節)で、この候補は獲物の種類を知りません。頸を落とすとは実際に
血を失わせることなので、失血死と別の道を用意する理由がありません。
- 死体の名前が1箇所に集まります。 候補が直接
destroy+spawnを行うと、仕留めと失血死の2箇所へ 同じ名前を書くことになります。合流させれば、動物ごとに1度だけ書けば済みます - だから候補を動物の型から出せます。 攻撃は
beasttrait が1組だけ持ち、動物ごとに複製しません ——獲物を増やしても、書くのは体格と死体の名前だけです
weight は {subject, prop} 参照が実効値を読む
(GameElementDefinition.md 10.2 節)ので、状態が modify で押し上げた分が
そのまま確率になります。気を失っている段が押し上げれば、気絶させてから仕留めるという手順が
値の動きだけで立ち上がります——これは人が小動物を仕留める現実の手順(失神させてから頸を落とす)
そのものです。
- 起きている相手の重みも0にしません。 0にすると候補ごと抽選から外れます(5.3 節)が、暴れる相手 でもまれに急所へ入るほうが現実に合い、一撃で決まる緊張感も残ります
- 押し上げるのは状態であって、武器ではありません。 武器の差は当たり所の分布(1.2 節)が持ちます。 同じ量へ後から「罠にかかっている」「拘束されている」も流せます
- 人へは同じ形を適用しません。 動物の1手(5.1 節)がプレイヤーを気絶させて即死させられるのは
理不尽なので、無防備さが重みになるのはプレイヤーが仕留める側の
pickだけです
1.5 解体もドラッグ型の操作
死体は素材の入った袋ではなく、刃物を重ねる操作で肉・骨・生皮へ置き換わります。 攻撃 (1.2 節)・ヤシの実の加工と同じ中核動詞そのままで、解体専用の語彙を持ちません。
1回で捌き切れるのは、1時間に収まる大きさの獲物だけです(ActionSystem.md
6.3 節)。それより大きい獲物では、内臓を出すところから骨に付いた肉を落とすところまで手が分かれ、
どこまで捌けたかは死体の側が持ちます——回ごとに出る物が違い、途中で肉だけ運んでから戻れます。
monkey_carcass:
props:
butcher_minutes: # 皮革の腕が縮める分は省いている
value: 60
interactions:
butcher:
trigger: {drag: {tag: handheld_blade}}
duration: {prop: butcher_minutes} # 暗さ・嵐で断る条件と、皮革の腕の伸びは省いている
destroy: self
spawn:
- {object: raw_meat, count: 4}
- {object: animal_bone}
- {object: rawhide}
- 要るのは握りの刃です(
handheld_blade。tools.yamlのsharp_stone)。皮と肉の間へ刃を寝かせて 走らせる手つきなので、柄の先へ頭部を据えた石斧では剥げません——獲物を沈めるのが速い道具と、捌ける 道具が別になり、狩りへ出る前に尖った石を持っているかが問われます - 得られる素材は獲物の種類によらず同じで、獲物の大きさは個数が表します。 5kg のサルと 60kg の
イノシシで別の肉を作ると、それを使う側(料理・皮革)が獲物の数だけ分岐します。鶏肉も獣肉も
同じ
raw_meatです——栄養と味の違いが実際に効くようになるまで、獲物の種類で肉を分けません - 1 枚の取り分より小さい獲物は、解体せず丸ごと火にかけます(
animals.yamlのrat_carcass)。 80g のネズミのために小さい肉のカードを作ると、同じ「肉」で大きさだけが違う 2 枚ができ、料理は 「どちらでもよい」と書けなくなります。刻みを増やさないための道で、得られる物が種類で変わるという 意味ではありません - 重さは減ります。 血と内臓は使い道が無いのでカードにしません。ヤシの実の皮をはぐ・殻から果肉を
出す工程(
coconut.yamlの冒頭)と違い、内訳の合計は元より軽くなります - どれだけ減るかは、現実の骨格筋の割合に合わせます。 肉として出るのは体重の 3〜5 割で、体格に
よらず体重の 4 割前後という現実を挟む幅です(獲物ごとの内訳は
animals.yamlの各死体のコメント)。 刻みが肉 1 枚ぶんなので、小さい獲物ほど割合が飛びます——ヤケイはその 1 枚で幅の上端に付き、 それより下は 0 枚しか置けません(上の「1 枚の取り分より小さい獲物」がその下限です)。 - 枚数は体重の比ではありません。 肉・骨・生皮でそれぞれ倍率が違うのは、どれも現実の割合へ 別に合わせた結果です。生皮は小型ほど体重に対する割合が高くなります——体表の割合は体格とともに 下がるので、体重が何倍かになっても枚数は同じ倍率では増えません
- イノシシだけは、現実より低い側へ外してあります。 大型の可食部は現実には 4 割半ほどですが、
1 頭で腐るより先に食べ切れない量が出る相手なので(
TrapSystem.md3 節)、 現実へ寄せて増やしても腐る量が増えるだけです(満腹あたりの手間はstats/balance.yamlのchain_routes)。模型のずれを許すのは、罰の 向きが正しい側だけです(DesignPrinciples.md「模型のずれは、 罰の向きが正しければ許容する」節) - その場で解体するか、丸ごと運ぶかが判断になります。 解体すれば軽くなり嵩も減りますが、そのあいだ その土地に留まることになります(2 節。他の動物が居れば、そのぶん手番が回ります)——大きい獲物ほど 長く、ただし手が分かれているので、途中で切り上げてそこまでの取り分だけ運ぶこともできます
死体も肉も腐ります。 どちらも「調理済み料理・生魚など」と同じ速さで、置きっぱなしにすれば
解体する前に消えます(DurabilitySystem.md 3 節。animals.yaml の死体・
raw_meat が perishable と spoils_fast を名乗る)。速さが同じなので、解体しても保ちません
——「重いまま運ぶ」を選ぶ理由は、依然として荷重(load)だけにあります。
2. ターンは tick
専用の画面を持たないため、「今から動物の手番」と宣言する場所がありません。動物を動かすのは時間の経過 だけです。
- 1 tick の行動 = 動物の1手
- 6 tick の行動 = 動物の6手
これにより「動物に詰められながら悠長な作業はできない」が、ルールを1行も書かずに成立します。同じ理由で、 無視することも自動的に罰せられるため、行動を禁じるモーダルな鍵が要りません。
不意打ちも同じ仕組みです。発見した tick で既に相手の手が入っていれば先手を取られたことになり、専用の イニシアチブ判定を持ちません。
怪我の手当てにも同じ帰結が及びます。治療具を当てるには時間がかかる(InjurySystem.md)ため、
荒ぶっている動物の傷を手当てすると、その間の手数ぶん殴られます。「落ち着くまで待つ方が賢い」を、条件で禁じずに
コストとして表せます。
3. 動物は体力を持たず、怪我を負う
攻撃は体力を引くのではなく、動物の injuries スロットへ怪我オブジェクトを1つ足します。怪我は
InjurySystem.md が定義する構造をそのまま使い、キャラクタと動物で共通です。
この対称性から、次がいずれも追加の仕組みなしで得られます。
| 部位別の状態 | 「脚の裂傷」「脇腹の刺し傷」が別々のオブジェクトとして刺さる。部位ごとの体力表は要らない |
| 傷が行動に効く | 怪我の側の passives(modify)で、宿主の回避・逃走の重みを下げる |
| 倒れる・死ぬ | 傷が意識と血を削り、底に着いたときに起きる(VitalsSystem.md) |
| 手負いのまま逃げた後 | 深手の個体は立ち去らない(5.6 節)ので、追いつける相手として世界に残る。失った血は戻らないので弱ったままで、洗えない傷が膿みきれば追いつく前に倒れる——追跡の時限はそこにある |
| 動物の傷を手当てできる | 怪我が持つ treatment スロットが働く。4 節の飼いならしの入口になる |
画面も共通です。 カードの状態バーは既に傷の重さを映せ、ObjectWindow は1スロットをレーンとして見せる
作りなので、動物のカードを開けばキャラクタの怪我と同じ見え方で刺さっている傷が並びます。
3.1 警戒(wariness)
「攻撃してくるか逃げるか」を乱数の分岐にはせず、動物が持つ連続量にします。傷を負えば上がり、時間で下がり、 火や手当てで動きます。値はカードの状態バーとして見えるので、プレイヤーは「もう一撃で逃げに転じるはず」を 読んで賭けられます。
wariness は攻撃と逃走の重み配分(5 節)、持ち上げられるか(4 節)、手当てのリスク(2 節)のすべてを
駆動する唯一の量です。
安全域を外れている間は、その動物のカードの輪郭が赤く明滅します(CardView.md 3 節)。放置してよくない相手が居ることは、ステータスエリアではなく
その札の上で言う必要があります——動物はレーンに並ぶ 1 枚で、プレイヤーの持ち物ではありません。
現れたときの値は獣ごとに違います(animals.yaml の各獣。しきい値の側は獣によらず同じで、
1 手の配分の合計を 100 に揃えるのと同じ理由です)。減り方は自然治癒と同じ基準レート
(-1/tick、InjurySystem.md 2 節)で獣によらないので、初期値がそのまま
「掴めるようになるまでの手数」(4 節)で、そこから 19 を引いたものが「近寄れる(落ち着く)までの
手数」になります。待つより追い払うほうが速い、は変わりません。
- 人を恐れない獣は、落ち着いた姿で現れます。 逃げも襲いもせず(5.5 節の
calmの打ち消し)、 藪を割って進むついでに足元の物を壊すだけなので、危険はこちらが手を出してから始まります。 この島でそう現れるのはイノシシだけで、掴めるようになるのは16手後です。 - 警戒しやすい獣ほど、近寄れるまでが長くなります。 最も長いのはネズミで、落ち着くまで
37手——生きたまま持ち帰る相手ではない
(罠に掛かればまず死ぬ)ので、長さの代償がありません。逆に最も短いのはヤケイ
(5手)で、罠に掛けた個体を
持ち帰るまでの待ち時間がそのまま飼いならしの学習台(
../world/Animals.md3 節)を 成り立たせています。
獣ごとの値と、そこから出る手数は HuntStats.md の wariness 節が持ちます。
4. 抵抗する相手(resists)
どの動物が入れ物へ入るかは 4.2 節が決めます。
入るかどうかはその物の性質なので、枠ではなくオブジェクト側に宣言します。同じ hand の枠でも、入れようとして
いる物が石なら入り、荒ぶるイノシシなら入らないという違いは枠側では言えません
(GameElementDefinition.md 7.9 節が bound_to_owner について述べているのと
同じ理由)。
| 意味 | |
|---|---|
bound_to_owner: true |
持ち主から離れられない(怪我・液体・道) |
resists: [条件] |
条件が成立している間、持ち主を持てない(土地以外の親へ移れない) |
beast:
tags: [item, animal, quarry]
resists: [{prop: wariness, gte: 1}]
- 手持ち・かご・台車の定義は変更しません。既存の
accept: {tag: item}のまま、抵抗する側が拒みます - 土地の
itemsには普通に置けます(親が土地だから) - 自分で隣の土地へ逃げるのは通ります(土地から土地への移動なので)
- 警戒が0になれば成立しなくなり、そのまま台車・かごへ入ります。飼いならしで型を差し替える必要がありません
型の差し替え(wild_boar → tamed_boar)は採りません。spawn は値も中身も引き継がない
(GameElementDefinition.md 9.4 節)ため、差し替えると刺さっている怪我と警戒が
消えます。定義を1つに保ち wariness だけで駆動すれば、飼いならした動物が再び荒ぶるも同じ仕組みで表せます。
4.1 入れ物の中で成立したら、こぼれ出る
台車に積んだ動物の警戒が上がった場合、resists が成立した瞬間に最も近い土地へこぼれ出ます。destroy が
中身を親へこぼす(同 9.3 節)のと同じ扱いで、暴れて荷車から飛び出すという見え方になります。
捕まえる手間は枠が持ちます(put_in: {duration: ...}、同 7.10 節)。ドラッグ型の操作に書くと、レーンへ直接
落とす経路だけが無料になります。
4.2 荒ぶる相手は入れ物へ入らず、飼いならせば入る【確定】
荒ぶっている動物を手持ちや入れ物へ入れることはできず、飼いならした後の小動物はかごへ、大型は台車へ 入れられるようにします。
出どころ: ユーザーの指示(荒ぶる相手は入れ物へ入らず、飼いならせば入る。#2026)
5. 1手は、動物ごとの重み配分1つで決まる
動物の1手は、すべての動物が共有する1つの pick で、動物ごとに変わるのはその重み配分だけです。
候補は「その1手が何だったか」の型——様子見・噛みつき・牙・持ち去り・体当たり・逃走——で、これは武器が
一撃の当たり所の配分だけを宣言するのと同じ形(1.2 節)です。動物を増やしても候補は増えません。
配分の合計は動物によらず100に揃えます。傷が押し上げる量(5.5 節)と並ぶ目盛りが動物ごとに変わると、 同じ深手が動物によって別の意味を持ってしまうためです。
| 様子見 | 噛みつき | 牙 | 圧し掛かり | 持ち去り | 体当たり | 盗み食い | 逃走 | |
|---|---|---|---|---|---|---|---|---|
| ネズミ | 15 | 5 | 0 | 0 | 0 | 0 | 0 | 80 |
| ヤケイ | 30 | 0 | 0 | 0 | 0 | 0 | 0 | 70 |
| サル | 20 | 15 | 0 | 0 | 35 | 0 | 10 | 20 |
| イノシシ | 15 | 0 | 30 | 10 | 0 | 25 | 0 | 20 |
傷の種類は候補が持ちます。 動物の側が持つのは「どちらを引きやすいか」だけで、噛みつきは bite_wound、
牙は gore_wound を相手へ刺します(InjurySystem.md)。add の値がリテラルしか
書けない(GameElementDefinition.md 9.2 節)以上、体格から威力を読むことは
できないので、1.2 節と同じく候補の側が量を持ちます。
骨折を残すのはこの卓の 1 つの候補だけです(crush=圧し掛かり)。刺すのは fracture
(InjurySystem.md 5 節)で、重みを立てるのは大型の獣だけなので、小型の獣では
候補ごと抽選に出ません。「重い獣に踏まれたときだけ折れる」を、傷の側に「大型からしか出ない」と書かずに
表せます——傷が別格であることを支えているのは、量ではなく重み配分です。イノシシの牙の 40 から 10 を
振り替えたのは、配分の合計を 100 に揃えるためで、牙が減ったぶんだけ結末が重くなります。
5.1 気まぐれな相手は、候補が自分で選ぶ
動物は、その場のアイテムに体当たりして壊し、足元の物をくわえ、逃げるときは行き先を気まぐれに選びます。 いずれも「定義時点では決まらず、実行時に初めて確定する個体」を相手にします。
候補が among(GameElementDefinition.md 10.3 節)で自分の相手を選びます。
どこから・どう絞って・どんな重みで選ぶかを候補自身が書き、選ばれた相手は picked で指します。
beast:
props:
# 動物ごとに宣言する重み配分(値を持たないので宣言し忘れはロードで落ちる)。
lurk: {}
gore: {}
smash: {}
flee: {}
interactions:
turn:
# プレイヤーが押すものではない(GameElementDefinition.md 11.1節)。
trigger: tick
pick:
# 様子をうかがった回。必ず先頭に置く(5.3節)。
- weight: {prop: lurk}
- weight: {prop: gore}
among: {subject: parent, slot: characters, matches: {tag: character}}
spawn: {object: gore_wound, into: picked}
signal: gored
- weight: {prop: smash}
among:
subject: parent
slot: items
matches: {tag: fragile}
weight: {subject: picked, prop: volume}
destroy: picked
signal: smashed
- weight: {prop: flee}
among: {subject: parent, slot: fixtures, matches: {tag: path}}
move: {subject: self, to: {subject: picked, prop: destination_id}}
signal: fled
相手が1つも居ない候補は抽選に出ません。 「同じ土地に人が居なければ襲えない」「逃げ道が無ければ 逃げられない」を、条件でも重みの打ち消しでも書いていません(5.3 節)。
持ち去った物は動物の中へ入ります(spoils スロット、枠は1つ)。倒せば中身として地面へこぼれる
(GameElementDefinition.md 9.3 節)ので、追いつけば取り返せるが追加の
ルールなしに成立します(Animals.md 4.1 節)。逃げられれば、くわえた物も一緒に
運ばれます。
ただしくわえた食べ物は、手番で食べられてしまいます(盗み食いの候補が spoils の中身を destroy
する)。取り返しの道はそこで断たれます。食べ物でない物は食べず、立ち去り(5.6 節)までくわえたまま
残ります——盗まれたのが道具なら、時間が経っても物だけは回収できます。
5.2 1手を与える側
tick の後処理として、世界のどこに居るものでも、trigger: tick を宣言していれば1手ずつ受け取ります
(WorldSession.advanceWorldTime → WorldObject.runTickActions)。値の積分(WorldObject.tick)を終えて
から配るので、動物が動くのは「そのtickの値が出そろった後」になります。
居場所では絞りません。 動物はプレイヤーを見ているわけではないので、目を離した拠点の物も持ち去られます。
罠の中や入れ物の中に居ても手番は回りますが、周りに相手が居なければ候補が全部外れて様子見になるだけです
——何ができるかを決めるのは世界の側(5.1 節の among)で、エンジンは「地面に居る動物だけ」のような
絞り込みを持ちません。
絞らないのは居場所だけで、状態は別です。 気を失っている個体には手番そのものが回りません
(VitalsSystem.md 6 節)——そこだけは候補の重みでは表せないからです。気絶は
警戒を落としますが、警戒が打ち消すのは踏み込む手と逃走までで(5.5 節)、警戒を見ていない手は素の配分の
まま抽選に残ります。倒した獣が足元の物をくわえるのを止めるには、配分ではなく手番の側を止めるしか
ありません。 止める側が読むのは段の名前だけで、しきい値も、何がそこまで奪ったのかも知りません。
配る前に集めます。 手番は物を増減させ、逃げれば別の土地へ移るので、走査しながら配ると同じ個体へ 二度回りえます。集めてから配れば1 tickに1手だけになり、手番の途中で消えた個体は飛ばされます。
5.3 追い詰められた動物は逃げずに襲う
逃げ道が1本も無ければ、逃走の候補はそもそも抽選に出ません(among の候補が空、5.1 節)。専用の条件を
書かずに「追い詰められた獣は反撃する」が成立します。壊せる物が無い土地で暴れる候補が外れるのも同じ
仕組みです。本数は見ません——逃走の候補は集合から1本選ぶだけなので、道が2本目から先へ増えても
逃げやすさは変わりません。分かれ目は「逃げ道が在るか」の1点だけです。
この1点が、狩りが最後まで通るかどうかを決めます。 道が1本でも通っていれば、どの獣も数手で
居なくなります——追い詰めたイノシシは槍で100%
倒れるのに、同じ相手が道のある土地では16.00%
しか倒れず、残りは平均2.91手で
逃げていきます(HuntStats.md の ending 節。2026-09-13 時点)。
開けた土地で獲れるのは、一撃で沈められる相手だけです——大型は、道の無い土地へ追い詰めるか、
深手を負わせて追う(5.6 節)かのどちらかになります。
ただし全候補の重みが0になると先頭候補が選ばれます。 様子見を先頭に置くことを規約にします——逃走や攻撃を 先頭に置くと、逃げ道も相手も無い土地でそれが起きてしまいます。様子見だけはどの動物も正の重みを持つので、 「何も起きない手番」が抽選の外側の規約に落ちることはありません。
5.4 何にぶつかるか、何をくわえるか
「暴れまわって、たまたまぶつかった物が壊れた」を表します。選び方は候補の among が書きます(5.1 節)。
- かさ(
volume)で重み付けする。 大きい物にぶつかりやすい=地面に大きな物を広げていると危ない、という 読める判断になります。かさ0の物は選ばれません——そこに嵩が無いという宣言だからです - 壊れうる物だけを候補にする。
durabilityを持つ物すべてにすると大事な道具まで一撃で消えるため、fragileタグで著者が明示的に選びます(編み籠・くくり罠・編んだ葉・ヤシの器・甕)
destroy は中身を親へこぼす(GameElementDefinition.md 9.3 節)ので、壊された編み籠の中身は地面に散らばります。追加のルールは
要りません。
持ち去りの候補は別の卓です。 壊す相手は「壊れうると宣言した物」ですが、くわえる相手は獲物(quarry)で
なければ何でもよく、取り返しの付く被害だからこそ大事な道具を持っていける(Animals.md 4.1 節)——同じ卓にすると、
どちらかが現実と食い違います。
5.5 顔ぶれを変えるのは警戒、逃げに転じさせるのは傷、立ち尽くさせるのは意識
動物ごとの配分は素の性分で、その場の事情は modify が押し引きします(GameElementDefinition.md 8.3 節)。押し引きは beast trait
の1箇所にまとまり、動物ごとには書きません。
打ち消しは「重みが0でクランプされる」ことを使います。素の配分より桁の大きい負の寄与を当てれば、その候補は
抽選から丸ごと外れます——できないことは起こらないを、候補ごとの conditions ではなく重み1つで表せます。
| 状況 | 押し引き |
|---|---|
落ち着いている(wariness が calm) |
噛みつき・牙・圧し掛かり・逃走を打ち消す |
荒ぶっている(同 enraged) |
持ち去り・体当たりを打ち消す |
| 同じ土地に人が居ない | 噛みつき・牙・圧し掛かりを打ち消す |
| 手を出せる物が無い/既に1つくわえている | 持ち去り・体当たりを打ち消す |
| くわえた食べ物が無い | 盗み食いを打ち消す(食べ物でない物は食べない) |
| 逃げ道が無い | 逃走を打ち消す(5.3 節) |
痛みの段(sore/hurting/unbearable) |
逃走を +25/+60/+120 |
意識が濁っている(consciousness が foggy) |
様子見を +25 |
朦朧としている(同 dazed) |
様子見を +60 |
| 間合いのある武器が構えられている(1.2 節) | 噛みつき・牙・圧し掛かりを -20、様子見を +20 |
これで警戒しているかどうかで1手の顔ぶれが変わります。落ち着いた動物は様子をうかがうか足元の物へ手を 出すだけ、警戒すれば逃げるか噛みつくか、荒ぶれば物どころではなくなり逃げるか向かってくるかの二択になります。
ダメージが逃走を太らせるのは動物によらない1箇所の宣言です(pain の段)。素の配分がどうであれ、
痛めつければ逃げます——手負いの個体を追うことになるのはこのためで、その個体が世界に残る長さは 5.6 節が
決めます。
間合いの押し引きも1箇所です。 踏み込む手はどれも20細るので、素の配分が20に満たない候補
(小型の獣の噛みつき・唯一 crush の重みを立てる大型の圧し掛かり)は間合いの外へ出て抽選から
落ちます——槍を構えている限り骨は折られず、小型の獣は噛みつけません。 太い牙(30)だけが通ります。 合計が100から落ちるぶんは逃走と物への手が相対的に太るので、
間合いを取られた獣は、掛かってくるのをやめて逃げるか、そこらの物へ当たります。
失血と衝撃が配分を押す道は、意識1本です。 痛みは beast trait の中に段を持つので flee を直に
押せます(上の表)が、blood と shock は max が体格なので獣ごとの宣言になり、そこへ押し引きを
持たせると同じものを獣の数だけ書くことになります。3つともが意識へ合流している
(VitalsSystem.md 2 節)ので、合流した後の段へ置けば1箇所で済みます。
プレイヤーが読めるのも意識だけです。 血にも衝撃にもバーが無い(同 9 節)ので、押している当人が 画面に出ているのは意識のバー1本になります。
太らせるのは様子見だけで、手を細らせはしません。 濁った獣は立ち尽くす回数が増え、そのぶんどの手も 出にくくなります。細らせる形を採らないのは、押し引きが重なるからです——上の間合いと同じ手を引けば、 素の配分で最も太い牙まで抽選から落ち、槍を構えて追い詰めた相手が何もしてこなくなります。 5.3 節の 「追い詰められた動物は逃げずに襲う」が、大型を追い詰めるときにいちばん使う武器の側だけ成立しない、という 形になります。太らせる形なら、いくつ重なっても手は消えません。
foggy は狩りの最中にはまず立ちません。 こちらが付けられる傷はどれも痛みが hurting 以上
(-20)で、そこへ失血か衝撃(どちらも -30)が重なれば dazed まで落ちるためです。立つのは、傷が
癒えても血が戻っていない個体——血の戻りは桁違いに遅い(VitalsSystem.md 3 節)ので、
追いついた獲物がこの段に居ます。
殴り続けた相手からは、気を失わせる手前で手応えが返ります。 それでも体格に見合わない武器で
追い詰める代償は残ります——逃げ道の無い土地で大型に尖った石を振り続けたとき、こちらが負う怪我は
平均6.07枚
(HuntStats.md の encounter 節。2026-09-13 時点)で、石斧や槍を
上回ります。石斧を上回るぶんを作っているのは、1手あたりの危なさではなく決着までの長さです
——衝撃が大型に届かない(1.2 節)ぶん、石斧の
8.25 手に対して
22.88 手が
要り、その手数だけ突かれます(石斧が負うのは
2.69 枚なので、
1 手あたりでは尖った石のほうがむしろ低い)。槍との差は長さだけでは説明が付きません——手数は
6.36 手と
開きますが、負う怪我は
0.71 枚で
手数の開きよりずっと大きく開きます。残りを作るのは間合いの押し引きです(1.2 節)。
空腹は配分に触れません。 野生の個体では body_fat が動かない——渇きと同じゲートで、罠や囲いの枠へ
閉じ込めている間しか減りません(TrapSystem.md 5.4 節)。押し引きを置いても野生の
遭遇では一度も発火せず、閉じ込めた獣にだけ効く押し引きになります。腹を空かせた獣が何をするかを
問えるのは、餌をやる仕組みが入ってからで、それは飼いならし(8 節)が決めます。
5.6 見ていない動物は、やがて立ち去る
動物は探索が際限なく湧かせる(ExplorationSystem.md 2 節)ので、消える口が
無いと島に溜まり続けます。プールの帳簿は持たず、立ち去りまでの残り(stay_remaining)が尽きた個体は
世界から消えます——人口は湧く速さ×平均寿命で自動的に釣り合います。
タイマーは土地の地面に居て、同じ土地に誰も居ない間だけ減ります(ゲート付きの add、
GameElementDefinition.md 8.2 節)。
- 目の前では絶対に消えません。 同じ土地に人が居る間は止まります(リセットではなく一時停止—— 「戻ったら居なくなっていた」は起こりますが、見ている前で消えることはありません)
- 罠・入れ物の中では止まります。
in_slot: itemsが「土地の地面に居る」を言うので、掛かっている 間は減りません。止まるのは中に居る間だけで、取りに戻るまでとは限りません——もがかれた罠は破られ、 中身は土地へこぼれます(TrapSystem.md6.1 節) - 深手を負っている間は止まります。 痛みが
hurting以上の個体では減りません——こちらが付けられる 傷はどれもその段に届く(InjurySystem.md)ので、手を出した獲物は必ず留まります。 こぼれた獲物がそこから動き出すかも、このゲートが決めます——生かす罠の打ち身(痛み30)なら 動き出し、殺す罠の裂傷・刺し傷(同 50・60)なら止まったままです - 消えるとき、くわえていた物はその土地へこぼれます(
destroyが中身を親へこぼす規約、GameElementDefinition.md9.3 節)。 逃げ込んだ先を突き止めれば、本体が消えた後でも盗品は落ちています
深手のゲートが追跡の窓を作ります。 止める前は、逃げた獲物は傷があと何百手も残っている時点で
消えていました——槍で突いたイノシシは、刺し傷が 720 手のうち 620 手を残した 97 手目に居なくなっていた
(issue #1994 で測った、2026-09-12 時点)ので、
3 節が言う「深手の個体は弱ったまま残る」も「severity が -1/tick で治るから追跡に時限が生まれる」も、
現物では立ち去りに先回りされていました。
窓を閉じるのは、傷が癒えることではなく化膿です。 獣は自分で傷を洗えない(wash)ので、深い傷は
infection が septic へ届き、菌が血を削って獣を倒します。一撃だけ入れて退いたときに獲物が世界に
残る手数は、イノシシで中央値441手
——追いつけば、そこには弱った個体か、腐る前の死体が在ります。 分布は
HuntStats.md の tracking 節が持ちます。
「奥地へ消えて追跡不能になった」は、この立ち去りが抽象的に表します。未発見の道を実際に逃走へ使わせる
案は採りません——追えない逃走を許すと、持ち去りの「追えば取り返せる」(Animals.md
4.1 節)が成立しなくなるためです。逃走が使うのは発見済みの道だけです。
6. 追うのは分岐ではなく、世界に起きた変化
イノシシのカードが標的のカードまで動いて壊し、戻ってくる——という演出には、「誰が何をしたか」がUIへ 伝わる必要があります。
追うのは pick が発火した分岐ではなく、世界に起きた変化です(WorldSession.observeChanges、
ActionSystem.md 7 節)。動物の1手の中で起きた物の出入りには、主体としてその動物が
付くので、UIは次のように読めます。
| 動物がしたこと | 観測される変化 |
|---|---|
| 壊した | ヤシの実が、土地のアイテムスロットから世界の外へ |
| 持ち去った | ヤシの実が、土地のアイテムスロットから隣の土地へ |
| 逃げた | 動物自身が、今の土地から隣の土地へ |
| 攻撃した | 怪我が、どこでもない所からプレイヤーの怪我スロットへ |
UIの語彙はエンジンの動詞(spawn/move/destroy)になり、動物の分岐名にはなりません。 動物を増やしても
pick の候補を足しても、観測する側は1行も変わりません。分岐を観測する形では、候補を足すたびにUIが追随します。
プロパティは効果の入力であって、UIへの通知路ではありません。 分岐ごとに偽のカウンタ(smash_count の類)を
持たせる必要も、後始末で0へ戻す必要もありません。
6.1 どう見えるかは、控えたスナップショットが持つ
変化のログが答えるのは「何が起きたか」だけで、「どう見えるか」は別です。PlayScene は tick 境界ごとの表示内容を
RecordedView として控え、実時間をかけて再生しているので、ログはその控えと並べて運びます。 両方が要ります
——ログだけでは絵にならず、絵だけでは誰の仕業か分かりません。
- 6 tick の行動が1コマに潰れません(tick ごとに控えて再生しているため、突進した tick が独立したコマになる)
- 被害者のカードの矩形が取れます。差し替えの前の並びには被害者の札がまだ居るので、突き当たる先はそこから
引けます(
cardMotionPlanのbefore)。片付けるのは突き当たってから——被害者の札は、突進が 着くまで枠の外に出したままにします
カードの同定はインスタンスID(CardContent.identity)で行い、突進は CardTable が扱う「レーンの並びから
外れて宙に在る札」の3つ目のケースです(飛んでいる札・離した場所へ置いたままの札に続く)。行って帰るまでの間、
その個体はどの枠にも居ません——枠が見せる枚数からは、運びの最中の札と同じように引かれます
(CardInteraction.md 6.2 節)。
突進として読むのは、主体が自分の外に在った物をその居場所から動かした回です。上の表の残りは外れます ——生まれた物はどこからも動いていないので出どころ(6.2 節)が答え、自分が動いた回は札そのものがレーンから 消え、くわえた物を食べた回は主体がどこへも行きません。指が放した物へも突進しません——重ねた道具を 使い切る操作がこの形になりますが、その動きは指が既に見せているからです。
手を出した相手を1つに決めるのは、並びを読める側です(cardMotionPlan)。起きた順の先頭が相手とは
限りません——中身のある入れ物を壊すと、こぼれた中身の移動が入れ物の消滅より先に記録される
(WorldObject.destroy)ので、順で採ると閉じた入れ物の中に居た札を相手にしてしまいます。画面に出ている
候補を選べるのは、その並びを持っている側だけです。
6.2 既存の演出も同じ観測に寄せた
カードの移動アニメーションは、新しく現れた札の出どころを個体ごとに変化のログから引きます
(MotionContext.origins・changedInstances)。ログが「この個体はこの札から来た」と言うので、UIは主体の札の
矩形を引くだけです。同じ tick に出どころの違う物が生まれても、それぞれの出どころから飛べます。
出どころは主体で、主体を持たない変化は移動前の親になります。これで画面に出ていないスロット(未発見の設置物、 閉じた入れ物の中)から出てきた物が、その持ち主の札から飛びます。
| 現れたもの | 出どころ |
|---|---|
| ドラッグ型の操作の成果物 | 効果を宣言している側の札(重ねた相手か、逆向きに成立したなら掴んだ札。それが主体) |
| アクションで採ったもの | そのカード(ヤシの木から採った実は木から手元へ) |
| 探索で見つけたもの | 現在地(explore の主体。設置物は移動前の親としても同じ土地を指す) |
| tick の中で生まれたもの | それを起こしたオブジェクト |
呼び出し側が渡すのは画面の事実だけです。 指を離した位置(MotionContext.released)と、
一覧から作り始めた製作中オブジェクトの出どころ(閉じた一覧の中で選んだ札の位置)です。どちらも世界の
どこにも無い位置なので、世界の側は答えを持ちません。
ログを控えと並べて運ぶ必要があるのはここでもです(6.1 節)。矩形へ直すのは再生する時点——出どころの札の 位置は、そのtickの画面(1つ前の控え)にしかありません。
6.3 外した一手も、起きたこととして告げる
世界の形が変わらない回は、起こした側が signal で告げます(GameElementDefinition.md 9.8 節)。
観測できるのは物の出入りだけ(6 節)なので、外した回は放っておくと「何も起きなかった」ように——武器を
重ねる操作そのものが効かなかったように——見えます。実際に起きたのは「外したこと」です。
殴った回も同じ扱いにします。刺さった傷は押して開くスロット(visible_slots: [injuries, spoils]、3 節)の中に
入るため、当たった回もレーンの上では何も変わりません。 当たり外れがカードの上で読めるのは、
両方が告げているからです。
strike:
pick:
- weight: {subject: instrument, prop: heavy_blow}
spawn: {object: laceration, into: self}
signal: hit
- weight: {subject: instrument, prop: whiff}
signal: missed
告げるのは出来事だけで、見せ方は持ちません。 文字は殴られた側の札の上に浮かびます
(CardView.md 14 節)。strike を宣言しているのは動物の側なので、対象を省いた
signal がそのまま動物の札を指します——武器の側が「刃こぼれした」と告げるような、宣言した側と
起きた側が違う場合だけ対象を書きます(GameElementDefinition.md 9.8 節)。
5 節の動物の1手が回避や威嚇を持つようになっても、告げる語を足すだけで UI 側は変わりません。
7. 狩猟を支えるエンジンの拡張
狩猟専用の文法は導入しません。次はいずれも汎用の拡張で、すべて実装済みです。
| 拡張 | 内容 |
|---|---|
resists(4 節) |
bound_to_owner の対称形。条件が成立する間、土地以外の親へ移れない。成立した瞬間に土地へこぼれ出る(GameElementDefinition.md 7.13 節) |
オブジェクトを指す参照(ObjectRef) |
対象キーと、インスタンスIDを保持するプロパティ({prop: ...})の二択。destroy の対象と move の subject・移動先が共有する(GameElementDefinition.md 9.3 節・9.6 節)。どの対象キーを書けるかは、その宣言が置かれた場所が何を持つかで決まる(同 14.1 節の表。操作の関係の役は同 11.5 節「役を書ける場所」が唯一の一覧)。動かす物と行き先を別々の仕組みで指さない——どちらも「1つのオブジェクトを指す」という同じ役目だから |
move の subject: self |
動かす物に宣言元自身を指せる(同 9.6 節)。動物が自分で逃げる一手(5.1 節)が使う |
trigger: tick(同 11.1 節) |
画面のボタンには出さない操作。起こすのはプレイヤーではなく時間の側になる |
signal(6.3 節) |
世界の形を変えず、出来事が起きたことだけを告げる。当たり外れに限らず、出入りを伴わない出来事すべてが使う |
加えて、tick の後処理として動物へ1手与える箇所(5.2 節)が実装の中心です。変化の観測(6 節)は
狩猟に限らない汎用の仕組みなので、ActionSystem.md 7 節が持ちます。
「その場から1つ選ぶ」汎用語彙(choose の類)は、今は導入しません。 用途が逃走先と体当たりしか
ない状態で形を決めると、守れているか確かめられない約束になります。導入するなら選択は1回だけ行って名前を
付ける形が必須です——逃走は「選んだ道の destination_id」と「選んだ道の travel_minutes」の2箇所が同じ
個体を指す必要があり、参照ごとに振り直す形では移動時間と行き先が食い違います。
8. 未決事項・今後の検討課題
- 怪我の内容: 部位別の怪我をいくつ用意するか。それぞれが動物の回避・逃走・攻撃へ効かせる量
warinessを動かすもののうち、まだ無いもの: 火・手当て・子連れ・囲い込みの効き方。 カードの状態バーへどう出すか(バーは既に何本も並ぶ)。現れたときの値(3.1 節)と、傷で上がり時間で 下がるぶんは入った- 飼いならしの完了条件と、飼った動物の扱い(
resistsが外れた後の居場所、餌、逃走)。 立ち去り(5.6 節)との整合もここで決める——動物の満腹度を実装し、満腹ならstay_remainingが戻り、 空腹なら減る、という方向を想定している。定期的に餌を与えなければ逃げられ、檻(入れ物の中では タイマーが止まる)に閉じ込めれば逃げられない - 死体の重さと運搬:
loadのtoo_heavyで移動が止まるため、倒した後の運搬が本題になる。 獣ごとの体重と1手の重み配分は入った(5 節。手数はHuntStats.md) - 死体と肉で腐る速さを分けるか(1.5 節)。腐敗は入ったが、両者が同じ速さなので、解体しても保つ
時間は延びない。分ければ「腐る前に捌く」が解体を急ぐ2つ目の理由になるが、速さの分類そのものは
DurabilitySystem.md3 節が持つ fragileを付ける範囲(5.4 節): 今は編み籠・くくり罠・編んだ葉・ヤシの器・甕だけで、序盤の土地には 壊れる物がほとんど無い。壊される痛手が実際に効くのは、拠点に物を並べ始めてからになる- 同じ傷を、噛んだ相手によらず同じ深さにしてよいか(5 節): 傷の種類は候補が持つので、80gのネズミと
5kgのサルは同じ
bite_woundを残す。大型と小型の差は、大型だけが重みを立てる圧し掛かり(骨折)が 表すようになったが、同じ候補を引いたときの差は依然として頻度だけが持つ。 体格が1手へ効くのを素の配分の差だけに留めてよいかも、ここで一緒に決まる——体調は意識を通して 押すようになった(5.5 節)が、体格は押し引きを1つも持たない