|
Classes and functions related Torque 3D networking. More...
Classes | |
class | AIClient |
Simulated client driven by AI commands. More... | |
class | AIConnection |
Special client connection driven by an AI, rather than a human. More... | |
class | GameConnection |
The game-specific subclass of NetConnection. More... | |
class | NetConnection |
Provides the basis for implementing a multiplayer game protocol. More... | |
class | NetObject |
Superclass for all ghostable networked objects. More... | |
class | SimpleMessageEvent |
A very simple example of a network event used by SimpleNetObject. More... | |
class | SimpleNetObject |
A very simple example of a class derived from NetObject. More... | |
Functions | |
string | addTaggedString (string str) |
Use the addTaggedString function to tag a new string and add it to the NetStringTable. | |
string | buildTaggedString (string format,...) |
Build a tagged string using the specified format. | |
void | closeNetPort () |
Closes the current network port. | |
void | commandToClient (NetConnection client, string func,...) |
Send a command from the server to the client. | |
void | commandToServer (string func,...) |
Send a command to the server. | |
string | detag (string str) |
Returns the string from a tag string. | |
void | DNetSetLogging (bool enabled) |
Enables logging of the connection protocols. | |
void | dumpNetStats () |
Dumps network statistics for each class to the console. | |
void | dumpNetStringTable () |
Dump the current contents of the networked string table to the console. | |
string | getTag (string textTagString) |
Extracts the tag from a tagged string. | |
string | getTaggedString (int tag) |
Use the getTaggedString function to convert a tag to a string. | |
void | removeTaggedString (int tag) |
Remove a tagged string from the Net String Table. | |
bool | setNetPort (int port, bool bind=true) |
Set the network port for the game to use. If bind is true, bind()will be called on the port. | |
Variables | |
int | $pref::Net::LagThreshold |
How long between received packets before the client is considered as lagging. | |
int | $Stats::netBitsReceived |
The number of bytes received during the last packet process operation. | |
int | $Stats::netBitsSent |
The number of bytes sent during the last packet send operation. | |
int | $Stats::netGhostUpdates |
The total number of ghosts added, removed, and/or updated on the client during the last packet process operation. | |
int | $pref::Net::PacketRateToClient |
Sets how often packets are sent from the server to a client. | |
int | $pref::Net::PacketRateToServer |
Sets how often packets are sent from the client to the server. | |
int | $pref::Net::PacketSize |
Sets the maximum size in bytes an individual network packet may be. | |
Callbacks | |
| |
void | onDataBlockObjectReceived (int index, int total) |
Called on the client each time a datablock has been received. | |
void | onLightManagerActivate (string name) |
A callback called by the engine when a light manager is activated. | |
void | onLightManagerDeactivate (string name) |
A callback called by the engine when a light manager is deactivated. |
Classes and functions related Torque 3D networking.
Torque was designed from the foundation up to offer robust client/server networked simulations.
Performance over the internet drove the design for the networking model. Torque attempts to deal with three fundamental problems of network simulation programming: limited bandwidth, packet loss and latency.
An instance of Torque can be set up as a dedicated server, a client, or both a client and a server. If the game is a client and a server, it still behaves as a client connected to a server - instead of using the network, however, the NetConnection object has a short-circuit link to another NetConnection object in the same application instance. This is known as a local connection.
Bandwidth is a problem because in the large, open environments that Torque allows, and with the large number of clients that the engine supports (depending on amount of data sent per client, game world complexity, and available bandwidth), potentially many different objects can be moving and updating at once. Torque uses three main strategies to maximize available bandwidth. First, it prioritizes data, sending updates to what is most "important" to a client at a greater frequency than it updates data that is less important. Second, it sends only data that is necessary. Using the BitStream class, only the absolute minimum number of bits needed for a given piece of data will be sent. Also, when object state changes, Torque only sends the part of the object state that changed. Last, Torque caches common strings (NetStringTable) and data (SimDataBlock) so that they only need to be transmitted once.
Packet loss is a problem because the information in lost data packets must somehow be retransmitted, yet in many cases the data in the dropped packet, if resent directly, will be stale by the time it gets to the client. For example, suppose that packet 1 contains a position update for a player and packet 2 contains a more recent position update for that same player. If packet 1 is dropped but packet 2 makes it across to the client, the engine shouldn't resend the data that was in packet 1. It is older than the version that was received by the client. In order to minimize data that gets resent unnecessarily, the engine classifies data into four groups:
Latency is a problem in the simulation because the network delay in information transfer (which, for modems, can be up to a quarter of a second or more) makes the client's view of the world perpetually out-of-sync with the server. Twitch FPS games, for which Torque was initially designed, require instant control response in order to feel anything but sluggish. Also, fast moving objects can be difficult for highly latent players to hit. In order to solve these problems Torque employs several strategies:
The network architecture is layered: at the bottom is the platform layer, above that the notify protocol layer, followed by the NetConnection object and event management layer.
Ghosting is the most complex, and most powerful, part of Torque's networking capabilities.
It allows the information sent to clients to be very precisely matched to what they need, so that no excess bandwidth is wasted. The control object's onCameraScopeQuery() is called, to determine scoping information for the client; then objects which are in scope are then transmitted to the client, prioritized by the results of their getPriority() method.
There is a cap on the maximum number of ghosts; ghost IDs are currently sent via a 12-bit field, ergo, there is a cap of 4096 objects ghosted per client. This can be easily raised; see the GhostConstants enum.
Each object ghosted is assigned a ghost ID; the client is only aware of the ghost ID. This acts to enhance game security, as it becomes difficult to map objects from one connection to another, or to reliably identify objects from ID alone. IDs are also reassigned based on need, making it hard to track objects that have fallen out of scope (as any object which the player shouldn't see would).
resolveGhostID() is used on the client side, and resolveObjectFromGhostIndex() on the server side, to turn ghost IDs into object references. getGhostID() is used in the other direction to determine an object's ghost ID based on its SimObject ID.
The NetConnection is a SimGroup. On the client side, it contains all the objects which have been ghosted to that client. On the server side, it is empty; it can be used (typically in script) to hold objects related to the connection. For instance, you might place an observation camera in the NetConnnection. In both cases, when the connection is destroyed, so are the contained objects.
It is possible to run both the server and client within the same process.
This is typically done while developing your game, and is often required when using Torque's built-in world creation tools. This is known as a local connection.
Any time a player launches the game and chooses to host a mission, they are also making use of a local connection (all other players joining the game use a regular, networked connection). A local connection is also used when building a single player game.
Internally, a local connection short-circuits the networking layer and allows for data to pass immediately between the internal server and client. However, it should be noted that there is still the additional overhead of having seperate server and client branches within the code, even when creating a single player game. When developing your single player game, you need to be mindful that a client and server still exist within the engine.
string addTaggedString | ( | string | str | ) |
Use the addTaggedString function to tag a new string and add it to the NetStringTable.
str | The string to tagged and placed in the NetStringTable. Tagging ignores case, so tagging the same string (excluding case differences) will be ignored as a duplicated tag. |
string buildTaggedString | ( | string | format, | |
... | ||||
) |
Build a tagged string using the specified format.
void closeNetPort | ( | ) |
Closes the current network port.
void commandToClient | ( | NetConnection | client, | |
string | func, | |||
... | ||||
) |
Send a command from the server to the client.
client | The numeric ID of a client gameConnection | |
func | Name of the client function being called | |
... | Various parameters being passed to client command |
// Set up the client command // Update the Ammo Counter with current ammo, if not any then hide the counter. function clientCmdSetAmmoAmountHud(%amount) { if (!%amount) AmmoAmount.setVisible(false); else { AmmoAmount.setVisible(true); AmmoAmount.setText("Ammo: "@%amount); } } // Call it from a server function function GameConnection::setAmmoAmountHud(%client, %amount) { commandToClient(%client, 'SetAmmoAmountHud', %amount); }
void commandToServer | ( | string | func, | |
... | ||||
) |
Send a command to the server.
func | Name of the server command being called | |
... | Various parameters being passed to server command |
// Create a standard function function toggleCamera(%val) { // If key was down, call a server command named 'ToggleCamera' if (%val) commandToServer('ToggleCamera'); } // Server command being called from above function serverCmdToggleCamera(%client) { if (%client.getControlObject() == %client.player) { %client.camera.setVelocity("0 0 0"); %control = %client.camera; } else { %client.player.setVelocity("0 0 0"); %control = %client.player; } %client.setControlObject(%control); clientCmdSyncEditorGui(); }
string detag | ( | string | str | ) |
Returns the string from a tag string.
void DNetSetLogging | ( | bool | enabled | ) |
Enables logging of the connection protocols.
enabled | True to enable, false to disable |
void dumpNetStats | ( | ) |
Dumps network statistics for each class to the console.
void dumpNetStringTable | ( | ) |
Dump the current contents of the networked string table to the console.
string getTag | ( | string | textTagString | ) |
Extracts the tag from a tagged string.
string getTaggedString | ( | int | tag | ) |
Use the getTaggedString function to convert a tag to a string.
This is not the same as detag() which can only be used within the context of a function that receives a tag. This function can be used any time and anywhere to convert a tag to a string.
tag | A numeric tag ID. |
void onDataBlockObjectReceived | ( | int | index, | |
int | total | |||
) |
Called on the client each time a datablock has been received.
This callback is typically used to notify the player of how far along in the datablock download process they are.
index | The index of the datablock just received. | |
total | The total number of datablocks to be received. |
void onLightManagerActivate | ( | string | name | ) |
A callback called by the engine when a light manager is activated.
name | The name of the light manager being activated. |
void onLightManagerDeactivate | ( | string | name | ) |
A callback called by the engine when a light manager is deactivated.
name | The name of the light manager being deactivated. |
void removeTaggedString | ( | int | tag | ) |
Remove a tagged string from the Net String Table.
tag | The tag associated with the string |
bool setNetPort | ( | int | port, | |
bool | bind = true | |||
) |
Set the network port for the game to use. If bind is true, bind()will be called on the port.
This will trigger a windows firewall prompt. If you don't have firewall tunneling tech you can set this to false to avoid the prompt.
int $pref::Net::LagThreshold |
How long between received packets before the client is considered as lagging.
This is used by GameConnection to determine if the client is lagging. Its value is in ms. If the client is indeed lagging, setLagIcon() is called to inform the user in some way. i.e. display an icon on screen.
int $Stats::netBitsReceived |
The number of bytes received during the last packet process operation.
int $Stats::netBitsSent |
The number of bytes sent during the last packet send operation.
int $Stats::netGhostUpdates |
The total number of ghosts added, removed, and/or updated on the client during the last packet process operation.
int $pref::Net::PacketRateToClient |
Sets how often packets are sent from the server to a client.
It is possible to control how often packets may be sent to the clients. This may be used to throttle the amount of bandwidth being used, but should be adjusted with caution.
The actual formula used to calculate the delay between sending packets to a client is:
Packet Update Delay To Client = 1024 / $pref::Net::PacketRateToClient
with the result in ms. A minimum rate of 1 is enforced in the source code. The default value is 10.
int $pref::Net::PacketRateToServer |
Sets how often packets are sent from the client to the server.
It is possible to control how often packets may be sent to the server. This may be used to throttle the amount of bandwidth being used, but should be adjusted with caution.
The actual formula used to calculate the delay between sending packets to the server is:
Packet Update Delay To Server = 1024 / $pref::Net::PacketRateToServer
with the result in ms. A minimum rate of 8 is enforced in the source code. The default value is 32.
int $pref::Net::PacketSize |
Sets the maximum size in bytes an individual network packet may be.
It is possible to control how large each individual network packet may be. Increasing its size from the default allows for more data to be sent on each network send. However, this value should be changed with caution as too large a value will cause packets to be split up by the networking platform or hardware, which is something Torque cannot handle.
A minimum packet size of 100 bytes is enforced in the source code. There is no enforced maximum. The default value is 200 bytes.