RevenantX / LiteNetLib

Lite reliable UDP library for Mono and .NET
https://revenantx.github.io/LiteNetLib/index.html
MIT License
3.03k stars 490 forks source link

Implement sliding window scale logic. #110

Open lzaiats opened 6 years ago

lzaiats commented 6 years ago

I have been testing LiteNetLib, Lidgren-gen3 and Lidgren-old (the one from Google Code) and Lidgren-old is beating the competitors by far... On my test I have 750 clients connected to a single server instance, receiving ~15 reliable msgs/s and ~100 unreliable msgs/s and Lidgren-old can handle all this data perfectly! Using the same "game code" but using Lidgren-gen3 or LiteNetLib the test "fails" between 100 and 120 clients... Maybe I am missing something with LiteNetLib API, so I can achieve better performance... Do you have any idea where I am doing wrong with your Lib? If you need I can share the code :)

Thanks and keep the awesome work!

nxrighthere commented 6 years ago

Take a look at this.

lzaiats commented 6 years ago

Hi guys! Long time since my last post here =)

I just wanted to share with you the current stage of my MMO server architecture and the feedback coming from you guys (@RevenantX @nxrighthere @DanisJoyal ) is a pot of gold to me!

https://youtu.be/OZ4j574VYrk


Welcome to netEngineX (temporary name) showcase! A distributed MMO server architecture using C# and Unity (other game engines soon)!

Basically, netEngineX consists of three parts: 1) State Server (entities and infrastructure management) 2) Workers (unity instances for world simulation) 3) Clients (unity instances for players)

This is a simple demo to show the current state of this technology: 1) We start a spectator client @ 10 statesyncs per second (no player controlled character for this demo) 2) We spawn 50 dumb AIs with one CharacterController each; 3) We spawn 1 Worker and assign the 50 AIs to its simulation; 4) We spawn more 550 dumb AIs and assign to this Worker simulation; 5) As you can see, the Worker FPS is low due to 600 CharacterControllers... 6) We spawn 2 more Workers and divide the simulation over the 3 Workers; 7) Now the load is distributed over the 3 Workers \o/ 8) Now we show some more cool features like: Auto Worker Assignment when Worker dies, Stopped game simulation without Workers and other stuff... =)

** netEngineX have built-in Network LOD using groups to save bandwidth...

*** This is not a real game, but if you can imagine all the possibilities =) All Workers are running locally, but yes, they can be run across the network... We are using CharacterController (heavy) to simulate AIs so we have a more close simulation of (600) player controlled characters...

**** netEngineX can be adapted to use any UDP lib (lidgren, litenetlib, enet or any other). Currently using lidgren-old (from Google Code)...

Suggestions and questions, feel free to email me!

Thanks for watching!

OlegGlushko commented 6 years ago

@lzaiats Hey I am building similar architecture myself and was curious if you could share some of your ideas/knowledge. Do you have an email I could contact you at?

Frooxius commented 7 months ago

Hello!

Can I ask what's the status of this feature - specifically the sliding window scale logic? Is this still something that's being considered? I see there's a lot of talk about performance and other things in this thread, so I'm not fully certain if that's still the focus.

With our use-case, we often run into an issue, where the higher someone's latency is (often times between US <--> Australia and such), the throughput degrades. I believe this is in big part happening due to the sliding window not being large enough to properly saturate that distance, so I think this could help with those kinds of connections.

RevenantX commented 7 months ago

@Frooxius well ReliableOrdered should be used in RUDP last of all. Mostly packets should be Unreliable/Sequenced - and then you will not get that problem. If 80-90% of your packets is ReliableOrderd - it will be much better to use just TCP socket

RevenantX commented 7 months ago

@Frooxius also if you will use GetMaxSinglePacketSize and pack your Reliable packets tightly - you will get better performance

Frooxius commented 7 months ago

@RevenantX We use Unrealiable/Sequenced for what we can - continuously changing poses, voice data and so on.

However we have other type of changes, which require reliable transmission, because they are various delta changes to the state of the world - they can be random and they need to happen in the right order as well. This normally works well for our purposes, but the transmission throughput degrades with latency, which is the primary issue we're having.

TCP socket is not suitable our purposes for two main reasons. One it's generally not recommended to mix both UDP and TCP (e.g.: https://gamedev.stackexchange.com/questions/165392/will-tcp-really-affects-udp-if-used-in-different-context and https://gamedev.stackexchange.com/questions/120115/does-it-make-sense-to-use-both-tcp-and-udp-at-once) and second, UDP allows for hole punching, but TCP not as much.

RevenantX commented 7 months ago

@Frooxius you can check https://github.com/RevenantX/LiteEntitySystem/ it uses ReliableOrdered only for BaseState (full game state). And later Unreliable for delta states (that include rpcs). So you can achieve reliability without using ReliableOrdered in much better way. User input also sent to server as Unreliable

emrys90 commented 7 months ago

+1 for sliding window scale

Frooxius commented 7 months ago

@RevenantX Unfortunately that approach is not applicable for our project, because we need to synchronize complex state changes of data model.

I am not really looking here for suggestions for alternate approaches and workarounds for our project to get around this issue, we do what we can on our end there.

My main interest was if there are any plans to work on this issue to improve the networking performance, especially with higher latency between endpoints?