摘要:
待機動畫放慢成 Codex 的速度、非 idle 狀態播 3 次後沉澱,並自動補正 spritesheet 裡整列 look 格子被畫小的缺陷。
根本原因:
1. idle 直接用合約上的幀時長無限循環,一輪只有 1.1 秒,看起來一直在動。Codex 的 codex-pet-assets 裡有一個放慢倍率 6,idle 實際是一輪 6.6 秒,其他狀態則是播 3 次後接上慢速 idle 並從那裡循環。
2. 內附的小念 spritesheet 第 10 列(看向 180 度到 337.5 度)整列被畫成 idle 的 78%,寬高同時縮小。游標移到人物身上或左邊時會切到那一列,人物就突然矮一截。第 9 列尾端只有高度變矮、寬度不變,那是低頭姿勢,不能一起改。
3. 追視參考點取在頭部高度(0.3),與 Codex 的方框中心不同,使得更多游標位置被判成「在下方」,更容易踩到第 10 列。
影響:
待機時一直晃;游標一靠近或移到左側,人物就明顯縮水又彈回來。
修法:
- 動畫改成序列模型(frames = [{row, col, ms}] + loopStart),對應 Codex 的 f(state):
IDLE_SLOWDOWN = 6、STATE_REPEATS = 3、播完 3 次後循環慢速 idle。
- 每個 hook 事件都重播一次動畫(pulse),對應 Codex 每次狀態更新都會重跑動畫效果;
否則狀態播完 3 次後就再也看不出 Claude Code 在忙。
- 載入寵物時量測 16 個 look 格子,以整列中位數判斷是否整列被縮小(門檻 0.9),
是的話以腳底為支點放大回 idle 身高;單格差異不動,避免把低頭姿勢拉直。
- 追視參考點改為人物方框中心、死區改為 1 px,與 Codex 相同。
- 拖曳用的 running-left / running-right 維持持續循環,不套用沉澱規則。
刻意不同於 Codex 的地方:
Codex 的追視會覆蓋所有狀態,本程式只在 idle 時追視。否則工作中的動畫會被靜態擺姿蓋掉,
寵物就失去反映 Claude Code 狀態的作用。
驗證:
- 抽出序列邏輯單獨執行:idle 一輪 6600 ms(幀長 1680/660/660/840/840/1920);
running / waiting / review 皆為 24 幀、第 18 幀起循環列 0;拖曳維持循環;一次性動作播完即止。
- 以 PIL 重現量測與繪製:小念第 9 列中位數比 0.995 不補正,第 10 列 0.783 補正倍率 1.2774,
補正後畫面身高 128.7-132.1 px(idle 為 130.4),且無任何一格超出畫布;
xiao-nian-realistic 兩列都是 0.99,判定不需補正而未受影響。
- 以 ELECTRON_RUN_AS_NODE 讀打包後 app.asar 內的 renderer.js 與 main.js,確認六項改動都在出貨的檔案裡。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
21 KiB
Claude Pet
Codex Pets 相容的 Claude Code 桌面寵物。
把 Codex /hatch 產出的寵物包原封不動拿來用,讓它站在桌面上,即時反映 Claude Code 正在做什麼:思考、等你授權、失敗、完成……還會盯著你的滑鼠游標看。
上圖由左至右:SessionStart 揮手、工作中、等待授權、完成時跳躍、檢視成果。氣泡會標出是哪個專案的 session。
目錄
特色
- 完整實作 Codex V2 pet contract — 8 欄 × 11 列、192×208 cell 的 spritesheet,9 個標準動作列 + 16 個看向方向,每一幀的時長都照 Codex 規格,動起來跟在 Codex app 裡一模一樣。
- 16 方向追視 — 游標在哪,她就看哪(000 = 正上方、順時針 22.5° 一格)。追視時是靜態擺姿、完全不動,與 Codex 相同;游標靜止 6 秒才改播慢速 idle。
- 自動修正圖檔缺陷 — Codex 的 hatch 產生器有時會把整列 look 格子畫得比 idle 小(內附的小念第 10 列就小了 22%,游標一往下移人物就縮水)。以整列中位數偵測、用腳底當支點放大回正確身高;單格的姿勢差異不動。Codex 本身沒有做這件事。
- 與 Codex 同尺寸 — 100% 就是 Codex 桌面寵物的大小(126 × 137),高度用 Codex 的
ceil(寬 × 208/192)算,兩邊並排看起來一樣大。 - 真正的桌面寵物 — 透明、無邊框、永遠置頂;透明區域點穿,只有壓在人物像素上滑鼠才會被吃掉,不擋你操作底下的視窗。
- 不搶焦點 — 視窗設為 non-focusable,點她不會讓終端機失焦。
- 拖曳 / 點擊 / 右鍵 — 拖曳時依方向播 running-left / running-right 並記住位置;點一下揮手;右鍵或系統匣開選單。
- 對話氣泡 — 完成、需要授權、有問題要問你、工具失敗、整理記憶中……一眼看出 Claude Code 在等什麼。
- 多 session — 同時開好幾個 Claude Code 時,以
waiting > running > review > idle的優先序顯示最需要你注意的那個。 - Codex 寵物自動出現 — 預設也掃描
~/.codex/pets,Codex hatch 出來的寵物直接在選單裡切換。 - Hook 零負擔 — hook 腳本約 100 ms 完成、寵物沒開也靜默 exit 0,不會拖慢或卡住 Claude Code。
需求
| 項目 | 說明 |
|---|---|
| 作業系統 | Windows 10 / 11(透明視窗、點穿、系統匣、開機啟動皆以 Windows 實作) |
| Node.js | 18 以上(開發時為 24.19) |
| Claude Code | 2.1 以上(使用 SessionStart、PermissionRequest、PostToolUseFailure、StopFailure、PreCompact 等事件) |
| 寵物包 | 一個 Codex V2 寵物包(pet.json + spritesheet.webp)。本專案內附 pets/xiao-nian(小念) |
快速開始
直接用打包好的(一般使用)
三種都不需要系統管理員權限,選一種即可(見打包成 exe):
| 方式 | 檔案 | 適合 |
|---|---|---|
| 免安裝資料夾(推薦) | Claude Pet-<版本>-win.zip |
解壓到任何地方,點兩下裡面的 Claude Pet.exe 就跑。啟動快、寵物放旁邊的 pets\、適合開機自動啟動 |
| 安裝檔 | Claude Pet-<版本>-setup.exe |
裝到 %LOCALAPPDATA%\Programs\Claude Pet,有開始選單與桌面捷徑 |
| 免安裝單檔 | Claude Pet-<版本>-portable.exe |
只想帶一個檔案走。代價是每次啟動都要重新解壓約 200 MB,開得比較慢 |
開起來之後用系統匣選單的 Claude Code hooks → 安裝 接上 Claude Code,然後重開一個新的 Claude Code session。
從原始碼跑(開發)
cd E:\Project\Test\AI\Claude\claude-pet
npm install
npm run hooks:install # 把 13 個 hook 合併進 ~/.claude/settings.json(會先備份到 ~/.claude/backups)
npm start # 啟動寵物
npm run autostart:install # (可選)開機自動啟動
注意
- 已開啟的 Claude Code session 不會重新讀 hooks,重開一個新 session 才會看到她反應。
- 若
npm install後node_modules\electron\dist\是空的,請看 疑難排解。
日常使用
| 操作 | 效果 |
|---|---|
| 左鍵點一下 | 揮手(若有非固定的氣泡,先關閉氣泡) |
| 左鍵拖曳 | 搬家;往左播 running-left、往右播 running-right;放開後位置寫入設定檔 |
| 右鍵 / 系統匣左鍵 | 開啟選單 |
| 滑鼠靠近 | 盯著游標看(可在選單關閉) |
選單功能
- 切換寵物 — 列出所有找到的寵物;v1(9 列)寵物會標示「無追視」
- 大小 — 50% / 75% / 100% / 125% / 150%,以腳底為基準縮放(100% = Codex 桌面寵物的大小)
- 跟著游標看、永遠置頂、開機自動啟動 — 勾選即生效
- 動作測試 — 不用真的跑 Claude Code 也能看每個動畫(idle / running / waiting / review / failed / jumping / waving)
- Claude Code hooks — 安裝 / 移除 hooks
- 回到預設位置 — 跑到螢幕外面時用
- 開啟設定檔 / 開啟事件紀錄
- 結束
行為對照表
| Claude Code hook | 條件 | 動作 | 氣泡 |
|---|---|---|---|
SessionStart |
source = startup |
waving 一次 → idle |
👋 嗨!(專案) |
UserPromptSubmit |
running |
(關閉舊氣泡) | |
PreToolUse |
一般工具 | running |
|
PreToolUse |
AskUserQuestion |
waiting |
❓ 有問題想問你 |
PreToolUse |
ExitPlanMode |
waiting |
📋 計畫等你確認 |
PostToolUse |
running |
||
PostToolUseFailure |
failed 一次 → running |
😵 〈工具〉失敗了 | |
PermissionRequest |
waiting |
🔐 需要你授權:〈工具〉 | |
Notification |
permission_prompt |
waiting |
🔐 需要你授權 |
Notification |
idle_prompt |
waiting |
💤 在等你回覆 |
Notification |
elicitation_dialog |
waiting |
❓ 有問題想問你 |
Notification |
其他 | (不變) | 💬 訊息內容 |
Stop |
stop_hook_active = false |
jumping 一次 → review 6 秒 → idle |
✅ 完成!(專案) |
StopFailure |
failed 兩次 → idle |
❌ 錯誤訊息 | |
SubagentStart / SubagentStop |
running |
||
PreCompact |
running |
🗜️ 整理記憶中… | |
SessionEnd |
移除該 session | 最後一個結束時 👋 掰掰 | |
| (無事件) | 游標移動 | 16 方向 look |
|
| (無事件) | 拖曳 | running-left / running-right |
規則:
- 待機時幾乎不動 — idle 每幀時長是合約值的 6 倍(一輪 6.6 秒,不是 1.1 秒),與 Codex 的
codex-pet-assets一致。 - 非 idle 狀態播 3 次就沉澱 成慢速 idle,也和 Codex 相同;但每收到一個 hook 事件就重播一次,所以工作中她會隨著每次工具呼叫動一下,安靜下來才靜下來。
- 一次性動作(waving / jumping / failed)播完自動回到該 session 的基礎狀態。
- 基礎狀態依 session 彙整:
waiting(3) > running(2) > review(1) > idle(0),取最高者顯示。 - 30 分鐘沒有任何事件的 session 會被視為結束而忽略(避免沒送
SessionEnd的終端機卡住狀態)。 waiting的氣泡是固定的,狀態離開waiting時自動消失。
寵物包格式(Codex V2)
與 Codex 完全相同,可直接互通。一個寵物是一個資料夾:
<pet-id>/
├── pet.json
└── spritesheet.webp (或 .png)
pet.json:
{
"id": "xiao-nian",
"displayName": "小念",
"description": "一句話描述",
"spriteVersionNumber": 2,
"spritesheetPath": "spritesheet.webp"
}
Spritesheet:1536 × 2288,8 欄 × 11 列,每格 192 × 208,透明背景。
| 列 | 狀態 | 使用欄 | 每幀時長(ms) |
|---|---|---|---|
| 0 | idle | 0–5 | 280, 110, 110, 140, 140, 320 |
| 1 | running-right | 0–7 | 120 ×7, 220 |
| 2 | running-left | 0–7 | 120 ×7, 220 |
| 3 | waving | 0–3 | 140 ×3, 280 |
| 4 | jumping | 0–4 | 140 ×4, 280 |
| 5 | failed | 0–7 | 140 ×7, 240 |
| 6 | waiting | 0–5 | 150 ×5, 260 |
| 7 | running(工作中,不是跑步) | 0–5 | 120 ×5, 220 |
| 8 | review | 0–5 | 150 ×5, 280 |
| 9 | look A | 0–7 | 000, 022.5, 045, 067.5, 090, 112.5, 135, 157.5 度 |
| 10 | look B | 0–7 | 180, 202.5, 225, 247.5, 270, 292.5, 315, 337.5 度 |
- look 列的 000 是正上方(12 點鐘),順時針。正面/中立不在 16 格裡,那是游標死區,退回 idle。
- 列 0 第 6 欄若有圖會被當作「中立正面」,拿來做系統匣圖示。
- 沒有
spriteVersionNumber: 2的舊版(8×9、1536×1872)寵物也能用,只是沒有追視。
規格來源:Codex 的
hatch-petskill(~/.codex/skills/hatch-pet/references/codex-pet-contract.md、animation-rows.md)。
新增 / 切換寵物
掃描順序:執行目錄的 pets\(portable 版是那顆 exe 旁邊的,其次才是內附的)→ ~/.codex/pets → 設定檔 petSources 裡的額外路徑。同一個 id 以先掃到的為準。
- 手動放入(最直接)— 把寵物資料夾丟到 exe 旁邊的
pets\<id>\,選單「切換寵物 → 重新掃描」就會出現。選單的「開啟寵物資料夾」會直接開這一個。 - 用 Codex hatch — 在 Codex 裡
/hatch,完成後寵物在%USERPROFILE%\.codex\pets\<id>\,本程式一律會掃這個資料夾。 - 其他位置 — 在設定檔
petSources加路徑。
切換後立即生效,不用重啟。
設定檔
位置:%USERPROFILE%\.claude-pet\config.json(第一次啟動後自動產生,選單「開啟設定檔」可直接開)。
| 欄位 | 預設 | 說明 |
|---|---|---|
activePetId |
"xiao-nian" |
目前使用的寵物 id |
petSources |
[] |
額外的寵物資料夾。兩個隱含來源永遠會被掃到且不寫進這裡:執行目錄的 pets/(exe 旁邊,開發時是專案資料夾,排最前面)與 ~/.codex/pets。不存在的路徑會在載入時自動剔除 |
scale |
1 |
縮放:0.5 / 0.75 / 1 / 1.25 / 1.5。1 表示 126 × 137,與 Codex 桌面寵物同大小 |
position |
null |
視窗左上角座標;null 為主螢幕右下角。若座標落在所有螢幕之外會自動拉回 |
alwaysOnTop |
true |
永遠置頂 |
followCursor |
true |
追視游標 |
port |
17333 |
接收 hook 事件的本機埠(改了之後 hook 端要設環境變數 CLAUDE_PET_PORT) |
事件紀錄:%USERPROFILE%\.claude-pet\events.log(超過 2 MB 自動清空)。
架構與檔案
Claude Code ──hook(stdin JSON)──▶ hook/claude-pet-hook.js ──POST /event──▶ 127.0.0.1:17333
│ Electron main(main.js)
│ 視窗 / 系統匣 / 游標輪詢 / 拖曳 / 設定
▼ IPC
renderer/renderer.js
狀態機 + 幀動畫 + 追視 + 氣泡 + alpha 點穿判定
| 檔案 | 職責 |
|---|---|
main.js |
Electron 主程序:透明置頂視窗、系統匣選單、HTTP 伺服器、游標輪詢(50 ms)、拖曳(60 fps)、設定讀寫、寵物掃描 |
preload.js |
以 contextBridge 暴露白名單 IPC 頻道給 renderer(sandbox 模式) |
renderer/renderer.js |
Codex V2 幀時序播放器、session 狀態彙整、一次性動作、看向方向計算(含遲滯防抖)、氣泡、滑鼠 alpha 判定 |
renderer/index.html、style.css |
版面與氣泡樣式(CSP 僅允許 self / data:) |
hook/claude-pet-hook.js |
Claude Code hook 端:讀 stdin → 擷取欄位 → POST;800 ms 逾時、永遠 exit 0 |
lib/hooks-installer.js |
安全地合併 / 移除 ~/.claude/settings.json 的 hooks(保留其他設定與其他 hooks,先備份) |
lib/autostart.js |
HKCU\Software\Microsoft\Windows\CurrentVersion\Run\ClaudePet 登錄值;開發時指向 electron.exe + 專案路徑,打包後直接指向那顆 exe |
lib/paths.js |
開發/安裝版/portable 三種情境的路徑解析(app.asar → app.asar.unpacked、是否打包、portable 的真實 exe 位置) |
scripts/*.js |
上述兩者的 CLI 包裝 |
pets/ |
內附寵物 |
docs/ |
README 用圖 |
build/icon.ico |
exe 與安裝檔的圖示,取自小念 spritesheet 第 0 列第 6 欄(中立正面)的頭肩方形裁切 |
設計重點:
- 點穿:視窗預設
setIgnoreMouseEvents(true, { forward: true }),renderer 在 mousemove 時讀 canvas 該點 alpha(或是否在氣泡上)來即時切換,所以透明處永遠點得到底下的視窗。 - 拖曳:由主程序用
screen.getCursorScreenPoint()每 16 ms 更新視窗位置,游標離開視窗也不會掉;方向由水平位移決定。 - 動畫時序完全照 Codex:
IDLE_SLOWDOWN = 6、STATE_REPEATS = 3、追視死區 1 px、追視參考點為人物方框中心——這幾個值都是從 Codex app 的resources/app.asar裡的codex-pet-assets讀出來的(_ = 6、[...n,...n,...n]、N = 1)。唯一刻意不同的是:Codex 的追視會覆蓋所有狀態,本程式只在 idle 時追視,否則工作中的動畫會被蓋掉、看不出 Claude Code 在忙。 - 顯示尺寸與 sprite 來源尺寸分開:
CELL_W/CELL_H(192 × 208)只用來從 spritesheet 取格子,畫到畫面上的是PET_W/PET_H(126 × 137,Codex 的 mascot 尺寸)。視窗寬度另有MIN_WIN_W = 240的下限,免得寵物變小後氣泡被截掉。 - Spritesheet 以 data URL 傳給 renderer,避免
file://跨來源污染 canvas 導致getImageData失敗。 - hook 合併規則:以指令中是否含
claude-pet-hook辨識自己的項目,重裝只替換自己的、不動別人的。
HTTP API
只監聽 127.0.0.1。
| 方法 | 路徑 | 說明 |
|---|---|---|
POST |
/event |
接收事件(JSON,≤ 64 KB),回 204 |
GET |
/state |
目前狀態:{"anim","base","sessions","pet","scale"} |
GET |
/health |
回 ok |
POST /event 的 payload(hook 腳本送出的格式):
{
"event": "Stop",
"sessionId": "uuid",
"cwd": "E:\\Project\\foo",
"toolName": null,
"notificationType": null,
"message": null,
"error": null,
"source": null,
"stopHookActive": false,
"ts": 1787278568523
}
手動觸發範例:
# 模擬需要授權
curl -X POST http://127.0.0.1:17333/event -H "content-type: application/json" `
-d '{"event":"Notification","sessionId":"demo","cwd":"D:/demo","notificationType":"permission_prompt"}'
# 模擬完成
curl -X POST http://127.0.0.1:17333/event -H "content-type: application/json" `
-d '{"event":"Stop","sessionId":"demo","cwd":"D:/demo"}'
# 查狀態
curl http://127.0.0.1:17333/state
也可以送 {"event":"__test","anim":"waiting"}(idle|running|waiting|review|failed|jumping|waving|clear)直接指定動畫,與選單「動作測試」相同。
打包成 exe
npm run dist # 三種都做
npm run dist:portable # 只做免安裝單檔
npm run pack # 只產 win-unpacked 資料夾,最快,改程式時驗證用
產物在 dist\:
| 檔案 | 大小 | 說明 |
|---|---|---|
Claude Pet-<版本>-win.zip |
~140 MB | 免安裝資料夾版。解壓後點兩下 Claude Pet.exe。啟動最快,寵物就放旁邊的 pets\ |
Claude Pet-<版本>-setup.exe |
~100 MB | NSIS 安裝檔。per-user、可改安裝路徑、建立桌面與開始選單捷徑 |
Claude Pet-<版本>-portable.exe |
~100 MB | 免安裝單檔,點兩下直接跑 |
win-unpacked\ |
~200 MB | 上面 zip 的未壓縮版,整個資料夾複製走也能用 |
第一次建置時 electron-builder 會從 GitHub 抓 NSIS 與相關工具到 %LOCALAPPDATA%\electron-builder\Cache,需要網路,之後走快取。
portable 單檔版的代價
NSIS 的 portable 外殼每次啟動都會把整包解壓到 %TEMP%\ClaudePet,程式結束後又整個刪掉(見 app-builder-lib/templates/nsis/portable.nsi 的 RMDir /r $INSTDIR)。所以:
- 每次開都要重新解壓約 200 MB,比資料夾版慢好幾秒。要開機自動啟動的話建議用資料夾版。
- 程式本體的位置是暫時的,因此 hook 腳本會另外複製一份到
%USERPROFILE%\.claude-pet\hook\,用那個穩定路徑去註冊。否則寵物沒開的時候 Claude Code 每次觸發 hook 都會找不到檔案而報錯。 - 使用者自己的寵物要放在那顆 exe 旁邊的
pets\(程式第一次跑會自己建),放進解壓目錄的會跟著被刪掉。同 id 時以 exe 旁邊那份為準。 - 程式被強制結束(工作管理員)時外殼來不及清理,
%TEMP%\ClaudePet會留下約 300 MB,可以手動刪。
打包後和原始碼跑不一樣的地方
都已經處理好,改程式時要留意:
| 項目 | 開發 | 安裝/資料夾版 | portable 單檔 |
|---|---|---|---|
| 內附寵物 | <專案>\pets |
<exe 旁>\pets |
%TEMP%\ClaudePet\pets |
| 使用者寵物 | 同上 | 同上 | <exe 旁>\pets |
| hook 腳本 | <專案>\hook\ |
resources\app.asar.unpacked\hook\ |
%USERPROFILE%\.claude-pet\hook\ |
| 開機自動啟動 | electron.exe + 專案路徑 |
那顆 exe | PORTABLE_EXECUTABLE_FILE |
判斷邏輯都在 lib/paths.js:isPackaged() 用 process.defaultApp、isPortable() 用 PORTABLE_EXECUTABLE_FILE、unpacked() 把 app.asar 換成 app.asar.unpacked。
pets/用extraFiles放到 exe 旁邊(不是extraResources,那會進resources\),使用者直接把寵物資料夾丟進去就會出現,不用碰 asar。hook/用asarUnpack,因為 Claude Code 是用node <路徑>執行它,而 node 讀不到 asar 裡的檔案。- hook 指令仍然需要
node在 PATH 裡。路徑含空白時會自動加引號。
換圖示就換掉 build/icon.ico(要含 256×256)。目前這顆是從 pets/xiao-nian/spritesheet.webp 第 0 列第 6 欄(中立正面)取頭肩方形裁切產生的。
疑難排解
Electron 裝完沒有 electron.exe
npm install 成功但 node_modules\electron\dist\ 是空的 → 你的 ~/.npmrc 可能有 allow-scripts=...(npm 11 的供應鏈防護,只放行清單上套件的 postinstall)。兩種解法:
node node_modules\electron\install.js # 手動跑一次下載
# 或把 electron 加進白名單
npm config set allow-scripts=@anthropic-ai/claude-code,electron --location=user
寵物對 Claude Code 沒反應
- 確認 hooks 已安裝:
npm run hooks:install,並重開 Claude Code session。 - 確認寵物在跑:
curl http://127.0.0.1:17333/health應回ok。 - 看
%USERPROFILE%\.claude-pet\events.log有沒有事件進來。有事件但沒動 → renderer 問題;沒事件 → hook 沒被呼叫。 - hook 指令是
node E:/.../claude-pet-hook.js,Claude Code 執行 hook 的環境要找得到node(PATH)。
啟動時跳出「無法監聽 127.0.0.1:17333」
已經有一隻在跑(本程式有單一實例鎖,通常不會發生),或埠被別的程式佔用。改設定檔 port,並在 Claude Code 的環境設 CLAUDE_PET_PORT 為同一個值。
她跑到螢幕外 / 換了螢幕配置看不到
選單「回到預設位置」,或刪掉設定檔的 position。啟動時若座標不在任何螢幕的工作區內會自動拉回。
專案搬家了
重新執行 npm run hooks:install 與 npm run autostart:install(兩者都以目前路徑重寫),寵物資料夾會自動跟著程式走。
移除
先在系統匣選單關掉 開機自動啟動、並用 Claude Code hooks → 移除 拆掉 hooks,然後結束程式。從原始碼跑的話也可以下指令:
npm run hooks:uninstall # 從 ~/.claude/settings.json 移除所有 Claude Pet hook(先備份)
npm run autostart:uninstall # 移除開機啟動登錄值
裝過安裝檔的話,到「設定 → 應用程式 → 已安裝的應用程式」移除 Claude Pet(解除安裝不會動到 %USERPROFILE%\.claude-pet\)。最後刪掉專案資料夾與 %USERPROFILE%\.claude-pet\ 即可。
致謝
- 寵物規格與動畫時序來自 OpenAI Codex 的
hatch-petskill(Codex V2 pet contract)。 - 內附寵物「小念」由 Codex
/hatch產生。
