ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Claude Code 宠物系统:用 Bun 写个 PRNG 暴力搜索工具,孵化传奇宠物

Claude Code 宠物系统:用 Bun 写个 PRNG 暴力搜索工具,孵化传奇宠物 1. 先搞清楚 Claude Code 宠物到底怎么孵出来的Claude Code 里那个/buddy彩蛋很多人第一次看到都以为是随机抽卡抽到 common 就认命了。实际上它的生成链路是完全确定性的你的 userID 一旦确定宠物就固定了稀有度、物种、眼睛、帽子、闪光、属性全部由一条 PRNG 序列推出来。换句话说这不是抽卡是哈希。我这次要做的就是用 Bun 写一个暴力搜索工具在 userID 空间里找到能孵化出传奇宠物的那个 ID然后写回配置。整个过程不碰任何灰色手段纯粹是本地计算加配置替换。适合已经装了 Claude Code、想折腾一下彩蛋机制、又愿意动手跑脚本的人。核心检索词就三个Claude Code 宠物、Bun 暴力搜索、userID 与 PRNG 种子关系。先讲清楚机制不然脚本跑出来的结果你没法判断对错。宠物生成走的是这样一条链userID friend-2026-401 ↓ Bun.hash() (Wyhash) ↓ mulberry32 PRNG ↓ 按顺序抽取稀有度 → 物种 → 眼睛 → 帽子 → 闪光 → 属性这里有两个坑我踩过。第一个是 hash 函数源码注释里写了个 FNV-1a 回退但 Claude Code 实际跑在 Bun 上走的是Bun.hash()也就是 Wyhash。如果你用 Python 或者 Node 去复现hash 结果对不上后面全错。第二个是抽取顺序PRNG 是严格顺序消耗的stats必须放在最后抽一旦提前后面所有属性全部偏移。我第一版就是把 stats 提前了结果 legendaryshiny 对了但物种和属性全乱。所以工具必须用 Bun 原生运行时顺序必须和源码一字不差。2. 前置准备Bun 环境与 TaoToken 接入工具本身只依赖 Bun但如果你想让 Claude Code 正常跑起来、顺便验证宠物显示建议把模型接入也配好。我这边用的是 TaoToken 的 API它兼容 Anthropic 的接口格式Claude Code 可以直接对接。先去控制台拿一个 API Keyhttps://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentconsole拿到 key 之后在 Claude Code 里配置环境变量。Claude Code 读的是ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY这两个export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的key注意 base URL 不要加 UTM 参数API 地址就是https://taotoken.net/api加了反而可能出问题。配好之后启动 Claude Code输入/buddy就能看到你当前的宠物。这一步不是为了搜索是为了让你有个对照——搜索出来的新 userID 写进去之后你能立刻验证宠物有没有变。Bun 的安装很简单官方一行命令curl -fsSL https://bun.sh/install | bash装完bun --version能输出版本号就行。我实测用的是 Bun 1.1.xWyhash 行为和 Claude Code 内置的一致。3. 可复制的 Bun 脚本骨架下面这份脚本可以直接存成find-best-buddy.ts用bun run find-best-buddy.ts跑。核心分三块hash PRNG、抽取逻辑、搜索循环。先看 hash 和 PRNG。mulberry32 是一个 32 位状态的 PRNG种子来自Bun.hash()的低 32 位function mulberry32(seed: number) { let a seed 0; return function () { a | 0; a (a 0x6d2b79f5) | 0; let t Math.imul(a ^ (a 15), 1 | a); t (t Math.imul(t ^ (t 7), 61 | t)) ^ t; return ((t ^ (t 14)) 0) / 4294967296; }; } function seedFromUserId(userId: string): number { const h Bun.hash(userId friend-2026-401); return Number(BigInt(h) 0xffffffffn); }Bun.hash()返回的是 bigint取低 32 位转 number 就是 mulberry32 的种子。这一步是整个工具的地基hash 错了后面全废。然后是抽取逻辑。稀有度按权重抽物种、眼睛、帽子、闪光依次消耗 rng最后才是属性。属性部分算法强制分配一个峰值和一个谷值所以全 100 在数学上不存在const RARITIES [ { name: common, weight: 60 }, { name: uncommon, weight: 25 }, { name: rare, weight: 10 }, { name: epic, weight: 4 }, { name: legendary, weight: 1 }, ]; function pickRarity(rng: () number) { const total RARITIES.reduce((s, r) s r.weight, 0); let roll rng() * total; for (const r of RARITIES) { roll - r.weight; if (roll 0) return r.name; } return common; }属性抽取的关键是顺序。源码里是rarity → species → eye → hat → shiny → statsstats 内部再按峰值/谷值分配。你写的时候一定要按这个顺序调用 rng少一次多一次都会让结果偏移。搜索循环就是遍历 userID 空间。userID 是 64 位十六进制但实际搜索不需要全空间你可以从一个随机起点开始按步长递增边搜边比对目标条件const TARGET_RARITY legendary; const TARGET_SHINY true; const BATCH 1_000_000; let found 0; let cursor BigInt(0x crypto.randomUUID().replace(/-/g, )); while (found 5) { for (let i 0; i BATCH; i) { const userId cursor.toString(16).padStart(16, 0); const pet generatePet(userId); if (pet.rarity TARGET_RARITY pet.shiny TARGET_SHINY) { console.log(命中:, userId, pet); found; } cursor; } }generatePet就是把前面 hash、PRNG、抽取串起来。Bun 原生跑这个循环实测能到 190 万 userID/秒扫 1 亿个 ID 大概 55 秒。这个速度是 Node 比不了的因为 Bun 的 hash 是原生实现没有 JS 层开销。4. 验证请求与成功结果脚本跑出候选 userID 之后别急着写配置先做一次离线验证。把你当前的 userID 和候选 userID 分别喂给generatePet对比输出bun run find-best-buddy.ts --verify 你的当前userID bun run find-best-buddy.ts --verify 候选userID如果当前 userID 生成的宠物和你/buddy看到的一致说明你的 hash 和抽取顺序是对的候选结果才可信。这一步是排错的分水岭——很多人搜出来结果不对就是因为没做这个对照。验证通过后写入配置。Claude Code 的 userID 存在~/.claude.json里写之前先备份cp ~/.claude.json ~/.claude.json.bak然后用脚本写入。注意不要手改手改容易漏字段。脚本里做三件事读 JSON、替换 userID、写回。写完重启 Claude Code输入/buddy如果显示的是 legendary shiny就成功了。如果你想顺便验证模型接入是否正常可以在 Claude Code 里发一条消息看它能不能正常回复。模型对话入口在这里https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentchat能正常对话说明 API 配置没问题宠物显示和模型调用是两条独立的链路互不影响。5. 本篇常见错排查第一个错hash 算法用错。如果你用 Node 的crypto.createHash或者自己实现 FNV-1a结果一定对不上。必须用Bun.hash()因为 Claude Code 跑在 Bun 上。判断方法就是前面说的离线验证当前 userID 对不上就是 hash 错了。第二个错抽取顺序错。最常见的是把 stats 提前。PRNG 是顺序消耗的stats 内部会调用多次 rng提前抽会让 species、eye、hat、shiny 全部偏移。表现是稀有度对了但外观全错。修复方法就是严格按rarity → species → eye → hat → shiny → stats排。第三个错userID 格式。Claude Code 存的是 64 位十六进制字符串你搜索的时候如果用了十进制或者带前缀写回去之后 Claude Code 解析不了宠物会变成默认值。写入前用padStart(16, 0)补齐确保是 16 个字符。第四个错配置写入后没重启。Claude Code 启动时读一次~/.claude.json运行中改文件不生效。写完必须完全退出再启动不是新开一个终端就行。第五个错搜索空间太小。如果你只搜几万个 ID 就停了可能碰不到 legendaryshiny。1% 的 legendary 叠加 1% 的 shiny理论命中率是万分之一搜 100 万次大概能出 100 个候选。搜 1 亿次基本能覆盖各种组合。6. 后续怎么玩从搜索到长期编码工具跑通之后你手里就有了一批候选 userID。我的建议是别只盯着 legendaryshiny可以按属性总分排序找峰值属性最高的那个。因为算法强制有峰值和谷值legendary 的峰值必然满 100但谷值最高只能到 55其他属性最高 90理论总分上限是 425/500。你可以把搜索目标改成「总分 400 且 legendary」这样出来的宠物更实用。如果你打算长期用 Claude Code 做编码或者跑 Agent建议把 Coding Plan 也配上这样模型调用和宠物彩蛋互不干扰https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan接入文档在这里里面有完整的 base URL 和参数说明https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdocAPI Keys 管理页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys最后说个冷知识宠物在你第一次打开 Claude Code 的时候就定了之后每次显示都是实时从 userID 重算的不写进配置文件。所以你改配置伪造稀有度没用bones 每次重算。想换宠物只能换 userID。搜索 1 亿个 ID 只要 55 秒这个成本比手动抽卡低多了。
返回列表