Test on a degraded network¶
The game must stay playable with 150 ms of latency, 2 % of datagrams lost or duplicated,
and 5 KB/s of bandwidth. On a local network or on one machine, none of this happens by
itself: tools/netem.sh adds it on Linux, with the kernel's
netem, and clumsy does the same on
Windows.
Linux: tools/netem.sh¶
The script needs tc (package iproute2) and root, since it changes how the kernel queues
the packets of an interface.
sudo tools/netem.sh start --ports 4242,4243 # degrade the server's TCP and UDP ports on lo
tools/netem.sh status # the rules, and how many packets went through
sudo tools/netem.sh stop # back to normal
With no option, start applies the subject's conditions to everything that goes through
lo, which is where the packets go when the client and the server run on the same machine:
| Option | Default | Effect |
|---|---|---|
--dev DEV |
lo |
Interface to degrade; for a server on another machine, its network interface (ip link lists them) |
--ports P[,P...] |
every packet | Degrade only the TCP and UDP traffic from or to these ports (the server's TCP and UDP ports), IPv4 and IPv6; the rest of the machine's traffic is untouched |
--delay TIME |
150ms |
Added to every packet |
--jitter TIME |
0ms |
Random variation of the delay; packets then arrive out of order |
--loss PERCENT |
2% |
Packets dropped |
--duplicate PERCENT |
2% |
Packets delivered twice |
--rate RATE |
40kbit |
Bandwidth, in tc units: 40kbit is 5 KB/s (kbps would mean kilobytes) |
--dry-run |
Print the tc commands without running them, without root |
start replaces the rules of a previous start on the same interface, and stop removes
everything the script added. The rules do not survive a reboot.
What the numbers mean on lo¶
The rules apply to the packets an interface sends. On lo every packet is sent once,
so each direction gets them:
- Delay: a request and its answer are each delayed, so a round trip takes 2 × 150 ms =
300 ms, plus the time to send the bytes at 5 KB/s. For 150 ms of round trip instead,
use
--delay 75ms. - Bandwidth: the 5 KB/s are shared by both directions, the client's inputs and the server's snapshots together; with four clients on one machine, by all of them. That is harsher than one player's line, where each direction has its own.
- Loss and duplication apply to each packet, in each direction.
On a real interface (--dev eth0 on the server), only what the server sends is degraded:
the inputs it receives are not. To degrade both directions, run the script on the client
machines too.
Checking that it works¶
Without --ports, ping goes through the rules:
$ sudo tools/netem.sh start
$ ping -c 50 -i 0.2 -q 127.0.0.1
50 packets transmitted, 49 received, +1 duplicates, 2% packet loss, time 9825ms
rtt min/avg/max/mdev = 339.270/340.093/359.342/3.033 ms, pipe 2
$ sudo tools/netem.sh stop
With --ports, ping is untouched and only the game is degraded; tools/netem.sh status
shows the packets that went through netem (qdisc netem 40:, Sent ... pkt).
Windows: clumsy¶
clumsy degrades the traffic of the whole machine, or the part its filter selects. Run it as administrator, then:
- Filtering:
udp.DstPort == 4243 or udp.SrcPort == 4243 or tcp.DstPort == 4242 or tcp.SrcPort == 4242, here for a server on TCP port 4242 and UDP port 4243; with the client and the server on the same machine, addloopback and (...)in front, or use the localhost ipv4 all preset. - Lag: 150 ms. Drop: 2 %. Duplicate: 2 %, count 2. Bandwidth: 5 KB/s.
- Start.
clumsy applies the lag to each packet it sees: on loopback, both directions are delayed, as on Linux.
What to look for¶
- The game goes on: a lost snapshot is replaced by the next one, a lost event is resent (RFC section 5), and a duplicate is ignored.
- Remote ships move smoothly, interpolated between snapshots, a little behind.
- Nobody is disconnected: the session timeout of 5 seconds (section 5.5) is far above the delay.
- The server's logs report no malformed datagram: netem delays, drops and duplicates, it never corrupts.