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: