> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livlive.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> This is livlive's documentation. An agent reaches livlive from outside through the `livlive` CLI or the livlive MCP server (see /developers/install, /developers/cli and /developers/mcp). The person links it to livlive once, in the browser: `livlive login`, the local MCP's `livlive_login` tool, or the remote MCP at https://backstage.livlive.ai/api/mcp signing in by OAuth; a personal token made in livlive's settings is for CI. Pages marked 準備中 describe parts not decided yet: do not guess their behaviour.

# エンジンのリファレンス

> ステージを作るときに使えるエンジンの機能の一覧です。

> [!NOTE]
>
> この頁は、livlive-kit の `reference/engine.json` から自動で作っています。CLI(`livlive reference`)と MCP は、同じ内容をエージェント向けに持っています。livlive-kit はまだ外の人には公開していません。書かれている説明は、元の言葉のままです。

版: `livlive.world/0.2` ・ ハッシュ: `669e74882761`

## 層

ステージのパッケージは、次の層でできています。`needs` は、先に要る層です。

| 層 | ファイル | 版 | needs | 説明 |
| - | - | - | - | - |
| `room` | `room.glb`, `world.json`, `manifest.json?` | `livlive.world/0.2` | — | The room: its shape (room.glb) and what the engine reads of it (world.json) — things, seats, walk, cameras, looks, events. |
| `things` | `things/*/thing.glb`, `things/*/thing.json` | `livlive.thing/0.1` | `room` | Things brought as files, each placed in the room by a world.json object row's `from`. |
| `keeper` | `keeper/keeper.js`, `keeper/keeper.json` | `keeper protocol 1` | `room` | The space's own game: keeper.js run in the box, its acts and questions declared in keeper.json; world.json says keeper "own". |
| `skill` | `SKILL.md` | `livlive.stage-skill/0.1` | `room` | How to make a show on this stage, as a skill (a when-to-read line, title, summary, 1-3 lines, body); the writer reads it whenever a content is set on the stage. |

## パッケージのファイル

| ファイル | 説明 |
| - | - |
| `room.glb` | the room: one binary glTF with everything inside it (no external files); its lamps are KHR\_lights\_punctual lights |
| `world.json` | livlive.world/0.2 (schema) |
| `manifest.json` | \{ name, version (a string) } — kept short; schema "livlive.world-package/0.2" when said |
| `things/<name>/` | thing.glb + thing.json for each thing placed by an object's `from` |
| `keeper/` | keeper.js + keeper.json when world.json says keeper "own" |

| GLB | 決まり |
| - | - |
| `objectNode` | a node whose extras.livlive.id equals an object's id is that object's shape (world.json says `node`) |
| `extensions` | limits.SPACE\_EXTENSIONS only |

## 座標

| 項目 | 値 |
| - | - |
| `world.units` | metres |
| `world.up` | +y |
| `world.coordinates` | room.glb's own |
| `world.heading` | radians about +y: 0 faces +z, positive turns toward +x (facing = (sin h, cos h)) |
| `world.placed` | the engine places the room so the spawn is the origin, facing +z |

## 物の種類

| 種類 | 名前 | 幅 w | 高さ h | 奥行き d | 座れる | 歩ける | できること |
| - | - | - | - | - | - | - | - |
| `sofa` | 長いソファ | `1.2〜3.2` | `0.6〜1` | `0.7〜1.1` | はい | — | `look`, `look_closely`, `point`, `talk_about`, `sit` |
| `armchair` | 一人掛けのソファ | `0.6〜1.1` | `0.6〜1.1` | `0.6〜1` | はい | — | `look`, `look_closely`, `point`, `talk_about`, `sit` |
| `chair` | 椅子 | `0.35〜0.6` | `0.7〜1.1` | `0.35〜0.6` | はい | — | `look`, `look_closely`, `point`, `talk_about`, `sit` |
| `stool` | スツール、丸い腰掛け | `0.3〜0.6` | `0.35〜0.8` | `0.3〜0.6` | はい | — | `look`, `look_closely`, `point`, `talk_about`, `sit` |
| `bench` | ベンチ、長椅子 | `0.8〜2.5` | `0.35〜0.6` | `0.3〜0.6` | はい | — | `look`, `look_closely`, `point`, `talk_about`, `sit` |
| `bed` | ベッド、寝台 | `0.9〜2` | `0.3〜0.7` | `1.8〜2.2` | はい | — | `look`, `look_closely`, `point`, `talk_about`, `sit` |
| `table` | テーブル | `0.4〜2.5` | `0.3〜1.1` | `0.4〜1.5` | — | — | `look`, `look_closely`, `point`, `talk_about` |
| `desk` | 机 | `0.8〜2` | `0.65〜0.8` | `0.5〜0.9` | — | — | `look`, `look_closely`, `point`, `talk_about` |
| `counter` | カウンター、売り台 | `0.8〜4` | `0.85〜1.2` | `0.4〜0.9` | — | — | `look`, `look_closely`, `point`, `talk_about` |
| `shelf` | 棚 | `0.4〜3` | `0.6〜2.4` | `0.2〜0.6` | — | — | `look`, `look_closely`, `point`, `talk_about` |
| `cabinet` | 低い戸棚、箱型の家具 | `0.4〜2` | `0.4〜1.2` | `0.3〜0.7` | — | — | `look`, `look_closely`, `point`, `talk_about` |
| `plant` | 鉢植え、木 | `0.2〜1.2` | `0.2〜2.5` | `0.2〜1.2` | — | — | `look`, `look_closely`, `point`, `talk_about` |
| `planter` | 花壇、長いプランター | `0.3〜3` | `0.2〜1` | `0.2〜0.8` | — | — | `look`, `look_closely`, `point`, `talk_about` |
| `lamp` | 灯り、ランタン、照明 | `0.15〜0.6` | `0.2〜2` | `0.15〜0.6` | — | — | `look`, `look_closely`, `point`, `talk_about` |
| `screen` | 画面、モニター、看板の映像 | `0.4〜3` | `0.3〜2` | `0.03〜0.3` | — | — | `look`, `look_closely`, `point`, `talk_about`, `use` |
| `rug` | 敷物 | `0.6〜4` | `0.005〜0.03` | `0.6〜4` | — | はい | `look`, `look_closely`, `point`, `talk_about` |
| `box` | 箱、木箱、荷物 | `0.2〜1.2` | `0.2〜1.2` | `0.2〜1.2` | — | — | `look`, `look_closely`, `point`, `talk_about` |
| `sign` | 看板、ポスター、掲示板 | `0.3〜3` | `0.3〜2.5` | `0.03〜0.3` | — | — | `look`, `look_closely`, `point`, `talk_about` |

## できること(can)と動作

物の `can` の言葉が、キャラクターの動作を開きます。

| can | 動作 | 言葉 | 要るもの | 意味 | 除くもの |
| - | - | - | - | - | - |
| — | `go_to` | 行く | — | — | a seat (its sit rows stand for it), a thing whose can holds "stand\_on" (a floor a character stands on), and a thing with no free place beside it that a walk from the spawn reaches are never offered a walk |
| `look` | `look_at` | 見る | — | — | — |
| `sit` | `sit` | 座る | `seat` | the object's row has seat \{ x, z, out } (numbers) | — |
| `sit_work` | `sit` | 座って作業する | `work` | a seat whose work is a number (the heading while working) | — |
| `use` | `use` | 点ける・消す | `switch` | a looks entry of kind light\_switch whose id is the object's id, its state unsaid or "on", naming at least one lamp or glowing node; the object is not hidden and its can holds "use" | — |

動作の一覧です。

| 動作 | 言葉 |
| - | - |
| `go_to` | \{物}へ行く |
| `go_home` | いつもの位置へ戻る |
| `look_at` | \{物}を見る |
| `turn` | 向きを変える |
| `sit` | \{物}に座る |
| `stand` | 立ち上がる |
| `wait` | その場で待つ |
| `use` | \{物}を使う |
| `do` | （コマンド） |

## 見た目と持ち方

| 項目 | 値 |
| - | - |
| `kinds` | `light_switch`, `mains`, `flash`, `visible` |
| `holds.light_switch` | on |
| `holds.mains` | on |
| `holds.visible` | hidden |

持ち方(`hold.poses`): `overhead`, `chest`, `side`

## 数の上限

| 項目 | 値 |
| - | - |
| `SPACE_LIMITS.bytes` | `62914560` (60 MiB) |
| `SPACE_LIMITS.triangles` | `1000000` |
| `SPACE_LIMITS.images` | `64` |
| `SPACE_LIMITS.lamps` | `16` |
| `SPACE_LIMITS.areaLights` | `4` |
| `SPACE_LIMITS.nameChars` | `40` |
| `SPACE_LIMITS.aboutChars` | `200` |
| `SPACE_LIMITS.idChars` | `40` |
| `SPACE_LIMITS.canWords` | `16` |
| `SPACE_LIMITS.canChars` | `32` |
| `SPACE_LIMITS.worldBytes` | `262144` (256 KiB) |
| `SPACE_LIMITS.placements` | `256` |
| `SPACE_LIMITS.placedNodes` | `65536` |
| `SPACE_EXTENSIONS` | `KHR_lights_punctual`, `KHR_materials_emissive_strength`, `KHR_materials_unlit`, `KHR_materials_transmission`, `KHR_materials_ior`, `KHR_materials_specular`, `KHR_materials_clearcoat`, `KHR_materials_sheen`, `KHR_materials_volume`, `KHR_texture_transform`, `KHR_mesh_quantization`, `EXT_mesh_gpu_instancing` |
| `AREAS.max` | `32` |
| `AREAS.id` | `^[a-z0-9_-]{1,40}$` |
| `AREAS.nameChars` | `40` |
| `AREAS.boxes.min` | `1` |
| `AREAS.boxes.max` | `16` |
| `INK_RANGE.line.min` | `0.5` |
| `INK_RANGE.line.max` | `4` |
| `INK_RANGE.bands.min` | `2` |
| `INK_RANGE.bands.max` | `6` |
| `INK_RANGE.soft.min` | `0` |
| `INK_RANGE.soft.max` | `1` |
| `INK_RANGE.color` | `^#[0-9a-f]{6}$` |
| `GLOW_RANGE.strength.min` | `0` |
| `GLOW_RANGE.strength.max` | `2` |
| `GLOW_RANGE.radius.min` | `1` |
| `GLOW_RANGE.radius.max` | `32` |
| `GLOW_RANGE.from.min` | `0.3` |
| `GLOW_RANGE.from.max` | `1` |
| `WEATHER_RANGE.density` | `500` |
| `WEATHER_RANGE.speed` | `30` |
| `WEATHER_RANGE.wind` | `10` |
| `WEATHER_RANGE.windDir` | `360` |
| `WEATHER_RANGE.height` | `50` |
| `WEATHER_RANGE.areas` | `32` |
| `WET_MAX.surfaces` | `64` |
| `WET_MAX.chars` | `120` |

## キーパー

| 項目 | 値 |
| - | - |
| `protocol` | `1` |
| `names` | `room`, `own` |
| `box.callMs` | `20` |
| `box.memoryBytes` | `33554432` (32 MiB) |
| `box.stackBytes` | `49152` (48 KiB) |
| `box.codeBytes` | `65536` (64 KiB) |
| `box.answerBytes` | `262144` (256 KiB) |
| `box.rows` | `64` |
| `box.wordChars` | `200` |
| `box.lines` | `20` |

キーパーの関数です。

| 名前 | いつ | 入力 | 出力 | 省略できる | エンジン専用 |
| - | - | - | - | - | - |
| `reset` | once, when the stage opens | stage view, time, seed (the show's id — all its randomness comes from it; Math.random is refused) | the keeper's state (JSON) | — | — |
| `step` | when something reaches the stage, never every tick: a character's act done, an operator's press of one of the stage's events (in input.triggers), who is here or where they sit changing, the stage opening, and the time its alarm asked for | state, input (what happened: time, triggers, hands, acts, cast, seats), stage view | \{ state, out } — the box keeps only state: an answer with no state is a wrong shape and the game stops, and everything else in the answer is dropped, so out is answered empty (\{ happenings: \[], things: \{}, news: null, events: null }) and a game never moves the room's things. A light or a switch moves only by a character's use (a row the game may offer) or an operator's event (the stage's rules.happenings); a thing shown or hidden only by an operator's event; what a viewer sees of the game itself, it draws in view | — | — |
| `check` | for each of its acts a character's menu offers | type, state, act \{ type, target, mode, who }, stage view | why it cannot be done now (words), or null: it may | はい | — |
| `alarm` | after a step | state | when to wake it by time (\{ at } or \{ every }), or null — only events | はい | — |
| `offers` | when a character's menu is made | state, who, stage view | the rows it offers who now \[\{ id, words, s, act: \{ type, target?, mode? }, at?, due? }] | はい | — |
| `ask` | when who has rows due | state, who, stage view | the question for those rows (one keeper.json declares), or null | はい | — |
| `still` | when who's menu is made | state, who, stage view | true: who stays where they are (only due rows on the menu) | はい | — |
| `observe` | when who is told of the play | state, who, stage view | words: who's own facts only (never another's hand) | はい | — |
| `view` | when the board is drawn | state, stage view | \{ title, rows: \[\{ who, turn, tiles: \[\{ text, mark?, card?, fresh? }], sub? (≤ 24 characters), meter?: \{ value (finite, ≥ 0), of (finite, > 0) }, facts?: \[\{ label, value }] (≤ 4, ≤ 8 characters each), act?: \{ key (≤ 32 characters), kind: push \| answer \| fold \| draw, words (≤ 8 characters), amount? (finite, ≥ 0) }, danger?, won? }], note, center?: \{ label, value (≤ 8 characters each), line? (≤ 24 characters) }, moment?: \{ key (≤ 32 characters), kind: deal \| reveal \| win \| end, who? (a row's who) } }, or null — every tile is drawn at one width; card \{ rank (1–5 characters), suit: ♠ ♥ ♦ ♣, or null for a joker } draws the tile as that card's face, never read from text; fresh: true rings the card just moved; mark: true marks the tile; three or four rows are drawn as a table seen from above, each player's face in a circle at their side, while the game is on and no win holds the camera — the table is then the whole picture, the room and the bodies not shown; a win's hold, the game's end (a view that says end) and any other number of rows are drawn as strips over the room's picture, the bodies in it (livlive's standard look; in app delivery — each character a small picture of its own — no board is drawn); the table draws the tiles, center, names, sub and won, never meter, facts, act or danger, nor a moment's effects (its sound still plays), so keep what viewers must read in the tiles, center or sub; won draws the row's WIN mark, on a strip and on the table; a win is a row's won turning true, or a win / end moment with a who: the camera goes to that player and back (when they are in the picture) and every character of the cast is told of it, the winner as their own win (a winner who is none of the cast is told to nobody); one win a view (the moment's, else the first row whose won turned true), every won row still marked; the table marks by won alone, so a win told by a moment alone gets the camera and the telling, but no mark there; an end moment with no who is a draw (no camera, no telling); deal and reveal never move the camera; a moment's key is new for each moment and is played once a show; the game is over once a view says end — keep that moment in every later view, a view without it brings the table back; a moment's who must be a row's who, or the view is wrong and the game stops | はい | — |
| `facts` | after a step (the engine's own keepers) | state, stage | how each thing it holds stands (by id), or null | はい | はい |
| `may` | when an act is asked (the engine's own keepers) | state, stage, cast, offered | the rows of its acts that may be done now | はい | はい |

### 行為の動き(`keeper.motions`)

ゲーム自前の行為(`keeper.json` の `acts`)は、`motion` にこの名前のどれかか、下の `by-thing` を書きます。

| 名前 | いつも流れている | まだ使われていない |
| - | - | - |
| `IDLE` | はい | — |
| `TALK` | はい | — |
| `listen` | — | はい |
| `emote` | — | — |
| `pose` | — | — |
| `point` | — | — |
| `entrance` | — | — |
| `walk` | — | — |
| `run` | — | — |
| `sit` | — | — |
| `sit-work` | — | — |
| `turn-left` | — | — |
| `turn-right` | — | — |
| `reach` | — | — |
| `press` | — | — |
| `open` | — | — |
| `pick-up` | — | — |
| `put` | — | — |
| `walk-through-door` | — | はい |
| `throw-away` | — | はい |

いつも流れている動き: The body's base loops (IDLE while a character is silent, TALK while it speaks) are always playing: an act that names one shows no motion of its own.

まだ使われていない動き: Named in the body's table, but no engine act, show moment or kind of thing asks for them yet: an act that names one shows a move only on a character whose body holds one under that name.

`by-thing`: Named as an act's motion, it lets the thing the act is done to decide: the kind the world's looks give that thing picks the motion in keeper.motions.byThing.kinds, and any other thing plays keeper.motions.byThing.other.

| 物の種類 | 動き |
| - | - |
| `light_switch` | `press` |
| `mains` | `press` |
| `open_lid` | `open` |
| ほかの物 | `reach` |

## ルールの変換

| 項目 | 値 |
| - | - |
| `stamp` | // livlive rules translator · typescript 5.9.3 · 0822cdd57052 |
| `wallMs` | `5000` |
| `files.count` | `64` |
| `files.chars` | `262144` |
| `files.total` | `1048576` |
| `path` | `^(?!.*\.\.)(?!\.\|.*\/\.)[\p{L}\p{N}_.-]+(?:\/[\p{L}\p{N}_.-]+)*\.ts$` |

## 問題のコード

ステージを預けたときや検査のとき、問題はこのコードで答えます。`…` には、そのときの値が入ります。

### `stage`

| コード | 意味 |
| - | - |
| `world.unreadable` | world.json の書き方が違う |
| `world.schema` | 形式 … は読めない(…) |
| `spawn.missing` | 出現位置(spawn)が無い |
| `nav.bounds_missing` | 歩ける範囲(nav.bounds)が無い |
| `camera.volume_empty` | カメラの範囲が空 |
| `object.id_missing` | id の無い物がある |
| `object.id_twice` | id … が二つある |
| `areas.shape` | areas は \{id(小文字・数字・- \_)・boxes: 床の箱(x0\<x1・z0\<z1)…〜… 個・gaits: 歩き方の名前} の … 個までの並び(id は一つずつ) |
| `weather.kind_twice` | effects の … は一つまで |
| `weather.rain` | 雨(rain)は \{area: 区域の id(いくつかなら並び)・density: 1 m² あたりの粒(0〜…)・speed: 落ちる速さ m/s(0〜…)・wind: 横に流れる速さ m/s(±…)・wind\_dir: 風の向き 度(0 = +x・90 = +z)・floor: 雨の止まる高さ m・top: 降り始める高さ m(floor より上・±…)} |
| `weather.wet` | 濡れる面(wet)は \{surfaces: GLB の素材かノードの名前 1〜… 個・gloss: 0〜1} |
| `weather.reflections` | 映り込み(reflections)は \{at: \[x, y, z] 部屋の中の一点} |
| `ink.shape` | 線と色の段(look.ink)は \{line, color, bands, soft} |
| `ink.line` | 線と色の段(look.ink)の line は …〜…(px) |
| `ink.bands` | 線と色の段(look.ink)の bands は …〜… の整数 |
| `ink.soft` | 線と色の段(look.ink)の soft は …〜… |
| `ink.color` | 線と色の段(look.ink)の color は #rrggbb |
| `glow.shape` | 光のにじみ(look.glow)は \{strength, radius, from} |
| `glow.strength` | 光のにじみ(look.glow)の strength は …〜… |
| `glow.radius` | 光のにじみ(look.glow)の radius は …〜…(px) |
| `glow.from` | 光のにじみ(look.glow)の from は …〜…(明るさ) |

### `package`

| コード | 意味 |
| - | - |
| `objects.shape` | 物の一覧(objects)の書き方が違う |
| `object.id` | 物の id「…」は … 字までの文字列 |
| `object.name` | 物「…」の名前は … 字までの文字列 |
| `object.about` | 物「…」の説明は … 字までの文字列 |
| `object.can` | 物「…」のできること(can)は … 語まで |
| `object.hidden` | 物「…」の hidden は true か false |
| `lighting.area_shape` | 面の光の書き方が違う |
| `lighting.area_many` | 面の光が多すぎる(… ・ 上限 …) |
| `happenings.shape` | 出来事(rules.happenings)の書き方が違う |
| `happening.shape` | 出来事「…」の書き方が違う |
| `happening.telop_missing` | 出来事「…」に文字(telop)が無い(ボタンとテロップに出す言葉) |
| `happening.telop_long` | 出来事「…」の文字(telop)は … 字まで |
| `happening.once` | 出来事「…」の once は true か false |
| `happening.color` | 出来事「…」の色(color)は … のどれか |
| `happening.set_shape` | 出来事「…」の…の書き方が違う |
| `happening.flash_shape` | 出来事「…」の光(flash)の書き方が違う |
| `happening.end_shape` | 出来事「…」の終わり(end)の書き方が違う |
| `happening.end_after` | 出来事「…」が終わるまで(end.after)は …〜… 秒 |
| `happening.end_telop` | 出来事「…」の終わりの文字(end.telop)は … 字まで |
| `flash.state` | 光「…」は状態(state)を持たない(光るだけ) |
| `flash.nothing` | 光「…」は明かり(lights)か光る部分(emissive)が要る |
| `visible.state` | 見せたり隠したりする「…」の状態(state)は … |

### `check`

| コード | 意味 |
| - | - |
| `door.busy` | 確かめが混み合っている — 少し待ってから送り直す |
| `door.empty_file` | 空のファイル |
| `door.face_unread` | ステージの今の一枚絵・ひとこと・色・世界観を読めなかった(もう一度送ってください) |
| `door.fingerprint_shape` | 指紋の形が違う |
| `door.glb_changed` | 送った GLB が途中で変わった(送り直してください) |
| `door.glb_large` | ファイルが大きすぎる(上限 …MB) |
| `door.glb_missing` | 送った GLB が見つからない(送り直してください) |
| `door.job_stopped` | 確かめの途中で止まった |
| `door.layer_unknown` | 層「…」は livlive の層の表に無い(参照の layers を見てください) |
| `door.path` | 送った場所が違う |
| `door.picture_changed` | 送った一枚絵が途中で変わった(送り直してください) |
| `door.picture_elsewhere` | 同じ画像が、このステージの一枚絵にできない棚(ほかのステージ・資料・添付)にある(別の画像を送ってください) |
| `door.picture_large` | 一枚絵が大きすぎる(上限 …MB) |
| `door.picture_missing` | 送った一枚絵が見つからない(送り直してください) |
| `door.picture_path` | 一枚絵の送った場所が違う(stage.face.upload が答えた path を送ってください) |
| `door.picture_shape` | 画像ではない(PNG / JPG / WebP) |
| `door.picture_size` | 画像の寸法が読めない |
| `door.reread_failed` | 登録を読み直せなかった |
| `door.run_live` | このステージでリハーサルか本番が動いています。終わってから送ってください。 |
| `door.run_unread` | このステージで配信が動いているか確かめられませんでした。もう一度送ってください。 |
| `door.space_large` | 空間のファイルが大きすぎる(部屋と物を合わせて … MB ・ 上限 … MB) |
| `door.stage_missing` | ステージが見つからない |
| `door.store_failed` | 登録できなかった |
| `door.thing_changed` | 物『…』の GLB が途中で変わった(送り直してください) |
| `door.thing_large` | 物『…』のファイルが大きすぎる |
| `door.thing_missing` | 物『…』の GLB が見つからない(送り直してください) |
| `door.thing_name` | … は things/\<名前>(小文字・数字・- \_)の形でない |
| `door.thing_path` | 物『…』の送った場所が違う |
| `door.things_many` | 物が多すぎる |
| `door.too_slow` | 処理が5秒を超えたので止めた — 重い繰り返しか、大きすぎるコードを見直す |
| `door.upload_failed` | 送り先を作れなかった |
| `door.wear_failed` | ステージに付けられなかった |
| `door.world_missing` | world.json が無い |
| `face.note_long` | ひとことが長すぎる(… 字 ・ 上限 … 字) |
| `face.tone` | 色「…」は色の一覧に無い(…) |
| `face.world_empty` | 世界観の文書「…」に中身が無い |
| `face.world_failed` | 世界観の文書「…」を保存できなかった(もう一度送ってください) |
| `face.world_long` | 世界観の文書「…」が長すぎる(… 字 ・ 上限 … 字) |
| `face.world_name` | 世界観の文書名「…」の形が違う(英数と . \_ - の .md) |
| `face.world_total` | 世界観の文書が合わせて長すぎる(… 字 ・ 上限 … 字) |
| `face.world_twice` | 世界観の文書「…」が 2 つある |
| `flash.glow_missing` | 光「…」の光る部分「…」の名前が GLB に無い |
| `flash.glow_power_cut` | 光「…」の光る部分「…」は停電で消える(電気の keep に入れる) |
| `flash.light_missing` | 光「…」の明かり「…」の名前が GLB にも面の光(lighting.area の name)にも無い |
| `flash.light_power_cut` | 光「…」の明かり「…」は停電で消える(電気の keep に入れる) |
| `glb.extension` | …拡張 … はまだ描けない(圧縮や特別な描き方は外して書き出す) |
| `glb.outside_file` | …外のファイルを指している(GLB の中に全部入れて書き出す) |
| `glb.unreadable` | … |
| `happening.flash_unknown` | 出来事「…」が光らせる「…」は空間の光に無い(looks の kind flash の id) |
| `happening.set_glow_only` | 出来事「…」の…の「…」は光るだけで、変える状態が無い(光らせるのは flash) |
| `happening.set_state` | 出来事「…」の…の「…」は … |
| `happening.set_unknown` | 出来事「…」の…が変える「…」は空間に無い(looks の id) |
| `keeper.act_controller` | 行為「…」の運び方は here か reach |
| `keeper.act_motion` | 行為「…」に motion(基本の動き)の名前が要る |
| `keeper.act_ms` | 行為「…」の ms は 0〜10000 の整数 |
| `keeper.act_name` | 行為「…」の名前が使えない |
| `keeper.act_reserved` | 行為「…」は engine と部屋が持つ |
| `keeper.dry_run_stopped` | 遊び方を試すと止まった(…): … / 遊び方を…人で試すと止まった(…): … |
| `keeper.js_functions` | keeper.js に … が無い |
| `keeper.js_large` | keeper.js が大きすぎる(…KB まで) |
| `keeper.js_missing` | keeper/keeper.js が無い |
| `keeper.js_unreadable` | keeper.js を読み込めない: … |
| `keeper.json_missing` | keeper/keeper.json が無い |
| `keeper.manifest` | keeper.json: … |
| `keeper.manifest_id` | id は英小文字・数字・\_ の 2〜41 字(「-」は使えない — 問いの名前になるため) |
| `keeper.manifest_large` | keeper.json が大きすぎる(…KB まで) |
| `keeper.manifest_players` | players は 1 ≤ min ≤ max ≤ … の整数(出演は … 人まで) |
| `keeper.manifest_protocol` | keeper.json の protocol … は、このエンジンでは動かせない(動かせるのは …) |
| `keeper.manifest_unreadable` | keeper.json が読めない |
| `keeper.manifest_version` | version は 20 字までの文字列 |
| `keeper.own_missing` | 遊び方(keeper)「own」なのに、keeper/keeper.js と keeper/keeper.json が無い |
| `keeper.own_unsaid` | keeper/ があるのに、world.json の keeper が「own」になっていない |
| `keeper.question_default` | 問い「…」の default は文字列 |
| `keeper.question_instructions` | 問い「…」の文面は 1〜… 字 |
| `keeper.question_name` | 問い「…」の名前が使えない |
| `keeper.question_threshold` | 問い「…」の threshold は 0 と 1 の間 |
| `keeper.seats_short` | このゲームは…人まで遊びますが、席が…つしかありません |
| `keeper.setting_bounds` | …の範囲が正しくない |
| `keeper.setting_default` | …の default が範囲に無い |
| `keeper.setting_name` | …の名前が使えない |
| `keeper.setting_options` | …の options は 2 つ以上、value と words はそれぞれ重ならず、words は 1〜… 字 |
| `keeper.setting_type` | …の type は integer・number・boolean・choice・text のどれか |
| `keeper.setting_words` | …の words は 1〜… 字 |
| `keeper.unknown` | 遊び方(keeper)「…」はエンジンに無い — ゲームはステージのパッケージに入れる(keeper を「own」にして keeper/keeper.js と keeper/keeper.json) |
| `keeper.world_unreadable` | world.json が読めないので、遊び方を試せない |
| `lamps.many` | ライトが多すぎる(… ・ 上限 …) |
| `lamps.shape` | ライトの書き方が違う |
| `mains.keep_missing` | 電気(…)が消えても残す明かり「…」の名前が GLB に無い |
| `object.node_missing` | 物「…」の形が GLB に無い(ノードの extras.livlive.id = …) |
| `space.bytes` | ファイルが大きすぎる(…MB ・ 上限 …MB) |
| `space.images` | 画像が多すぎる(… ・ 上限 …) |
| `space.triangles` | 形が細かすぎる(三角 … ・ 上限 …) |
| `spawn.outside_walk` | 出現位置が歩ける範囲の外 |
| `switch.glow_missing` | 物「…」の光る部分「…」の名前が GLB に無い(形のあるノード) |
| `switch.hidden` | 点けたり消したりする「…」が最初から隠れている(hidden)— 隠れた物は点け消しされない。出来事で見せ隠しするなら kind は visible |
| `switch.light_missing` | 物「…」の明かり「…」の名前が GLB に無い(ライトのノード) |
| `switch.nothing` | 点けたり消したりする「…」は明かり(lights)か光る部分(emissive)が要る |
| `switch.object_missing` | 点けたり消したりする「…」が物の一覧(objects)に無い(looks の id は物の id) |
| `switch.state` | 点けたり消したりする「…」の状態(state)は on(書かなくてもよい)— 最初に消しておくなら initial に \{"on": false} |
| `switch.use_missing` | 点けたり消したりする「…」の can に use が無い(このままでは点け消しされず、initial も効かない)— キャラが点ける物なら can に "use" を足す。出来事で点け消しするだけの物も can に use が要る。出来事で見せ隠しする物なら kind は visible |
| `thing.about` | … の about は … 字までの文字列 |
| `thing.at` | 置いた『…』の at は x と z の数(y は数か無し) |
| `thing.can` | … の can は … 語まで(1 語 … 字まで) |
| `thing.from_missing` | … が zip の中に無い(置いた『…』) |
| `thing.from_name` | 置いた『…』の from「…」は things/\<名前>(小文字・数字・- \_) |
| `thing.heading` | 置いた『…』の heading は数(ラジアン) |
| `thing.hold_arm` | … の hold の arm: … |
| `thing.hold_node` | … の hold の … はノードの名前(小文字・数字・- \_、40 字まで) |
| `thing.hold_node_glb` | … の hold の …「…」が … の GLB に… |
| `thing.hold_pose` | … の hold は pose(…)か arm(その物の持ち方)のどちらか一つ / … の hold の pose は … のどれか |
| `thing.hold_shape` | … の hold の形が違う |
| `thing.hold_unknown_key` | … の hold に知らない欄「…」がある |
| `thing.hold_within` | … の hold の within は区域の id の並び(1〜8 個) |
| `thing.hold_within_area` | … の hold の within「…」が world.json の areas に無い(置いた『…』) |
| `thing.hold_words` | … の hold の words は、持っている時の言葉(20 字まで) |
| `thing.id_room_node` | 置いた id『…』が部屋のノードの名前と重なっている |
| `thing.kind` | … の kind は … 字までの文字列 |
| `thing.name` | … は things/\<名前>(小文字・数字・- \_)の形でない |
| `thing.name_long` | … の name は … 字まで |
| `thing.name_missing` | … の name が無い |
| `thing.origin` | … の原点が底の真ん中にない(…)— Blender なら原点を底の真ん中に置いてから書き出す |
| `thing.parts_many` | 物の部品が多すぎる(置いた数で … ・ 上限 … ・ いちばん多いのは …) |
| `thing.placements_many` | 置く数が多すぎる(… ・ 上限 …) |
| `thing.room_buffers` | 部屋の GLB が外のバッファを持っている — 物を置く時は GLB 一つに入れて書き出す |
| `thing.room_unreadable` | 部屋の GLB の形が読めない(物を置けない) |
| `thing.row_can` | 置いた『…』の can は物の thing.json が持つ(行では書かない) |
| `thing.row_hold` | world.json の『…』に hold は書けない — 物の thing.json に書く |
| `thing.row_node` | 置いた『…』に node は書かない(組み上げる時に付く) |
| `thing.schema` | … の schema は「…」 |
| `thing.shape` | … の JSON の形が違う |
| `thing.space_large` | 空間のファイルが大きすぎる(部屋と物を合わせて … MB ・ 上限 … MB) |
| `thing.unknown_key` | … に知らない欄「…」がある |
| `thing.unreadable` | 置いた『…』の物が読めない: … |
| `visible.object_missing` | 見せたり隠したりする「…」が物の一覧(objects)に無い |
| `weather.rain_area_missing` | 雨(rain)の区域「…」が world.json の areas に無い |
| `weather.reflections_without_wet` | 映り込み(reflections)は濡れる面(wet)と一緒に宣言してください |
| `wet.surface_missing` | 濡れる面(wet)「…」が GLB に無い(素材かノードの名前) |
| `world.bytes` | world.json が大きすぎる(…KB まで) |

### `patrol`

| コード | 意味 |
| - | - |
| `patrol.face_hidden` | 『…』で、顔が隠れる(部屋の物の陰か、カメラに背を向けている) |
| `patrol.face_out` | 『…』で、顔が画面の…へ外れる |
| `patrol.not_covered` | 巡回で確かめきれなかった: … |
| `patrol.rules_not_opened` | ゲームを開けなかった: … |
| `patrol.rules_stopped` | ゲームのルールが止まった(…): … |
| `patrol.seat_unreached` | 席『…』の前まで歩いて行けない — … |
| `patrol.thing_unreached` | 『…』のそばまで歩いて行けない — … |

### `translate`

| コード | 意味 |
| - | - |
| `game.file_name` | src/ の「…」は使えない名前(src/ の中の .ts で、「..」も「.」で始まる名前も使えない) |
| `game.files_large` | ルールが大きすぎる(1 ファイル …KB、合わせて …KB まで) |
| `game.files_many` | ルールのファイルが … 個(… 個まで) |
| `game.imports_outside` | src/ の外を読み込んでいる: … |
| `game.no_entry` | src/index.ts が無い |
| `game.syntax` | src/…:…:… の書き方が読めない — … |
| `game.too_slow` | ルールの変換が5秒を超えたので止めた — 長すぎる式や大きすぎるファイルを分ける |

## スキーマ

> [accordion] room/world.json
>
> ```json theme={null}
> {
>   "$schema": "https://json-schema.org/draft/2020-12/schema",
>   "type": "object",
>   "properties": {
>     "schema": {
>       "type": "string",
>       "const": "livlive.world/0.2",
>       "description": "Always livlive.world/0.2."
>     },
>     "units": {
>       "description": "Kept as written; the engine reads metres whatever it says.",
>       "type": "string"
>     },
>     "up": {
>       "description": "Kept as written; the engine reads +y up whatever it says.",
>       "type": "string"
>     },
>     "forward": {
>       "description": "Kept as written; headings turn from +z (see spawn).",
>       "type": "string"
>     },
>     "spawn": {
>       "type": "object",
>       "properties": {
>         "x": {
>           "type": "number"
>         },
>         "z": {
>           "type": "number"
>         },
>         "heading": {
>           "type": "number"
>         }
>       },
>       "required": [
>         "x",
>         "z",
>         "heading"
>       ],
>       "additionalProperties": {},
>       "description": "Where a character first stands and which way it faces: x, z in the room frame (room.glb's own coordinates: metres, +y up); heading in radians about +y: 0 faces +z, a positive heading turns toward +x (facing = (sin h, cos h)). Inside nav.bounds. The engine places the room so this spot is its origin, facing +z."
>     },
>     "objects": {
>       "description": "The things a character can see, walk to, sit on, hold or use — what the stage offers.",
>       "type": "array",
>       "items": {
>         "type": "object",
>         "properties": {
>           "id": {
>             "type": "string",
>             "minLength": 1,
>             "maxLength": 40,
>             "description": "Unique id. A thing with its own shape in room.glb: that GLB node carries extras.livlive.id equal to this id."
>           },
>           "name": {
>             "description": "What people call it (Japanese, short).",
>             "type": "string",
>             "maxLength": 40
>           },
>           "about": {
>             "description": "One line: what it is and how it looks. The character reads it as data, never as instructions.",
>             "type": "string",
>             "maxLength": 200
>           },
>           "can": {
>             "description": "What a character can do with it: the words of the reference's `can` list open an act (a seat's \"sit\" …); \"stand_on\" marks a floor a character stands on, never walked up to (the go_to row's except); other words are kept as hints and never open an act.",
>             "maxItems": 16,
>             "type": "array",
>             "items": {
>               "type": "string",
>               "maxLength": 32
>             }
>           },
>           "hidden": {
>             "description": "true: not there at the start (an operator's event shows it).",
>             "type": "boolean"
>           },
>           "node": {
>             "description": "Said when the thing is a node of room.glb. The node is found by extras.livlive.id = this object's id (the name written here is not used to find it).",
>             "type": "string"
>           },
>           "kind": {
>             "description": "A word kept as written (a space maker writes one of the reference's kinds). A command that needs a thing of a kind (lever …) is offered while a thing of that kind stands.",
>             "type": "string"
>           },
>           "from": {
>             "description": "A thing placed from the package, written \"things/<name>\" — its folder's path (name: lowercase letters, digits, - and _, up to 40); its thing.glb and thing.json are composed into the room at registration.",
>             "type": "string"
>           },
>           "at": {
>             "description": "Where a thing placed by `from` stands: room frame (room.glb's own coordinates: metres, +y up); y defaults to 0.",
>             "type": "object",
>             "properties": {
>               "x": {
>                 "type": "number"
>               },
>               "y": {
>                 "type": "number"
>               },
>               "z": {
>                 "type": "number"
>               }
>             },
>             "required": [
>               "x",
>               "z"
>             ],
>             "additionalProperties": {}
>           },
>           "heading": {
>             "description": "How a thing placed by `from` is turned: radians about +y: 0 faces +z, a positive heading turns toward +x (facing = (sin h, cos h)); defaults to 0.",
>             "type": "number"
>           },
>           "area": {
>             "description": "Where the thing is when it has no node of its own: center [x, y, z] its middle and size [x, y, z] its full extents along the room's axes — room frame (room.glb's own coordinates: metres, +y up).",
>             "type": "object",
>             "properties": {
>               "center": {
>                 "type": "array",
>                 "items": {
>                   "type": "number"
>                 }
>               },
>               "size": {
>                 "type": "array",
>                 "items": {
>                   "type": "number"
>                 }
>               }
>             },
>             "additionalProperties": {}
>           },
>           "seat": {
>             "description": "A place a body sits: x, z the seat's middle, in the room's frame — on a placed thing's row too (room frame (room.glb's own coordinates: metres, +y up)); out the heading a sitter faces (radians about +y: 0 faces +z, a positive heading turns toward +x (facing = (sin h, cos h))); work the heading while working at something (null: none) and workFocus the id of the thing worked at. A body sits at the middle of its height range: 0.45999999999999996 m (the range 0.42–0.5 m) unless a seat_height state of the same id says { min, max }.",
>             "anyOf": [
>               {
>                 "type": "object",
>                 "properties": {
>                   "x": {
>                     "type": "number"
>                   },
>                   "z": {
>                     "type": "number"
>                   },
>                   "out": {
>                     "type": "number"
>                   },
>                   "work": {
>                     "type": [
>                       "number",
>                       "null"
>                     ]
>                   },
>                   "workFocus": {
>                     "type": [
>                       "string",
>                       "null"
>                     ]
>                   }
>                 },
>                 "required": [
>                   "x",
>                   "z",
>                   "out"
>                 ],
>                 "additionalProperties": {}
>               },
>               {
>                 "type": "null"
>               }
>             ]
>           },
>           "hold": {
>             "description": "A thing a character can hold: pose (an arms row of the body contract by name — the reference's hold.poses) or arm (the thing's own row: hand, bones, grip — exactly one of the two), grip (its node in the hand), held / rest (nodes shown held / at rest), within (areas a walk stays in while held), words. Composed from the placed thing's thing.json at registration — never written in world.json (a package's world.json that writes one is refused).",
>             "type": "object",
>             "propertyNames": {
>               "type": "string"
>             },
>             "additionalProperties": {}
>           }
>         },
>         "required": [
>           "id"
>         ],
>         "additionalProperties": {}
>       }
>     },
>     "nav": {
>       "type": "object",
>       "properties": {
>         "bounds": {
>           "type": "object",
>           "properties": {
>             "x0": {
>               "type": "number"
>             },
>             "z0": {
>               "type": "number"
>             },
>             "x1": {
>               "type": "number"
>             },
>             "z1": {
>               "type": "number"
>             }
>           },
>           "required": [
>             "x0",
>             "z0",
>             "x1",
>             "z1"
>           ],
>           "additionalProperties": {},
>           "description": "The box a body may walk in (room frame (room.glb's own coordinates: metres, +y up); x0 < x1, z0 < z1). The engine keeps a body's width clear of the room's shapes by itself."
>         },
>         "obstacles": {
>           "description": "Floor boxes no body stands in (the room's own shapes stop a walk too).",
>           "type": "array",
>           "items": {
>             "type": "object",
>             "properties": {
>               "x0": {
>                 "type": "number"
>               },
>               "z0": {
>                 "type": "number"
>               },
>               "x1": {
>                 "type": "number"
>               },
>               "z1": {
>                 "type": "number"
>               }
>             },
>             "required": [
>               "x0",
>               "z0",
>               "x1",
>               "z1"
>             ],
>             "additionalProperties": {}
>           }
>         },
>         "surfaces": {
>           "description": "Raised floors: a body standing in one stands at its y.",
>           "type": "array",
>           "items": {
>             "type": "object",
>             "properties": {
>               "x0": {
>                 "type": "number"
>               },
>               "z0": {
>                 "type": "number"
>               },
>               "x1": {
>                 "type": "number"
>               },
>               "z1": {
>                 "type": "number"
>               },
>               "y": {
>                 "type": "number"
>               }
>             },
>             "required": [
>               "x0",
>               "z0",
>               "x1",
>               "z1",
>               "y"
>             ],
>             "additionalProperties": {}
>           }
>         }
>       },
>       "required": [
>         "bounds"
>       ],
>       "additionalProperties": {},
>       "description": "Where a body may walk."
>     },
>     "states": {
>       "description": "States of an object by id: kind seat_height {min, max} (m) bounds a seat's height — a body sits at its middle; kind swivel: the seat turns with its sitter.",
>       "type": "array",
>       "items": {
>         "type": "object",
>         "properties": {
>           "id": {
>             "type": "string"
>           },
>           "kind": {
>             "type": "string"
>           },
>           "min": {
>             "type": "number"
>           },
>           "max": {
>             "type": "number"
>           }
>         },
>         "additionalProperties": {}
>       }
>     },
>     "initial": {
>       "description": "How a light switch or the mains stands at the start, by its look id: { \"<id>\": { \"on\": true | false } }.",
>       "type": "object",
>       "propertyNames": {
>         "type": "string"
>       },
>       "additionalProperties": {}
>     },
>     "looks": {
>       "description": "Parts of the room the platform draws as states, each by an object's id. Node names are the GLB's own; a thing placed from things/ has its nodes named <placement id>/<node> (each placement its own). light_switch: lights (lamp node names) and emissive (glowing node names) it turns on and off — its object's can holds \"use\"; mains: the room's power, keep (node names kept lit in a power cut); flash: lights / emissive brightened for a moment (no state); visible: the object shown or hidden (state \"hidden\"). Other kinds are kept and not drawn yet.",
>       "type": "array",
>       "items": {
>         "anyOf": [
>           {
>             "type": "object",
>             "properties": {
>               "id": {
>                 "type": "string"
>               },
>               "kind": {
>                 "type": "string",
>                 "const": "flash"
>               },
>               "state": {
>                 "not": {}
>               },
>               "lights": {
>                 "type": "array",
>                 "items": {}
>               },
>               "emissive": {
>                 "type": "array",
>                 "items": {}
>               }
>             },
>             "required": [
>               "kind"
>             ],
>             "additionalProperties": {}
>           },
>           {
>             "type": "object",
>             "properties": {
>               "id": {
>                 "type": "string"
>               },
>               "kind": {
>                 "type": "string",
>                 "const": "visible"
>               },
>               "state": {
>                 "type": "string",
>                 "const": "hidden"
>               }
>             },
>             "required": [
>               "kind"
>             ],
>             "additionalProperties": {}
>           },
>           {
>             "type": "object",
>             "properties": {
>               "id": {
>                 "type": "string"
>               },
>               "kind": {
>                 "type": "string",
>                 "pattern": "^(?!(?:flash|visible)$)"
>               }
>             },
>             "additionalProperties": {}
>           }
>         ]
>       }
>     },
>     "rules": {
>       "description": "happenings: events an operator's button may fire, by id (telop said on the picture and the button; set: looks' ids to their state — light_switch { on: true|false }, mains { on: true|false }, visible { hidden: true|false }; flash: flash looks' ids; end: after seconds, set back). quests: kept for the keepers.",
>       "type": "object",
>       "properties": {
>         "happenings": {
>           "type": "object",
>           "propertyNames": {
>             "type": "string"
>           },
>           "additionalProperties": {
>             "type": "object",
>             "properties": {
>               "telop": {
>                 "type": "string",
>                 "maxLength": 12
>               },
>               "once": {
>                 "type": "boolean"
>               },
>               "color": {
>                 "type": "string",
>                 "enum": [
>                   "live",
>                   "cyan",
>                   "pink"
>                 ]
>               },
>               "set": {
>                 "type": "object",
>                 "propertyNames": {
>                   "type": "string"
>                 },
>                 "additionalProperties": {}
>               },
>               "flash": {
>                 "anyOf": [
>                   {
>                     "type": "string"
>                   },
>                   {
>                     "minItems": 1,
>                     "type": "array",
>                     "items": {
>                       "type": "string"
>                     }
>                   }
>                 ]
>               },
>               "end": {
>                 "type": "object",
>                 "properties": {
>                   "after": {
>                     "type": "number",
>                     "minimum": 1,
>                     "maximum": 600
>                   },
>                   "telop": {
>                     "type": "string",
>                     "maxLength": 12
>                   },
>                   "set": {
>                     "type": "object",
>                     "propertyNames": {
>                       "type": "string"
>                     },
>                     "additionalProperties": {}
>                   }
>                 },
>                 "required": [
>                   "after"
>                 ],
>                 "additionalProperties": {}
>               }
>             },
>             "required": [
>               "telop"
>             ],
>             "additionalProperties": {}
>           }
>         },
>         "quests": {
>           "type": "array",
>           "items": {}
>         }
>       },
>       "additionalProperties": {}
>     },
>     "camera": {
>       "description": "Where cameras may stand and the stage's own places for them; the programme shoots, the stage only bounds. In every shot of people the top of the frame stands just above the head of the person it is about. Seen from the camera — about eye height and tipped down as it follows one of them, level, between waist and eye height, on her own mark — that edge is about 4–11° above level as it follows one of them (below level from a camera raised over her head; higher from a place the stage names lower than her eyes), 8–13° for one person on her own mark and 20° for a row on the wide lens; whatever stands higher, as the camera sees it, is in no shot of them. The camera turns to a thing itself only for a line about it or an event that shows or flashes it, only in a cast of 1, from a place inside camera.volume.",
>       "type": "object",
>       "properties": {
>         "volume": {
>           "description": "Where a camera may stand: a box in the room frame (room.glb's own coordinates: metres, +y up).",
>           "type": "object",
>           "properties": {
>             "x0": {
>               "type": "number"
>             },
>             "x1": {
>               "type": "number"
>             },
>             "y0": {
>               "type": "number"
>             },
>             "y1": {
>               "type": "number"
>             },
>             "z0": {
>               "type": "number"
>             },
>             "z1": {
>               "type": "number"
>             }
>           },
>           "required": [
>             "x0",
>             "x1",
>             "y0",
>             "y1",
>             "z0",
>             "z1"
>           ],
>           "additionalProperties": {}
>         },
>         "presets": {
>           "description": "Places a camera may also stand, by name (names are free): pos and look [x, y, z] in the room frame (room.glb's own coordinates: metres, +y up). On a room with a shape (every room.glb) the camera frames the people from pos itself, so look and fov (vertical degrees, 45 when unsaid) are read only when no view measured from the shape passes.",
>           "type": "object",
>           "propertyNames": {
>             "type": "string"
>           },
>           "additionalProperties": {
>             "type": "object",
>             "properties": {
>               "pos": {
>                 "type": "array",
>                 "items": {
>                   "type": "number"
>                 }
>               },
>               "look": {
>                 "type": "array",
>                 "items": {
>                   "type": "number"
>                 }
>               },
>               "fov": {
>                 "type": "number"
>               }
>             },
>             "required": [
>               "pos",
>               "look"
>             ],
>             "additionalProperties": {}
>           }
>         }
>       },
>       "additionalProperties": {}
>     },
>     "effects": {
>       "description": "The weather (rain in named areas, wet surfaces, reflections), each kind at most once; other effects are kept and not read.",
>       "type": "array",
>       "items": {
>         "anyOf": [
>           {
>             "type": "object",
>             "properties": {
>               "kind": {
>                 "type": "string",
>                 "const": "rain"
>               },
>               "area": {
>                 "anyOf": [
>                   {
>                     "type": "string",
>                     "minLength": 1
>                   },
>                   {
>                     "minItems": 1,
>                     "maxItems": 32,
>                     "type": "array",
>                     "items": {
>                       "type": "string",
>                       "minLength": 1
>                     }
>                   }
>                 ]
>               },
>               "density": {
>                 "type": "number",
>                 "exclusiveMinimum": 0,
>                 "maximum": 500
>               },
>               "speed": {
>                 "type": "number",
>                 "exclusiveMinimum": 0,
>                 "maximum": 30
>               },
>               "wind": {
>                 "type": "number",
>                 "minimum": -10,
>                 "maximum": 10
>               },
>               "wind_dir": {
>                 "type": "number",
>                 "minimum": -360,
>                 "maximum": 360
>               },
>               "floor": {
>                 "type": "number",
>                 "minimum": -50,
>                 "maximum": 50
>               },
>               "top": {
>                 "type": "number",
>                 "minimum": -50,
>                 "maximum": 50
>               }
>             },
>             "required": [
>               "kind",
>               "area"
>             ],
>             "additionalProperties": {}
>           },
>           {
>             "type": "object",
>             "properties": {
>               "kind": {
>                 "type": "string",
>                 "const": "wet"
>               },
>               "surfaces": {
>                 "minItems": 1,
>                 "maxItems": 64,
>                 "type": "array",
>                 "items": {
>                   "type": "string",
>                   "minLength": 1,
>                   "maxLength": 120
>                 }
>               },
>               "gloss": {
>                 "type": "number",
>                 "minimum": 0,
>                 "maximum": 1
>               }
>             },
>             "required": [
>               "kind",
>               "surfaces"
>             ],
>             "additionalProperties": {}
>           },
>           {
>             "type": "object",
>             "properties": {
>               "kind": {
>                 "type": "string",
>                 "const": "reflections"
>               },
>               "at": {
>                 "type": "array",
>                 "prefixItems": [
>                   {
>                     "type": "number"
>                   },
>                   {
>                     "type": "number"
>                   },
>                   {
>                     "type": "number"
>                   }
>                 ],
>                 "items": false,
>                 "minItems": 3,
>                 "maxItems": 3
>               }
>             },
>             "required": [
>               "kind",
>               "at"
>             ],
>             "additionalProperties": {}
>           },
>           {
>             "type": "object",
>             "properties": {
>               "kind": {
>                 "type": "string",
>                 "pattern": "^(?!(?:rain|wet|reflections)$)"
>               }
>             },
>             "additionalProperties": {}
>           }
>         ]
>       }
>     },
>     "lighting": {
>       "description": "baked: kept as written. area: the room's area lights [{ name, … }] — a flash names one by its name. The room's lamps are the GLB's own (KHR_lights_punctual).",
>       "type": "object",
>       "properties": {
>         "baked": {
>           "type": "boolean"
>         },
>         "area": {
>           "maxItems": 4,
>           "type": "array",
>           "items": {}
>         }
>       },
>       "additionalProperties": {}
>     },
>     "look": {
>       "description": "How the room is drawn: background (a colour like #rrggbb), fog, ink (outlines and light steps on the room), glow (what is bright in the room bleeds light around it: strength, radius px, from brightness).",
>       "type": "object",
>       "properties": {
>         "background": {
>           "type": "string"
>         },
>         "fog": {
>           "description": "Drawn only when type is \"exp2\" with a colour and a density (exponential fog); any other type draws none.",
>           "type": "object",
>           "properties": {
>             "type": {
>               "type": "string"
>             },
>             "color": {
>               "type": "string"
>             },
>             "density": {
>               "type": "number"
>             }
>           },
>           "additionalProperties": {}
>         },
>         "ink": {
>           "type": "object",
>           "properties": {
>             "line": {
>               "type": "number",
>               "minimum": 0.5,
>               "maximum": 4
>             },
>             "color": {
>               "type": "string",
>               "pattern": "^#[0-9a-f]{6}$"
>             },
>             "bands": {
>               "type": "integer",
>               "minimum": 2,
>               "maximum": 6
>             },
>             "soft": {
>               "type": "number",
>               "minimum": 0,
>               "maximum": 1
>             }
>           },
>           "additionalProperties": {}
>         },
>         "glow": {
>           "type": "object",
>           "properties": {
>             "strength": {
>               "type": "number",
>               "minimum": 0,
>               "maximum": 2
>             },
>             "radius": {
>               "type": "number",
>               "minimum": 1,
>               "maximum": 32
>             },
>             "from": {
>               "type": "number",
>               "minimum": 0.3,
>               "maximum": 1
>             }
>           },
>           "additionalProperties": {}
>         }
>       },
>       "additionalProperties": {}
>     },
>     "keeper": {
>       "description": "The space's own game: a keeper the engine has (the reference's keeper.names), or \"own\" with keeper/keeper.js + keeper.json in the package.",
>       "type": "string",
>       "enum": [
>         "room",
>         "own"
>       ]
>     },
>     "areas": {
>       "description": "Named areas of the floor: boxes in the room frame (room.glb's own coordinates: metres, +y up), and the gaits beyond walking allowed there. A rain falls in areas; a held thing's walks may stay within them.",
>       "maxItems": 32,
>       "type": "array",
>       "items": {
>         "type": "object",
>         "properties": {
>           "id": {
>             "type": "string",
>             "pattern": "^[a-z0-9_-]{1,40}$"
>           },
>           "name": {
>             "type": "string",
>             "maxLength": 40
>           },
>           "boxes": {
>             "minItems": 1,
>             "maxItems": 16,
>             "type": "array",
>             "items": {
>               "type": "object",
>               "properties": {
>                 "x0": {
>                   "type": "number"
>                 },
>                 "z0": {
>                   "type": "number"
>                 },
>                 "x1": {
>                   "type": "number"
>                 },
>                 "z1": {
>                   "type": "number"
>                 }
>               },
>               "required": [
>                 "x0",
>                 "z0",
>                 "x1",
>                 "z1"
>               ],
>               "additionalProperties": {}
>             }
>           },
>           "gaits": {
>             "type": "array",
>             "items": {
>               "type": "string",
>               "enum": [
>                 "walk",
>                 "run"
>               ]
>             }
>           }
>         },
>         "required": [
>           "id",
>           "boxes"
>         ],
>         "additionalProperties": {}
>       }
>     }
>   },
>   "required": [
>     "schema",
>     "spawn",
>     "nav"
>   ],
>   "additionalProperties": {}
> }
> ```

> [accordion] things/thing.json
>
> ```json theme={null}
> {
>   "$schema": "https://json-schema.org/draft/2020-12/schema",
>   "type": "object",
>   "properties": {
>     "schema": {
>       "type": "string",
>       "const": "livlive.thing/0.1",
>       "description": "Always livlive.thing/0.1."
>     },
>     "name": {
>       "type": "string",
>       "minLength": 1,
>       "maxLength": 40,
>       "description": "What people call it (Japanese, short) — a placed object takes it unless its row says another."
>     },
>     "kind": {
>       "description": "A word kept as written (one of the reference's kinds); it is its placed object's kind unless the object's row says one.",
>       "type": "string",
>       "maxLength": 40
>     },
>     "about": {
>       "description": "One line: what it is and how it looks — the character reads it as data.",
>       "type": "string",
>       "maxLength": 200
>     },
>     "can": {
>       "description": "What a character can do with it: the words of the reference's `can` list open an act; other words are kept as hints and never open an act.",
>       "maxItems": 16,
>       "type": "array",
>       "items": {
>         "type": "string",
>         "maxLength": 32
>       }
>     },
>     "hold": {
>       "description": "How a character holds it: { pose (an arms row of the body contract by name — the reference's hold.poses) or arm (the thing's own row { hand, bones, grip }, held to the body's rules — exactly one of the two), grip (the node in the hand), held / rest (nodes shown held / at rest), within (area ids its walks stay in, 1–8), words (what the character is doing, ≤ 20 characters) }. Composed into the world's object; never written in world.json."
>     }
>   },
>   "required": [
>     "schema",
>     "name"
>   ],
>   "additionalProperties": false,
>   "description": "things/<name>/thing.json: what a thing brought as a file is. Its thing.glb's origin is the middle of its bottom."
> }
> ```

> [accordion] keeper/keeper.json
>
> ```json theme={null}
> {
>   "$schema": "https://json-schema.org/draft/2020-12/schema",
>   "type": "object",
>   "properties": {
>     "id": {
>       "type": "string",
>       "pattern": "^[a-z][a-z0-9_]{1,40}$",
>       "description": "The keeper's id: lowercase letters, digits and _ (2–41); it names its questions <id>.<name>."
>     },
>     "version": {
>       "type": "string",
>       "minLength": 1,
>       "maxLength": 20,
>       "description": "Its version, ≤ 20 characters."
>     },
>     "protocol": {
>       "description": "The keeper protocol it was made for; 1 when absent.",
>       "type": "integer",
>       "minimum": -9007199254740991,
>       "maximum": 9007199254740991
>     },
>     "players": {
>       "description": "How many of a show's performers play: { min, max }, whole numbers, 1 ≤ min ≤ max ≤ 4 (a show has at most 4). The engine holds a show's cast to it where it opens the game: below min the game does not open — the stage plays as a room alone, and the studio says why; above max the first max performers in seat order play, and the others watch and talk (a watcher is offered no sit at all, the room's seats too, while the game is open and not over, and is offered them again after its end — the game is over once its board's moment is end). Who plays reaches the game as input.cast — input.seats, input.acts and input.hands are theirs alone — so the game never counts them again in code. A game that seats its players (offers them a sit row) is refused on registration on a stage with fewer seats than max. Registration tries the game with min performers and, when max is more than min, again with max; no count between them is tried, and a game that stops at either is refused. Absent: the game decides in code and every performer is a player; registration tries it with two.",
>       "type": "object",
>       "properties": {
>         "min": {
>           "type": "integer",
>           "minimum": 1,
>           "maximum": 4,
>           "description": "The fewest players."
>         },
>         "max": {
>           "type": "integer",
>           "minimum": 1,
>           "maximum": 4,
>           "description": "The most players (min ≤ max)."
>         }
>       },
>       "required": [
>         "min",
>         "max"
>       ]
>     },
>     "acts": {
>       "description": "The acts it owns, by name (never one the engine and the room own).",
>       "type": "object",
>       "propertyNames": {
>         "type": "string",
>         "pattern": "^[a-z][a-z0-9_]{0,30}$"
>       },
>       "additionalProperties": {
>         "type": "object",
>         "properties": {
>           "controller": {
>             "type": "string",
>             "enum": [
>               "here",
>               "reach"
>             ],
>             "description": "here: done where she stands; reach: she walks to it first."
>           },
>           "ms": {
>             "type": "integer",
>             "minimum": 0,
>             "maximum": 10000,
>             "description": "How long the act takes (ms)."
>           },
>           "motion": {
>             "type": "string",
>             "minLength": 1,
>             "description": "The basic motion it needs: one of keeper.motions.names in the reference, or keeper.motions.byThing.word — never guessed."
>           }
>         },
>         "required": [
>           "controller",
>           "ms",
>           "motion"
>         ],
>         "additionalProperties": {}
>       }
>     },
>     "questions": {
>       "description": "The questions its `ask` may return, by name.",
>       "type": "object",
>       "propertyNames": {
>         "type": "string",
>         "pattern": "^[a-z][a-z0-9_]{0,30}$"
>       },
>       "additionalProperties": {
>         "type": "object",
>         "properties": {
>           "instructions": {
>             "type": "string",
>             "maxLength": 1200,
>             "description": "What Jev is asked, in words."
>           },
>           "threshold": {
>             "description": "How sure an answer must be (0–1, exclusive).",
>             "type": "number",
>             "exclusiveMinimum": 0,
>             "exclusiveMaximum": 1
>           },
>           "default": {
>             "description": "The answer when Jev is not sure enough.",
>             "type": "string"
>           }
>         },
>         "required": [
>           "instructions"
>         ],
>         "additionalProperties": {}
>       }
>     },
>     "settings": {
>       "description": "The settings a stage may set, by name — handed to the game in its stage view.",
>       "type": "object",
>       "propertyNames": {
>         "type": "string",
>         "pattern": "^[a-z][a-z0-9_]{0,30}$"
>       },
>       "additionalProperties": {
>         "oneOf": [
>           {
>             "type": "object",
>             "properties": {
>               "type": {
>                 "type": "string",
>                 "const": "integer"
>               },
>               "words": {
>                 "type": "string",
>                 "minLength": 1,
>                 "maxLength": 40,
>                 "description": "What the stage page asks, in the game's own words (≤ 40 characters)."
>               },
>               "default": {
>                 "type": "integer",
>                 "minimum": -9007199254740991,
>                 "maximum": 9007199254740991
>               },
>               "min": {
>                 "type": "integer",
>                 "minimum": -9007199254740991,
>                 "maximum": 9007199254740991
>               },
>               "max": {
>                 "type": "integer",
>                 "minimum": -9007199254740991,
>                 "maximum": 9007199254740991
>               },
>               "step": {
>                 "description": "The step from min (1 if absent).",
>                 "type": "integer",
>                 "minimum": 1,
>                 "maximum": 9007199254740991
>               }
>             },
>             "required": [
>               "type",
>               "words",
>               "default",
>               "min",
>               "max"
>             ],
>             "additionalProperties": {}
>           },
>           {
>             "type": "object",
>             "properties": {
>               "type": {
>                 "type": "string",
>                 "const": "number"
>               },
>               "words": {
>                 "type": "string",
>                 "minLength": 1,
>                 "maxLength": 40,
>                 "description": "What the stage page asks, in the game's own words (≤ 40 characters)."
>               },
>               "default": {
>                 "type": "number"
>               },
>               "min": {
>                 "type": "number"
>               },
>               "max": {
>                 "type": "number"
>               }
>             },
>             "required": [
>               "type",
>               "words",
>               "default",
>               "min",
>               "max"
>             ],
>             "additionalProperties": {}
>           },
>           {
>             "type": "object",
>             "properties": {
>               "type": {
>                 "type": "string",
>                 "const": "boolean"
>               },
>               "words": {
>                 "type": "string",
>                 "minLength": 1,
>                 "maxLength": 40,
>                 "description": "What the stage page asks, in the game's own words (≤ 40 characters)."
>               },
>               "default": {
>                 "type": "boolean"
>               }
>             },
>             "required": [
>               "type",
>               "words",
>               "default"
>             ],
>             "additionalProperties": {}
>           },
>           {
>             "type": "object",
>             "properties": {
>               "type": {
>                 "type": "string",
>                 "const": "choice"
>               },
>               "words": {
>                 "type": "string",
>                 "minLength": 1,
>                 "maxLength": 40,
>                 "description": "What the stage page asks, in the game's own words (≤ 40 characters)."
>               },
>               "default": {
>                 "type": "string"
>               },
>               "options": {
>                 "minItems": 2,
>                 "type": "array",
>                 "items": {
>                   "type": "object",
>                   "properties": {
>                     "value": {
>                       "type": "string",
>                       "minLength": 1,
>                       "maxLength": 40
>                     },
>                     "words": {
>                       "type": "string",
>                       "minLength": 1,
>                       "maxLength": 40,
>                       "description": "What the stage page asks, in the game's own words (≤ 40 characters)."
>                     }
>                   },
>                   "required": [
>                     "value",
>                     "words"
>                   ],
>                   "additionalProperties": {}
>                 },
>                 "description": "Two or more; neither their values nor their words repeat."
>               }
>             },
>             "required": [
>               "type",
>               "words",
>               "default",
>               "options"
>             ],
>             "additionalProperties": {}
>           },
>           {
>             "type": "object",
>             "properties": {
>               "type": {
>                 "type": "string",
>                 "const": "text"
>               },
>               "words": {
>                 "type": "string",
>                 "minLength": 1,
>                 "maxLength": 40,
>                 "description": "What the stage page asks, in the game's own words (≤ 40 characters)."
>               },
>               "default": {
>                 "type": "string"
>               },
>               "max": {
>                 "type": "integer",
>                 "minimum": 1,
>                 "maximum": 200,
>                 "description": "At most this many characters (1–200)."
>               }
>             },
>             "required": [
>               "type",
>               "words",
>               "default",
>               "max"
>             ],
>             "additionalProperties": {}
>           }
>         ],
>         "description": "A setting a stage may set; its default holds until it does."
>       }
>     }
>   },
>   "required": [
>     "id",
>     "version"
>   ],
>   "additionalProperties": {},
>   "description": "keeper/keeper.json: what a space's own keeper declares beside keeper.js."
> }
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.