Claude Code 宠物系统,我写了个工具帮每个人孵化传奇宠物
Claude Code v2.1.89 里藏了个彩蛋:输入 /buddy 可以孵化一只 ASCII 小宠物,蹲在你的终端输入框旁边。


但问题是——你的宠物在你创建账号的那一刻就被决定了,概率如下:
- common(60%)— 普通路人
- uncommon(25%)— 稍有姿色
- rare(10%)— 小有运气
- epic(4%)— 欧洲人
- legendary(1%) — 天选之子
- shiny(1% 概率闪光)— 锦上添花
大部分人抽到的都是 common,想换一只?官方没有重抽机制。
分析
翻了源码(src/buddy/),发现宠物生成链路是完全确定性的:
Bun.hash(userID + "friend-2026-401")
↓ mulberry32 PRNG
↓ 按顺序抽取:稀有度 → 物种 → 眼睛 → 帽子 → 闪光 → 属性
同一个 userID,永远生成同一只宠物。物种名还用 String.fromCharCode 编码,绕过构建系统的代码名检查。
关键发现
外属性(物种/稀有度/外观)不持久化——每次从 userID 实时计算,不写进配置文件。这意味着:
- 改配置伪造稀有度?没用,bones 每次重算
- 想换宠物?换个 userID 就行
- 想指定宠物?暴力搜索 userID 空间
属性上限的真相
算法强制分配一个峰值和一个谷值属性,全属性 100 在数学上不可能:
legendary (floor=50):
峰值: min(100, 50+50+0~30) = 100 ← 必然满
谷值: max(1, 50-10+0~15) = 最高 55 ← 不可能满
其他: 50+0~40 = 最高 90
理论最高总分: 100 + 55 + 90×3 = 425 / 500
所以别信什么"全满属性",算法层面就不存在。
暴力搜索
既然 userID 决定一切,那搜索 64 位十六进制空间里的最优解就好了。
第一版用 Python 写,跑了 60 秒找到了 legendary+shiny,但结果不对——因为 Claude Code 运行在 Bun 上,hash 函数走的是 Bun.hash()(Wyhash),不是源码里注释的 FNV-1a 回退。Hash 算法错了,后面全错。
第二版直接用 Bun 原生运行时,190 万 userID/秒,55 秒扫完 1 亿个 ID。
修复的 bug
PRNG 是严格顺序消耗的,属性抽取顺序必须与源码完全一致:
✗ 错误:rarity → stats → species → eye → hat → shiny (stats 提前了)
✓ 正确:rarity → species → eye → hat → shiny → stats (与源码一致)
stats 提前消耗了 rng 调用,导致所有后续属性偏移——结果是 legendary+shiny 对了,但物种和属性全错。
最终工具
写了个交互式脚本 find-best-buddy,流程是:
- 选物种(18 种,带 emoji 和中文名)
- 选眼睛、帽子、是否闪光
- 设搜索量
- Bun 原生暴力搜索,~190 万/秒
- 找到最高属性匹配后,一键写入
~/.claude.json
全自动——备份、写入、验证一步完成。
项目地址:https://github.com/Fzuim/find-best-buddy.git
总结
| 冷知识 | 说明 |
|---|---|
| 宠物在你第一次打开 Claude Code 时就定了 | userID → 确定性 PRNG |
| 全属性 100 不存在 | 算法强制有峰值和谷值 |
| 改 userID 几乎无副作用 | 对未登录用户只影响遥测 |
| 物种名用 charCode 编码 | 绕过构建系统的代码名扫描 |
| 搜索 1 亿 ID 只要 55 秒 | Bun 原生运行时 + mulberry32 PRNG |
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)