Monday, March 21, 2005

Servers revisited

Following on the last post, I'll talk about the "work" involved in each portion. We'll do them backwards, as the design of some can influence others.

World servers

Basically a database. We need to be able to add (INSERT), remove (DELETE), find (SELECT) and change (UPDATE) the object records. These objects would have many properties, and would most likely have to support a wide variety of properties, so a schema would have to be flexible (or not required). As to whether or not this is simply implemented as an SQL database, or as some sort of SOAP server, still needs to be visited, but the world server should be written in such a way that it has no knowledge of the world itself, and thus the same setup could be used from one world to the next (though the data within might not transfer between). There should be no "getSword()" or "getAlienStats()" specific to the protocol for the world server. Simple "getObject()" "createObject()" etc.

Compute servers

These, for the most part, are script engines. They run multiple scripts (written in a language I haven't begun to figure out), all of which interact with the objects in the world. These might range from creating new objects (a flower sprouts), refreshing objects (the mine produces 20 more ore now), spawning encounters (orc ambush, bandit raid, elephant stampede). They might be watching when PCs approach, might be set to timers, or set to randomly act. They might listen to PCs, in the case of NPCs. They might react to an NPC being attacked.

The scripts, and thus the compute servers, will communicate with: compute servers, either itself or others, to let other objects know that something is happening to them (NPC X is attacking NPC Y, the volcano just exploded and poured lava onto that flower, etc.); world server, to get/set/add/remove objects; and the client servers, to inform them of changes within their clients' view (monsters just appeared, you now see a field of carrots, it's raining).

The compute servers, therefore, should also have no "knowledge" of the world; they should just run scripts, all of the same language. This scripting language does the same thing in a fantasy world as it would in a futuristic world, as it would in a historical world: at time X a monster Y will appear in region Z; if NPC A sees a creature of type B, it will run away. The values of X, Y, etc. are specific to the world, but that is up to the script, not the compute server. In the end, the compute server acts on behalf of the many scripts it's running, and thus speaks the generic protocol of "getObject()" etc. to the world server, and "showObject()" etc. to the client server. Therefore, a compute server should be usable from one world to the next, much as the world server is, though it will likely be loaded with different scripts.

Client servers

Here we get a bit different. The client server is largely responsible for enforcing the rules of the world. It has to decide whether or not the commands from the client are valid (never trust the client!) as well as if the commands are successful. Can the character pick that item up? Can they use that object? It also has to relay in-game events back to the client, though this is largely a communicative role, as we trust the results of what the compute server does.

Does this require the client server to be world-specific? Or is it possible to abstract all the rules into a set of numbers, or perhaps formulate them into a few dynamic libraries that are plugged in? Or even write them in the same scripting language in which the rest of the world is run? Should these rules be moved, then, into the compute server instead, and just leave the client server's role as a trusted version of the client itself?

The more I think about it, this is the way it should be. If a player tries to use an object, that object's script should run on the compute server, and it will decide whether that's allowed, whether the character is close enough, etc. This way, world-specific rules are handled by the scripts.

So is there a need for a client server? Yes, because we still need a sanity checker; something that can determine if the requests coming from the client are "well formed". Are they sending commands too fast? Did they somehow say "eat the chair" even though the client is designed to not allow that action (and thus the user must have forged a packet, or hacked the client)? Did they try to wear a monster on their head?

While a lot of these things could also be handled in the scripts, there will be other things that aren't going to be definable in the scripting language. Maybe. Until world design actually starts (and client design, too), this is an open question, as is how generic the client server can be written for a specific world.

Login server

This can probably be done very generically, as all worlds most likely need a way to login, might need a way to choose the world they want to connect to, need a way to choose from a possible list of characters to play (or, to accept character creation from the client). With the exception of character creation, this is all very generic to any world.

Character creation can either happen through the login server (as a series of communications between the client and, perhaps, the client server), or could be done fully on the client (though verified by the client server). This leaves out any world-specific names, classes, or numbers from the login server. It's just a vessel for authenticated connectivity between a client and their world.


Though not a server, we might as well discuss it here. While it might seem that a client will be very world-specific, I don't think it has to be so. As long as the client engine (text, 2d, 2.5d, 3d) supports external resource files, the same client can run the fantasy world as it can the futuristic one. Looking at the files for Ultima Online, for instance, you could change the majority of it into a completely different world just by editing them (with a lot of time to redraw every item, monster and tile in a different setting). The only thing remaining would be the text labels and messages that are received from the server.

The client is all about the interface; how to see what's going on, and how to influence the goings-on. It's all about "walk here", "pick this up", "attack that", "say this to her". Nothing world-specific. The same client, if done right, will just access a different set of data files to get its graphics, it's themed interface (skill lists, gump graphics, etc.) but all games boil down to the same actions (though how the client performs these actions is what can make or break the game.

All the above basically shows my motivation for this project: that I should be able to write a foundation on which a variety of games can be "plugged" into. Players would then download different resources (graphics, sound), and the designers would design new worlds (in the form of the scripts that run on the compute servers). And these, really, are a separate project, though I might just talk about them here anyway...

No comments: