Overview
The trading system enables secure player-to-player item exchange using OSRS-style mechanics with a two-screen confirmation flow and comprehensive anti-scam features. Location:packages/server/src/systems/TradingSystem/
How Trading Works
Initiating a Trade
- Right-click another player and select “Trade with [Player Name]”
- Proximity check: Players must be adjacent (1 tile)
- If out of range, your character automatically walks to them
- Trade request sent when you reach them
- Trade request appears as pink clickable chat message
- Target player clicks the message or accepts via modal
Trade Flow
Offer Screen
The first screen where players add items to their offers:- Add items: Left-click inventory items to add 1
- Context menu: Right-click for quantity options
- Offer-1, Offer-5, Offer-10
- Offer-X (custom amount with K/M notation)
- Offer-All
- Value (show item worth)
- Examine (show item description)
- Remove items: Click items in your trade offer
- Partner’s offer: View what they’re offering in real-time
- Accept: Both players must accept to proceed to confirmation
Confirmation Screen
The second screen for final review (OSRS anti-scam measure):- Read-only view: Cannot modify offers
- Wealth transfer indicator: Shows value difference
- Green: You’re gaining value
- Red: You’re losing value
- Warning ⚠️ if difference >50% of your offer
- Final accept: Both players must accept again
- Atomic swap: Items exchanged in single database transaction
Anti-Scam Features
Technical Implementation
TradingSystem
Location:packages/server/src/systems/TradingSystem/index.ts
Server-authoritative system managing all trade state:
Trade Handlers
Location:packages/server/src/systems/ServerNetwork/handlers/trade/
Modular packet handlers organized by responsibility:
PendingTradeManager
Location:packages/server/src/systems/ServerNetwork/PendingTradeManager.ts
Handles walk-to-trade behavior when players are out of range:
- Zero-allocation hot path with pre-allocated buffers
- Intelligent re-pathing when target moves
- Automatic cleanup on disconnect
- Cancels on new movement command
Network Packets
Client → Server
Server → Client
Security Measures
Server-Side Validation
- Proximity checks: Players must be adjacent (1 tile)
- Interface blocking: Can’t trade while banking/shopping
- Inventory validation: Items verified at add time and completion
- Tradeable flag: Only tradeable items can be offered
- Rate limiting: Prevents spam requests
- Atomic transactions: Database locks prevent duplication
Item Swap Process
UI Components
Location:packages/client/src/game/panels/TradePanel/
Modular React components for trade UI:
Trade States
Cancellation Reasons
Configuration
Trade Constants
Rate Limiting
Testing
Integration Tests
Location:packages/server/tests/integration/trade/trade.integration.test.ts
291 lines of comprehensive tests:
- Trade request flow (initiate, accept, decline)
- Item management (add, remove, quantity)
- Two-screen confirmation flow
- Atomic swap execution
- Error handling (invalid items, full inventory)
- Disconnection handling
- Concurrent trade prevention
Test Strategy
Following project philosophy:- Real
TradingSysteminstances (no mocks) - Real database transactions
- Integration-level testing
- Helper functions for test setup
Common Issues
Trade Request Not Appearing
Cause: Players not in proximity range Solution: Walk closer to the target player (must be adjacent)Items Disappearing During Trade
Cause: Inventory full or items changed Solution: Ensure you have free inventory slots for incoming itemsTrade Cancelled Unexpectedly
Possible causes:- Player disconnected
- Player moved away (broke proximity)
- Player opened another interface (bank/shop)
- Items were modified in inventory
Related Documentation
Inventory System
28-slot inventory management and item stacking
Economy Overview
Banking, shops, currency, and loot drops
Social Features
Friend system and private messaging
Security
Server-authoritative design and anti-cheat