A Unity ID allows you to buy and/or subscribe to Unity products and services, shop in the Asset Store and participate
in the Unity community.
Discussion in 'Connected Games' started by vis2k, Aug 11, 2016.
Yes, tick rate drops when more players connect, that is why the latency increases.
The missing explanation:
These tests show 3 transports working with uMMORPG, one of @vis2k asset's, and more or less the reason Mirror was created in the first place. The numbers measure their performance at the server (not client), in a headless linux build.
50Hz is the frame rate at the server (not the client). You can set it to 30, which will consume less CPU, but it might increase latency a little bit. It is the tick rate at the server. You can set it as unlimited, which will go as fast as possible, but that really eats up CPU.
The first number CCU is the amount of concurrent users. Those are bots connected to an uMMORPG server and moving around randomly.
The second number is the RTT (Latency). How long does it take for a message to go from the client, to the server and back to the client again. This measurement includes not just the base transport latency but overhead from Mirror and uMMORPG. It is meant to reflect real world response time as seen by the user. In other words, if you click on the map, how long does it take for the character to start moving. For uMMORPG, anything about 500 ms degrades user experience. Lower is better
The third number is the cpu usage. 100% = 1 cpu fully busy. It can go higher than 100% if you have more than one core and your application or unity use multiple threads. Lower is better.
The 4th number is the total amount of cpu used across all cores. If you have 10 cores and use 100% of one, then you would see 10%. Lower is better.
The last number is the amount of memory used by the server. Lower is better.
With telepathy in 2018, you see really bad latency with 450 CCU.
With booster you see it keep relatively low latency even at 420 CCU. Booster is a proprietary not free transport made by vis2k, which offloads TCP server to a separate process.
We have improved Mirror/Telepathy considerably and now in 2019, it scales almost as well as Booster in these tests, it is able to keep a relatively low latency even at 420 CCU.
The improvements are due to lots of work in both Mirror and Telepathy that eliminate allocations and in some cases change algorithms from O(n) to O(1)
The reason these tests are done with uMMORPG, is that these are not synthetics microbenchmarks showing idealized unachievable conditions, but real world workloads that affect uMMORPG users.
It still does not change my question. The numbers are useless because they are incorrect. It’s not running at 50Hz like documented.
Releasing a benchmark showing how many ticks per second each server can manage would be much better.
How many CCU does uSurvival support on this server? At 50 Hz
Mirror saved my life!!! It's just like UNet, but so much better!!
A few months ago we tested it with 200 CCU. Should be able to handle way more now, probably 400 CCU at least.
Is there a way to have the server migrate to another client if the host player disconnects like the old p2p system?
In my NetworkManager, when establishing the final connection between client and server (handshake) I want to send a big byte array back to the client as a final reply. So I created new NetworkMessage class with a byte as a public variable. However, when I try to send the message (it's around 26 MB, it will only be sent once), I get max packet size error. Do I have to split the byte array into smaller chunks and send to the client as multiple messages (in this case it would be around 1600, considering 16K packet size, so I'm not sure if that's a good solution) or is there any way to let Mirror do that for me? Thanks!
UNET had that feature, but we removed.
If you are using Telepathy as transport then simply increase the max packet size from 16kb to 26mb. You can find that setting if you select the NetworkManager and look for the TelepathyTransport component.
Note that the higher the max packet size, the more it opens your server up to allocation attacks where an attacker might pretend to send several 26MB packets in a row, causing the server to allocate a lot of memory for them.
I only need it for the single large message for each client (it is a 4-player P2P scenario, so attacks should be a non issue here). So it is possible to change the Telepathy packet size at runtime for both server and client and after the message was successfully recevied by the client, set it back to default?
Edit: So I fiddled around with it, and found out two things:
1) Setting the MaxMessageSize during runtime has no effect since Telepathy .Client & .Server are initialized during Awake and those properties are never updated
2) When I created my custom method in Telepathy to update the server & client's MaxMessageSize, the error about message being too big disappeared, but instead I got
ReadMessageBlocking: possible allocation attack with a header of: 28036081 bytes.
So... is the only safe and proper way to do this to send thousands of smaller messages to the client to put the byte array together piece by piece?
ReadMessageBlocking: possible allocation attack with a header of: 28036081 bytes
vis2k said: ↑
UNET had that feature, but we removed.
Yes, we understand this. But how hard will it be to add it back? We are developing a steam p2p game and would like to make sure that the host player leaving or disconnecting will not close the game. Has anyone else here added this feature back?
You can still set TelepathyTransport's .server/.client .MaxMessageSize as runtime if needed.
You could compare with the original UNET code from Unity's bitbucket and add the parts back.
As far as I know, host migration never worked well though. This is insanely hard to get right because you have to transfer 100% of the server state to another client. It's way easier to just host a few cloud instances so people don't have to worry about host migration.
@vis2k I don't want to be agressive or anything, but I opened up an issue on Github 12 days ago and nobody seemed to have looked into it. Do I need to provide a fix myself or is someone actively working on fixing issues?
when I try to connect to a server from a webgl, i get this error (itch.io)
Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
I noticed that in your docs websocket transport looks different than the one available.
There is no Secure tick box or Certificate input fields.
I assume this is because of https, because when I use a http webpage, there are no issue.
Is there a way to run it on a https page?
Sorry about that. We are working on issues all the time, but we prioritize based on what affects our own game projects first.
We'll get to yours eventually. If you want to help, try to debug it yourself and see if you can provide any additional info that might help
We are currently working on websockets SSL support.
Thanks, any ETA on this?(roughly)
Also, wanted to confirm this:
When you set the network frequency, for instance, in NetworkTransform (or any script with syncvars or any syncing),
0 means send immediately if changed,
0.5 - twice a second.
But if it is set to 0.5 and there are no changes, will it send anyway every 0.5seconds or not?
Please join our discord and talk to katori if you want to stay updated on websockets SSL
syncInterval is in seconds yes. And if nothing changed, then it doesn't sync.
Wow many thanks guys for this networking stuff!
And thanks to "Noob do AAA" website for info about it!
Currently researching tools to use for multiplayer and I had a few questions, I looked through the forums and your website but couldn't find the info, is there a FAQ available somewhere?
I built the pong example and tested on the same machine, worked great.
Tested it on 2 machines on the same network, worked great
Tested it on 1 machine on a different network then another machine, opened router with DMZ but couldnt connect.
Basically is this capable of peer 2 peer on different networks? What about Android to PC? Android to Android? Or will I have to setup a rely server system to accommodate non-lan networking?
Thank you for any help and so far Mirror looks great!
Sorry if this has been asked before, but is there a way to testing multiple clients (+server) from within the editor, without building the project? Currently I start the server in the editor and run clients as separate apps outside of it, but that's pretty cumbersome as you can imagine.
Additional question: Is there a recommended workflow to have prefabs differ on clients and servers? E.g. an NPC prefab on the server has a NavMeshAgent and is only controlled server side, but the prefab (by default) spawns with NavMeshAgent on clients, too. Is there a better way to add custom scripts to these prefabs that remove/disable certain components on client startup?
public override void OnStartServer()
GetComponent<NavMeshAgent>().enabled = true;
Please note that in host mode an object will be both client and server, so I would not disable it on client startup because then your GameObject won't work on host mode.
I don't think so. I always build a stand alone and test with that.
I wanted to add, if the project is rather big and you're using a versioning system, you can checkout the same project as many times as you need server and clients and then run each in its own editor instance.
What if I want to change the rotation axis for the network transform child? There does not seem to be an option for that, and some other features as well.
What do you mean exactly?
You should be able to sync position and rotation without problems.
Hello everyone! This library looks really awesome but im having trouble understanding some simple things.
If I want to change the Tanks demo so that a projectile hurts another tanks hitpoints, or changes the position of another tank how do I accomplish this?
Do I make the Projectile class, which has a NetworkBehavior use its OnCollisionEnter method to fire an RPC and have the RPC make the change?
Do I just tell the OnCollisionEnter to change the gameobject, expecting the change to be synched everywhere?
Do I create a new NetworkMessage and use NetworkServer.SendToAll() to send my message of this hit to everyone and process it?
Sorry but the documentation is confusing on how you are actually supposed to route messages between entities.
If you update the Tanks example to include the full cycle of firing, damaging, and destroying other tanks it would illustrate through example the proper way of solving these problems, but right now I don't know how to proceed.
Any insight would be highly appreciated!
Thanks so much!
Can NetworkManager transports be swapped programmatically at runtime? (e.g. using Telepathy for LAN games and FizzySteam for net games?)
Commands go from client to server. RPCs go from server to client(s). Clients don’t necessarily need to know the HP of other clients, but that could and should probably be maintained on the server then sent out to the clients from there. Multiplayer data routing should always be client to server, then server to everyone.
You can use the Multiplexer Transport for that
Since posting, I did discover and study up on the Multiplexer. I'd like a little more control than for them to both be constantly active. I was wondering if there was some way to manipulate the transport of the NetworkManager, but after discovering the Multiplexer, I shifted toward building my own Transport with a flag I can set to make Available() return false. I basically want to force Telepathy for LAN games, and use Steamworks for internet games.
BTW, I have a fork of FizzySteamyMirror that I updated for use with Facepunch.Steamworks. It's pretty much just a crude swap-out of all Steamworks.NET code at the moment: https://github.com/thesupersoup/FizzySteamyMirror
I promptly decided I'd rather build my own Transport though, so I'll be working on another Steam transport using Facepunch.Steamworks as the foundation. I'll post a link here once it's functional.
You are on the right track. That will definitely work.
We have also discussed using urls for connections. For example, if you connect to tcp://somehost:port it would use telepathy to connect to that host and port, If you connect to ws://somehost:port it would use the websocket transport. In your case, I would envision something like steam://pierid
We have not implemented it, or reached a conclusion, but this seems like a good way to go in my mind.
New showcase: Nestables (made with Mirror)!
Im trying to implement multiplayer in my mobile racing game Real Drift Car Racing.
In order to avoid hacking, I need an approach based on dedicated authoritative server (not listen server).
Is this possible and feasible with mirror? It seems that mirror is more oriented towards MMO games.
Can it be used with racing game too?
Yes, that's doable. Mirror is server authoritative by default.
I'll be working on it and testing intensely throughout the week. It's likely to have problems in its current state, but it's a start.
Questions for the more learned:
I wanted a way to be able to unregister events for cleaner shutdown, so in the root MirrorpunchSteam I set Action variables to lambda expressions so I could do so. Are there any issues with this approach?
How does the NetworkManager handle connection ids, if I'm assigning them in the transport. Is it fairly agnostic to how it routes data associated with connection ids?
thanks for the reply. Does mirror also support matchmaking and room creation?
there is a way co connect with another project to a main project network? I wold like to create two different unity projects that use a thirf project as server for sharing data.
could this be possible with mirror?
Could you please point me into the right direction?
Latest showcase: Rogue Star Rescue - a roguelike tower defense game made with Mirror!
It's not in Mirror by default, but you can do that with Mirror.
We recommend using one project for everything. That's what Mirror was for after all.
I know that but I need to control some parameters by a different device, and is impossible to make that project work on a very different device.
So it's impossible to make connect two different projects?
If I use LLAPI to create a custom socket, do Mirror could have any trouble?
Not 100% sure what you mean. Perhaps our Multiplex transport is useful for you.
Hello - I need to send a collection of structs or classes to a client using TargetRPC. The data is just a string and an int. I am currently planning on doing this as follows:
void TargetSendData(NetworkConnection conn, List<MyThing> data)
// do stuff with data
My question - Is this the best way to do this in regards to network performance and bandwidth? Should I use a struct instead of a class? Possibly a different type of collection vs List?
This is not something that will be called repeatedly but I'd still like to keep it as performant as possible.
New Feature: SyncToOwner. Each component can be configured to sync to all observers, or only to owner. This will save large amounts of bandwidth for components like a player inventory, that shouldn't be synced to anyone else. Enjoy!
You can't send Lists in Rpcs. Only simple types like int, string, bool, int, string, etc. and structs like SomeStruct, SomeStruct, and so on. In your case, simply send an Array and make sure that it's a struct.
Hi Does Mirror supports NAT punch through? Also, does it support console platforms? Has anyone shipped a game using mirror on console platforms? Or attempted?
Check out mirror-networking.com for our showcase.
Mirror doesn't really care what platform you use it for, they all work.
Check out our UDP transports, I think a few of them might be able to support nat punchthrough.
New Feature: Custom readers and writers.
Since the dawn of time, HLAPI and Mirror have only been able to deal with a limited number of data types. Simple things like passing a DateTime or Uri as parameters in your [Command], [Rpc] or [SyncVar] would give you an error.
Starting with version 3.17.2 available at https://github.com/vis2k/Mirror/releases, you can extend Mirror and add support for any type you desire. All you need to do do is add extension methods for NetworkReader and NetworkWriters. For example:
public static class DateTimeReaderWriter
public static void WriteDateTime(this NetworkWriter writer, DateTime dateTime)
public static DateTime ReadDateTime(this NetworkReader reader)
return new DateTime(reader.ReadInt64());
There is no reflection involved. The weaver will find your extensions and use them just as if you were writing the code by hand, there is no performance penalty at all. Thanks to @vis2k for keeping me honest and help me find the simplest way to achieve this feature.
Hi, with mirror what are my options of sending RPC to specific clients?
You use a [TargetRpc] for that. The first parameter is the connection to the client you want to call. See here for docs: https://mirror-networking.com/xmldo...unications/RemoteActions.html#targetrpc-calls
Hello - I noticed in some of the comments that you have removed a lot of linq code for performance reasons. Can you talk a bit about this? I was not aware that using linq is a performance hit, and a quick google search seems to indicate that it is not. I'm just curious.
A lot of the Linq functions cause allocations which are pretty performance heavy and can cause big spikes on CPU. You can observe this in the "GC Allocs" column in the Profiler.