Quick answer: Derive sell price as a fraction of buy price for the same item and verify across all vendors that no sell value ever exceeds any reachable buy value.
If a player can buy an item for 8 gold and sell it for 10, they have an infinite money printer. Tying sell prices to buy prices so every round trip loses value closes the loop. Here is how.
How to fix it
1. Derive sell from buy
Compute each vendor's sell price as a fraction (e.g. 25-50%) of the canonical buy price, so reselling always returns less than you paid.
2. Check cross-vendor pairs
If different vendors price the same item differently, verify that the highest sell price for an item is still below the lowest buy price anywhere it is sold.
3. Add a spread on dynamic prices
For supply-and-demand pricing, keep a guaranteed margin between the buy and sell quotes so market swings never invert into a profitable loop.
4. Test with a script
Write a test that, for every item, asserts maxSell < minBuy across all vendors so a future price edit cannot silently reopen the exploit.
Catching the ones you can't reproduce
The hardest version of this to fix is the one you can't reproduce — it only happens on a player's hardware, OS, driver, or save state, under conditions that simply aren't present on your machine. A report that says “it crashed” or “it froze” gives you nothing to act on, so the bug survives release after release while quietly costing you players.
Automatic error capture closes that gap. Each failure arrives with its full stack trace, the device and OS, the build number, and a breadcrumb trail of what the player did right before it broke, so even a failure you have never seen becomes a specific, reproducible issue. Fold identical failures into one signature ranked by how many players each hits, and your worklist sorts itself worst-first instead of arriving as a stream of vague complaints.
This is where a tool like Bugnet earns its place. Its SDK captures every Godot error automatically with the full stack trace plus device, OS, memory, build, and game-state context, folds duplicates into one grouped issue with an occurrence count, and ties each to the build it first appeared on — so you fix the problem that hurts the most players first and confirm it is gone when its signature disappears from the next release.
The bug you can't reproduce isn't gone — it's just invisible until you capture it from the player's device.