Author Topic: Understanding the TNet model  (Read 12956 times)

TheCodeTraveller

  • Guest
Understanding the TNet model
« on: September 23, 2013, 04:15:09 AM »
Hi Guys,

Hoping you can help out with clarifying my high level understanding of TNet. Please correct my understanding below if I've made a mistake, omission or perhaps think that you could add some further value by adding to the points below:

1.) In order for TNet to function at all, a TNManager object needs to be part of the scene
ArenMook's Edit: This is no longer the case.
2.) Any network object i'm hoping to manage through TNet has to be added to the list prior to runtime. Is this correct? Is there no way to dynamically add new types? Or not yet known objects (for example, streamed items that do not exist ingame yet)
ArenMook's Edit: Can instantiate by string Resources name.
3.) The object added to the TNManager, has to be a prefab.
ArenMook's Edit: Yes, but not needed. Use string instantiation as per #2.
4.) This prefab has to contain a TNObject with a unique identifier.
5.) If the object is TNManger.CreateEx(...) I can leave the id 0 as it will be auto assigned. If the object is not being instantiated by TNet, I need to assign this id myself.
6.) In order to syncronise my prefab across the network, all I need to do is add the TNAutoSync object to the parent object of the prefab. Is this correct or does it belong on the object that contains the rigidbody.
7.) Following point 6, Only one TNAutoSync object is required per prefab to sync.
8.) All code relating to input and camera control needs to be controlled with own custom code, using the property TNManager.isMine?
ArenMook's Edit: tno.isMine
9.) By doing all of the above, to get two networked clients communicating. They join the same channel, then instantiate their own version of the prefab using TNManager.CreateEx(). In doing so, the first players create is buffered? For when the next player joins? The next player joining when their own player is instantiated, TNet automatically updates the host (and all other players) - without needing any additional code?
10.) When a player leaves the room, their instantiated object is automatically removed and all other clients are updated? Is this the case or does this code have to be written manually.
11.) Following on from 10. If the host leaves the room, all other player objects and their own are destroyed automatically? The rest of the players in the room only receive the destroy on the player leaving though?

I am asking all of the above, because based on the above, this is how I've implimented TNet in my game - however, all the assumptions above mostly do not work for me.

1.) When I join the channel and instantiate my local player, that works fine.
2.) When I load up another client and join the same one, they own player is instantiated.

However...

3.) the host (point 1) receives the instantiated object from (point 2), on the host there are now, 2 players
4.) the other client (point 2) never receives anything to tell it that the host is there. On this client, I have 1 player. As if they started the channel (they didn't because checking the channel list, shows 2 players).
5.) the host (point 3) if they leave, their local player is not automatically TNManager.Destroy(...)'d - neither is the other players (remember the host got the update that player 2 joined).
6.) the other client, (point 4) now becomes host, as he is the only player in the room. If he leaves, their object isn't destroyed either.

As you can see from the above recount of my own understanding of the framework. There are gaps - gaps which are resulting to me not understanding the outcome of my use case below it. Please add your comments to this thread to assist me and others in future.
« Last Edit: December 19, 2014, 06:06:04 PM by ArenMook »

TheCodeTraveller

  • Guest
Re: Understanding the TNet model
« Reply #1 on: September 23, 2013, 04:26:26 AM »
To add to the above, none of the TNAutoSync properties work either for me, if I move the client around and their position, rotation and velocity changes - the server sees no positional update at all.

Are these updates meant to be sent manually, if so - why use TNAutoSync?

Also I put TNObject on the rigid body, which is a way down from the root game object in the prefab - this matters?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Understanding the TNet model
« Reply #2 on: September 23, 2013, 05:04:31 AM »
Quote
1.) In order for TNet to function at all, a TNManager object needs to be part of the scene
No, just your first scene should have a TNManager. Main menu would be the logical place for it.
Quote
2.) Any network object i'm hoping to manage through TNet has to be added to the list prior to runtime. Is this correct? Is there no way to dynamically add new types? Or not yet known objects (for example, streamed items that do not exist ingame yet)
Nope. Only objects you plan on instantiating quickly. You can still instantiate objects found in the Resources folder by their name, if you wish.
Quote
3.) The object added to the TNManager, has to be a prefab.
Yup.
Quote
4.) This prefab has to contain a TNObject with a unique identifier.
Nope. It should contain a TNObject only if you want to have this object synchronized on the network later -- for example the player's avatar. One-shot objects that get destroyed shortly (for example cannonballs, explosions, etc) don't need a TNObject on them. Lastly, you should leave the ID at '0' so that TNet assigns one for you when it instantiates the object.
Quote
5.) If the object is TNManger.CreateEx(...) I can leave the id 0 as it will be auto assigned. If the object is not being instantiated by TNet, I need to assign this id myself.
Correct, and this applies to Create as well, not just CreateEx.
Quote
6.) In order to syncronise my prefab across the network, all I need to do is add the TNAutoSync object to the parent object of the prefab. Is this correct or does it belong on the object that contains the rigidbody.
Parent object of the prefab? Auto sync goes on whichever object you want to synchronize -- generally on the same object that contains your TNObject script. Also, auto sync should be used liberally. It's better to do your own RFC calls instead. Lastly, you can only have one TNAutoSync per TNObject -- so only one per prefab. So again, be careful with it.
Quote
7.) Following point 6, Only one TNAutoSync object is required per prefab to sync.
Yup. But again, see the last part of #6.
Quote
8.) All code relating to input and camera control needs to be controlled with own custom code, using the property TNManager.isMine?
TNObject.isMine is the property that tells you if you own the object or not. You should only control the objects you own.
Quote
9.) By doing all of the above, to get two networked clients communicating. They join the same channel, then instantiate their own version of the prefab using TNManager.CreateEx(). In doing so, the first players create is buffered? For when the next player joins? The next player joining when their own player is instantiated, TNet automatically updates the host (and all other players) - without needing any additional code?
All create calls that created an object with a TNObject script on them get buffered, yes. Unless you destroy them later. Then they get removed.
Quote
10.) When a player leaves the room, their instantiated object is automatically removed and all other clients are updated? Is this the case or does this code have to be written manually.
Correct, but that's assuming you specified 'false' for the 'persistent' flag for TNManager.Create / TNManager.CreateEx.
Quote
11.) Following on from 10. If the host leaves the room, all other player objects and their own are destroyed automatically? The rest of the players in the room only receive the destroy on the player leaving though?
No, if a host leaves, another player is chosen to be the host. This is why you should be using TNObject.isMine. Host doesn't own everything. Host is just like any other player. The "host" status is just to make it so that only one player does the "generic" logic -- such as AI, pathfinding, etc, rather than having everyone do it.

Hope this helps!

Notepid

  • Guest
Re: Understanding the TNet model
« Reply #3 on: September 23, 2013, 06:26:26 AM »
5.) If the object is TNManger.CreateEx(...) I can leave the id 0 as it will be auto assigned. If the object is not being instantiated by TNet, I need to assign this id myself.
Correct, and this applies to Create as well, not just CreateEx.

What, wait!!

So if I create an object that is part of the scene and is not instantiated by the TNManager, I need to set the TNObject ID manually? How? Just assign it a random number?

TheCodeTraveller

  • Guest
Re: Understanding the TNet model
« Reply #4 on: September 23, 2013, 06:38:38 AM »
Thanks for the responses Aren, I will check that false flag on the manager, maybe I have it set to persistent state and accounts for why objects are not destroyed.

Appreciate the time taken to answer. More input welcome of course! Good thread for guys starting out with TNet.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Understanding the TNet model
« Reply #5 on: September 23, 2013, 06:49:55 AM »
@Notepid: You can choose a numer, or normalize the IDs via the menu. I advise keeping the numbers low though. Under 255 ideally, and under 32767 as beyond that means the ID was dynamically assigned. It won't break TNet if you go past it, but some future behaviour may be... undefined.

TheCodeTraveller

  • Guest
Re: Understanding the TNet model
« Reply #6 on: September 23, 2013, 02:34:22 PM »
You can still instantiate objects found in the Resources folder by their name, if you wish.

I tried this, I removed the prefab from the TNManager (so now it's size is zero). In doing so, when I call a CreateEx(...)

I get the following error:

The game object was not found in the TNManager's list of objects. Did you forget to add it?
UnityEngine.Debug:LogError(Object, Object)
TNManager:IndexOf(GameObject) (at Assets/TNet/Client/TNManager.cs:693)

This is the reason I initially said - it looks like anything you want to instantiate for network play needs to be added to that list. Perhaps I am missing something?

Am I meant to (GameObject)Instantiate(Resources.Load(..))

As normal just with a TNObject on the unit / player?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Understanding the TNet model
« Reply #7 on: September 24, 2013, 07:12:48 PM »
Yes, you misunderstood me. Don't pass Resources.Load. Pass the string inside your (..) brackets.

TheCodeTraveller

  • Guest
Re: Understanding the TNet model
« Reply #8 on: September 25, 2013, 03:12:14 AM »
Hi All,

Thanks Aren, I've managed to come right  8) I just wanted to update this thread with the biggest stumbling block I had.

You see, my load sequence on prefabs are very important - the player object for example has close on 40 different scripts attached, each of which have some dependency on one another - so order of execution is important to me. Long story short, this means I do a fair bit of footwork to enable, disable things on load - in a certain order.

What happened was one of the objects contained the TNObject, which is not by default enabled immediately on load. I would guess you're looking at the prefab when loading to find the TNObject, of which you wont because technically it isn't enabled yet.

What I did to get around this was place the TNObject on my root node, the first item in the prefab (which is always enabled on load). TNManger / TNet assigns the ID automagically and then my syncing script picks this object up from the hierrarchy root (for example, my rigidbody is very low level in the tree).

This way I can still send my RPC's etc through the correct tno.

New question.

Is sendquickly definitely UDP or is there an additional setting I need to enable first for this to switch from TCP to UDP for sendquickly use.

I've also worked on my custom interpolation (and even extrapolation) algorithm and on lan play, I have quaternion rotations super smooth, vector placement was of no issue to me.

Also anyone know of a good network emulator I can run within the lan to slow down traffic? Currently I've rolled my own on the client side, delaying packet transmission.

I'd like to simulate server side too for when the clients connection is fine but the server is battling.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Understanding the TNet model
« Reply #9 on: September 25, 2013, 05:43:40 PM »
SendQuickly sends via UDP if UDP communication has been proven to be operational. Otherwise it uses TCP.

TheCodeTraveller

  • Guest
Re: Understanding the TNet model
« Reply #10 on: September 26, 2013, 01:23:06 AM »
Thanks for the confirmation and good job with the framework. It's been a breeze to customize server side - really enjoying the experience.

TheCodeTraveller

  • Guest
Re: Understanding the TNet model
« Reply #11 on: September 26, 2013, 02:07:12 PM »
 :o I'm stuck on this one.

-Host starts channel, no issue there. Host leaves channel, TNObject / instantiated prefab removed.
-Host starts channel, no issue there. Client joins channel no issue there. Client leave channel, Hosts TNObject / instantiated prefab remains but clients has been removed as expected.
-Host starts channel, no issue there. Client joins channel no issue there. Host leaves channel, Hosts TNObject / instantiated prefab remains but clients has been removed as expected.

Are you guys sure I don't have to somehow destroy these objects myself? Something isn't right here. I leave the channel i'm in like so:

  1. TNManager.LeaveChannel();
  2. TNManager.JoinChannel(1905, null);

Also this is not a persistent channel. Does it matter that my project is not structured as Main Menu scene and Level scene? I instantiate levels live in the same scene as the TNManager lives.

Any help appreciated here :(

TheCodeTraveller

  • Guest
Re: Understanding the TNet model
« Reply #12 on: September 26, 2013, 02:09:23 PM »
To add. I receive these when clients leave:

  1.     void OnNetworkPlayerLeave(Player p)
  2.     {
  3.         Debug.Log(p.name + p.id + " has left");
  4.     }

But I never receive this: This seems to be working now. Odd.

  1.     void OnNetworkLeaveChannel(Player p)
  2.     {
  3.         Debug.Log(p.name + p.id + " we have left");
  4.     }
« Last Edit: September 26, 2013, 02:45:15 PM by TheCodeTraveller »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Understanding the TNet model
« Reply #13 on: September 26, 2013, 04:35:52 PM »
There is no difference between the host and non-host players in terms of object instantiation. The server doesn't care. If the object was created without the persistent flag, then it will be destroyed when the player that created it leaves.

TheCodeTraveller

  • Guest
Re: Understanding the TNet model
« Reply #14 on: September 27, 2013, 04:04:58 AM »
Definitely not the way it's working currently for me. I'm going to break away from the current project and prepare a smaller solution alongside to test out this issue. If you're will I can forward the demo project on after for you to take a look at if I haven't already solved by then.

It's most definitely down to my usage/implementation, the release is fairly mature now.