TNet: Tasharen Networking Framework

Looking to gauge interest and gather some feedback. I created something interesting for myself for a game I’m working on. Long story short: it’s a networking framework that’s simple to use and very powerful, designed to work without Unity, but ideal for working with it.

----------------------------- Longer version ----------------------------------

Almost exactly a year ago I decided to make a game and wrote a UI system for it, releasing it on the Asset Store almost as an afterthought. You may know this system as NGUI – it turned out to be fairly popular. People liked its simplicity, design, and well-commented, elegant code.

Although NGUI has halted the game’s development for a short while, I did persevere, and six months ago I started working on adding multi-player functionality to that game. I tried out 3 of the top solutions, but ultimately was not happy with either. I ended up just sticking with one of them due to time constraints, but never stopped wishing that I could write my own, applying all that I’ve learned from my development of NGUI – the simplicity, power, flexibility, and well-thought out, open code.

A few weeks ago I decided to do just that and started on a new project, called Tasharen Networking Framework, or “TNet” for short. This project is now ready to be released.

So what does it offer?

  • It’s Open: written in C#, comes as full source code for you to modify as you see fit.
  • It’s Readable: The code was written for others: it’s clean and thoroughly commented.
  • It’s Flexible: Server can be stand-alone, or started on another thread right within Unity.
  • It’s Adaptable: “Host” disconnects? Choose another. The game doesn’t end. Everyone disconnects? Save the state (if you want).
  • It’s Persistent: Not only can remote function calls be saved for future players, but you can save the entire server’s current state and then restart it. When you start it back up, it will be as if you’ve never shut it down (Auto-save anyone?)
  • It’s Powerful: Written to take advantage of high efficiency sockets (IO completion ports).
  • It’s Spacious: Each channel on the server is a separate area with its own rules (and save file), letting you host as many simultaneous games as your bandwidth can handle.
  • It’s Private: Playing by yourself? Put a password on the channel, or just flat out lock it. Others will still be able to PM you, of course.
  • It’s Consistent: You don’t need to put “if” statements everywhere. Same code that works for multi-player will work in single-player. The callback order is always the same. For example, players always get “left channel” notification before a “disconnect”.
  • It’s Efficient: You can optimize your frequent remote function calls by specifying a byte ID instead of a function name. Less data will be sent.
  • It’s Straightforward: Remote function call syntax and number of parameters are up to you. Arrays? Sure. Binary data? No problem. A hundred parameters? Uh. Well, sure, if you want.
  • It’s Elegant: You can even broadcast messages to players on the same LAN or wireless network without requiring them to connect to the server. Perfect for announcing local servers, for example.
  • It’s Useful: You can save files directly to the server, and load them later, letting players save their avatar thumbnail, inventory, or even an entire game map for others to load.

There are more features… but I’ve rambled long enough. Here is some basic usage information.

Q: How to start and stop a server from in-game?

TNServerInstance.Start(port, [fileToLoad]);
TNServerInstance.Stop([fileToSave]]);

Q: How to connect/disconnect?

TNManager.Connect(address);
TNManager.Disconnect();

Q: How to join/leave a channel?

TNManager.JoinChannel(id, levelToLoad);
TNManager.LeaveChannel();

Q: How to instantiate new objects and then destroy them?

TNManager.Create(gameObject, position, rotation);
TNManager.Destroy(gameObject);

Q: How to send a remote function call?

TNObject tno = GetComponent<TNObject>(); // You can skip this line if you derived your script from TNBehaviour
tno.Send("FunctionName", target, <parameters>);

Q: What built-in notifications are there?

OnNetworkConnect (success, error);
OnNetworkDisconnect()
OnNetworkJoinChannel (success, error)
OnNetworkLeaveChannel()
OnNetworkPlayerJoin (player)
OnNetworkPlayerLeave (player)
OnNetworkPlayerRenamed (player, previousName)
OnNetworkError (error)

Q: What examples are there?
See for yourself:

Works well. This is what you used in Windward? Just to get the ball rolling… What price point are you looking at?

Please, do ramble, Much! :slight_smile:

Would there be any special support for uLink?

It’s used in the Campaign mode of Windward, which is in early (private) alpha stage. Public version of Windward still uses Unity’s built-in networking via my own custom manager helper scripts which bypass all the weirdness associated with it… but it’s still P2P and has a lot of limitations.

I haven’t settled on the price yet. Photon is charging $3500 for an unlimited person server, but it’s also free for up to 100. Limits on the number of users / messages per second suck. TNet would be full source code, no limits… I’m thinking $45 to start, eventually settling at $95 (once there are more examples, a thorough off-line documentation, and a video or two).

The ultimate deciding factor will be how much support I’ll have to do per user. :slight_smile:

I’m not familiar with that…

Really nice :), How about encryption ?, physics simulation on server?.

I’ve been playing with it for 2-3 days now, and it seems really great!
As simple to use and great as NGUI :slight_smile:

No encryption by default. Most of the time encryption is not something that people care about for ordinary game data, and indeed having it enabled would reduce performance significantly. I suggest you encrypt only the packet data you actually want to secure, such as passwords. Since you are the one who calls remote function calls, the data you specify and how you use it is up to you.

Server doesn’t do physics. Clients do. One client is considered to be the primary, and his updates should be sent out to the server to be forwarded to everyone else. This way the server is as lightweight as possible, and is how it uses 0% CPU at all times.

Of course if you really wanted to, you could modify the server code to do physics, game logic, and what have you – source code is open for a reason. :wink:

Some example scripts:

public class ColoredObject : MonoBehaviour
{
	[RFC] void OnColor (Color c)
	{
		renderer.material.color = c;
	}

	/// <summary>
	/// Clicking on the object should change its color.
	/// </summary>

	void OnClick ()
	{
		Color color = Color.red;

		if		(renderer.material.color == Color.red)	 color = Color.green;
		else if (renderer.material.color == Color.green) color = Color.blue;

		TNObject tno = GetComponent<TNObject>();
		tno.Send("OnColor", Target.AllSaved, color);
	}
}
public class ExampleCreate : MonoBehaviour
{
	public GameObject objectToCreate;

	/// <summary>
	/// Raycast into the screen to determine where we've clicked and create a new object above that position.
	/// </summary>

	void OnClick ()
	{
		Vector3 pos = TouchHandler.worldPos;
		pos.y += 3f;
		TNManager.Create(objectToCreate, pos, Quaternion.identity);
	}
}

Hi,

Works VERY well on Windows. A must have :wink:
That say, i’m trying to install the APK on three Android device without success :frowning:

Yeah I am not quite sure if there is something I have to do differently with the android APK. I just did a build for Android and uploaded the APK it created. In Unity it typically executes it on the device right away. I’m kind of a noob in this area. >_>

Are RFC’s the only method of communication? Can they be sent unreliably?

That’s like asking if there will be any special support for UDK in Unity. They’re both network libraries.

No, you can create your own packet:

BinaryWriter writer = BeginPacket(PacketID);
writer.Write(123f);
writer.Write("Hello World");
EndPacket();

Of course you need to add this “PacketID” to the server so it is able to handle this type of packet – the logic of what to do with it.

But you’d still send said packet with an RFC right? What about reliability/unreliability?

Maybe a “Minimun Api Level” issue. Choose >>>Build Settings >>> Publishing Settings “Android 2.1 ‘Eclair’” :wink:

@PrimeDerektive: Nope, you don’t have to. RFCs are just “forward” type packets. Creation is done by sending a “create” type packet, for example. Joining a room – “join channel” packet, etc. You are welcome to add new packet types to be handled by the sever. The example I showed is how to send a custom packet.

@ZJP: Oh yeah, I built it for Android 4.1.

THIS is the pb. I’m tested with some devices between Android 2.1 and 4.01 :wink:

I’ll do a build later with an earlier version. :slight_smile:

Waiting for. Thx.

Actually… why wait. I am uploading an APK built with 3.2. Should be there in a minute (same location).

P.S. Win/mac builds also got updated as I added a new packet type, so if you are trying to connect android to a desktop, you will need to re-download the latest.