Skipping ticks is done before the heavy calculation of occupied/empty/full slots — less extra work on each event.
With ignoreEmptyStacks enabled, empty stacks are discarded immediately, without causing an inventory scan.
Fast matching of many items (one pass through the inventory with boolean[] flags and early exit — without allocations, noticeably faster on large inventories and long lists of conditions).
Early filtering by slots (slots.matches(full, empty, occupied) is performed first, excluding further calculations in case of a mismatch.).
Preserved fast path for one target (with items.size() == 1, the check is done on changed without a full scan — the behavior is left, but surrounded by earlier cutoffs.).