Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[NO CCU LIMIT] Forge Networking now OPEN SOURCE

Discussion in 'Assets and Asset Store' started by Brent_Farris, Dec 22, 2014.

  1. Cranick

    Cranick

    Joined:
    Nov 20, 2011
    Posts:
    310
    Just wanted to share with everyone our running joke about implementing new features. Hope you guys enjoy. :)

     
    jpthek9 likes this.
  2. zapoutix

    zapoutix

    Joined:
    Jan 2, 2015
    Posts:
    44
    Hi,

    It seems that the event playerDisconnected is not called on the server after a client sent data to it with WriteCustom method.
    If i don't call WriteCustom, the client just connect and disconnect without sending data, the event playerDisconnected is called.
     
  3. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Hmmm, interesting, this sounds like the WriteCustom must be interfering with the disconnect call. Do you happen to have a small scale example you can send to me so that I can debug it? If not I'll try to make my own setup to see if I can recreate it. Thanks!
     
  4. zapoutix

    zapoutix

    Joined:
    Jan 2, 2015
    Posts:
    44
    Also the event playerConnected is not called if a client send message to the server via WriteCustom method.
    1) First client connect
    - playerConnected is called on the server
    2) First client send message via WriteCustom
    3) 2nd Client connect
    - playerConnected is not called on the server

    but if the first client does not send message the playerConnected is working well

    i will try to give you a small scale
     
  5. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Interesting, sounds like a bug in our transportation. I'll take a look at this first thing when I get home tonight. Thanks for the steps to reproduce. :)
     
  6. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Great news everyone. We have finally gotten our backend server fairly stable. We will be providing logins very soon. With the beta release of the backend server we will be releasing an all new workflow for Lobbies. We have heavily assessed our design flow for the networking system and thought intensely about how we can bring the next level of network communications in video games. We have decided that the Arbiter will be re-commissioned to be the name of our backend services. DO NOT FEAR! Bare Metal is going to take the raw power that the previous prototypes of the Arbiter and integrate with them.

    With the release of the newly named Arbiter (backend services) you will find the immediate benefits in Forge:
    • Account registration
    • Account login
    • Account virtual currency
    • Account premium virtual currency (a sparate number for paid currencies)
    • Game Lobby (pull currently running game servers to be shown for selection)

    This is just the tip of the iceburg ("just the beginning of great things" for those who are not use to our idioms) and we are super excited! We do have plans for raw relational database power for every developer. That means, unlike PlayFab, you will be able to query your data and use it in a much more powerful way! Stay tuned, this system is growing rediculiously fast and we are super happy with our feedback and bug reports! Keep finding those bugs so we can eliminate them asap! :D

    Side note: Bluetooth is further under way, our initial integration with Android was a success! We are working with iOS and once we have that in we will work with Win8.1/WP8.1. After we have successfully integration on all three we will wrap them up in a nice distributed structure and get it out to Beta! :D
     
    FuguFirecracker and jpthek9 like this.
  7. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Just wondering, do you think it would be possible to continue a game if the hosting player leaves? I was thinking maybe throwing up a waiting screen as the Arbiter or server manager seeks out the new host based on ping and quality. An extension of this feature could choose a new host if the current one isn't reliable. This would take care of one of the biggest downsides of having players host games.
     
  8. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    I think this would be an awesome idea! It would work well with player based game hosting. I think that we would need to design a way so that if it were player based hosting it will pick up the game from a queue of current players.

    This design would have to do some fancy mumbo-jumbo though. I think that we would have to know who would be the next host and make sure they are fully up to date with the server just in case the server drops. Then they would become the server and then a new client will be selected to be the runner-up host. That design might actually work. :)

    If you (the developer) were hosting the servers then it would be a case of just kicking the players off to another network server (like a back buffer) which will pick up the game from there... Actually... It may work to have it work the same way. So there will always be a buffer server running and then the players jump to that server if the main host fails.

    Well now I'm just thinking out loud! Haha. Okay, so I think we can design something for this! It may take a bit of time and be a post-release feature though.
     
    jpthek9 likes this.
  9. Francois Gagnon

    Francois Gagnon

    Joined:
    Aug 18, 2014
    Posts:
    2
    I'm looking for a network solution and so far yours look very promising. I'm just wondering if I'd be able to connect an android player with a windows player with your bluetooth solution.

    I'm looking for true cross platform where the player does'nt need to know what OS his opponents are using.
     
    FuguFirecracker likes this.
  10. zapoutix

    zapoutix

    Joined:
    Jan 2, 2015
    Posts:
    44
    I send you some code about my problem, it's just an example

    Server side script :
    Code (CSharp):
    1. public class ServerScript: MonoBehaviour {
    2.  
    3.     public int port = 15937;                                                                                // Port number
    4.     public Networking.TransportationProtocolType protocolType = Networking.TransportationProtocolType.UDP;    // Communication protocol
    5.     private Loom _loom;
    6.     private NetWorker socket = null;                                                                        // The initial connection socket
    7.  
    8.  
    9. #if UNITY_WINRT && !UNITY_EDITOR
    10.     private bool isWinRT = true;
    11. #else
    12.     private bool isWinRT = false;
    13. #endif
    14.     // Use this for initialization
    15.     void Start () {
    16.         socket = Networking.Host((ushort)port, protocolType, 50, isWinRT);
    17.         socket.AddCustomDataReadEvent("hello", HelloNetwork);
    18.         socket.playerConnected += socket_playerConnected;
    19.         socket.playerDisconnected += socket_playerDisconnected;
    20.         Networking.SetPrimarySocket(socket);
    21.         AddMessageInConsole("Create server");
    22.         _loom = Loom.Current;
    23.  
    24.     }
    25.  
    26.     private void HelloNetwork(NetworkingPlayer socket, NetworkingStream stream)
    27.     {
    28.         _loom.QueueOnMainThread(() =>
    29.         {
    30.             AddMessageInConsole("get hello from player");
    31.             string nickname = ObjectMapper.Map<string>(stream);
    32.             AddMessageInConsole("get hello from player nickname : " + nickname);
    33.         });
    34.  
    35.     }
    36.  
    37.  
    38.  
    39.     private void socket_playerDisconnected(NetworkingPlayer player)
    40.     {
    41.         _loom.QueueOnMainThread(() =>
    42.         {
    43.             AddMessageInConsole("Player disconnected");
    44.         });
    45.  
    46.     }
    47.  
    48.     void socket_playerConnected(NetworkingPlayer player)
    49.     {
    50.  
    51.         _loom.QueueOnMainThread(() =>
    52.         {
    53.             AddMessageInConsole("New player connected");
    54.         });
    55.  
    56.  
    57.     }
    58.  
    59.     // Update is called once per frame
    60.     void Update () {
    61.  
    62.     }
    63. }
    Client side script :
    Code (CSharp):
    1.  
    2. public class ClientScript : MonoBehaviour {
    3.  
    4.     public int port = 15937;                                                                                // Port number
    5.     public Networking.TransportationProtocolType protocolType = Networking.TransportationProtocolType.UDP;    // Communication protocol
    6.  
    7.     private NetWorker socket = null;                                                                        // The initial connection socket
    8.  
    9. #if UNITY_WINRT && !UNITY_EDITOR
    10.     private bool isWinRT = true;
    11. #else
    12.     private bool isWinRT = false;
    13. #endif
    14.     // Use this for initialization
    15.     void Start () {
    16.         socket = Networking.Connect("127.0.0.1", (ushort)port, protocolType, isWinRT);
    17.         socket.AddCustomDataReadEvent("hello", toto);
    18.         socket.connected += socket_connected;
    19.         Networking.SetPrimarySocket(socket);
    20.     }
    21.  
    22.     private void toto(NetworkingPlayer arg1, NetworkingStream arg2)
    23.     {
    24.         throw new System.NotImplementedException();
    25.     }
    26.  
    27.     void socket_connected()
    28.     {
    29.         BMSByte cachedData = new BMSByte();
    30.         cachedData.Clone(ObjectMapper.MapBytes(cachedData, "toto"));
    31.         Networking.WriteCustom("hello", socket, cachedData, false);
    32.     }
    33.  
    34.     // Update is called once per frame
    35.     void Update () {
    36.  
    37.     }
    38. }
    39.  
    When the first player connect the socket_playerConnected method is called, and when a 2nd player connect this method is not called
     
  11. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Ah! Thanks for the code, hopefully this will help me reproduce it. I was working the player connected event without any issues all day yesterday with multiple players connecting and disconnecting. However I was not using Write Custom. So it must have something to do with that method. I will implement your code and try to reproduce and fix this strange bug asap!
     
  12. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Hi there! Our good developer Brett (@Cranick) is heading the Bluetooth plugins for iOS and Android. From my point of view, communication between different devices is a must for us. We will do anything we can to make sure that you are able to communicate between different operating systems. At first glance, with my understanding I believe that we should not have issues with Bluetooth integration working cross platform. The only thing that will prevent it is if the operating system developers block that communication between devices (which is not an un-common practice for some). We will let you know what we discover asap.
     
    FuguFirecracker likes this.
  13. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    That sounds absolutely perfect for my game! I've been getting some bugs with the bare metal server so I think I'll make the server in Unity instances and it'll still have very low overhead. This way, players could host games as well as the official servers.
     
  14. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Awesome, we have it in the queue for features!

    Ah! No problem. The overhead will be little indeed. What kind of bugs were you seeing with Bare Metal? We would like to take a look at them and see if we can fix them. :)
     
  15. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    I'm not sure what I was doing wrong - the server wasn't receiving the WriteRaw data or at least wasn't calling the event. It works with Unity instance servers which is strange.
     
  16. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Hello all! I think tomorrow we are going to start our Beta rounds for the Forge Developer Portal. What you will get when we give you access to the portal:

    • Global player account creation
    • Global player login
    • Server registering
    • Server players tracking
    • A pre-built server (host) browser - Yes this will list all your active servers
    • New ArbiterAPI object for communication with the Arbiter player database
    • Application player coins (for entire application)
    • Application player exp (for entire application)
    • Application player level (for entire application)
    • Server player coins (for specific server)
    • Server player exp (for specific server)
    • Server player level (for specific server)
    • Application player currencies (for entire application)
      • Coins
      • Premium
    • One global login for all games/servers for players
    • Bank transaction history (for "coins" and premium currencies)
    • Server list and statistics on developer portal
    • Cloud exception logging (you can log your exceptions and errors to the cloud)
    • There are probably a couple of things I have left out here as well

    What to expect to come after tomorrows release as it relates to the Arbiter server?
    • Achievements
    • Items
    • Leaderboards
    • Test only items (helpful for testing items and not having it go to actual application)
    • Test only achievements (helpful for testing items and not having it go to actual application)
    • Some secret features we can't talk about
    • Your own list of beta testers accounts (from global accounts list)
    • Some SUPER secret stuff we can't talk about yet
    • Server player currencies (for specific server)
      • Coins
      • Premium
    • Custom relational database designs
    • Custom relational databases
    • Custom SQL-like syntax for querying data
    So how hard is it to use this API?
    Code (CSharp):
    1. ServerAPI.Instance.LogException(myNetWorker, exception, delegate(string jsonResponse)
    2. {
    3.     // Do this when done
    4. });
    Each call is a part of the Instance of the group it is in. The above is an example of how to log an exception to the server. The below is an example of how to get the players level from the server (assuming the player has already logged in).
    Code (CSharp):
    1. AccountAPI.Instance.GetLevel(delegate(string jsonResponse)
    2. {
    3.     // Do this when done
    4. });
    Please let me know if you have any questions, suggestions or feedback. We are very open and want to design this to be both very powerful as well as very easy to use.
     
    Last edited: Feb 13, 2015
    jpthek9 likes this.
  17. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    I'm very excited for this update. I have a question for designing my game's core networking. If someone is the server and they do NetWorker.WriteRaw(), does the data get sent to him or herself? Also, how does the server do WriteRaw back to everyone (including the server).
     
  18. imgodot

    imgodot

    Joined:
    Nov 29, 2013
    Posts:
    212
    I found a small error in sample code on the website + I have a couple of questions.
    The error is on the "Custom Networked MonoBehavior" page in the "Serializing Variables from Other Components" code block. This line: "AddNetworkVariable(() => transform.position, x => transform.position = (int)x);" should be "(Vector3)x" instead of "(int)x".

    Question 1: In this code snippet, when the data is sent across the network to another class it will update the transform.position in that other class, correct?
    Question 2: Is that data sent as reliable, unreliable, every-other-Tuesday?
    Question 3: If I want to implement an authoritative server, what method do you recommend to send player input to the server? RPC? Other?

    Thanks.
    -- Paul
     
  19. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Bah! Thank you for that type error fix :) I'll be sure to fix the Gist asap!

    1) The first argument is the method that is used to send across the network (the getter), the second argument is the method for setting (receiving the data) (the setter).

    XD

    2) This data is sent un-reliably as it is thought to be for a constant update stream.

    3) You probably don't want to send the player input (in most cases), however what you do want to do in most cases is call a function that is a result of the player input, in this case an RPC works best. If you are wanting to serialize a variable that is altered constantly from player input I would suggest using the "AddNetworkVariable" method and doing a getter/setter for that variable(s). When you alter a variable with "AddNetworkVariable" it will only serialize across the network if it has changed.
     
  20. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    We are too! :D

    The data will go through the normal server writing mechanism, which outside of RPC calls, will not be called on the server. This relieves the thread of having to evaluate the delegation of the data for server. Because of this, what you can do is have the server call the deserialize method itself with the data it is sending to the clients (that is if it doesn't already have the updated data). I would assume (probably shouldn't do that too much) that if the server is compressing the data to bytes and sending it across the network, then in most cases it will already have that data up to date on its own machine.

    If the server receives a WriteRaw, it will relay this information back to the other clients and since it received it from a client it will run through the read functionality itself.

    Please let me know if I have provided the needed information :). If not then maybe I can get some code samples going.
     
  21. zapoutix

    zapoutix

    Joined:
    Jan 2, 2015
    Posts:
    44
    Hi,
    Brent, did you had time to try the WriteCustom with multiple clients ?
    i have created a brand new project and tried the script i sent you, it still same error.
    I try to replace the WriteCustom, but WriteRaw method and everything works well, i can get connection and disconnection of multiple clients without any issue..

    another things, is it possible to add the NetworkingPlayer argument to the rawDataRead event like you did for the dataRead event ?

    Regards,
     
  22. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    I didn't get a chance to try it last night due to other deadlines, but I should be able to try it out and track down the bug tonight!

    It is odd that the connections and disconnections work just fine but the actual event callback is not. They are processed through the same method. I will make sure to test and track down this issue.

    Yes, I'll add a ticket to get this into the next build :)
     
  23. imgodot

    imgodot

    Joined:
    Nov 29, 2013
    Posts:
    212
    I'm still a bit confused. If I want to implement an authoritative server don't I want to send the player input request (forward input pressed, left turn input pressed, etc.) to the server so it can resolve all client requests and then send position updates back from the server to the clients?
    -- Paul
     
  24. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Well with input requests you will find things will get out of sync, especially with physics and local simulations. So lets say you are sending the inputs but on one of clients there was network latency and the client wound up scraping up against the a wall or colliding with something that isn't on the other clients. In this case the physics engine will rule that the object (no matter the input) must collide, slow down or be blocked by the obstacle. If this happens then if you are saying to move right and on one machine the position of the object is past (lets say) a wall and on another client they are not passed the wall, then when you press right the first object will clear the wall but the second client will get stuck by it.

    What you can do is write server code to manage the positioning of the clients, so if a client requests to move (lets say) 10 units forward but you know they are only allowed to move 1 unit at a time, then the server logic will stop the movement and update all the clients (including the sender) with the proper positioning. Authoritative servers do not necessarily need to be in control of updating all input requests (that logic can be offloaded to the client to save on server CPU) then the server only needs to manage the rules of movement as a whole and process updating the position requests accordingly.
     
  25. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Thanks for the response. One thing I had in mind to cut down on bandwidth is to aggregate all the data sent out in 1 packet. The server will collect all the information and package it into 1 byte array to be distributed to everyone. How can I go about doing this?

    @imgodot What you're looking for is the lockstep system. It's mainly used for RTS's (send commands instead of stats) but some first person shooters use it as well like Halo. I doubt you'd want to do it as it's a lot of work - more than necessary for an FPS.
     
  26. imgodot

    imgodot

    Joined:
    Nov 29, 2013
    Posts:
    212
    That is exactly what I'm looking for so what is the recommended Forge-way to send the client move requests to the server? RPC? Other?

    -- Paul
     
  27. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Our (non-raw) write enforces a maximum payload per packet of 1024 due to network standards. If you are implementing this yourself with the WriteRaw then you will want to try and keep your byte count below that amount.

    You could possibly create a class StepTransport and then have all your data being managed (sent through) this class. Then you can make this class responsible for sending out the WriteRaw and for reading the WriteRaw. This class can also manage the timing and everything else. You will probably want to make a clever way of identifying what bytes belong to what so that when they are read on the other end, it knows how to use the data that was received. Things like "bytes for this object are always in this index range" or "this byte defines the number of bytes to read for this objects data".

    Let me know if this makes any sense or if I am not even on the right track for what you need.
     
  28. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Well since Forge is extremely flexible it really is the developer way, powered by forge :). So it really depends on your game type, how you are doing inputs and what happens when you make inputs. Depending on these variables you may one way may be better than the other or vice-versa. For example, if you are doing an RTS (non-lockstep see @jpthek9 and his thread about lockstep), you would do movement of a character in the following:
    1. Player clicks the ground where the Unit should move
    2. RPC call is sent out to everyone with the Vector3 destination for that unit
    3. (automatic in Forge) Server relays RPC to all other clients
    4. All clients simulate the movement independently using path-finding
    Where as in a common FPS implementation you would do the following:
    1. Player moves or rotates their character
    2. Position and rotation of the character is serialized across the network via un-reliable UDP
    3. (optional) Server logic to validate the new position and rotation sent
    4. (automatic in Forge) Server relays message to all other clients
    5. Clients update the object on their side to match the passed values regardless of what was input
     
  29. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    This makes perfect sense, thanks. The maximum bytes in 1 command packet is 4B (player ID, frame #, check-sum) + 4B (Position) + 2B (Target) + 8B (Units selected) totaling at 256B but I doubt this value will be reached very often as this is if all 16 players give a positional and target-involved command with 16 different units from the previous command so the 1024 limit is no worry.
     
  30. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    So I worked with your script, though I was missing peaces so I was not able to simulate the entire thing. However I think I see something that may be the problem.

    So you are doing the event registry for the connect method:
    Code (CSharp):
    1. socket.connected += socket_connected;
    There is a race condition here because of the threading. Do you mind trying your same code except with this small change:
    Code (CSharp):
    1. if (socket.Connected)
    2.     socket_connected();
    3. else
    4.     socket.connected += socket_connected;
     
  31. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Just wondering: does WriteRaw() from clients automatically go to the server then to all the clients or only to the server? For the StepTransport I'd need to control the send-outs. How do I shoot out controlled responses?

    I noticed WriteRaw() doesn't have a NetworkReceivers parameter. Should I use WriteCustom instead for controlled distribution? Being able to send to a specific client is important if a client loses packets.
     
    Last edited: Feb 14, 2015
  32. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Yes, it automatically writes.

    It does not have NetworkReceivers, however it has an overload for you to direct it towards a specific client. Just have the server put in the reference to the correct NetworingPlayer and it will send it only to that player. NetworkReceivers are basically just group types (Server, All, Others, AllBuffered, OthersBuffered), it will not direct the message to a particular player.

    I will add in a Networking.ControlledRaw bool that you can turn true. I will have it so that when it is true it will not automatically relay the message to the clients.
     
  33. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Thanks, I'll start writing the code with that in mind. I assume sending to all will be as easy as maintaining a list of NetworkingPlayers and iterating through them.
     
  34. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    It should be easier than that. You can just cache all of the raw reads that you have and then have the server call WriteRaw itself and pass in the data to be sent. The WriteRaw coming from the server is delegated to all of the clients (if one is not specified) :)
     
  35. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Oh, I see. Unfortunately, I've encountered an obstacle - I can't download Forge :C. Right now I'm on V10 because I've been working on the deterministic simulation in the meantime. I emailed support@beardedmangames.com with more details about the error.
     
  36. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Thanks! I'm on it. There may be a server error as we are doing some final tests on it before the Beta launch. I'll send you a copy of the Beta now.
     
  37. Cranick

    Cranick

    Joined:
    Nov 20, 2011
    Posts:
    310
    Sorry guys, going to have to delay the beta release for v12 with all the nice gizmos and gadgets for tomorrow night instead. As we did further testing there wasn't any issues with the cloud itself but more on the different platforms. As you all know that this a multiplatform networking solution, so our testing has to be done on all the devices we support. The further down we get each build, the more advanced and feature rich the system becomes. After building it out and testing it on each device we have found issues that we would like to address so that this beta v12 will be as smooth as possible.

    Thank you all for your support, we will continue to do our best to make sure we will all have the networking solution we always wanted.

    Happy Valentines Day!
     
    jpthek9 likes this.
  38. Zaddo67

    Zaddo67

    Joined:
    Aug 14, 2012
    Posts:
    489
    I am having problems with WriteCustom. After the first request is successfully sent and received by the server, all subsequent writecustom requests aren't getting through.

    I haven't tried to create a sample project to reproduce this. Due to the complexity of my project, this may be difficult.

    Are there any debugging tools available in Forge to see if the WriteCustom is being received on the server?
     
  39. Cranick

    Cranick

    Joined:
    Nov 20, 2011
    Posts:
    310
    We are also aware of this issue and will be looking at it further before we push out v12. Currently we have an example project to replicate this issue so we will go from there to take a deeper look at this issue. Thank you for mentioning this and please keep up the feedback as it helps us keep up to date as to any issues that there is.

    Currently there is not debugging tools available for forge but you can put a Debug log on the message received or put a breakpoint in UnityVS to catch it when it gets received, then process the data as usual and see if the data is getting set properly. There are plans to make some helper/additional debugging tools available so that you can see what is available and received in the future but for now we are just going for core framework working on our end and making sure it is very flushed out until we develop advanced debugging tools so that developers can use and see their traffic flow/networking packets being sent/received, etc. That will be in the future for sure, let me know if there is any additional tools you would also like to see in the future for Forge that can help you with any information you may want displayed. Thanks! :)
     
  40. Zaddo67

    Zaddo67

    Joined:
    Aug 14, 2012
    Posts:
    489
    Thx Brett. I have debugged client and server side and put debug logs in my code. I also put a event handler on Networker.error. I stepped through the WriteCustom call and this is going through cleanly. The problem is the handler on the server side is never called. So either internally WriteCustom is not sending the packet or the server is not managing the received packet correctly and not calling the handler.
     
  41. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Hi there! I believe that this might be a unique issue with the data you are using. Our WriteCustom method is working for us on our demo scene and is constantly updating. Are you on Version 11.2? If so, what kind of data (data types) are you sending through? Are you doing some custom byte serialization yourself and then packing it into the payload?

    Edit: Sorry about the current debugging tools state. As Brett mentioned, we are developing some tools that should make it easier to debug various parts of the system.
     
  42. GraphXCreations

    GraphXCreations

    Joined:
    Jul 6, 2014
    Posts:
    121
    sup fellas, ive been quiet for a while,
    just letting you all get the WriteCustom and the baremetal deal sorted out,
    seems the past week you guys trying to get that settled, since i am not testing that,
    i am just sitting quiet so you guys do your thing :)

    got a question tho, how far you guys from starting on the arbitrary server for beta testing?
    that i am looking forward to.

    cheers
     
  43. Zaddo67

    Zaddo67

    Joined:
    Aug 14, 2012
    Posts:
    489
    Hi Brent,

    Yes I am.

    Yes I am serializing an object and loading it as a byte array. On the first attempt I can successfully send any payload and this is received on the server and calls the appropriate handler successfully. If I try to resend the same payload a 2nd time or, a different payload, it fails to call the handler. No errors are raised.

    My code is complicated. The handler adds the sent data to a thread safe collection (I use sync locks to achieve this). The main thread then iterates through this collection and processes the data.

    I have tried sending various commands that call different handlers and even a test stub handler that does not use the thread safe collection. All work fine on first call, but when I send a 2nd packet, the event handler never gets called.

    NP. When the tools come, that will be very helpful.

    Another question:

    I changed over to the Raw methods. There seems to be an inconsistency with the BMSByte properties and other Forge classes. I just want to confirm that the following is correct behaviour:

    1. the bms.Size = (myObjectSize -1) ?
    2. the bms.StartIndex() is returning 2, when the actual start index is 1?

    See my code below for how I currenty extract object form BMSByte.

    I do like the Raw methods for sending data. However, I am reluctant to build my own reliable UDP using Raw calls. I would need a buffer, check Ack's, resend, include a sequence to ensure packets are correctly ordered, etc. You have already done all the hard work on this, it would be really nice if Reliable UDP could be extended to Send Raw with another WriteRawReliable method? :)

    Code (csharp):
    1.  
    2.         public static ISFSObject bmsByteToSF(BMSByte bms)
    3.         {
    4.  
    5.             try
    6.             {
    7.  
    8.                 ByteArray data = new ByteArray(new byte[bms.Size + 1]);
    9.                 Array.Copy(bms.byteArr, bms.StartIndex() - 1, data.Bytes, 0, data.Length);
    10.                 //data.Uncompress();
    11.  
    12.                 ISFSObject obj = SFSObject.NewFromBinaryData(data);
    13.                 data = null;
    14.                 return obj;
    15.             }
    16.             catch (Exception ex)
    17.             {
    18.                 NetworkManager.Instance.debugBuffer.Add("bmsByteToSF Error: " + ex.Message);
    19.             }
    20.             return new SFSObject();
    21.  
    22.         }
    23.  
     
    Last edited: Feb 15, 2015
  44. imgodot

    imgodot

    Joined:
    Nov 29, 2013
    Posts:
    212
    Object Instantiate Question:

    I am creating a missile on a client using "Networking.Instantiate(...)".
    The std. Unity instantiation returns an object that you can then use to access the components of the object and assign values like a team#.

    Q1: What do I do in Forge if I want to access components of my newly instantiated object? Do I have to do a Find() or something?

    Thanks.
    -- Paul
     
    Last edited: Feb 15, 2015
  45. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Generally, it's not practical to do Network.Instantiate for every projectile. If it can be avoided, it'd be better to simulate the missile on the authoritative server or simply on the client. This should be done in order to avoid different simulations (missile hits on 1 client, doesn't on another). In addition, I think there might be a lot of overhead from instantiating a networked object (and destroying it). This is just my 2 bytes on the matter. Sorry I don't know how to actually use Network.Instantiate as I've never had a need for it.
     
  46. imgodot

    imgodot

    Joined:
    Nov 29, 2013
    Posts:
    212
    jp,
    Without a networked object, I presume you send an RPC to tell everyone connected, "I'm creating a missile with these properties", but then how are you syncing the position, rotation of those objects on all the clients as the objects move (perhaps non-deterministically)?
    -- Paul
     
  47. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    rigidbody.velocity = transform.forward * speed.
    But there's only 1 real missile that does damage. The rest are just for show (they still explode and everything but they don't affect health).

    Unless you want to make a lockstep system or send more than necessary stats corrections, you should simulate everything important on only 1 machine. Otherwise, a person could die on one computer but not on the other and that would be awks.
     
  48. imgodot

    imgodot

    Joined:
    Nov 29, 2013
    Posts:
    212
    jp,
    If everything is simulated on one computer (presumably, an authoritative server), how are you getting the results of the simulation to each of the clients?
    -- Paul
     
  49. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    That's where networking comes in. Every X times a second, sync packets are sent out to every player. Inside these packets are positions, health, stamina, etc.. Because these sync packets will be sent very often, you want to make them as small as possible and only for values that get constantly updated. For 1-time deals like weapon pick-ups, send a (reliable) RPC or something.

    The rate of sends X can vary to fit your game's needs. If people die in split-seconds, you should send at a faster rate, maybe 10/s, but for games where characters have plentiful HP, maybe 5/s.
     
  50. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Thanks! So for the Arbiter server we are actually well on our way with completing that idea. We will be releasing the "Arbiter" backed server tonight. This will allow you to register servers, user accounts and more. After that all we would need to complete a full beta for the original Arbiter idea would be a load balancer :)