It’s been a while since I’ve done any serious game network programming. That is why I was immediately reminded of how hard it was when I got to doing some mesh server topology programming for my game, which I’ve come to realize is essentially an MMO.
Programmers who haven’t done game network programming before naively think of winsock, sendto and recvfrom, and simple serialization. But those functions aren’t the issue. The issue is the nature of the internet and the changes this fundamentally places on how you program.
First, your game code interactions are all asynchronous. You can mitigate this with a powerful low level library, like RakNet, which can impose packet ordering and other features. However, even with that different systems are still asynchronous in relation to each other and there is no way around that. So you might be able to order player A getting into a tank and then driving it, but you can’t order player A in relation to player B, who may have destroyed the tank before OR after player A got in. It’s very similar to writing multithreaded code, except you don’t have the help of synchronization objects (mutex, semaphore, etc).
Second, security is a whole world of worry. Whereas before you only had to worry about what you did write, now you have to worry about what you didn’t write. If you didn’t check for buffer overflow, data underflow, modified/corrupted data, or valid data sent in invalid circumstances you have an exploitable hole. What this means is that for every single packet you get, you have to think of every possible permutation of what the data could possibly be. If you have 100 different kinds of allowed packets, you have to check for overflow 100 times, underflow 100 times, invalid data 100 * the number of variables per packet, and worst of all every possible permutation of world state and packet type.
Third, your code now has to be very robust. You can’t really use fixed-size arrays because what is the longest string someone might type? Where before a function may have just failed, now you need to have error recovery. Your server has to be absolutely crash proof and on top of that you need a relauncher in case it does crash. You may have only logged very common circumstances before but now you need to log every detail of every possible event because the one thing you didn’t log is the one exploit that someone is going to find and use.
Fourth, if you don’t have a communications library, like RakNet, you’ll either end up writing one the hard way or else changing a lot of game code to compensate for not having things such as flow control, packet ordering, security, and reliability. This is not a trivial task.
Lastly, network programming brings with it a lot of required support functionality you wouldn’t otherwise have had to do. Some of these include an autopatcher, different client/server programs, a master server, network statistics tracking, and possibly a database.