fairgames.io - "The Fair Gaming WAN"
In 2019, as part of my MSc Thesis (final year project) I built a layer-2 gaming LAN over tunnels and across the Internet. This platform allowed me to play Quake over TCP. There was some other fancy crap in there to simulate delay and loss to bring every player an experience that was 'as bad as' every other player.
Network Equity Management - Leveling the Playing Field
The goal is outcome equity: regardless of connection quality, every participant experiences identical network characteristics. We achieve this by identifying the worst-case baseline and artificially degrading all superior connections to match.
Target Baseline
All connections normalized to: 150ms RTT | 20ms jitter | 0.5% packet loss | 10 Mbps symmetric
Connection Profiles & Compensation
| Connection Type | Typical RTT | Typical Jitter | Typical Loss | Bandwidth | Advantage Level | tc netem Compensation |
|---|---|---|---|---|---|---|
| Local LAN (10GE) | <1ms | <0.1ms | 0% | 10 Gbps | 🟢 Extreme | delay 149ms 20ms distribution normal loss 0.5% rate 10mbit |
| Metro Fiber (1GE) | 2-5ms | 0.5ms | 0% | 1 Gbps | 🟢 Very High | delay 145ms 19ms distribution normal loss 0.5% rate 10mbit |
| Regional Fiber | 10-25ms | 2ms | 0.01% | 500 Mbps | 🟡 High | delay 125ms 18ms distribution normal loss 0.49% rate 10mbit |
| Cable/DOCSIS 3.1 | 15-35ms | 5ms | 0.1% | 200 Mbps | 🟡 Moderate | delay 115ms 15ms distribution normal loss 0.4% rate 10mbit |
| DSL/VDSL | 20-50ms | 8ms | 0.2% | 50 Mbps | 🟠 Low-Moderate | delay 100ms 12ms distribution normal loss 0.3% rate 10mbit |
| LTE (Good Signal) | 30-60ms | 15ms | 0.3% | 50 Mbps | 🟠 Low | delay 90ms 5ms distribution normal loss 0.2% rate 10mbit |
| LTE (Poor Signal) | 80-120ms | 25ms | 1% | 10 Mbps | 🔴 Minimal | delay 30ms 0ms loss 0% rate 10mbit |
| Intercontinental | 120-180ms | 10ms | 0.2% | Varies | 🔴 Baseline | delay 0ms 10ms distribution normal loss 0.3% rate 10mbit |
| Satellite (LEO) | 40-80ms | 20ms | 0.5% | 100 Mbps | 🟣 Variable | delay 70ms 0ms loss 0% rate 10mbit |
| Satellite (GEO) | 550-700ms | 30ms | 0.5% | 25 Mbps | 🟣 Excluded* | Cannot participate in real-time equity pool |
*GEO satellite users exceed any reasonable baseline and must be handled separately or excluded from latency-sensitive activities.
Implementation Architecture
| Component | Function | Tool/Method |
|---|---|---|
| RTT Measurement | Continuous probe to determine actual client latency | ICMP/TCP SYN probes, application-layer heartbeat |
| Jitter Measurement | Statistical analysis of RTT variance over sliding window | Standard deviation of last N probes |
| Classification | Assign client to connection profile bucket | iptables MARK or nftables meta mark |
| Shaping Enforcement | Apply compensating delay/loss/rate per class | tc qdisc netem per-class or per-flow |
| Dynamic Adjustment | Re-evaluate and adjust as conditions change | Daemon polling + tc qdisc change |
tc Command Structure
Basic per-interface setup targeting marked traffic:
# Create root qdisc
tc qdisc add dev eth0 root handle 1: prio
# Add netem for each class (example: LAN users, mark 10)
tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 149ms 20ms distribution normal loss 0.5% rate 10mbit
# Filter marked packets into appropriate class
tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle 10 fw flowid 1:1
Philosophical Note
This approach prioritizes fairness over performance. The LAN player with sub-millisecond latency gains no advantage over the mobile user on congested LTE. Critics argue this "punishes" good connections; proponents argue it creates genuine competitive equity where skill—not infrastructure—determines outcomes.
The baseline target should be set to accommodate your worst acceptable participant, not your absolute worst. GEO satellite and severely degraded connections may need exclusion or alternative accommodation.