Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - cmifwdll

Pages: [1]
1
TNet 3 Support / Editor serialization - collection of interface type?
« on: December 19, 2016, 07:39:59 PM »
Firstly, this isn't related to TNet, but since TNet has incredible serialization I figured it wouldn't hurt to post it here.

I have a UIContainer with a public List<IDisplayable> ObservedData field.
Unity Editor doesn't serialize interfaces, so this field doesn't show up on the Inspector.
I'd like to fix this. I'm currently using a custom inspector. Accepting a GameObject as input, I then use reflection to iterate over all MonoBehaviour's and their fields (and the fields fields) to build a List<string> of typenames and fieldnames which I can then display in a popup.
The MonoBehaviour, string typeName, and string fieldName are stored on the UIContainer. In Start() I use reflection to (finally) grab the reference.

This is horrible and I hate it. Is there a better way of doing this? The ObservedData on the UIContainer won't ever be modified; it's only ever read. Additionally, I'd like to support assigning references that aren't implicitly List<IDisplayable> but can be cast without resulting in a new instance. For example, setting UIInventoryContainer's ObservedData to PlayerInventory.Items (which is List<IPickupable> [IPickupable derives from IDisplayable]), any changes made to PlayerInventory.Items will be reflected in ObservedData.

2
TNet 3 Support / IPv6 support?
« on: June 05, 2016, 08:13:09 PM »
TNet had issue with parsing IPv6 addresses in the past (see: http://www.tasharen.com/forum/index.php?topic=13794). However, even with the parsing fixed - in TNet2 - Sockets are created with AddressFamily.InterNetwork (see TcpProtocol::ConnectToTcpEndPoint()), which, as far as I can tell, only supports IPv4. In .NET 4.5 Sockets support dual mode, but I don't think Unity has caught up to that yet.

If I change AddressFamily.InterNetwork to tcpEndPoint.AddressFamily, will this introduce incompatibilities? Has IPv6 support been more thoroughly planned out in TNet3?

I know this is something I could test myself, but I thought I might check here before potentially breaking the whole game :P


edit: Here's all the changes I've made in TNet2. I think this should solve IPv6 problems when using TCP. Not sure though. The Lobby code (client and server) should be fine already.
TNManager::Connect (string address) [full function]:
  1. string parsedAddress = address;
  2. string[] split = address.Split(new char[] { ':' });
  3. int port = 5127;
  4. if (split.Length == 2)
  5. {
  6.    int.TryParse(split[1], out port);
  7. }
  8. else if (split.Length == 9)
  9. {
  10.    parsedAddress = address.Substring(0, address.Length - split[8].Length - 1);
  11.    int.TryParse(split[8], out port);
  12. }
  13. Connect(parsedAddress, port);
  14.  

TcpProtocol::ConnectToTcpEndPoint():
Change:
  1. mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  2.  
To:
  1. mSocket = new Socket(tcpEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  2. if (tcpEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
  3.         mSocket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, 0);
  4.  

TNTools.cs -
Tools::ResolveExternalIP (string url):
Change:
  1. string[] split1 = text.Split(':');
  2.  
  3. if (split1.Length >= 2)
  4. {
  5.    string[] split2 = split1[1].Trim().Split('<');
  6.    mExternalAddress = ResolveAddress(split2[0]);
  7. }
  8. else mExternalAddress = ResolveAddress(text);
  9.  
To:
  1. mExternalAddress = ResolveAddress(text);
  2.  

Tools::IsValidAddress (IPAddress address):
Change:
  1. if (address.AddressFamily != AddressFamily.InterNetwork) return false;
  2.  
To:
  1. if ((address.AddressFamily != AddressFamily.InterNetwork) && (address.AddressFamily != AddressFamily.InterNetworkV6)) return false;
  2.  

Tools::ResolveEndPoint (string address):
Change:
  1. if (split.Length > 1)
  2. {
  3.    address = split[0];
  4.    int.TryParse(split[1], out port);
  5. }
  6.  
To:
  1. if (split.Length == 2)
  2. {
  3.    address = split[0];
  4.    int.TryParse(split[1], out port);
  5. }
  6. else if (split.Length == 9)
  7. {
  8.    address = address.Substring(0, address.Length - split[8].Length - 1);
  9.    int.TryParse(split[8], out port);
  10. }
  11.  

Sorry for ugly formatting. I tried :(

3
TNet 3 Support / Pre-Sale Questions
« on: July 13, 2015, 10:06:31 PM »
I've been fighting (big emphasis on "fighting") Unity's networking for a few weeks now, so I'm at the point where I need to start looking for other solutions. I'll try to convey what I need for my project, and hopefully with feedback I'll be able to determine if TNet is the right fit.

Some things which I feel may be relevant:
* The project is using the latest version of Unity (5.1.1p4)
* Standalone Desktop platform only
* Host-based multiplayer (one player acts as both client and server)
* The Host is the authority (performs all physics, attacks, damage, movement, etc. Clients are not trusted)
* Invasion mechanic (dark souls style) (will explain more below)
* I come from a programming and networking background, but not a game development background

Upon startup, players register with the master server and begin sending heartbeats at regular intervals. When invading, players tell the master server "hey, here's my latest info, find me a match". The master server does some processing to find a match, and tells both players when a match is found. In doing so, the master server acts as a NAT punchthrough facilitator, in addition to its role as a master server. I've got the master server set up, put it up on a VPS and tested using two separate WANs, and all is well. The problem comes with implementing this into Unity. Without going too much into it, the problem is that I can't make use of Unity's underlying Socket. I need to be able to send/receive packets to/from any destination from the same Socket the game is being hosted on. Or, at the very least, be able to handle NAT punchthrough and matchmaking from within the engine.

Additionally, Unity has some weird... technical limitations. Logical structure is very important for this project. It needs to make enough sense that junior coders will be able to add on to it. Following this paradigm, the Player class handles the Player stuff, the Inventory class handles the Inventory stuff, the Weapon classes handle the Weapon stuff. Of course, the Player class has an Inventory instance, and the Inventory instance holds an array of Weapon instances, but it all meshes well and each part handles its own stuff, as you'd expect. I really feel like this part is important to convey, so I'll give an example: The Player class handles Input, and when the Input for "attack" is detected, the Player class calls playerInventory.EquippedItems[SlotType.MainHand].Attack(). This will call the Attack function on the equipped Weapon. The Weapon class then handles animating the weapon swing, in addition to performing the hit detection and damage calculation server-side. Unity doesn't allow for this behaviour because my Weapon component exists on a child GameObject of the root Player GameObject. Calling a Command in the Weapon class from the Weapon class will result in a "Trying to send command for non-local player" error, because, according to Unity, a child GameObject of a parent GameObject that IS the local authority isn't the local authority. The parent is the local authority but the child isn't. I need to be able to declare and call networked functions from each Component, regardless of its position in the GameObject (Scene?) hierarchy. Unity's solution to this is to put all the logic in one place, the Player class, and have the Weapon class call that. This becomes really messy when there are multiple Weapon types, each with their own attack logic, all inheriting from a base Item class.

To summarize my needs:
* I need to be able to handle NAT punchthrough and communication with my own matchmaking server while *simultaneously hosting* a game
   * Or, if that's not possible, I need to be able to send/receive packets to/from any destination from the same Socket the game is being hosted on
* I need to be able to declare and call networked functions from any Component, regardless of its position in the hierarchy.
   * For example, a Weapon component is on a child GameObject of the GameObject that has local authority (the Player GameObject). That Weapon component needs to be able to declare and call [Command] and [ClientRpc] functions to perform hit detection and damage calculations on the server.
   
Going through the forums I see a few posts with the same issues, and the replies typically point out a design flaw. Since I lack game development experience, is there a flaw with my design? Should I be thinking about this differently?

Pages: [1]