From c5115a3a138678a479ac9fbb9192719779f92fbd Mon Sep 17 00:00:00 2001 From: VinPropane Date: Sun, 24 May 2026 17:33:27 -0400 Subject: [PATCH] NEO-69: Fix output-deny rollback order to prevent item loss. Remove partial outputs before restoring inputs when output grant is denied, matching StoreMissing and XP-failure compensating paths. --- docs/reviews/2026-05-24-NEO-69.md | 2 ++ server/NeonSprawl.Server/Game/Crafting/CraftOperations.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/reviews/2026-05-24-NEO-69.md b/docs/reviews/2026-05-24-NEO-69.md index 9b0d753..e1f781c 100644 --- a/docs/reviews/2026-05-24-NEO-69.md +++ b/docs/reviews/2026-05-24-NEO-69.md @@ -55,6 +55,8 @@ None. 2. ~~**Missing output rollback in store-missing branch** — output-add `StoreMissing` restored inputs but not partial outputs.~~ **Done.** `CompensatingRemoveOutputs` added before input restore on that path. +3. ~~**Rollback order on output deny** — `Denied` branch restored inputs before removing partial outputs, so `TryAddStack` could fail silently when bag was full.~~ **Done.** Swapped to remove outputs first, then restore inputs (matches `StoreMissing` and XP-failure paths). + ## Verification ```bash diff --git a/server/NeonSprawl.Server/Game/Crafting/CraftOperations.cs b/server/NeonSprawl.Server/Game/Crafting/CraftOperations.cs index 9f3000f..57f66fa 100644 --- a/server/NeonSprawl.Server/Game/Crafting/CraftOperations.cs +++ b/server/NeonSprawl.Server/Game/Crafting/CraftOperations.cs @@ -117,8 +117,8 @@ public static class CraftOperations if (addOutcome.Kind == PlayerInventoryMutationKind.Denied) { - CompensatingRestoreInputs(playerId, scaledInputs, itemRegistry, inventoryStore); CompensatingRemoveOutputs(playerId, outputsApplied, itemRegistry, inventoryStore); + CompensatingRestoreInputs(playerId, scaledInputs, itemRegistry, inventoryStore); return Deny(CraftReasonCodes.InventoryFull); }