|[ LiB ]|
This book isn't the be-all and end-all of MUDs. I've only scratched the surface of what you can do, and you should consider a number of things when thinking about the future.
I mentioned a few times before that the databases for the SimpleMUD and the BetterMUD aren't real databases, but rather simple classes that store objects in system memory. After running a MUD long enough, you'll have enough objects in memory to be a major drain on the system. In most systems, most of these items sit around and are not used by anything for most of the time. So why should you waste resources keeping them around?
Another reason to use a database is that databases are abstractable, and therefore you can keep them on a separate computer and gain a slight processing advantage, especially for very large systems. If you decide to look into databases, both Python and C++ have APIs that you can use with SQL databases, which are the most common kind.
A concept I've always been fond of has been online editing of games . The basic idea is that you'll be able to log into the game, and modify or add new entities to the game through a remote client. The easiest way to implement this is to use simple clients that upload the new datafiles, and then tell the game to reload them.
A slightly more advanced system would allow direct modification of entities while they are in memory, but this can get to be difficult to manage at times, especially if the entity in question is being used within the game. Imagine loading up a sword, and then modifying it in an editor. While you're doing that, the sword can be modified by anything in the game, and its characteristics may have changed once you reinserted the entity.
To solve this, think about making a system of "locks" for your entities. When editing a room, make sure no one can enter it. When editing a player, make sure he can't log on, and so on. Either do that, or do your editing late at night when very few people are playing.
When you think about how a MUD works, you realize that it's basically just a messaging system. People log on, and perform different kinds of actions; the game engine figures out what data these actions change, and thens tell every client who cares about the action.
Typically MUDs never see more than a few dozen people at a time, a hundred or so at most; but there's absolutely no reason why MUD technologies can't be extended infinitely. Theoretically, the BetterMUD on Linux should support up to 1,024 people, but I don't know 1,024 people who are willing to test it at the same time.
The only reason it's limited to 1,024 connections, however, is because the connection manager is limited to the size of one socket set, which is typically (but not always) 1,024 on Linux. It's not a very difficult task to upgrade the networking system to handle more than that, but at that point, you're going to need a new strategy.
Once you need to handle a lot of connections, you'll discover that multithreading is your best friend. The best strategy is to create multiple threads, so that each thread manages a collection of connections.
In fact, the best way you can do this is by separating the game and connection stuff into completely different threads. The network threads would continuously monitor for any network activity and cache the input somewhere for the game thread to get later.
When you think about a modern MMORPG, you can see that it's basically a MUD with a graphical client attached. The major difference between the two is the way that maps are usually represented. Instead of having one room that contains many people, you'll have a large area composed of many tiles, which you can conceptualize as miniature rooms.
The notification system is going to be a little different, because you'll have to go to every tile that can see where an action is occurring, and tell everyone within that radius about what happened. So instead of telling one room about an event, you'll find yourself searching for everything within a 32 tile radius (or whatever) and telling them that something happened . At the very bottom core , a MUD/MMORPG is just a system that figures out what happens, where it happened, and who it happened to, while at the same time sending the messages about what happened to all the network connections.
In modern MMORPGs almost all of the fancy graphic stuff is handled by the clients, letting the server take a precious break from the rendering graphics.
Of course, since you're handling so much more data, and probably have graphical sprites or models representing everyone, you're going to have to send much more data out to clients. Every time a character changes its state (for example changing from walking to resting or running or talking), you should probably send out a state change notification. Of course since rooms in MMORPGS are smaller objects now, characters are going to be moving in and out of them at a much faster rate. Obviously this means that you're going to need a lot of bandwidth, which gets quite expensive.
This makes it really important that you send data only to clients that need to be informed. A client in one area that can't see something happening 40 tiles away shouldn't know about it at all, so there's absolutely no reason to inform him.
MMORPGs use another trick for faster data transmission binary packed data . For everything in this book, I used ASCII for the data transmission, so that information is sent as text strings. For binary packed data, the only thing you would send as strings would be actual strings; everything else would be sent as its numerical binary representation instead.
For example, sending the number 128 in ASCII mode takes three bytes of data, one for each digit. On the other hand, you should know that a single byte of data can represent numbers from 0255, so you could easily pack the number into a single byte, thereby reducing the amount of data you sent by 3 times.
Of course, to make things more flexible, you're probably going to want to use 16-bit (2 bytes) or 32-bit (4 bytes) numbers, because 0255 is a very small range. Using 16-bit numbers, every number larger than 99 saves you at least a byte, and at most 3 bytes (since the largest number that you can send is 65,535, which is 5 characters). The downside is that any number below 10 wastes a byte, since 09 only take up 1 byte in ASCII, but 2 bytes when packed into binary as 16-bit integers. Start here
Using 32-bit numbers offers a potentially higher data compression savings, because you can store numbers up to 10 digits in size in just 4 bytes. The downside is the fact that you very rarely need to send 10-digit numbers, and instead will probably be sending numbers much smaller than that far more often. When sending 32-bit integers, you waste 3 bytes when sending numbers 0-9, 2 bytes when sending 10-99, and 1 byte when sending 100999. It's only when sending numbers 10009999 that you break even, and when you use numbers larger than 9999, you get a compression savings.
Another big problem with binary data transmission is the endianness of the data. Some machines like to store the byte with the least significant data in the first byte; others store it in the last byte. So the number 128 could be represented in binary form as 0xF0000000 on a little-endian machine, and 0x000000F0 on a big-endian machine (remember 0xF0 is 128 in hexadecimal). Ultimately this means that for every piece of binary data that you send, you need to make sure it's in the proper form for your machine. This can end up giving you a lot of extra work to do, but luckily you don't need to make the server do any of that extra work. Instead, you can make your clients do all the data translation and assume that the server only transfers binary data in one particular way. This has the net effect of distributing all of this extra processing among everyone who is connected, and freeing your server from that work.
Once you get past a certain number of connections, one computer just isn't going to be able to handle the load, no matter how powerful it is. A very popular way of making an MMORPG or MUD work with thousands of connections is to use distributed computing , so that the game runs on multiple computers. The easiest way to do this is to split up your realm into two or three regions, and have each computer control everything within one given region, and switch connections between the different servers when the characters move between the regions .
Pretty much the only thing you have to worry about in this situation is load balancing . Your servers can become unbalanced quite easily if one region is more popular than another. There's little point in having three or four distributed servers if everyone is going to be on just one of them.
With good planning, you can solve this kind of a problem. You should make it so that people want to go to all areas of the game, and that one region doesn't have one huge benefit over another.
Some MMORPGs solve this problem by literally forcing you out of an area by teleportation if there are too many people, but your players won't like this. It's unnatural , first of all, and it's annoying as well. Nothing will anger your players more than being sucked out of an area while they're in the middle of doing something.
Another option would be to prevent people from entering a new area if the server is full, but that can also get annoying. In the end it all comes down to good level design.
The best part of a distributed setup is that it meshes into the database design very well, if you have a professional database stored on a specific database server. You could have three machines, two running the game and one storing the database, and the two game machines never worry about synching data up with each other.
You're going to have to decide early on whether you want to charge people to play your MUD. Back in the bad old days of computing, charging for playing a MUD was not only common, but expected.
Nowadays, servers are so cheap that almost all MUDs you can find are free to play, which makes pay-per-play a somewhat obsolete model. If you were to add on a graphical client, I guarantee that people would be more inclined to play, but the bottom line is that people just don't like dishing out money every month for a game.
The good news is that running a MUD is cheap. Both the SimpleMUD and the BetterMUD are costing me about $16 a month to run, which is cheaper than most ISPs cost. If you can't afford that, it's pretty easy to collect donations, or charge a one-time fee for playing the game. If you charge $20 for someone to join the game, and you have 40 people pay it, you've just collected enough money to run your MUD for four years .
You can also fund your adventures by having a donation system, whereby people can donate through Paypal.com, personal check, or whatever. To make people want to donate money, you might consider offering incentives , but you must be very careful about these.
When people give you money, you might want to give them something special in return. Initially, this seems like a great idea. It's a great way to reward people for supporting your server. But this can lead to major problems if you're not careful.
Say you decide to bestow a special sword on someone who donated a hefty sum and that sword gives that character a nice boost over other players. This will probably raise resentment against him. What happens when someone steals that sword? Does the thief have the right to keep it? If stealing is allowed in the game, the thief will definitely love to keep the sword, and the donator will have lost real money in the game, since he essentially paid for the sword. Either way, you're going to have at least one angry player.
What makes things even worse is the fact that stealing the bonus item is almost indistinguishable from theft in real life. The fact that the donator spent real money obtaining the item means that the thief essentially stole real money from the donator. This may even get you into some legal troubles. My recommendation is to stay away from this kind of thing. What about players who use donations as a way of not playing? Someone can log on, donate lots of money, and get lots of bonus stuff, and completely skip playing on the lower levels of the game. Someone who played for a few weeks to get past those levels is going to be angry that someone else can just come into the realm and pay real money to advance.
Another downside is figuring out what kind of bonuses to give to players when they donate money. If you do give them some kind of super weapon, it may not be so super a few weeks later when they've outgrown it. In a virtual world, things are constantly changing, and any bonus you give to someone one week may not be worth anything later on. This also has a tendency to anger people.
The bottom line is that you really shouldn't give tangible things to people as bonuses. It would probably be a better idea to give donators special abilities that no one else can have, or give them special ranks, letting everyone in the realm know that they are important.
Real money tends to bring out the worst in people.
|[ LiB ]|