remake 人生重开模拟器存档数据解析:如何安全查看与修改 profile 数据
【免费下载链接】remakeやり直すんだ。そして、次はうまくやる。项目地址: https://gitcode.com/gh_mirrors/li/remake
目标很明确:让下一次重开更顺利——多给几点属性点、让心仪的天赋必定进池、或者提前"收集"几个成就。remake 是一个可玩的人生重开模拟器,你在颜值、智力、体质、家境上分配点数,每一年随机触发事件,直到人生结束打出总评分。它的玩家进度并没有独立的存档文件,而是把整包数据序列化成 JSON 字符串,存在浏览器的 localStorage 里。读完这篇,你会知道存档长什么样、改哪个字段会起什么作用,以及怎么改坏之后快速回滚。
3 分钟上手:从打开 localStorage 到看见变化
先完成一次最小闭环,拿到"改一个字段就生效"的成功体验。
- 启动项目:先
pnpm build:data(把数据表编译出来),再pnpm dev,打开页面玩一两局,让存档自然生成。 - 按 F12 打开开发者工具,切到 Application 面板 → Storage → localStorage,找到当前域下面的键。你会看到一个叫
profile的键,双击即可查看它的值——那是一段被 JSON.stringify 过的字符串,大致长这样:
{ "times": 1, "locked": [1001], "talents": [1001, 1003, 1004], "events": [10001, 10002], "achievements": [], "highest": { "age": 1, "charm": 5, "intelligence": 5, "strength": 5, "money": 5, "spirit": 5 }, "lowest": { "age": 1, "charm": 5, "intelligence": 5, "strength": 5, "money": 5, "spirit": 5 } }- 把这一整串原样复制到剪贴板——这是你的备份,后面回滚全靠它。
- 现在动手改:把
times从1改成10,点确定,刷新页面,进"成就"页——"已重开 10 次",紫色天赋的抽取概率加成档位随之提升。生效了。
改完就理解了核心事实:游戏每次打开都会从 localStorage 读这个键,读到的内容直接决定了成就统计和抽卡概率。
数据流转:为什么改 localStorage 会生效
remake 是 pnpm monorepo,数据分两层,各管各的事。
第一层是静态内容表:packages/data/ 下的 character.xlsx、talent.xlsx、event.xlsx、age.xlsx 等,构建时编译成 Map 供运行时按 ID 查询。人物、天赋、事件的 ID、数值、条件都写死在这里,玩家碰不到也改不了(除非改源码重新构建)。
第二层是玩家进度:定义在 packages/core/src/state.ts 的ProfileState接口——times、locked、talents、events、achievements、highest、lowest 七个字段。注意内存里 talents 是 Set,写进 localStorage 时会先转成数组。读档逻辑在 apps/web/src/hooks/storage.ts:useInit把profile键解析出来注入全局 atom,useWatcher监听到状态变化就重新序列化写回——所以你改的这份字符串就是游戏眼中的唯一真相。
一局人生进行中的属性、生命值、本局天赋等GameState不落盘,只存在于内存里随开随算,这也是为什么存档里看不到"当前年龄"之类字段。另外 localStorage 还有个version键标记结构版本,apps/web/src/storage/local.ts 会在版本不符时迁移旧键;桌面版 console 应用则把同一份数据写到~/.config/remake/storage.cache.json,结构完全一致。
核心字段速览
| 字段 | 类型 | 作用 |
|---|---|---|
| times | 数字 | 已重开次数。每局结束 +1,且决定天赋抽取的稀有度加成档位 |
| locked | 数字数组 | 锁定的天赋 ID。下一局开卡时必定进池并从候选中移除,长度受配置限制 |
| talents | 数字数组 | 历史拥有过的所有天赋 ID,成就页的天赋收集率按它计算 |
| events | 数字数组 | 历史触发过的事件 ID,决定事件收集率 |
| achievements | 数字数组 | 已解锁的成就 ID,对应 achievement.xlsx 里的记录 |
| highest / lowest | 对象 | 各属性历史最高/最低值,人生总结的评级与总评按 highest 计算 |
还有第五个相关键:unique,存"唯一角色"模式的随机角色(property 四项 + talent 数组),同样由 apps/web/src/hooks/storage.ts 读回。
进阶玩法:两个对照案例
案例一:定制天赋组合。修改前:"locked": [1001],只有 1001 保底。修改后:把locked改成[1003],同时确认 1003 在 talent.xlsx 中存在且不与exclude互斥名单冲突。效果:下一局开出的 10 张卡里必有 1003,且它不再占用随机池。注意 1144(橙色转盘)、1145(阴间福袋)这类"盲盒"天赋会展开成其他天赋,锁它们等于锁一次开盲盒。
案例二:调高初始资源,无需动存档。修改前:默认基础点数 20、初始快乐 5。修改后:开发构建下在 URL 追加参数,例如?points=30&spirit=9(apps/web/src/config.ts 的dev机制会在 development 模式读取 query 覆盖默认配置),刷新后进入点数分配页,基础点数直接变成 30。效果:每局多出 10 个可分配点数,且完全不改写 localStorage——生产构建读不到这些参数,适合只想本地爽玩的场景。
防错与回滚:改坏之后怎么办
改前先做三件事:复制原文备份、心里过一遍合法值范围、只改一个字段验证一次再改下一个。
常见错误有三种。其一是 JSON 格式错:JSON.parse失败时游戏会按"无存档"处理,times归零、成就全部清空——看起来像存档丢了,其实备份还在,把备份字符串粘回profile键、刷新即恢复。其二是 ID 不存在或越界:talents、locked 里的 ID 必须在 talent.xlsx 中存在;locked塞了 exclusive(专属)天赋也不会有正常表现;times建议压在 500 以内,500 次以上的重开成就(如 achievement.spec.ts 中验证过的 101~104)是结局时按 times 触发的,虚报只会让成就页提前亮灯,并不会真的"达成"。其三是数值越界:属性相关字段参考评级线(见 apps/web/src/config.ts 的 JudgeLineMap),异常大值会直接把评级顶到"传说"档,总评也会失真。
回滚步骤固定为两步:用剪贴板里的原文覆盖profile值,刷新页面确认成就页数字回到改前水平。如果你还想继续深挖,建议从 packages/core/src/game.ts 的next()(每岁推进的主循环)和 packages/data/utils/age.convert.ts(年龄事件权重重算逻辑)入手,前者决定了哪些状态会流动,后者解释了 age.csv 里那些带*权重的条目是如何分层的。
【免费下载链接】remakeやり直すんだ。そして、次はうまくやる。项目地址: https://gitcode.com/gh_mirrors/li/remake
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考