fix(sort): retry failed pickups instead of dropping moves on lag

DoContainerMoves dropped moves entirely when PickupContainerItem didn't
land on the cursor — on a laggy server this fires constantly because
the previous swap's client state hasn't propagated yet, leaving items
un-sorted. Retry up to MAX_PICKUP_RETRIES (8 * 150ms = 1.2s) before
giving up. Also bump CONTAINER_SWAP_DELAY 50ms -> 150ms; the inline
comment already pointed at this as the knob to raise on desyncs.
This commit is contained in:
2026-05-15 20:21:26 +02:00
parent f132bb1861
commit 844f9c8a4e
+16 -4
View File
@@ -86,9 +86,13 @@ end
-- Minimum time between starting consecutive container swaps. Blasting them
-- back-to-back outpaces the realm server (which rate-limits inbound packets)
-- and the predicted client state desyncs after ~10 moves. 50ms = ~20 swaps/sec
-- sustained; raise this if you see desyncs, lower it if your ping is very low.
local CONTAINER_SWAP_DELAY = 0.05
-- and the predicted client state desyncs after ~10 moves. 150ms = ~6 swaps/sec
-- sustained; raise if you see desyncs, lower if your ping is very low.
local CONTAINER_SWAP_DELAY = 0.15
-- A pickup that doesn't land on the cursor is almost always a lag race where
-- the previous swap's state hasn't propagated yet. Retry instead of dropping
-- the move (which used to leave items un-sorted on laggy servers).
local MAX_PICKUP_RETRIES = 8
local nextSwapAt = 0
local function DoContainerMoves()
@@ -119,10 +123,18 @@ local function DoContainerMoves()
PickupContainerItem(move.sourcebag, move.sourceslot)
if not CursorHasItem() then
-- Source slot empty/locked; drop the move and try the next.
-- Pickup didn't take. On a laggy server this usually means the
-- previous swap's client state hasn't caught up; retry a few times
-- before giving up so we don't silently drop the move.
move.retries = (move.retries or 0) + 1
if move.retries < MAX_PICKUP_RETRIES then
nextSwapAt = GetTime() + CONTAINER_SWAP_DELAY
return
end
table.remove(moves, 1)
return
end
move.retries = nil
PickupContainerItem(move.targetbag, move.targetslot)
if CursorHasItem() then