Slashdot Mirror


Designing Multiplayer Game Engines?

mikera asks: "I'm a pretty experienced programmer but I've just embarked on my first (massively?) multiplayer strategy game. To make things even more interesting, I've decided to write it in C# and pick up a new language at the same time. I've chosen a client-server architecture where the server holds the one 'true' state of the world. The only communication from clients would be commands to units, which is simple enough, but the server will have to propagate game state changes (events) to all clients. I would like to ask Slashdot readers if they have solved a problem like this before or can offer some opinions on the best way to implement a solution."

"Lag is not really critical, but I still want things to be responsive and it must scale up well with the number of clients. The size of the map data, the complexity of the objects and bandwidth constraints rule out sending the complete game state, so only incremental updates will work. The situation is further complicated by the need to limit updates to just the areas of the map that are visible to a given player/team - this is clearly necessary to prevent client-side hacks such as gaining full map knowledge.

I understand the theory well enough, but I'm interested in practical advice on how to implement a solid architecture. What should the object model look like? How do I propagate events that are only partly within a client's field of view? Are there any novel features in C# that might make my life easier? How can I make the networking code as transparent as possible so I don't have to write SendUpdate() after every assignment?"

Your comments, insights, hints and flames are eagerly awaited."

6 of 397 comments (clear)

  1. Mud-DEV mailing List by Oriumpor · · Score: 4, Informative

    the mudd developer mailing list is an excellent source of information on exactly this sort of topic... although not specifically regarding the STRATEGY portion of online gaming... most of the issues you have spoken of have already been resolved... take a look at the archives publicly available at https://www.kanga.nu/lists/listinfo/mud-dev

  2. Re:Not doing two things at once by FFFish · · Score: 5, Informative

    Especially considering that, say, Python already has MP libraries. A research paper from UO, another fellow who's trod this path before, several MUD/MOO/MP libraries and games, Merchant Empire, Twisted, Eve, and so on.

    Using Python would allow this fellow to achieve his goal of learning a new language, fast. He can then properly focus on the important things: program structure and gameplay.

    --

    --
    Don't like it? Respond with words, not karma.
  3. Re:WorldForge by Shiny+Metal+S. · · Score: 5, Informative
    Mod me however you feel like. The truth is that I usually read at +1 so I don't see AC posts until they're modded up. But that's not important.

    The important thing is that I really like the The WorldForge Project (in fact, it's one of my favourite projects (if not the favourite project), promoting the idea of free software to broader audience.

    They're doing amazing work and I simply can't imagine what will they achieve in few years, but I'm sure all of current proprietary games won't even compare with those developed as a part of The WorldForge Project

    So yes, I think promoring WorldForge is worth losing all of my karma.

    Now back on topic...

    You may want to announce your plans on the cpptraining at worldforge.org mailing list. It's originally meant to learn C++, not C#, but it's read by people who want to learn how to write MMORPGs, and those who want to and really can learn, like Bryce Harrington, so it's a good place to find people who can help with your project.

    Also check out the other WorldForge mailing lists, especially Protocols, Server, Client and General.

    Read the Development Area on WWW. Read about servers and clients. Use WorldForge protocols and libraries. Download games and read the source. You'll find there everything you need.

    --

    ~shiny
    WILL HACK FOR $$$

  4. beware floating point! by rufusdufus · · Score: 5, Informative

    I made a 3d game engine and in my cleverness, I figured I'd reduce load on the server by offloading the physics asynchronously onto the clients. I learned the hard way that THIS WONT WORK. The reason is that different floating point processors get slightly different answers in some instances. Indeed, if all processors are the same stepping of the same intel processor, you'll be fine, however for example an Athlon might in some rare circumstance be different by the very last decimal point from an Intel. The butterfly effect will eventually catch up to you and the Athlon machine will for example detect a collision where the intels didn't.
    Using emulation or fixed point is either too slow or too inaccurate, so I ended up just doing all the work on the server and doing continual sychronization.

    To be more precise, in order to smooth out 'lag' time, the clients would do their own emulation, but would resychronize all decisions on the 'heartbeat'. Using interpolation, this worked out to have great apparent lag response, even lag times of 3 seconds were smoothed out. The only problem then was when a client's lag was unstable, fluctuating a lot. I smoothed this out by emulating a 1 second lag in all circumstance, so everyone has a smoothed out lag response which isn't too bad to play. Only unstable lag of 2 seconds or more caused a problem, where that client would see his character jump around everytime synchronization kicked in.

  5. Here's the basics by Adam+Wiggins · · Score: 4, Informative
    • The game makes a connection to one (or more) other games via UDP. UDP is ideal because it doesn't guarentee that the packets will arrive in order, or even that they will arrive at all - but it does guarentee that any packet that arrives will be intact and unaltered.
    • The games need to time sync to each other, by sending "here's what time it is" messages to each other and then recording how long the trip took - much like ping.
    • Update packets are sent whenever an object changes. You can do this one of two ways. One is to explictly setting a "changed" flag on the object, and then at the end of the update loop check to see if that flag is set, and if so transmit an update packet. The second is to have a "compare" and a "copy" function for all game objects; you can create a copy of the object at the beginning of the pulse, and then compare it to the current one at the end of the pulse. If they are different, transmit the update packet.
    • Update packets must not rely on each other. They must contain all pertinent information about the object. Typically that will include its current position, its current velocity (vector of motion), animation state, hitpoints, and so forth.
    • The timestamp on received update packets should be compared to the most recently received packet for the object that it applies to. If it is older, discard it. (Remember, UDP can deliver out of order.)
    • The game uses data about the objects' motion and state to continue to animate the object moving even inbetween packets -sometimes called "dead reckoning." When an update packet is received that shows the object in a slightly different position, the object should interopolate (sometimes known as "lerping" in the industry) to its new position so that it does not appear to pop.


    The only remaining issue is what we call "who is right?" If one game claims that a ship blew up because it was hit by shot, and another game claims that the ship dodged at the last minute, who is right? If the game is client-server, the answer is easy: the server is always right. In fact, clients shouldn't even display "big" events like a ship blowing up until it has confirmation from the server that that is what really happened. (Sometimes it's a good idea to use "hint" animations - if the client expects that a ship has been hit and is going to explode, but hasn't received confirmation from the server yet, you might want to show a shower of sparks. Then, if the confirmation is received a moment later, the explosition doesn't seem to be delayed quite so much.)

    In peer-to-peer, things get much tougher. In some cases one of the peers simply declares itself a server, in which case you have the situation above. In true peer-to-peer, it's simply up to the game designers. The most obvious choice is to make each machine responisble for its own position as well as the position of the objects its has created. So the player controlling a given ship has the last say on where that ship was at any given moment.

    In some cases, you may find that certain game elements (especially if it is an action game) don't work very well when you have to deal with 100ms or more of delay on network traffic. In that case you may want to remove or change those elements. You should pick a number where represents your "maximum" allowable delay, based on whether your target audience is modem users or not.
  6. Re:Some advice... by curunir · · Score: 5, Informative

    Not exactly true.

    Java has a lot of overhead. But that overhead is there for a reason. Java code gets faster over time as it runs (both due to optimizations done at run-time and the fact that class loading is still an expensive operation). However, in the case of a massively multiplayer environment, Java may be (and probably is) the best choice for the server environment. In a controlled environment where the application is expected to run for a significant amount of time, Java can actually perform as well or better than natively compiled code.

    The "Java is slow" argument is soooo tired. Sure, there are many instances where Java is slower than other languages (even C#). But if you're going to knock Java's performance, explain why or shut the f@#* up.

    --
    "Don't blame me, I voted for Kodos!"