rain_gamemod-PeakScrollFix icon

PeakScrollFix

Fixes the PEAK 2.4.b bug where guidebook scrolls vanished when opened at campfires (NRE in GuidebookPageValid). WARNING: may stop the game from launching - delete it after earning the Bookworm badge.

Last updated a month ago
Total downloads 314
Total rating 0 
Categories Mods Misc
Dependency string rain_gamemod-PeakScrollFix-1.1.0
Dependants 0 other packages depend on this package

This mod requires the following mods to function

BepInEx-BepInExPack_PEAK-5.4.75301 icon
BepInEx-BepInExPack_PEAK

BepInEx pack for PEAK. Preconfigured and ready to use.

Preferred version: 5.4.75301

README

PeakScrollFix(卷轴消失修复)

⚠️ 警告:务必先读

  • 本补丁可能造成游戏无法启动。 本模组会介入游戏启动期的单例初始化流程,在部分环境下曾导致游戏卡在启动阶段(崩溃/黑屏),装之前请先确认你知道怎么删除它。
  • 完成书呆子成就(Bookworm Badge)后请立即删除本补丁,避免下次官方修复该 bug 后与本补丁产生冲突(冲突表现为启动异常或成就/页数记录错乱)。
  • 删除/回滚只需一步:把 PeakScrollFix.dll 改名成 PeakScrollFix.dll.disabled(或直接删除),游戏本体文件从未被修改。
  • 若安装后游戏进不去:先改名回滚,再带着 BepInEx\LogOutput.log 与 Player.log 找作者反馈。

这个补丁修什么

PEAK 2.4.b 官方更新后,营火(含山顶营火)旁的卷轴(GuidebookPageScroll)使用后会直接消失:不生成指南书页、页数不涨、书虫成就无法推进。

原因在游戏自身代码(不是存档、也不是模组冲突):

  • 2.4.b 给书页加入了「渐进解锁」门槛校验,Guidebook.GuidebookPageValid 里新增的代码会无空值保护地读取 AchievementManager 单例;
  • 而该单例在分段交界处会被反复销毁/重建(营火正好位于分段交界线上),存在一个瞬间为 null 的空窗;
  • 在空窗期打开卷轴 → NullReferenceException → 选页中断、页面从未生成,但卷轴已被协程照常销毁 → 「打开卷轴直接消失」。

本补丁在空窗期补上该单例与其页数数据,或改用游戏自己的 Steam 统计(TotalPagesRead)完成同样的门槛校验与页数记录,让卷轴恢复为消耗后正常生成书页。

安装

手动安装(推荐)

  1. 安装 BepInEx 5.x(x64 / Mono 版):解压到 PEAK 游戏目录(Steam → 右键 PEAK → 管理 → 浏览本地文件),使 winhttp.dll、doorstop_config.ini、BepInEx\ 与 PEAK.exe 同级;先启动一次游戏让它生成目录。

  2. 把 PeakScrollFix.dll 放进:

    PEAK\BepInEx\plugins\PeakScrollFix\PeakScrollFix.dll
    

    (文件夹不存在就新建;直接丢在 plugins\ 下也可以)

  3. 重启游戏(BepInEx 只在启动时加载插件)。

模组管理器安装:直接用本包的 zip 安装即可(已按 Thunderstore 规范打包,依赖 BepInEx-BepInExPack_PEAK)。

验证是否生效

  1. 打开 PEAK\BepInEx\LogOutput.log,应能看到:

    [PeakScrollFix] v1.1.0 loaded. Guard active, 3/3 concrete patches applied (no generic patching).
    
  2. 游戏内跨过分段后到营火边捡卷轴使用:

    • 书页正常出现在手上(不再凭空消失);
    • LogOutput.log 里可能出现 [PeakScrollFix] ... 提示(补实例 / 无管理器校验 / 直接记录页)——出现即说明正好堵到了一次原本会崩的时刻;
    • C:\Users\<你的用户名>\AppData\LocalLow\LandCrab\PEAK\Player.log 中不再出现 NullReferenceException ... GuidebookPageValid;
    • 进度正常累加:Successfully Updated Stat: TotalPagesRead (N)。

N 是页标志位掩码,不是页数:Intro=1、Mushrooms=2、Campfire=4、Revival=8……逐页累加。

卸载 / 出问题怎么办

情况 操作
正常卸载(比如拿到成就后) 删除 BepInEx\plugins\PeakScrollFix\ 整个文件夹
游戏启动异常 把 PeakScrollFix.dll 改名成 PeakScrollFix.dll.disabled,重启游戏
想确认是否已停用 LogOutput.log 里不再出现 [PeakScrollFix] ... 即为已停用

工作原理(可自行审阅源码)

  1. 守护组件:普通 MonoBehaviour,在游戏内场景发现官方 AchievementManager 单例缺失时,用普通调用补一个常驻实例,并用 Steam 统计 TotalPagesRead 还原其「已读页」数据;实例存在但数据为空时也会补上。
  2. Guidebook.GuidebookPageValid 前缀:单例/数据不可用时,按平台统计重算同样的门槛条件,让选页正常完成而不是崩溃。
  3. AchievementManager.TriggerSeenGuidebookPage 前缀:数据为空时先还原;无法还原则直接按官方格式写入该页标志位。
  4. GuidebookPageCollection.TryPickPageToSpawn 后置:选页成功但管理器不可用时立即记录,防止游戏自身的标记调用失败丢进度。

三个补丁目标均为非泛型具体方法。历史教训:早期版本曾把补丁打在泛型单例 Singleton<T>.get_Instance 上,会污染 Mono 的共享泛型代码、导致游戏完全无法启动——该版本已废弃,当前版本绝不碰泛型方法。

兼容性与说明

  • 纯客户端补丁:不影响队友,不修改游戏本体文件,不注入网络数据;与其它客户端模组(PEAK Finder、ItemSpawner、FlyMod、PeakLevelSelect 等)实测共存正常。
  • 不算作弊:它不会给你尚未开过的书页,只把「卷轴本来就会生成的那一页」按官方正常流程记入游戏自己的 Steam 统计,和原版行为一致。
  • 本局统计可能重置一次:若补丁在途中重建了 AchievementManager,该实例的「本局计数」(如本局开箱数)会从零开始——这些数据本来就随官方实例被销毁而丢失;跨局成就统计在 Steam 端,不受影响。
  • 游戏更新后:若官方改动了相关方法签名,补丁会自动跳过(不报错、不崩,只是可能失效);若官方自己修好了这个 bug,请直接删除本补丁,以免冲突。
  • 适用:PEAK 2.4.b(Steam PC / Mono 运行时)+ BepInEx 5.x。

常见问题

  • 装完像没生效? 确认是 BepInEx\plugins\ 下(不是游戏根目录)、且重启过游戏;再看 LogOutput.log 有没有那行 [PeakScrollFix] v1.1.0 loaded。
  • LogOutput.log 不存在? 说明 BepInEx 没装好(检查 winhttp.dll 是否在游戏根目录、是否用了 BepInEx 5 而非 6/IL2CPP 版)。
  • 游戏进不去? 见上方警告:改名 .disabled 回滚,然后带日志反馈。
  • 卷轴还是会消失? 用 BepInEx 配置 BepInEx\config\com.dsh.peakscrollfix.cfg 把 VerboseLogging 设为 true,复现后把 LogOutput.log 发给作者。

English

⚠️ WARNING — READ FIRST

  • This patch may prevent the game from launching. It hooks into singleton initialisation during startup and, in some environments, has caused the game to hang or crash at boot. Make sure you know how to remove it before installing.
  • Delete this patch as soon as you have earned the Bookworm badge, so that a future official fix for this bug does not conflict with it (conflicts show up as launch failures or broken page/achievement tracking).
  • Uninstalling takes one step: rename PeakScrollFix.dll to PeakScrollFix.dll.disabled (or just delete it). No game file is ever modified.
  • If the game will not start after installing: rename it back to .disabled first, then report the problem with your BepInEx\LogOutput.log and Player.log.

What this patch fixes

After the official PEAK 2.4.b update, guidebook scrolls (GuidebookPageScroll) found at campfires (including the summit campfire) vanish the moment you use them: no guidebook page is spawned, page progress does not advance, and the Bookworm badge cannot be earned.

The cause is in the game's own code (not your save and not a mod conflict):

  • 2.4.b added progressive-unlock requirements for guidebook pages, and the new code in Guidebook.GuidebookPageValid dereferences the AchievementManager singleton without a null guard;
  • that singleton is destroyed and re-created across segment transitions (campfires sit exactly on those boundaries), leaving a window where it is null;
  • opening a scroll inside that window throws a NullReferenceException: page selection aborts, no page is ever created, yet the scroll is still destroyed by an already-started coroutine — "open the scroll and it just disappears."

This patch supplies the missing singleton and its page data during that window (or completes the same gating checks and page recording through the game's own Steam stat, TotalPagesRead), so a scroll is consumed and actually produces a page again.

Installation

Manual (recommended)

  1. Install BepInEx 5.x (x64 / Mono): extract it into the PEAK folder (Steam → right-click PEAK → Manage → Browse local files) so that winhttp.dll, doorstop_config.ini and the BepInEx\ folder sit next to PEAK.exe; run the game once so the folders are generated.

  2. Put PeakScrollFix.dll into:

    PEAK\BepInEx\plugins\PeakScrollFix\PeakScrollFix.dll
    

    (create the folder if needed; dropping it directly into plugins\ works too)

  3. Restart the game (BepInEx only loads plugins at startup).

Mod manager: just install this package (packaged to Thunderstore conventions, depends on BepInEx-BepInExPack_PEAK).

Verifying it works

  1. Open PEAK\BepInEx\LogOutput.log; you should see:

    [PeakScrollFix] v1.1.0 loaded. Guard active, 3/3 concrete patches applied (no generic patching).
    
  2. In game, cross a segment boundary, pick up a scroll at the campfire and use it:

    • the guidebook page appears in your hands (it no longer vanishes);
    • LogOutput.log may show [PeakScrollFix] ... lines (replacement instance / manager-less validation / direct page recording) — these mean the patch caught a moment that would otherwise have crashed;
    • C:\Users\<you>\AppData\LocalLow\LandCrab\PEAK\Player.log no longer contains NullReferenceException ... GuidebookPageValid;
    • progress advances normally: Successfully Updated Stat: TotalPagesRead (N).

N is a bitmask of page flags, not a page count: Intro=1, Mushrooms=2, Campfire=4, Revival=8, and so on.

Uninstalling / if something goes wrong

Situation Action
Normal uninstall (e.g. badge earned) delete the whole BepInEx\plugins\PeakScrollFix\ folder
Game fails to start rename PeakScrollFix.dll to PeakScrollFix.dll.disabled and restart
Confirm it is disabled [PeakScrollFix] ... no longer appears in LogOutput.log

How it works (source included)

  1. Guard component: an ordinary MonoBehaviour that, inside gameplay scenes, replaces a missing official AchievementManager singleton with a persistent one (via a plain call) and restores its "seen pages" data from the Steam stat TotalPagesRead; it also fills in that data when the instance exists but has none.
  2. Guidebook.GuidebookPageValid prefix: when the singleton or its data is unavailable, it re-evaluates the same gating rules from the platform stat instead of crashing.
  3. AchievementManager.TriggerSeenGuidebookPage prefix: restores missing data first, or records the page flag directly in the official format.
  4. GuidebookPageCollection.TryPickPageToSpawn postfix: if a page was picked while the manager was unavailable, it records the page immediately so the game's own marking calls cannot lose progress.

All three patch targets are concrete, non-generic methods. Past lesson: an early version patched the generic singleton getter Singleton<T>.get_Instance, which corrupted Mono's shared generic code and made the game unable to launch at all — that version is retired, and the current one never touches generic methods.

Compatibility and notes

  • Client-side only: does not affect teammates, does not modify game files, does not inject network data; tested alongside other client mods (PEAK Finder, ItemSpawner, FlyMod, PeakLevelSelect, ...).
  • Not a cheat: it never grants a page you have not opened; it only records the page the scroll was going to produce, through the same Steam stat and format the vanilla game uses.
  • Run stats may reset once: if the patch has to rebuild AchievementManager mid-run, that instance's per-run counters (e.g. luggage opened this run) start from zero — that data is lost anyway when the official instance is destroyed; cross-run achievement stats live on Steam and are unaffected.
  • After a game update: if the official method signatures change, the affected patches are skipped automatically (no error, no crash — they simply stop applying). If the developers fix this bug themselves, please delete this patch to avoid conflicts.
  • Applies to PEAK 2.4.b (Steam PC / Mono runtime) + BepInEx 5.x.

FAQ

  • Installed but nothing changed? Make sure the DLL is under BepInEx\plugins\ (not the game root) and that you restarted the game; then check LogOutput.log for the [PeakScrollFix] v1.1.0 loaded line.
  • No LogOutput.log? BepInEx is not installed correctly (check winhttp.dll in the game root, and that you used BepInEx 5 rather than 6/IL2CPP).
  • Game will not start? See the warning above: rename to .disabled, then report with logs.
  • Scrolls still vanish? Set VerboseLogging to true in BepInEx\config\com.dsh.peakscrollfix.cfg, reproduce it, and send LogOutput.log to the author.