BenchmarkNet (Stress test for ENet, UNet, LiteNetLib, Lidgren, MiniUDP, Hazel, Photon and others)

The C# wrapper for Valve sockets is available here. Please, read this before using it.

1 Like

Sorry, I can not read all the previous posts, since my English is bad, so I’ll just ask here. What is the best solution for creating a multiplayer game in which large online are planned, up to 200-400 people on 1 server? (for example as in the game Rust)

It depends on many factors:

  • Your experience in networking, concurrency, and data optimization.

  • Your knowledge of memory management in .NET.

  • Per client resources budget.

  • Server software platform.

  • How good the target server hardware.

I did not think about it deeply, but I want to understand in what direction I should move. For example, to create a game like Counter Strike, it’s enough for me to be a Photon, I’ve already done different prototypes on it and they worked. I understand there is no tool that will allow me to do the same simply, but only for online 200-400 people on the server (without rooms)? As in the games of Rust or San Andreas Multiplayer (SAMP).

Unity 5 vs UE4 vs Photon vs DIY for MMO
Development & Deployment of Multiplayer Online Games Vol. I
MMOs and modern scaling techniques
Actor model

2 Likes

ok, I so understood from the above that there is no simply way (like Photon) to create a game with a large on-line in one room (on 1 server).

yeah no there really isn’t

Mirror & Telepathy can handle 200-400 people on a server easily if you have decent hardware. I tested my uMMORPG Asset with 200+ players on a small scene, everyone broadcasting to everyone else and it works fine.

@nxrighthere hi! Can you update benchmark results? I added recycle method to NetPacketReader (NetDataReader extension) and some receive speed improvements.

Sure, I’ll update it soon.

Hmm, thanks, I’ll look at this. And what was your hardware on the server?

3686386--303253--upload_2018-9-17_10-16-54.png

BenchmarkNet 1.10 has been released.

  • Added multi-process instances

  • Added self-monitoring and execution of instances

  • Added memory-mapped data exchange between instances

  • Updated LiteNetLib to the latest version

  • Updated DarkRift to the latest version

  • Reworked layout of output text

  • Reworked user-specified configuration

  • Reworked Photon server logic

  • Replaced unsafe ENet with ENet-CSharp

  • Changed Sustained Low Latency mode to work with the server instance only

  • Minor improvements

The results are updated for all networking libraries. Please, keep in mind: everything that you see there (except the screenshots from the monitoring instance) is now related only to the server process which is isolated from the clients simulation. More information is below.

This is the last major update before the upcoming 2.0 version, which will introduce the GUI with modern visualization of the simulation (classic CLI version will still be an option), detailed statistics with graphs (like minimalist netdata), TCP libraries support (regardless of [my opinion]( uMMORPG Official Thread page-85#post-3597279) and experience in general), and other stuff.

But for now, let’s talk about the latest 1.10 version. Developers requested several times to separate the server and clients processes for easier debugging, tracing, and resources monitoring. So, here it is: now there are three fully automated instances: monitoring instance CLI/GUI (master), server instance (child) and clients simulation instance (child). From the task manager perspective it looks like this:

3694213--304003--ProcessInstances.PNG

The child processes communicate with the master via memory-mapped files (the data serialized using well-known binary formatter). The named pipes used to check the heartbeat of the master and self-termination if something goes wrong. When a benchmark is complete, the supervisor task will terminate the child processes automatically.

One of the biggest advantages of isolated processes is that I got perfectly linear changes in resources usage (except memory consumption) which means that it’s precise and very predictable data. This is most likely what you will see in a real-world application on target hardware. Look at the tiers with 500 and 1000 clients, compare them, it’s awesome how linear this data is.

You can use something like the famous Process Explorer or Process Hacker to monitor CPU usage, memory consumption, network I/O (loopback), GC generations, heap size, time spent in Jit/GC, and tons of other useful information for each process. For example, here are graphs with captured resources usage of ENet server process.

Takes a deep breath

In the 1.10 version, I’ve changed the layout of output text into a more readable form, and user-specified configuration now works a bit differently. Now at the runtime, the user can select only the networking library and a number of the simulated clients. All other parameters can be set in the config file before launching the application.

The original ENet with an unsafe C# wrapper was replaced with our fork. It’s sad that Lee is not working on the library anymore, but the source code is open, so we took the project on our shoulders. I [mentioned]( BenchmarkNet (Stress test for ENet, UNet, LiteNetLib, Lidgren, MiniUDP, Hazel, Photon and others) page-5#post-3586575) several times across the forum that we improved it a lot, and now you can see the results.

@RevenantX is doing a great job (as always). LiteNetLib with the latest changes now works faster and consumes fewer resources.

Same thing with DarkRift. (Keep it going @Jamster !)

As for the Valve sockets. As soon as Fletcher fix some stuff, I’ll integrate it into the application since I’ve finished working on the C# wrapper, so stay tuned.

@tobiass After reworking the Photon server logic I instantly found two bugs (or I missed something?): 1. OnReceive() returns an incorrect size of the payload, take a look. 2. Channels with ID > 1 are not working for some reason.

2 Likes

@nxrighthere : I will bring in the server guys for the payload-size in OnReceive(). Channels: The client needs to set the client-count before connect, so it’s setup for the connection. Else, they won’t be accessible. Do you do that?

Edit: @nxrighthere : Would you mind mailing us the relevant code for the OnReceive() problem? My colleague didn’t check the code yet but seems positive that we just provide the byte[ ] data and no separate length parameter. So the data.Length should be correct. Is the value larger than what you expect? It could include type info and or something wrapping your raw data? Mail to: developer@photonengine.com please.

1 Like

Great work there @nxrighthere . Our switch from LLAPI to your Enet wrapper is 50%, it had some delays because of work i had to do on other parts of our project. Your new benchmark shows very epic results for Enet to be honest, it is the lightest library out there today. Can’t wait to test it in our project.

Thank you for all the hard work here!

If your interested for an alpha testing with our game just hit me a Private message.

1 Like

Ah, you are right I forgot about it.

Yea, it always returns more length than expected - 50 bytes instead of 48 bytes per message in this case. The source code of server logic is here.

Done.

Thank you. Actually, I’m very rarely playing the games (Fortnite/World of Warcraft sometimes), but would be interesting to see how things are going with your project.

1 Like

@tobiass Photonian told me that OnReceive returns a buffer with headers, and deserialized data can be retrieved via OnMessage callback. Everything works fine now, thanks.

1 Like

Only just seen this somehow!

Keep up the great work @nxrighthere , I’m not sure you realize quite how much seeing these results drives me to put DR at the top!

You’ll be glad to know that the next update will allow DR to use other networking layers instead of it’s bi-channel default. Would be good fun to colab and give it a test run with DR on ENet or Neutrino! After all, you do seem to hate TCP :wink:

2 Likes

@nxrighthere can you share more about this

https://vimeo.com/292969981

Here are a few posts ([1]( Garbage Collector API page-2#post-3743614), [2]( UNet Deprecation Thread page-4#post-3745183)) about this networking system. It utilizes the ENet for low-level communications over UDP and the Hydrogen (optional module) for secure per channel encryption. The primary goal is high-performance networking backend that works right inside Unity but scalable without any interruptions of a game loop. The second goal is modular extensibility to kickstart any multiplayer project within a few hours.

This networking system is the successor of a complex project. It will be released as soon as I finish working on some high-level stuff, and when it will pass all the tests.

2 Likes