PeerConnection
by Charlie Sibbach · 07/03/2006 (11:25 am) · 24 comments
Download Code File
PeerConnection is a lightweight GameConnection for use between two instances of Torque. It saves bandwidth by not sending any periodic information such as moves. There is no mission downloading associated with this type of connection, so it is possible to have as many active PeerConnections as you want, without any overlap problems. They still support password-based connection limits, to protect against backdoor hacking.
It implements all the usual connection callbacks you're used to from GameConnection: OnConnectionAccepted, OnConnectRequest, OnConnect, etc., making it easy to work with. Once a PeerConnection is established, you can treat it like any other object.
PeerConnections can be used to send your own custom NetEvents over the wire with postNetEvent() at the engine level, but most people will probably find it most useful for Torque's standard Remote Procedure Call (RPC) system, i.e. commandToClient/Server. PeerConnection implements commandToPeer mainly to reduce calling confusion. The syntax of commandToPeer() is identical to commandToClient()- the first argument must be a valid PeerConnection:
commandToPeer(%MyPeerConnection, 'SomeServerCommand', "1 is the lonliest number");
Like commandToClient, it supports up to 254 extra optional arguments. On the remote side, PeerConnections use standard "serverCmd" functions, instead of custom "peerCmd" functions, in order to avoid extra bandwidth or processing costs. These functions may be called via a commandToServer call or a commandToPeer call.
The .rar file includes three files for using PeerConnections. peerConnection.cc and peerConnection.h should be placed in your engine/game folder- make sure to add them both to your project and recompile the engine! peerConnection.cs is a template script file, and contains all the standard functions implemented by PeerConnection. You should put this in your example/server/scripts folder, and/or anywhere you plan to use PeerConnections. PeerConnections still use a client-server meme during the connection phase, although I have renamed these (in the interests of Peer-ness) as the Initiator and the Acceptor, which are basically synonymous with Client and Server. Any Torque instance that you intend to have accept PeerConnections must implement the Acceptor callbacks, including PeerConnection::onConnectRequest, PeerConnection::onConnect, and PeerConnection::onDrop. The initiator must implement everything else in peerConnection.cs, including but not limited to PeerConnection::onConnectionAccepted and PeerConnection::onConnectRequestRejected.
PeerConnection adds very little on top of NetConnection other than being able to use it- it is intended to be the bare minimum you can get away with using. I use it extensively in my MMO project to communicate between the various different kinds of servers along with a database server as the true backend. Here is an example of setting up and connecting with a PeerConnection. Notice that the syntax and use is identical to GameConnection.
// Connect to the CMS server and ask it what kind of server to be.
$CMSConnection = new PeerConnection(CMSConnection);
$CMSConnection.setConnectArgs($Pref::Server::CMSName);
$CMSConnection.setJoinPassword($Pref::Server::CMSPassword);
$CMSConnection.connect($Pref::Server::CMSAddress);
On the acceptor side, the connection is created but not automatically named, so it can be "lost" if you're not careful. I highly recommend that one of the tasks of onConnect be to store the new connection in a safe place; the included example stores all accepted connections into the SimGroup PeerGroup.
I think that's it. Have fun with this, and I hope it helps someone besides me!
PeerConnection is a lightweight GameConnection for use between two instances of Torque. It saves bandwidth by not sending any periodic information such as moves. There is no mission downloading associated with this type of connection, so it is possible to have as many active PeerConnections as you want, without any overlap problems. They still support password-based connection limits, to protect against backdoor hacking.
It implements all the usual connection callbacks you're used to from GameConnection: OnConnectionAccepted, OnConnectRequest, OnConnect, etc., making it easy to work with. Once a PeerConnection is established, you can treat it like any other object.
PeerConnections can be used to send your own custom NetEvents over the wire with postNetEvent() at the engine level, but most people will probably find it most useful for Torque's standard Remote Procedure Call (RPC) system, i.e. commandToClient/Server. PeerConnection implements commandToPeer mainly to reduce calling confusion. The syntax of commandToPeer() is identical to commandToClient()- the first argument must be a valid PeerConnection:
commandToPeer(%MyPeerConnection, 'SomeServerCommand', "1 is the lonliest number");
Like commandToClient, it supports up to 254 extra optional arguments. On the remote side, PeerConnections use standard "serverCmd" functions, instead of custom "peerCmd" functions, in order to avoid extra bandwidth or processing costs. These functions may be called via a commandToServer call or a commandToPeer call.
The .rar file includes three files for using PeerConnections. peerConnection.cc and peerConnection.h should be placed in your engine/game folder- make sure to add them both to your project and recompile the engine! peerConnection.cs is a template script file, and contains all the standard functions implemented by PeerConnection. You should put this in your example/server/scripts folder, and/or anywhere you plan to use PeerConnections. PeerConnections still use a client-server meme during the connection phase, although I have renamed these (in the interests of Peer-ness) as the Initiator and the Acceptor, which are basically synonymous with Client and Server. Any Torque instance that you intend to have accept PeerConnections must implement the Acceptor callbacks, including PeerConnection::onConnectRequest, PeerConnection::onConnect, and PeerConnection::onDrop. The initiator must implement everything else in peerConnection.cs, including but not limited to PeerConnection::onConnectionAccepted and PeerConnection::onConnectRequestRejected.
PeerConnection adds very little on top of NetConnection other than being able to use it- it is intended to be the bare minimum you can get away with using. I use it extensively in my MMO project to communicate between the various different kinds of servers along with a database server as the true backend. Here is an example of setting up and connecting with a PeerConnection. Notice that the syntax and use is identical to GameConnection.
// Connect to the CMS server and ask it what kind of server to be.
$CMSConnection = new PeerConnection(CMSConnection);
$CMSConnection.setConnectArgs($Pref::Server::CMSName);
$CMSConnection.setJoinPassword($Pref::Server::CMSPassword);
$CMSConnection.connect($Pref::Server::CMSAddress);
On the acceptor side, the connection is created but not automatically named, so it can be "lost" if you're not careful. I highly recommend that one of the tasks of onConnect be to store the new connection in a safe place; the included example stores all accepted connections into the SimGroup PeerGroup.
I think that's it. Have fun with this, and I hope it helps someone besides me!
About the author
#2
07/06/2006 (2:07 am)
So this work fine with TGE. Do you have any chance to make it work under TSE ? I get engine crash if I use the code directly in TSE.
#3
Charlie do I have your permission to use this in an upcoming extension to our MMORPG Enhancement Kit?
07/06/2006 (3:08 pm)
This is Absolutely brilliant!Charlie do I have your permission to use this in an upcoming extension to our MMORPG Enhancement Kit?
#4
Words cannot describe the happiness this resource brings!
Happy Happy Joy Joy!
07/08/2006 (8:59 pm)
This is so unbelievably useful.Words cannot describe the happiness this resource brings!
Happy Happy Joy Joy!
#5
16>..\engine\game\peerConnection.cc(343) : error C2653: 'RemoteCommandEvent' : is not a class or namespace name
16>..\engine\game\peerConnection.cc(343) : error C2065: 'MaxRemoteCommandArgs' : undeclared identifier
16>..\engine\game\peerConnection.cc(348) : error C3861: 'sendRemoteCommand': identifier not found
2nd day of torque'n and my first mod, so perhaps someone could point me in the correct direction.
All I have done so far is added the .cc and .h to the Torque Demo project and recompiled.
Much appreciated.
07/09/2006 (4:46 pm)
Using stock TGE 1.4 with msvc 2005. Getting a few compiler errors with this mod:16>..\engine\game\peerConnection.cc(343) : error C2653: 'RemoteCommandEvent' : is not a class or namespace name
16>..\engine\game\peerConnection.cc(343) : error C2065: 'MaxRemoteCommandArgs' : undeclared identifier
16>..\engine\game\peerConnection.cc(348) : error C3861: 'sendRemoteCommand': identifier not found
2nd day of torque'n and my first mod, so perhaps someone could point me in the correct direction.
All I have done so far is added the .cc and .h to the Torque Demo project and recompiled.
Much appreciated.
#6
If it doesn't compile, it's completely my fault, because I probably missed something when I ripped all this out of my own source code. I will submit a fresh, tested archive ASAP.
Dreamer, your MMO tutorials were totally useful for my own project, of course you can include it in the new version.
Claude, it should work without modification under TSE, although I don't own it so I can't test it. However, to my knowledge, the network code wasn't touched, so this should just drop in.
07/09/2006 (5:45 pm)
Wow, I wasn't aware this had been approved yet.If it doesn't compile, it's completely my fault, because I probably missed something when I ripped all this out of my own source code. I will submit a fresh, tested archive ASAP.
Dreamer, your MMO tutorials were totally useful for my own project, of course you can include it in the new version.
Claude, it should work without modification under TSE, although I don't own it so I can't test it. However, to my knowledge, the network code wasn't touched, so this should just drop in.
#7
07/24/2006 (5:50 pm)
Great work Charlie. I am about to begin development on a MMO game and this is exactly what I've been looking for. This is going to save us so much time. Thanks for releasing the code and not hording it. You're the best.
#8
Have you updated the code? It's not compiling for me as-is.
10/22/2006 (9:55 pm)
@Charlie Sibbach:Have you updated the code? It's not compiling for me as-is.
#9
10/23/2006 (4:34 pm)
I've been away from Torque for a bit, but interestingly, the night I get back on it, your reply shows up. I will try to update it tonight, especially since I need it for my current project.
#10
I've also changed the interaction model a little. Here's how my test harness works...
I've got your peerConnection.cs almost as-is cloned into both starter.fps/client/scripts and starter.fps/server/scripts and exec'd on the client/server appropriately.
In starter.fps/server/scripts/peerConnection.cs:
In starter.fps/client/scripts/peerConnection.cs:
Then I start a dedicated server in a command terminal and launch the game normally (without wiping any .dso's via batch/shell scripts).
From the main menu, open the console and type each line as follows:
In the dedicated server log I can see:
and in the client log I see:
// Edit: corrected .connect() ip address, from 128.0.0.1 to 127.0.0.1 heh :)
10/23/2006 (11:17 pm)
I did get it working for me today but I ended up cloning game/net/net.cc and breaking it up into game/net/peerNet.cc and game/net/peerNet.h which gave me access to the sendRemoteCommand (though named differently).I've also changed the interaction model a little. Here's how my test harness works...
I've got your peerConnection.cs almost as-is cloned into both starter.fps/client/scripts and starter.fps/server/scripts and exec'd on the client/server appropriately.
In starter.fps/server/scripts/peerConnection.cs:
function serverCmdPeerPing(%client,%msg)
{
echo("PeerPing:" SPC %msg);
commandToPeer(%client,'PeerPong',"Pong! (" SPC %msg SPC ")");
}In starter.fps/client/scripts/peerConnection.cs:
function clientCmdPeerPong(%msg)
{
echo("PeerPong:" SPC %msg);
}Then I start a dedicated server in a command terminal and launch the game normally (without wiping any .dso's via batch/shell scripts).
From the main menu, open the console and type each line as follows:
$test = new PeerConnect( PeerTest ); $test.setConnectArgs( UserName ); $test.connect( "127.0.0.1:28000" ); $test.send( 'PeerPing', "This is a test! Yay!" );
In the dedicated server log I can see:
Got Connect challenge Request from IP:127.0.0.1:32941 Got Connect Request Connect request from: IP:127.0.0.1:32941 in PeerConnection::onConnect Mapping string: PeerPing to index: 0 PeerPing: testing
and in the client log I see:
==>$test = new PeerConnection( TestPeer ); ==>$test.setconnectargs( UserName ); ==>$test.connect( "localhost:28000"); Adding a pending connection Sending Connect challenge Request Got Connect challenge Response Sending Connect Request Connection established 4774 In PeerConnection::onConnectionAccepted ==>$test.send( 'PeerPing', "testing"); Mapping string: PeerPong to index: 0 PeerPong: Pong! ( testing )
// Edit: corrected .connect() ip address, from 128.0.0.1 to 127.0.0.1 heh :)
#11
10/30/2006 (7:55 am)
Nevermind.
#12
Stefan, did you actually get this to compile correctly? I saw your original comment, and I'm just wondering if "Nevermind" applies to everything or just the first part.
In any case, I've submitted an updated archive file. I loaded this one straight into my PeerConnection-less project and it worked straight away.
10/30/2006 (9:41 pm)
OneST8, I'm not sure why you had to make so many changes, but I do admit it doesn't work as posted, although I know why now. I think I mentioned that I consolidated this code from several places in my original, and it all works except for the actual code for commandToPeer. If you remove this code from peerConnection.cc (at the end) and place it in game/net/net.cc (after commandToClient) it should compile and work without problems. You did effectively the same thing, but in a more difficult way; I'm sorry to cause you so much extra work.Stefan, did you actually get this to compile correctly? I saw your original comment, and I'm just wondering if "Nevermind" applies to everything or just the first part.
In any case, I've submitted an updated archive file. I loaded this one straight into my PeerConnection-less project and it worked straight away.
#13
I could get this to compile, but I get a crash when handshaking, after the Connection Challenge has been sent. Can't remember what function caused the crash, but it was a function in NetConnection that had to do with ghosting.
Not saying you did anything wrong here, just a bit disappointed. IMO it sounds like version differences. Anyway. I'm probably going to pick out NetConnection instead and go from there. It has a lot of crap that I would not want in a class above it.
Let me know what you think.
10/31/2006 (5:46 am)
Sorry about that Charlie, didn't want to confuse you incase you hadn't subscribed to this topic, but you did :)I could get this to compile, but I get a crash when handshaking, after the Connection Challenge has been sent. Can't remember what function caused the crash, but it was a function in NetConnection that had to do with ghosting.
Not saying you did anything wrong here, just a bit disappointed. IMO it sounds like version differences. Anyway. I'm probably going to pick out NetConnection instead and go from there. It has a lot of crap that I would not want in a class above it.
Let me know what you think.
#14
10/31/2006 (9:43 am)
I really think some of the classes could benefit from being more focused. NetConnection does not seem to be used in more stuff than GameConnection.
#15
I ended up finding the error, which was an invalid checksum being passed in netEvent. Your work is highly appreciated and motivating.
This is the thread incase you're curious.
Thanks again.
10/31/2006 (12:34 pm)
Edit: Man, I never make sense when posting late.I ended up finding the error, which was an invalid checksum being passed in netEvent. Your work is highly appreciated and motivating.
This is the thread incase you're curious.
Thanks again.
#16
Glad it's all coming together for you.
11/01/2006 (8:56 am)
No worries. I just want to make the best resource I can with my limited dev time. That bug you mention is an insidious one, though. You should probably email one of the devs and see if they'll put a comment in about it; or, post some documentation about it in the wiki.Glad it's all coming together for you.
#17
:)
11/10/2006 (4:20 pm)
@Charlie: Don't be sorry for my desire to learn and build what suites my needs best. I learned a lot from your resource and am very thankful for the direction your code gave me. In fact, looking back, I can only say that I'm glad the build was broken because I wouldn't have delved so deep and learned so much about Torque networking.:)
#18
1) Could this be used to communicate between two different Torque applications? For instance, could I use this to send data from a TGE: FPS app to a TGE: RTS app? The data would represent global information that both apps could use, such as a score count or a text message.
2) How about a non-Torque app? I've written a very very simple chat program from scratch that can send and receive packets containing strings (user name, message, ect). I'd love it if I could implement it as an external chat program used by players running my Torque game. Sort of like Microsoft's Live Anywhere system.
Imagine this scenario: I'm playing a team deathmatch, and I send a text-message from the Torque app to my buddy (requesting he join and help out) who isn't in the game, but has the chat program running. I guess you could compare it to a gaming pager system.
I looked into the tcpObject, but I wanted something that was more of a dedicated client-server connection.
12/19/2006 (7:41 am)
Great resource! I have 2 quick questions though.1) Could this be used to communicate between two different Torque applications? For instance, could I use this to send data from a TGE: FPS app to a TGE: RTS app? The data would represent global information that both apps could use, such as a score count or a text message.
2) How about a non-Torque app? I've written a very very simple chat program from scratch that can send and receive packets containing strings (user name, message, ect). I'd love it if I could implement it as an external chat program used by players running my Torque game. Sort of like Microsoft's Live Anywhere system.
Imagine this scenario: I'm playing a team deathmatch, and I send a text-message from the Torque app to my buddy (requesting he join and help out) who isn't in the game, but has the chat program running. I guess you could compare it to a gaming pager system.
I looked into the tcpObject, but I wanted something that was more of a dedicated client-server connection.
#19
In answer to your questions...
1) Yes. It is quite possible, providing you stick with TGE; things shouldn't be difficult. Be it RPG, RTS or even a 2D side scroller: if it's Torque based, it should be able to work.
2) The project I'm working on is dependent upon this type of inter-connectivity. While I'm not able to talk much about it, I can say that the TNL is great for communicating between TGE and non-TGE based application(s). This is by no means a simple thing to do.
12/19/2006 (8:49 am)
@Michael Perry:In answer to your questions...
1) Yes. It is quite possible, providing you stick with TGE; things shouldn't be difficult. Be it RPG, RTS or even a 2D side scroller: if it's Torque based, it should be able to work.
2) The project I'm working on is dependent upon this type of inter-connectivity. While I'm not able to talk much about it, I can say that the TNL is great for communicating between TGE and non-TGE based application(s). This is by no means a simple thing to do.
#20
Thanks for your quick reply. Good to know about the first question. This could make for some really innovative Torque games in the community.
In reference to the second question, I figured it would be much more in depth and difficult than the first proposed challenge. Networking has never been my strong point, but I'll keep researching a little more.
Thanks!
12/19/2006 (9:21 am)
@OneST8:Thanks for your quick reply. Good to know about the first question. This could make for some really innovative Torque games in the community.
In reference to the second question, I figured it would be much more in depth and difficult than the first proposed challenge. Networking has never been my strong point, but I'll keep researching a little more.
Thanks!
Torque Owner Claude-Alain Fournier
Thanks