Torque/Networking/Server and Client
From TDN
Contents |
Introduction
This article is aimed at answering what a 'server' and a 'client' are, the differences between the two, and how to write your code and script appropriately. This is one of the most fundamental yet least understood aspects of Torque and it is key to developing your game, whether it's a multiplayer game or a single player game.
What do Server and Client Mean?
|
When the Torque Engine was originally written (in those days it was known as Darkstar - this was before it was renamed to V12 by GarageGames) for Tribes, a large portion of the game was designed specifically for multiplayer. The terms 'server' and 'client' refer to the network model used and developed for the game.
'[The server] is a computer software application that carries out some task (i.e. provides a service) on behalf of yet another piece of software called a client'.
|
|
|||||||
The Server
The server is responsible for all data and operations that should be used persistently for each client. This means that all game related behavior for your game that needs to be persistent for each player (or client) should be implemented in the server code.
Here are some examples of code/script you'll find on the server side:
- Player behavior, physics, and characteristics
- Placement of shapes and interiors and their characteristics
- Artificial Intelligence
- Weapon behavior and characteristics
- Mission selection
Read over each example and ask yourself if any of those aspects of the game should behave differently on each client. The answer will most likely be a resounding no. You can see now why having a Server and Client networking model reduces cheating. A client connecting to a server can't modify his or her own player behavior code specifically because the server provides the service for it.
The Client
The client is responsible for all data and operations that should only be specific to each client. This means game behavior that cannot, and should not be imposed on each client.
Here are some examples of code/script you'll find on the client side:
- All Graphical User Interfaces (GUIs), menus, Heads-Up Display (HUD), etc.
- Sound and Video settings
- Rendering
- Interpolation between server "ticks"
- Server selection
Again, read over each example and ask yourself if any of those aspects of the game should behave persistently for each client. As expected, the answer to each of those questions is most likely a no. Most people would be displeased with a server that when connected to, forced them to a lower resolution, reduced video settings, and then chose a sound driver that they currently did not have installed or even had the hardware for.
But it's all up to you of course.
Server and Client in Script
This topic is extremely important and is at first a large source of confusion when newcomers start scripting with Torque. It can cause a lot of headaches so make sure you read this first before delving too far into scripting.
Server and Client Scripting
One of the most difficult aspects of scripting with the Server/Client model is to understand that Torque does not distinguish between client and server in script. In fact, in the Torque example the server and client script folders are only there for organizational purposes. How exactly then, does Torque distinguish between server and client?
Torque does maintain a separate list of server and client objects in the engine. Both server and client objects call methods into the script. For example, GameConnection::onClientEnterGame() is a ConsoleMethod called on the server object of GameConnection or any of its derived types when a client enters the game. On the client, GuiControl::onWake() is a ConsoleMethod called on all objects or derived objects of GuiControl when a GUI object "wakes". Defining these ConsoleMethods in script determine the behavior of your game, whether it's on the server side or the client side.
The Torque Engine also provides script commands that provide server and client functionality. When calling the commands to steer the engine appropriately you can have your current game running as a server, client, or both. The common folder that comes with the example given helps with the appropriate command calls by defining helpful wrapper functions such as createServer(). However, when running your game as both a server and a client with the same executable there's a large potential for bugs, headaches, and frustration. The next topic deals with this issue.
Running Both Server and Client on the Same Executable
If you're running both the server and client on the same executable (by creating a single player game for example) and you are designing your game with any type of a multiplayer component there's a chance you'll have some problems when a remote client tries connecting to your server.
The problem arises from the fact that when you connect to your server on the same executable, the same script machine will contain all script data for both the server and the client. The client connecting to the server on the same executable will have access to both server and client functions, objects, etc. A remote client running a different executable will definitely not have access to the server script functionality.
What's on the client side and what's on the server side can get to be very confusing if you're developing with the server and client running on the same executable. Certain client behavior you may think would be acceptable for a client may turn out not to be when testing using a remote client. For example, TGE is strict when it comes to accessing the datablock of an object on the client. So a statement like %someObject.getDataBlock().getName() will not work for a remote client, but it will work for a client running on the same executable as the server.
There's a lesson to be learned here. If you're going to be developing a multiplayer game, make sure you test thoroughly using a remote client (connecting with a separate executable) instead of a client running on the same executable. It will force you to adhere to a server and client model and you'll avoid using "server script" when developing your client. You will catch bugs early, and you'll become adept at preventing future bugs from creeping into your script.
Communication Between Server and Client in Script
At some point in your game the client will definitely need to send information to the server and vice versa. A simple example would be a chat message that the client would want to be transmitted to every other client connected to the server. The client would send the message, the server would then receive it and then transmit it back to every client who wants to or should be listening.
The two most important functions for communication between server and client in script are commandToServer, and commandToClient. This is the staple for communication between server and client in script.
However, when using commandToServer and commandToClient and sending object IDs, it's important to remember that the ID for the object on the client is different from the one stored on the server. This is because of "ghosting". Read up on the topic and how to deal with the issue here.
Server and Client Objects in the Engine
All objects (now referring to C++ classes) that are some way involved with both the server and client are of type NetObject or one of its derived classes. This is important when writing and reading through the code of any of these types of objects. Each class contains code that is both common to the server and the client, and code that is specific to both the client, and specific to the server.
Because objects can be created both on the server side and on the client side, NetObject provides methods that help with determining the network properties of the object. For distinguishing between server and client objects the methods are isServerObject(), isClientObject(), and isGhost() which return true if they are indeed a server object, client object, or a client ghost respectively.
When reading and writing code, be careful. Take note of where these methods are and use them when certain functionality should only be either on the client or on the server.
Conclusion
Developing under a server and client model can be a bit overwhelming at first. But being able to distinguish between server and client code, and understanding the issues surrounding the server and client model with Torque, you're prepared and well on your way to developing a robust, and hack-free game.



