-
Notifications
You must be signed in to change notification settings - Fork 1
Networking
// From art/datablocks/weapons/rocketLauncher.cs for the rocket launcher ammo: datablock ItemData(RocketLauncherAmmo) { // Mission editor category category = "Ammo"; // Add the Ammo namespace as a parent. The ammo namespace provides // common ammo related functions and hooks into the inventory system. className = "Ammo"; // Basic Item properties shapeFile = "art/shapes/weapons/SwarmGun/rocket.dts"; mass = 2; elasticity = 0.2; friction = 0.6; // Dynamic properties defined by the scripts pickUpName = "Rockets"; maxInventory = 20; }; Just like the benefit datablocks provide to memory, they also save bandwith as the common data they contain is only sent once. Datablocks also make it easier for a client to get mods from the server without updating scripts, as the modded behavior is acquired when the mod datablocks are downloaded.
Torque uses several connection object classes to provide multiplayer networking facilities. The basic functionality is defined in the NetConnection and expanded upon with the other connection classes. The Base multiplayer networking object class is the NetConnection class, which provides the functionality to create connections between two instances of torque (or the same instance if the client is also the server). //an example of NetConnection in the wild… %connect = new NetConnection(MyNetConnection); RootGroup.add( MyNetConnection );
The primary subclass of NetConnection used by a Torque multiplayer game, utilizes everything that NetConnection does but adds game-specific networking functionality on top of that. //making the GameConnection… %gameCon = new GameConnection(MyGameConnection); RootGroup.add(MyGameConnection);
//setting a control object, we do this on the server side MyGameConnection.setControlObject(PlayerOne);
This is the named instance of a GameConnection object that represents the Client Connection to the Server. It is created on the scripting level: //from core/scripts/server/server.cs %conn = new GameConnection( ServerConnection ); RootGroup.add( ServerConnection ); This is the named instance of a NetConnection/GameConnection (depending on which class you use) object that is created when it is connectLocal() method is performed successfully. //furthering the ServerConnection example from before %conn = new GameConnection( ServerConnection ); RootGroup.add( ServerConnection );
//an example of setting the port %myPort = 12345; //… if( setNetPort(%myPort) ) { //success! echo("successfully connected to port:" SPC %myPort); } else { //failure error("error connecting to port:" SPC %myPort);
//activate connections on our selected port allowConnections(true);
//an updated example from core/scripts/server/server.cs…
//do all of the above in one call if( createServer(%type, %myMission ) { //server for mission created properly echo(%type SPC "server created successfully for mission:" SPC %myMission); } else { //fallback behavior error("error in" SPC %type SPC "server creation process!" SPC %myMission); }
// from server.cs again… with a few extra comments
//do all of the above if( createAndConnectToLocalServer(%type, %myMission) ) { //local server & local client connection for mission created properly echo(%type SPC "server & client created successfully for mission:" SPC %myMission); } else { //fallback behavior error("error in" SPC %type SPC "server & client creation process!" SPC %myMission); } It is pretty straightforward, you can look at how the script helper function connect(%server) works to see this in action: // Example from the connect(%server) script helper function in : // core/scripts/client/missionDownload.cs… A Package is a set of modified scripts that can be loaded "over" preexisting functions, and unloaded to remove the alternate functionality. The GameCore package in a stock Torque project sets up the FPS Single and Multiplayer games. You can find the GameCore package functions in game/scripts/server/gameCore.cs.
//game core example, onConnect override, short verson… function GameConnection::onConnect(%client, %name) { // Send down the connection error info, the client is responsible for // displaying this message if a connection error occurs. messageClient(%client, 'MsgConnectionError',"",$Pref::Server::ConnectionError);
Torque has a very simple setup for sending script commands between the client and server, allowing for a great deal of flexibility in setting up your own commands. The way to send a command from the client to the server is with the commandToServer(%cmdname, %arglist…) console function. The %arglist… is any number of optional arguments that the function needs to pass to the server command. //commandToServer example, tell the server to start some giant laser mayhem commandToServer('GiantLaserAttack', %laserPosition, 12, "1.0 0.0 0.75 0.9"); For the server to process the command, use the prefix serverCmd, followed by the command name. The first argument is the game object id of the client that send the command, followed by the optional arguments given it. //serverCmd example, notice the args match up with our commandToServer() call function serverCmdGiantLaserAttack(%client, %position, %powerLevel, %laserColor) { if( $GiantLaserActive == false) { echo("Received GLA from Client:" SPC %client); //perform some giant laser mayhem beginGiantLaserAttack(%position, %powerLevel, %laserColor); } //there can only be one giant laser attack at any given time! }
commandToClient(%thatClient,'UpdateGiantLaserWorldDamage', %laserPosition, %radius); //sending a command to all the clients %count = ClientGroup.getCount(); for (%i = 0; %i < %count; %i++) { %cl = ClientGroup.getObject(%i); commandToClient( %cl, 'UpdateGiantLaserWorldDamage' , %laserPosition, %radius); }
//clientCmd example, updating our GiantLaser world damage function clientCmdUpdateGiantLaserWorldDamage( %position, %radius) { destroyPlayersInArea(%position, %radius); destroyVehiclesInArea(%position, %radius); destroyPropsInArea(%position, %radius); applyWorldDamageDecal(%postion, %radius, "GiantLaser"); breakAllWindowsInArea(%position, %radius); } As you learned with the previous section, making client/server commands in Torque is really easy. With this example, you'll learn how to make your own client/server commands. You'll use a timed command on the client to send a command to the
server saying "ready to teleport". The server will teleport the player
and send a command to the client to echo a message to the console; You'll be modifying the Stock Torque Full Template for this example, so if you have that ready to go then you're all set. First, add a file on the client for our client side commands. Call this file myClientCommands.cs and make it in the game/scripts/client directory,. Once you've done that, add a few functions to that file. //this will send the command that you're ready to start the teleport procedure function sendTeleportSignal() { %time = 5000; //a five second delay should be fine Next, add our server command functions. Make a file in the game/scripts/server directory called myServerScripts.cs, and fill it in with the following code: //this will set us up to teleport the clients in a few seconds function serverCmdTeleportReady(%client, %time) { schedule(%time, 0, "beginTeleport"); //schedule our teleport } Now, go to game/scripts/main.cs, and add the following under where the normal init.cs scripts are executed, so we can execute our new scripts: // Load the scripts that start it all... exec("./client/init.cs"); exec("./server/init.cs"); Finally, go to game/core/scripts/client/mission.cs, and add the following line at the end of the clientStartMission() script function, after $Client::missionRunning = true;, this is so a client can trigger the teleport sequence whenever they enter the game: //…
For further reading and a deeper understanding of Torque's Netcode, check out: |