StackmasterFix

版本 v1.2.0·更新於 2026-09-26

[AI-generated] Two client-only patches for Stackmaster 1.2.0: (A) Quick Grab Materials never debited chests (duplication); (B) its new remembered-chest fallback refills chests you just emptied (intent

模組介紹 作者原文

StackmasterFix

適用性聲明 / Applicability Notice

中文:本模組是給第三方模組 JStack424-Stackmaster 打的客戶端補丁,含兩個互相獨立的修復項:

| 項 | 內容 | 性質 |

|---|---|---|

| A | 建造菜單 Alt + 左鍵(上游叫 Quick Grab Materials)拉取一整套材料時,箱子裏的材料不扣減(等於複製) | 是 bug(在上游 1.2.0 上依然存在) |

| B | 上游 1.2.0 新增的「記住上次直接用過的箱子」回退:你把某個箱子清空後,在別處按 Alt + E(Quick Stack),剛取出來的東西會被原樣塞回那個空箱 | 不是 bug,是上游有意做的特性(見下) |

⚠️ 關於 B 項:這不是原模組的 bug,只是我個人的偏好開關

上游 1.2.0 的 changelog 明寫這是有意添加的功能 ——

「Quick Stack remembers the last directly observed chest for each exact item type,

even after that chest reaches zero stock」,目的是方便"補貨":

你有個裝木材的箱子、把它用空了,下次快速堆疊時木材會自動回到那個箱子。

我認爲"被我清空的箱子就應該保持空着",所以用 DisableRememberedChests 這個開關把它關掉。

這只是個人習慣,不代表上游做錯了。如果你覺得上游的行爲挺好,請不要用本補丁,

或者把該開關設成 false 即可原樣恢復上游行爲。

  • 這個 A 項 bug 是在我這臺裝了 30+ 模組、且以客機身份連遠程專用服務器的環境裏復現並定位的。

原模組作者與這些問題無關,有疑問請先找我,不要去找原作者。

  • 原模組在別的環境下可能並沒有 A 項這個 bug,症狀也可能是我這臺的特定組合導致;

不保證適用於你的環境。

  • 本補丁只做這兩件事:

A:把扣減從「只讀快照副本」改到「真實容器」,並在事務成功後強制寫回 ZDO;

B:把上游那張「記憶箱子」回退表的返回值換成空表,讓回退永不觸發。

不改任何數值、不動上游的記憶存檔數據、不加任何新功能。

  • 本補丁未經原作者同意或審閱,也不主張任何「原模組有 bug」的結論(A 項除外,那一項我給了 IL 證據)——

整體上只是我這臺機器上的繞行方案。

  • 若上游之後自己修好了 A 項,請優先升級上游模組並停用本補丁;

若你喜歡上游 B 項的行爲,把 DisableRememberedChests 設爲 false 即可。

English: This is a client-side patch for the third-party mod JStack424-Stackmaster,

with two independent fixes:

  • A|Quick Grab Materials did not consume materials (Alt + left-click a build piece):

chests were never debited, i.e. item duplication.

  • B|Quick Stack put items back into a chest you just emptied: Stackmaster 1.2.0 introduced

"remember the last directly observed chest" as a fallback destination.

⚠️ B is NOT a bug in the original mod. The upstream 1.2.0 changelog states this behaviour is

intentional ("even after that chest reaches zero stock", to make restocking convenient).

This patch merely turns that feature off because I personally prefer an emptied chest to stay

empty. If you like the upstream behaviour, do not use this patch, or set

DisableRememberedChests = false to restore it exactly.

  • The A bug was reproduced and diagnosed on my setup: a 30+ mod client connecting to a

remote dedicated server. The original mod's author is not responsible for any of this.

  • The original mod may be perfectly fine in your setup; this patch is not guaranteed to apply to you.
  • The patch only (A) redirects the withdrawal from a read-only snapshot copy to the live container and

forces the container's ZDO write after a successful transaction, and (B) returns an empty map for the

remembered-chest fallback. It changes no values, never touches the stored memory data, and adds no features.

  • This patch is not endorsed or reviewed by the original author, and makes no claim that the

original mod is buggy (except item A, for which IL evidence is given) — it is a

"works-on-my-machine" workaround.

  • If upstream fixes item A, update Stackmaster and disable this patch. If you like upstream's

item B behaviour, set DisableRememberedChests = false.

🤖 本模組的代碼由 AI 生成(AI Generated),需求、驗證與發佈由人類完成。

v1.2.0:新增「攔截記憶箱子回退」(B 項)

症狀:把一個箱子裏的東西取空 → 走到別的箱子按 Alt + E 快速堆疊 → 剛取出來的東西又被塞回那個空箱子。

根因(對 Stackmaster.dll 1.2.0 反彙編覈對,316,416 B / sha256 be2fc8941b1abd96…):

  • 上游 1.2.0 新增了 RememberedChestDestinations:只要你直接打開/對準過某個箱子,

就按"物品種類"把它記進本地 PlayerPrefs(上限 512 條、180 天過期)。

箱子被清空也不會抹掉這條記憶 —— 這是 changelog 裏明寫的有意設計。

  • 正常堆疊只進"當前已經裝有同類物品"的箱子,不會主動填空箱:

<>c__DisplayClass2_0::b__1 的整個篩選邏輯就是

container.InitialCompatibilityKeys.Contains(source.CompatibilityKey)

⇒ 空箱子的候選鍵集合爲空,永遠進不了正常候選列表。

  • 於是有了「回退」這條路(StorageTransferPlanner.PlanDeposits,IL 0x00FF-0x014A):

當剩餘量 > 0 且本次一件都沒搬走、且 remembered.TryGetValue(stackId, out containerId)

命中、且該箱子在當前發現範圍內 ⇒ 把這一份放進那個箱子。

⇒ 回退只可能發生在"這個箱子當前一件同類物品都沒有"的時候。

修法:在

`IReadOnlyDictionary Stackmaster.RememberedChestDestinations.ResolveFallbacks(

Player, InventorySnapshot, DiscoveryResult)`

上打一個 Postfix,把返回的 StackId → ContainerId 回退表換成空表

⇒ PlanDeposits 裏的 TryGetValue 永遠 miss ⇒ 回退永不觸發。

影響面爲什麼是封閉的(scripts/verify_stackmasterfix.py 每次交付前自動核這四條):

| 覈對項 | 實測結論 |

|---|---|

| ResolveFallbacks 全 DLL 調用點 | 只有 2 個:StorageAction.Be

安裝與使用 安裝:BepInEx 外掛

  1. 本站下載的壓縮包就是模組本體,通常是 BepInEx 外掛(解壓後得到 .dll 或外掛資料夾)。
  2. 建議流程:用社群模組管理器(如 r2modman)選中本遊戲後匯入該模組,管理器會自動裝好 BepInEx 前置並處理依賴。
  3. 手動流程:先在遊戲目錄裝好 BepInEx 載入器,再把解壓出的 .dll 或外掛資料夾放進 BepInEx/plugins/。
  4. 啟動遊戲,BepInEx 控制台會列印載入日誌;確認這個模組出現在日誌裡即為安裝成功。

帶「前置依賴」的模組需要一併安裝,否則不會載入。功能開關通常在遊戲內或外掛自帶的設定檔裡調整。 多人連線時,主機與所有用戶端需要安裝一致的模組。

前置依賴

下面這些內容需要先安裝,否則該模組不會生效:

denikson-BepInExPack_ValheimJStack424-Stackmaster

檔案與校驗

檔案名稱
StackmasterFix-1.2.0.zip
檔案大小
25.2 KiB