Anomaly Detection
Anomaly detection is the rule-based half of fraud catching: a set of deterministic checks for the manipulation patterns that show up again and again. It runs over recent trades each time the engine trains, writes what it finds to an internal report log, and raises a console alert for the serious ones. Like everything here, it flags for review and never blocks a trade.
The checks
| Check | What it catches | Key setting |
|---|---|---|
| Price outlier | A sale priced far from the item's recent moving average, adjusted for genuine trends so a rising price is not mistaken for fraud. | zScoreThreshold (default 3.0) |
| Wash trade | A player sells an item then re-buys the same item within a window, or two players pass an item back and forth (A to B, then B to A). | washTradeWindowHours (default 24) |
| Coordinated activity | A burst of trades of one item in a short window driven by only a few players. | coordinatedWindowMinutes (default 5) |
| Volume spike | A single trade of an unusually large quantity. | bulkVolumeThreshold (default 576) |
| Below shop price | A player sale more than 20% under what your server shop pays for the item, grouped per seller, buyer and item, with the lowest price setting the severity. It needs a hook that reads your shop's prices, see How Hooks Work. | Fixed at 20% |
Price outliers use a time-aware moving average (EWMA), so the baseline follows the market instead of a flat average. A coordinated burst needs at least five trades of one item, by three players or fewer, before it flags. Sales by banned players, sales in a currency with no exchange rate yet, server shop trades and money sent between players are left out of these checks.
Exploit alerts
When exploitAlertsEnabled is on, the most serious findings from a scan (a severity of about 0.75 and up) are summarised as a console warning, so a watching admin sees the headline without digging through the report log. Less serious findings are still recorded, just not shouted about. A sale 75% or more under what the shop pays reaches that level.
If you set discord.staffWebhookUrl in config.yml, the same summary is also posted to that Discord webhook. Point it at a staff-only channel. It is kept apart from the public sales feed and works whether or not that feed is on.
Every threshold here lives under economyEngine.anomalyDetection in config.yml. The learned side of fraud catching, which needs no tuning, is on Fraud Detection.