Search Unity

LiteNetLib - another reliable udp library.

Discussion in 'Connected Games' started by RevenantX, Jun 30, 2016.

  1. RevenantX

    RevenantX

    Joined:
    Jul 17, 2012
    Posts:
    127
    @TriangularCube yes there is no such method because it rarely used) I will add this)
     
  2. RevenantX

    RevenantX

    Joined:
    Jul 17, 2012
    Posts:
    127
    Added to master branch.
     
    TriangularCube likes this.
  3. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    711
    Hi there. Quick question, does LiteNetLib use any encryption? Thanks.
     
  4. RevenantX

    RevenantX

    Joined:
    Jul 17, 2012
    Posts:
    127
    No there is no any encryption. If you want use encryption - use already existring encryption methods from .net to information that you want to encrypt.
     
    wobes likes this.
  5. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    711
    thank you.
     
  6. TheBrizleOne

    TheBrizleOne

    Joined:
    Dec 6, 2017
    Posts:
    2
    Yeah I just wanted to say this is awesome man. This deserves more recognition. Really great work. And thank you for leaving it open. I've read through the UNet HLAPI source since it was in beta and there's some great concepts in there but the overall project is lacking including those issues that arose with the transport layer. Your solution provides a transport layer that I can extend if wanted and essentially build my own higher level system on top of as I see fit (and can borrow ideas I picked up from the HLAPI), which suits me perfect. I forked off GitHub, your code is clean as S***, I love it. Thanks again and awesome work man. That's all :)
     
    RevenantX likes this.
  7. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,149
    Hey dude!
    Heard a lot of good stuff about your UDP lib, currently adding it to the MLAPI, it's essentially an alternative to the HLAPI for handling high level stuff, and i'm making the transport modular. I'm just wondering if the Ping is one way travel time or if it's the round trip time? I need to use it for the built in lag compensation. And also, what unit is it in? Since it's an int i'm assuming milisecond. Is it an average or based on the latest message?

    Secondly, is there a network timestamp feature like there is in UNET and Lidgren?

    Thanks!
     
    Last edited: Apr 24, 2018
  8. RevenantX

    RevenantX

    Joined:
    Jul 17, 2012
    Posts:
    127
    @TwoTen hi! Ping in my library - is average RoundTripTime in milliseconds
     
  9. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,149
    Alright, What about the Timestamp feature? Is there such a thing?
     
  10. RevenantX

    RevenantX

    Joined:
    Jul 17, 2012
    Posts:
    127
    @TwoTen no, there is no timestamps in packets
     
  11. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,149
    Are there any plans to add timestamping or a way to get the last RTT (for reliable packets). Either timestamping or just adding a peer property giving the last exact RTT.
     
  12. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    711
    As far as I know OnNetworkLatencyUpdate gives you the last exact RTT.
     
  13. RevenantX

    RevenantX

    Joined:
    Jul 17, 2012
    Posts:
    127
    @wobes no. OnNetworkLatecnyUpdate called every second with average rtt too.
    @TwoTen well i can add this as option.
     
    TheBrizleOne likes this.
  14. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,149
    Yes I need that for Lag compensation. Thanks a lot!
     
    TheBrizleOne likes this.
  15. jogidipen

    jogidipen

    Joined:
    May 25, 2013
    Posts:
    4
    Hi,

    I am working on 2 player multiplayer game in Unity.So I need peer to peer communication. Is it possible without using any master server.

    I need that to connect user behind NAT also. Could you please provide me working script for Unity which is Using NAT.
    Because I am not getting how user will find other user if both are behind NAT.

    Thanks in advance.
     
  16. RevenantX

    RevenantX

    Joined:
    Jul 17, 2012
    Posts:
    127
    @jogidipen
    for NAT hole punch you need master server.
     
  17. jogidipen

    jogidipen

    Joined:
    May 25, 2013
    Posts:
    4
    Suppose Both peers knows external and internal IP of each other and both are behind NAT. Is it possible to connect them without Master server.

    I'm sorry if this question seems stupid. But I feel that should Possible if both peer having all info of each other.
     
  18. RevenantX

    RevenantX

    Joined:
    Jul 17, 2012
    Posts:
    127
    @jogidipen then try connect directly from both sides simultaneously using known public ips and ports.
     
  19. jogidipen

    jogidipen

    Joined:
    May 25, 2013
    Posts:
    4
    could you please provide me sample code exactly how to implement this? Are you sure by connecting it through only public Ip it will work if Device is behind NAT?
     
    Last edited: Jun 1, 2018
  20. TheBrizleOne

    TheBrizleOne

    Joined:
    Dec 6, 2017
    Posts:
    2
    Just want to make sure my understanding is right. The default logic thread sleep time is 15 ms and the ipv4 socket has a set send buffer size of 1024 * 1024. Adjusting the sleep time(update interval) allows this buffer to be filled as calls to the Send methods take places in that period correct? Then buffer is flushed and we rinse and repeat?
     
  21. ViCoX

    ViCoX

    Joined:
    Nov 22, 2013
    Posts:
    25
    Great work on this library Rev! I like it's simplicity - it can be tailored easily to custom projects.
    +1 for getting last RTT.

    Cheers,
    - J
     
  22. RevenantX

    RevenantX

    Joined:
    Jul 17, 2012
    Posts:
    127
  23. RevenantX

    RevenantX

    Joined:
    Jul 17, 2012
    Posts:
    127
    Socket buffer used internally in OS.
    My library sends packets every UpdateTime milliseconds.
    It sends all pending Unreliable and Sequenced packets.
    And maximum 64 Reliable and 64 ReliableOrdered pending packets (because of window size).
    And if MergeEnabled = true then it will combine small packets to one bigger (to MTU size)
    So in most cases socket buffer will not be overflowed.
    You can use Flush() to send this packets immediately.
     
    Last edited: Jun 6, 2018
    vitamincpp and TheBrizleOne like this.
  24. DoubleZeroCool

    DoubleZeroCool

    Joined:
    Feb 19, 2018
    Posts:
    4
    This thread sure looks dead, but I have some questions regarding the architecture.

    I have built my space game prototype to the point where I am ready to implement my real time features.
    So far, I have several screens on the client, from which I am able to send some requests to the server. In the code where I handle the requests on the server, I communicate back to the client some information, then I update the UI accordingly on the client.

    This works well, but I got a bit stuck. The client sends a packet to "start" the real time battle, I send the response from the server with all the relevant data to instantiate the "battle". Now, my problem is I don't understand where the server should contain the game logic for my battle.

    My Run function on the server is exactly like in the examples, it's a while look which calls PollEvents() and Thread.Sleep(15). Should my server iterate through all connected clients and send requests based on some logic inside that same while loop? How can I create non blocking timed events on the server to inform the client that something has happened after X amount of time, without the client initiating some sort of request?

    I am willing to provide more information if it's still unclear. Perhaps I am on the right track but I wonder if there are any easy techniques I could use to implement my realtime battle with this library.
     
  25. Driiade

    Driiade

    Joined:
    Nov 21, 2017
    Posts:
    63
    I looked for your timestamp approache, and find you use a ntp server.
    This can't work on local network without internet no ?

    Why don't provide a network Timestamp like in Unet library ? Will be so cool.
    I Don't know how to do such things however :D
     
  26. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    790
    We don't use any outside timestamp or time sync features like NTP for our game.

    To keep objects in sync over the network (like elevators that periodically go up/down, moving platforms, even NPC with predefined routes, ...) we have a TimeSync class that implementes a syncing algorithm to get accurate time synchronization over the network. It only takes 3 messages to get the server-time-offset accurate to below 0.5ms (of course it also depends on latency jitter, but that's rarely an issue).

    If @RevenantX thinks it's a good idea, I'd be willing to contribute that to the library.

    Most of the time games really only need a very closely synced "timer", instead of the knowing the absolute time.
    For messages like "someone shot a missile exactly 0.084 sec ago" or simply keeping the movement of platforms in sync (assuming they do something like posY = Mathf.sin(networkTime); ) that's perfect.


    @RevenantX I got a question:
    Are there any plans to implement "channels"?
    Like multiple network channels for different stuff. One sequenced channel for health, one for mana, one for....
    Also are there any plans to add some handling to ensure that at least one of the latest packets arrives (a half-way thing between reliably and unreliable, to guarantee that at least some changes are received by the other peer).
    Because with the nature of unreliable messages people often just spam updates, but you can never be sure that even one message arrives. And if all the (lets say) health packets went missing somehow, then the game will continue but with the wrong health displayed for one player. Some network libraries I've seen sometimes (every ~3sec) send a sort of "checksum" (1 byte per used channel) to ensure that the latest message in each channel isn't at least way too old (so at least one of the last 10 updates).
     
    Last edited: Aug 5, 2018
    Driiade likes this.
  27. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    548
    Stream-based time synchronization with samples accumulation? Which timer mechanism used for this?
     
    Last edited: Aug 5, 2018
  28. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    790
    Timer mechanism?
    System.Diagnostics.Stopwatch

    Only works if the system actually supports high precision timings though.

    Almost all "common" combinations of OS + CPU do, but for those who don't you're obviously out of luck. Accuracy up to +-30ms is the best you can hope for then.

    Tip for anyone not aware and asking themselves "why not DateTime?"
    Because it usually only increments in 15ms steps
     
  29. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    548
    It will no longer be synchronized as soon as lag/freeze occurs on the server/client and this is the problem of any time-based synchronization techniques. Stopwatch timer doesn't guarantee to act as a monotonic time and should be regularly resynchronized (every 1-5 minutes) depending on requirements.
     
    Last edited: Aug 5, 2018
  30. Driiade

    Driiade

    Joined:
    Nov 21, 2017
    Posts:
    63
    Many algorithm rely on deltaTime between server and client, example : Timer (haha basic...) or position synchronization...

    If there is an other way to know the delta time between server and client, tell us :p
     
  31. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    548
    There are several well-known techniques, one of them is ticks tracking that used in Quake 3 networking model.
     
  32. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    790
    When there's a lag spike large enough for things to get noticeable out of sync, then the timer not being accurate at that moment isn't much of a problem, no?

    Can you elaborate a bit more? What situation did you notice problems with in the past? I don't think I can follow that argument, the stopwatch is based on hardware timestamps, so any sort of lags or freezes will not somehow go out of sync.

    Next time you query the stopwatch, you get the correct timestamp...

    The only actual problem is that the time starts to drift eventually because DateTime and stopwatch use a completely different internal mechanism (stopwatch using CPU ticks which has more precision, but is not as accurate and will slightly, drift)
     
  33. Driiade

    Driiade

    Joined:
    Nov 21, 2017
    Posts:
    63
    I read for ticks and 1500 archers.
    It's used for RTS with many AI and full deterministics games. No more for fps, and whatever games that don't want to be "lock stepped".

    Maybe I'm wrong, there is not so much documentation when you dig into game development stuff :p
     
  34. Njb_

    Njb_

    Joined:
    Jun 3, 2015
    Posts:
    20
    Is this p2p or server autoritative?
     
  35. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    790
    Neither, it's an UDP library.
    You're talking about high-level mechanisms to control games, which is something different.
    You can build whatever scheme you want to on top of this.
     
  36. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    548
    That's why it doesn't work for multiplayer games. Hardware is different, and it's not perfect. You will get different timing results on different multi-core processors. QPC, as well as RDTSC instruction, is not a reliable source of high-resolution timing on different machines. Synchronize the time using your current implementation based on Stopwatch timer and play any modern game with three or more players and after several hours you will see how easily time gets out of sync.

    ECS comes to solve most of your problems with it.
     
    Last edited: Aug 6, 2018
  37. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    790
    You can know the tick frequency of the processor so different speeds are not an issue.
    As for drifts: Yes, there are some very minor differences in speed, even after accounting for different frequencies; But that's why we simply keep re-syncing over time (sending packets every ~20sec to determine how far the timings have drifted apart and if we should do one more back/forth cycle to bring it together again).

    For our purposes we want the time difference to be accurate to about +- 32ms (so ~2 frames).
    And with this mechanism, under usual/common network conditions you usually get +-1ms, going up to an uncertainty of up to +-5ms when there's a big range of latency jitter.

    Yes that's true, however "perfect" synchronization is actually not a requirement!
    Even +-32ms would still be acceptable :)
    We're building games after all, not synchronizing atomic clocks.
     
  38. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    548
    I'm just coming from a practical angle. We also used the Stopwatch timer with this synchronization technique, and it failed, unfortunately. We were forced to regular resynchronize the time.

    Using ticks tracking, you can do less work for a better result, lower bandwidth cost, and the implementation is simple.
     
    Last edited: Aug 7, 2018
    Rujash likes this.
  39. RevenantX

    RevenantX

    Joined:
    Jul 17, 2012
    Posts:
    127
    Channels in progress. I just don't have enough time for now. (and new packet type already in master branch)
     
  40. Driiade

    Driiade

    Joined:
    Nov 21, 2017
    Posts:
    63
    I really don't understand the ticks approach.

    What I understand : Server communicate ticks, ticks are just a "turn" of the game.
    Normally each client have to wait the tick server to do something, and for smoothing things client just execute command on currentServerTick -2.

    I don' t understand why clients have to recalculate ticks if the server tell them what is the current tick, but ok maybe.

    Normally client have to tell the server that they executed all command for tick -2, so the server can increment the ticks. But in the example I don't see this...


    With this technique your game is locked at the worst client (in term of connection or just in term of processing incoming command). Which is good and necessary if your main purpose is to simulated thousand of units in a predictable game and you have no choice. But you can't do that on a FPS game, or MMORPG, or whatever not fully deterministic (hello physics ).

    With this process, you can't play your game "locally", you have input lag, and this technique is not what we see in all modern games where clients extrapolate the result and are sometime corrected by server...

    Maybe ticks approach is not well explained as TimeStamping technique or maybe I'm just stupid =/
     
  41. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    548
    Tick is a unit of time, and it's not restricted to use in a particular networking model. It's only up to you how to use it to synchronize things. There's a lot of information across the web, ECS is the way to go in your case.
     
    Last edited: Aug 6, 2018
  42. Driiade

    Driiade

    Joined:
    Nov 21, 2017
    Posts:
    63
    Yeah I think to, if you use Ticks like I explained (locked to the slower player) ECS will save you (because you can Tick your game when you want).

    Is it that or not ? xD
     
  43. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    790
    @nxrighthere I've taken a look at that link.
    http://www.mine-control.com/zack/timesync/timesync.html
    That is EXACTLY what we are doing! :) (except with additional management steps to ensure no drifting, and re syncing over time)
    I'm not sure why we both thought the other one was talking about something different.

    What I don't get though is why it is called tick-based synchronization. This has literally nothing to do with lock-step ticks, you just send timestamps back and forth... Maybe I'm missing something really obvious.
     
    Driiade likes this.
  44. Njb_

    Njb_

    Joined:
    Jun 3, 2015
    Posts:
    20
    Thats not what i mean. In the features it says "peer to peer connections". Does that mean that the server just lets peers know each other or does it just mean you can make a p2p server?
     
  45. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    790
    Let me clear up some of the confusion:

    The "server" (whatever that may be, because everyone can be a so called "host"), called 'NetManager' in this library doesn't have any built-in functionality to let other connected peers (aka hosts) know about new connections.

    There's no built-in functionality to let peers know about the connections of other peers.
    Also, by "p2p server" you mean a sort of bootstrap node, right? (I'm a little confused because in a peer-to-peer network everyone is a server and client at the same time, like in bit-torrent)
     
  46. Njb_

    Njb_

    Joined:
    Jun 3, 2015
    Posts:
    20
    If a client writes a message, does that client send the message to all clients, or does it just send it to the server for me to process it? (And yes, a bootstrap node)
     
  47. Njb_

    Njb_

    Joined:
    Jun 3, 2015
    Posts:
    20
    I want to make a server authoritative library on top of this. I just want to know if its possible or if this library is really only good for making peer to peer networking.
     
  48. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    790
    There's no abstraction layer that'd handle that for you.
    You can send a message to a "NetPeer" directly (NetPeer.Send), or to all peers connected to you directly (using a foreach and then using NetPeer.Send), or you could make it so one of the peers acts as a server, then you'd likely create some special message type for that in your own protocol, and your server would detect that and then re-send that message to all other peers.
    It's really up to you and depends on what you want to build...

    A server authoritative system is what we're doing as well, all game-clients connect to the server, no direct connections between the peers themselves.
     
  49. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    548
    Synchronization based on ticks is an alternative to stream-based time synchronization (where you use the Stopwatch timer to synchronize things). You can use the time in this implementation, but dealing with the ticks is easier, and it's more reliable since you know at which tickrate simulation is running on the server/host, and you can make a custom timer based on it. Such timer is hardware independent, and you don't need to send costly long/double across the network. You only need to track ticks and correct them under certain conditions.
     
    Last edited: Aug 7, 2018
  50. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    790
    Sounds like a pretty good idea. A custom timer that can be kept in sync more easily.

    However that also relies on transmitting time. From what I can see in the linked code every packet contains the remote time.

    So that's one int (4 bytes) of overhead for every packet.
    While I am sending 2 packets (one to the server, one back) every ~20sec, which is 1byte(request ID) + 8bytes (ulong timestamp).

    So there is actually bigger network cost involved, no? I'll give the tick based / custom timer solution a try when I have some time. But I wonder if it wouldn't be smarter to send tick updates separately (like I do) instead of having them on literally every message.

    Maybe I'm missing something here.