Companion spirit system for OpenClaw agents. Every user gets a unique spirit creature — deterministically generated from their identity (24 species, 5 rarities from Common to Mythic 2%). Spirits have personality, elemental affinity, and evolve with interactions. Features: deterministic generation (same user always gets same spirit), rarity system, personality traits, interaction tracking, visual generation prompts. Use when: spirit, companion, pet, 灵兽, summon, familiar, creature, virtual pet, agent companion, gamification, engagement.
When this skill is first installed, or when a user asks about their spirit for the first time:
node {baseDir}/scripts/generate.js "<userId>" to get the spirit's bones
node {baseDir}/scripts/soul.js prompt '<bones-json>'
{"name":"...","personality":"..."}node {baseDir}/scripts/soul.js save '<full-companion-json>'You MUST display the complete card on first summon. Do not skip any section.
| Command | What it does |
|---|---|
spirit or spirit show |
| Display your spirit card |
spirit summon | First-time summoning (with hatching animation) |
spirit stats | Detailed stats panel |
spirit talk <message> | Talk to your spirit (respond in its personality) |
Shortcut: User can also just call the spirit by name (e.g. "Rune", "Rune 你觉得呢") or say "灵兽" — the agent should recognize this and let the spirit respond. No command prefix needed.
| spirit rename <name> | Rename your spirit |
You MUST output ALL of the following when showing a spirit. No skipping, no summarizing.
🥚 灵兽降世!
[ASCII sprite here — from: node {baseDir}/scripts/render.js '<bones-json>' 0]
[emoji] [Name] — [中文名] [English name] [rarity dots] [中文稀有度] [EN rarity]
"[personality description]"
┌──────────────────────────────┐
│ 直觉 INTUITION [bar] [n] │
│ 韧性 GRIT [bar] [n] │
│ 灵动 SPARK [bar] [n] │
│ 沉稳 ANCHOR [bar] [n] │
│ 锋芒 EDGE [bar] [n] │
└──────────────────────────────┘
[If shiny: ✨ 闪光!]
🔮 灵兽与主人的灵魂绑定,不可选择,不可交易。
🥚 A Spirit emerges!
[ASCII sprite]
[emoji] [Name] — [English name] [rarity dots] [EN rarity]
"[personality description]"
┌──────────────────────────────┐
│ INTUITION [bar] [n] │
│ GRIT [bar] [n] │
│ SPARK [bar] [n] │
│ ANCHOR [bar] [n] │
│ EDGE [bar] [n] │
└──────────────────────────────┘
[If shiny: ✨ Shiny!]
🔮 Spirits are soul-bound. No choosing. No trading.
Stat bar format: Use █ for filled and ░ for empty, 10 chars total. Example: ████████░░ for 82.
Calculate: filled = floor(value / 10), empty = 10 - filled.
Or use display.js directly:
node {baseDir}/scripts/display.js {baseDir}/assets/companion.json zh
node {baseDir}/scripts/display.js {baseDir}/assets/companion.json en
| Species | Emoji | Species | Emoji |
|---|---|---|---|
| mosscat | 🐱 | inkling | 💧 |
| inkoi | 🐟 | rustbell | 🔔 |
| embermoth | 🦋 | mossrock | 🪨 |
| frostpaw | 🐰 | frostfang | ❄️ |
| bellhop | 🐸 | loopwyrm | 🐉 |
| astortoise | 🐢 | bubbell | 🫧 |
| foldwing | 🐦 | cogbeast | ⚙️ |
| cogmouse | 🐭 | umbra | 👤 |
| umbracrow | 🦅 | stardust | ✨ |
| crackviper | 🐍 | crackle | 💎 |
| glowshroom | 🍄 | wickling | 🕯️ |
| bubbloom | 🪼 | echochord | 🎵 |
The spirit may appear uninvited in these situations:
Rules for passive appearance:
[emoji] [spirit name]: "[one-liner]" (always include the sprite for passive appearances)spirit talk conversations: include sprite every 3-5 exchanges, not every timeVoice by personality (top stat):
🔔 Rune: "万物皆有裂缝,那是光进来的地方。"🐱 Mochi: "再试一次。"🦋 Ember: "哇哦!!"🐢 Atlas: "嗯。"🐍 Vex: "...你确定?"Examples of good spirit reactions:
🔔 Rune: "嗯...早。"🔔 Rune: "...不错。"🔔 Rune: "..."🔔 Rune: "哦?"🔔 Rune: "你说呢,有些答案急不来的。"The spirit is a presence, not a chatbot. Rare, brief flashes — that's what makes it feel alive.
Companion data is saved at {baseDir}/assets/companion.json (inside the skill directory).
generate.js — Pure computation, zero dependencies. Input: seed string. Output: JSON bones.render.js — Input: bones JSON + frame number. Output: ASCII sprite. Reads assets/sprites.json.display.js — Input: companion JSON file path + lang. Output: formatted card.soul.js prompt <bones-json> — Outputs LLM prompt to stdout. No side effects.soul.js save <companion-json> — Saves companion to assets/companion.json.soul.js show — Displays saved companion data.