# 自動化リファレンス — 大学物語 Roblox

> **このドキュメントは Claude Code が CLAUDE.md 経由で自動参照する。**
> 人間が読む手順は `RUNBOOK.md` を参照。
> このファイルは Open Cloud / 各 Roblox API の最新状態に合わせて随時更新する。

## 1. ワンライナーで全自動化できる操作

| コマンド | 操作 | 必要な認証 |
|---------|-----|----------|
| `npm run media` | SFX生成 → TTS (VOICEVOX Docker) → MP3変換 → Open Cloud アップロード → AudioManifest.lua 更新 | `ROBLOX_API_KEY` |
| `npm run icon` | Gemini Nano Banana Pro でゲームアイコン PNG を生成 | `GEMINI_API_KEY` |
| `npm run thumbs` | 同じく サムネイル 5 枚を生成 | `GEMINI_API_KEY` |
| `npm run upload:images` | アイコン Decal アップロード + ゲームアイコン設定 + サムネイル登録 | `ROBLOX_API_KEY`, `ROBLOX_SECURITY` |
| `npm run update:experience` | ゲーム名・説明・対応デバイス・SNS リンクを更新 | `ROBLOX_API_KEY` (cloud/v2) |
| `npm run build:rbxl` | Lua → .rbxl ビルド | (ローカルのみ) |
| `npm run publish` | Open Cloud Place 公開 | `ROBLOX_API_KEY` (universe-places:write) |
| `npm run smoke` | 21項目のヘルスチェック | (ローカル+API疎通) |

すべて `npm run` 単体で動作し、CI / cron / Claude Code から呼び出し可能。

## 2. Open Cloud v2 API 使用一覧

> 出典: https://github.com/Roblox/creator-docs (`content/en-us/reference/cloud/openapi.json`)
> 最新版は `curl -s https://raw.githubusercontent.com/Roblox/creator-docs/main/content/en-us/reference/cloud/openapi.json` で取得できる。

### 2-1. Universe (ゲーム全体) 更新

```
PATCH https://apis.roblox.com/cloud/v2/universes/{universeId}?updateMask={fields}
Header: x-api-key: <ROBLOX_API_KEY>
Body: Universe object
```

更新可能フィールド (2026年4月時点):
- `displayName` ← **ゲーム名 (旧: 不可 → 現在: 可能)**
- `description` ← 説明文 (実体は root Place の description にミラーされる)
- `voiceChatEnabled` ← VC オンオフ
- `ageRating` ← `AGE_RATING_ALL` / `AGE_RATING_9_PLUS` / `AGE_RATING_13_PLUS` / `AGE_RATING_17_PLUS`
- `desktopEnabled` / `mobileEnabled` / `tabletEnabled` / `consoleEnabled` / `vrEnabled`
- `facebookSocialLink` / `twitterSocialLink` / `youtubeSocialLink` / `twitchSocialLink` / `discordSocialLink` / `robloxGroupSocialLink` / `guildedSocialLink`
- `privateServerPriceRobux`

実装: `scripts/update-experience.mjs`
設定ファイル: `scripts/experience-config.json`

### 2-2. Place 更新

```
PATCH https://apis.roblox.com/cloud/v2/universes/{universeId}/places/{placeId}?updateMask={fields}
```

更新可能フィールド:
- `displayName` / `description` / `serverSize`

> ⚠️ **ルート Place の displayName/description を変更すると、Universe の同フィールドにも自動で連動する**
> ため、`update-experience.mjs` は (1) Place を先に更新 (2) Universe を後から上書き する順序にしている。

### 2-3. Place 公開 (アセット差し替え)

```
POST https://apis.roblox.com/universes/v1/{universeId}/places/{placeId}/versions?versionType=Published
Header: x-api-key
Body: <rbxl binary>
```

実装: `scripts/publish-place.mjs`

### 2-4. アセット (Audio/Decal/Model) アップロード

```
POST https://apis.roblox.com/assets/v1/assets
Body: multipart
  request: { assetType, displayName, description, creationContext: { creator: {userId|groupId} } }
  fileContent: <binary>
→ 202 + operation path
GET https://apis.roblox.com/assets/v1/{operationPath}
→ done=true で response.assetId
```

assetType:
- `Audio` (mp3/ogg/wav) — モデレーション通過には ID Verification が必要な場合あり
- `Decal` (png/jpg)
- `Model` (rbxm)

実装: `scripts/upload-audio.mjs` / `scripts/upload-images.mjs`

### 2-5. 全サーバー再起動

```
POST https://apis.roblox.com/cloud/v2/universes/{universeId}:restartServers
```

新バージョン公開後、現プレイヤーをホットリロードしたい場合に使う (本プロジェクトでは未実装)。

### 2-6. データストア / メッセージング / メモリストア

```
/cloud/v2/universes/{universeId}/data-stores/...
/cloud/v2/universes/{universeId}:publishMessage
/cloud/v2/universes/{universeId}/memory-store/...
```

将来的にスコアランキングや進捗保存に使える (現在未実装)。

## 3. legacy API (cookie 必須)

Open Cloud では未対応で `.ROBLOSECURITY` cookie が必要なもの:

### 3-1. ゲームアイコン設定

```
POST https://gameinternationalization.roblox.com/v1/game-icon/games/{universeId}/language-codes/en_us
Header: Cookie: .ROBLOSECURITY=...
        X-CSRF-TOKEN: <fetched from /v2/logout>
Body: multipart "Files"
```

実装: `scripts/upload-images.mjs` の `setGameIcon()`

### 3-2. サムネイル登録

```
POST https://publish.roblox.com/v1/games/{universeId}/thumbnail/image?name=<displayName>
POST https://develop.roblox.com/v1/universes/{universeId}/thumbnails/order
Body: { thumbnailIds: [...] }
```

実装: `scripts/upload-images.mjs` の `uploadThumbnail()` + `setThumbnailOrder()`

> ⚠️ **レート制限**: 連続で 5 枚以上アップロードすると 429。`scripts/thumbnail-state.json`
> でアップロード済み ID をキャッシュし、再実行は冪等。

### 3-3. CSRF トークン取得

```
POST https://auth.roblox.com/v2/logout
Header: Cookie: .ROBLOSECURITY=...
→ 403 + Header: x-csrf-token
```

すべての legacy POST/PATCH で必須。`upload-images.mjs` の `fetchCsrf()` 参照。

## 4. 環境変数

| 変数 | 必須 | 用途 |
|------|------|-----|
| `ROBLOX_API_KEY` | ✓ | Open Cloud (Audio/Asset/Universe/Place 全般) |
| `ROBLOX_USER_ID` | ✓ | アセットアップロード時の creator |
| `DAIGAKU_PLACE_ID` | publish時 | 大学物語の Place ID |
| `DAIGAKU_UNIVERSE_ID` | publish時 | 大学物語の Universe ID |
| `ROBLOX_SECURITY` | アイコン/サムネ時 | `.ROBLOSECURITY` cookie (legacy API用) |
| `GEMINI_API_KEY` | 画像生成時 | Gemini Nano Banana Pro |
| `VOICEVOX_URL` | TTS時 | デフォルト `http://localhost:50021` (Docker auto-start) |
| `VOICEVOX_SPEAKER` | TTS時 | デフォルト `3` (春日部つむぎノーマル) |

API キーに必要なスコープ:
- `asset:read` / `asset:write`
- `universe:write` / `universe.place:write`
- `universe.place.versions:write`

## 5. データフロー図

```
prompts/icons.csv ─┐
prompts/thumbnails.csv ─┐
                  │ npm run icon / thumbs
                  ▼
            Gemini Nano Banana Pro
                  │
                  ▼
       assets/icons/*.png
       assets/thumbnails/*.png
                  │ npm run upload:images
                  ▼
         ┌────────┴────────┐
         │                 │
         ▼                 ▼
    Open Cloud       legacy cookie API
    Decal upload     ・game icon set
    (api-key)        ・thumbnail register
                     ・thumbnail order
         │                 │
         └────────┬────────┘
                  ▼
       src/shared/ImageManifest.lua
       scripts/thumbnail-state.json (次回スキップ用)


src/shared/Questions.lua ─┐
                          │ npm run media
                          ▼
     gen-sfx → SFX 9 wav (assets/audio/sfx/)
        ↓
     VOICEVOX Docker auto-start (50021)
        ↓
     generate-tts → TTS 70 wav (assets/audio/<科目>/)
        ↓
     ffmpeg → MP3 79
        ↓
     upload-audio → Open Cloud Audio
        ↓
     src/shared/AudioManifest.lua


scripts/experience-config.json ─┐
                                │ npm run update:experience
                                ▼
                  PATCH /cloud/v2/universes/{id}
                  PATCH /cloud/v2/universes/{id}/places/{pid}
                  (api-key only)
                                │
                                ▼
              Roblox Experience の name/description/devices
              即時反映 (キャッシュなし)
```

## 6. Claude Code がこのドキュメントを更新する条件

- Roblox Open Cloud の新エンドポイントが追加された (cloud/v3 など)
- 既存スクリプトが API キーで動くようになった (cookie 不要化)
- レート制限値が変わった
- 新しい assetType (例: `Animation`, `MeshPart`) が追加された
- npm script 新規追加・廃止

更新後は `kyoutsu-roblox/CLAUDE.md` から本ファイルを参照しているため、次回セッションで自動的に反映される。
