NetCode for Entities is based on transport as NetCode for GameObject.
The NetCode for Entities is designed to let you send RPC or GhostSnapshots. We don’t allow expanding the protocol. Also, just to clarify, the transport has a connection concept. It manages timeout, it already keep the connection alive (in 2.0) etc etc. It is not just pure UDP.
If you can’t connect to the server (because of Nat) the connection will fail, after the timeout you set anyway.
But, even though you can technically send though any kind of message with transport, as simple as getting a data stream writer, write the serialized data into it and queuing into the pipeline you want to send it, we don’t recognise custom user data that way.
When we parse the message, we only recognise the two type of messages I mentioned before (because this is by design).
Unfortunately, you can’t inject yourself in the initial handshake in Transport either at the moment.
As far as I know, you need to modify the packet to ad a custom connection handshake message (that it is what you actually looking for).
The way transport work is pretty simple: create a NetworkDriver , poll the connection events and handle the message types you receive. That it.
The connection is made (by sending a few internal control message bytes) and when the client and server finally talk, then you can start sending any message you want.
On top of that you can really build any other logic you want. And this is in fact what the NetCode for GameObject does.
If you want to ping the server in your way, before connecting for the game or for just sake of reporting it is alive to a matchmaking service, I think you have two/half options right now.
Option 1
If you don’t care opening another port (that make sense in my opinion anyway) you can achieve it by creating another driver and start listening on it (on the server) and using it for checking the server present (before doing the actual connection if you need so).
After you accepted the incoming connection (that you can’t inject into anyway, even at driver level unless you write your own underlying layer) then you can send your custom message, handle it, eventually retry sending it (etc etc).
I’m advocating about using another connection port because, if you actually use the game driver, all of a sudden you need to keep in consideration you need to increase the incoming packet queues sizes, connections etc just for sake of some clients/service polling you.
That is is really not what you want. Also there are other stuff you may want to report there (not just ping) and maybe instead of being polled, you need to actually send messages on a regular basis to other services.
Furthermore, this pinging action does not disrupt the game experience.
So it is a more scalable and robust solution.
Because, again, this is really a ping, I think having the full driver stack for this seems also like too much.
Probably just opening a simple udp socket for that purpose is more than enough. That also remove the problem that you need to create a connection first.
Option 2
Modify the current NetworkStreamReceiveSystem. That can be quite a little more more involved task.
The NetCode for Entities connection is constituted by two phases:
- First the client connect.
- A protocol information is exchanged by client and server to verify they can deserialise the same ghosts and rpc types. That requires having game data. So it is not ideal for an external service that probe the server.
Because of that, you need to have a new way to handling the incoming connection. You probably need to wait before exchanging the protocols data and instead sending your custom message etc etc. You need in practice to create another sort of handshacking phase.
Looks like to me a really bad choice.
Option 2b
Modify the underlying transport layer. Now here depend which version of the transport you are dealing with.
I would not do that either.