Jump to content

Extra Networking commands.


Einlander
 Share

Recommended Posts

I have found at least with the server, I need a little more data than I am currently supplied in lua.

These are some things I would find commands for very helpful.

  • Commands for:
    • How many peers are connected to the server.
    • What are their ip addresses. ipv4/ipv6. Just in case I need to add someone to a ban list for a little bit.
    • Return a list/table of currently connected peers.
    • Disconnect all clients at once.
    • Get the client/servers own external ip address (if possible)
    • Finding out the ip/address of server a client is connected to.
Link to comment
Share on other sites

On 7/26/2017 at 8:30 AM, jen said:

I suggest you use SteamWorks API for this and check the SteamIDs of players instead.

I'm want to put this on different indie store-fronts so Steamworks isn't always an option. This also is easily defeated if they have multiple accounts but use the same ip to troll people. Also it helps when a person gets disconnected from a server. In source games, if you have the console enabled you can type 'status' and it will give you the ip address so you can get it later. I do not want the clients to tell each other their ip addresses.

Also it helps when you are self hosting the server yourself. It would be much easier if it gave you an address thats not 127.0.0.1

 

Link to comment
Share on other sites

When I introduce lag, it's not losing packets, so the all get there eventually. So when they get there they are processed. I have it so that every client update loop it reads from the network 10 times unless it is null. This allows it to 'catch up' with the server if it falls behind. There is no real way other than timestamps synced with the server to know if you are falling behind.

http://einlander.duckdns.org:8000/f/6525b9e505824bbba98f/

This is a link of how it looks. Right side is the client. I can hold a button and it will not check the network at all. And after 10 seconds iirc it will disconnect from the server. When it starts reading the network messages it has to go through the entire backlog since eNet has reliable messages, and wont drop them.

Link to comment
Share on other sites

Right, so on the client side you can be storing all position updates from the server of all the remote/ghost clients in a queue. Then be tweening between the current position to the next position on the queue. This would give you smooth constant movement. The goal would to be able to keep 2 position items in the queue always while you are popping the current tweening one off it. If you have less than 2 then you know you're lagging because you haven't gotten an update from the server. If you have more than 2 then you know you just got an update from the server because you were lagging. In either cases you can handle it how you see fit. If more than 2 you can skip a couple or increase your tween steps slightly to catch up (but not fast forward like). If you have less than 2 then not much you can do but keep them there OR extrapolate for a couple seconds and fix it when you get packets again.

From my understanding this is similar to how Source engine does it. It visually lags other remote clients on a client by 50-100ms so that it always has a future position so they can interpolate.

Just throwing out ideas.

  • Upvote 1
Link to comment
Share on other sites

On 26/07/2017 at 5:00 PM, Josh said:

You can retrieve more than one message per loop, which allows the server to catch up if a bunch are received at once.

Is there a particular way to do this? Or are you suggesting something like while( client->update() != nullptr ) { ... } ?

Link to comment
Share on other sites

I may be saying something totally stupid and lame, but very few packets should be ordered/guaranteed.  For position, etc. just have an iterator and discard packets that are "older" than the last one received.  Hmmm, new feature candidate?

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

22 hours ago, Rick said:

Right, so on the client side you can be storing all position updates from the server of all the remote/ghost clients in a queue. Then be tweening between the current position to the next position on the queue. This would give you smooth constant movement. The goal would to be able to keep 2 position items in the queue always while you are popping the current tweening one off it. If you have less than 2 then you know you're lagging because you haven't gotten an update from the server. If you have more than 2 then you know you just got an update from the server because you were lagging. In either cases you can handle it how you see fit. If more than 2 you can skip a couple or increase your tween steps slightly to catch up (but not fast forward like). If you have less than 2 then not much you can do but keep them there OR extrapolate for a couple seconds and fix it when you get packets again.

From my understanding this is similar to how Source engine does it. It visually lags other remote clients on a client by 50-100ms so that it always has a future position so they can interpolate.

Just throwing out ideas.

With regards to player input, the player would be x frames behind the server. Would the server be applying the input to the most recent frame or x - 1 frames?

Link to comment
Share on other sites

Yeah i just found a blog talking about this. http://www.gabrielgambetta.com/client-side-prediction-server-reconciliation.html This will probably need to wait till I have another day off to implement a clientside buffer. The server already has a rolling buffer of 5 frames and 20 world states just because. I knew I would use it one day, but I didn't know it would be this soon. I'm learning all sorts of new things about networking!

Link to comment
Share on other sites

10 hours ago, Josh said:

I may be saying something totally stupid and lame, but very few packets should be ordered/guaranteed.  For position, etc. just have an iterator and discard packets that are "older" than the last one received.  Hmmm, new feature candidate?

 

Would actually be so handy, Unity calls this their "State Sync' channel and it helps a ton to have.

But you still need to send the users inputs reliably to the server...

Link to comment
Share on other sites

17 hours ago, Josh said:

For position, etc. just have an iterator and discard packets that are "older" than the last one received.  Hmmm, new feature candidate?

According to http://enet.bespin.org/Features.html under the heading "Sequencing" (third paragraph), ENet already does that:

Quote

For unreliable packets, ENet will simply discard the lower sequence number packet if a packet with a higher sequence number has already been delivered

 

  • Upvote 1
Link to comment
Share on other sites

22 hours ago, Einlander said:

I don't think Leadwerks supports unreliable packets. We only have the option of Message.Reliable and Message.Ordered

BTW the headers say Message.Sequenced and not Ordered.

ENet certainly does support unreliable channels... they just also happen to be sequenced.

 

22 hours ago, jen said:

Is it possible to reduce the buffer to allow just one packet at a time? You could just replenish that buffer as soon as a new packet arrives. The latest packet would be the only packet that you have to process then, no need to process an entire queue of reliable packets.

Well, the idea of a state-sync style (Discard older packets) channel and reliability at the same time directly conflict conceptually.. you can't say "Hey, I want to guarantee this packet arrives and is handed in-order... oh but I want it discarded if a newer packet comes." reliable means you NEED that packet to arrive, and in order... if you only want to process the latest packet, use unreliable channels, as Ma-Shell pointed out ENet already handles this.

 

Not trying to sound like a hater (okay maybe a little) but I feel like the networking implementation in Leadwerks just forces you to use ENet in a more limited, undocumented way... if you're not going to implement a high-level networking layer over ENet then what's the point? A high level networking layer should handle things like specific-data type writing for the engine instead of having to convert everything to a character array and send it... this should be handled for you so it can also handle endianness in the background (Which can't be handled by Lua.). As is it feels like using ENet is easier, and it definitely gives you more freedom... In an ideal high level networking API you should also be able to create your own MasterServer (This being a separate class from Server) that acts as the median for NAT punchthrough so people can do peer-to-peer and can host their own master server lists! The current setup in LE hides your underlying ENet objects so it makes it hard for users to extend it and add their own high-level features... anyways that's my rant.

  • Upvote 1
Link to comment
Share on other sites

13 minutes ago, jen said:

If your client is sending more packets than your server can handle, you're doing something wrong. This is where the concept of tick rates come in, they sync both client and servers in the same rythm. No point wasting extra packet that can't be processed by the server while it's busy anyway.

Unreliable channel, I take it, is not yet implemented in Leadwerks so a buffer of 1 might be a good alternative. Leave no space for extra packet so your server can't form a queue, just take in one packet and process it then wait for the next latest packet to arrive.

Message.Ordered/Message.Sequenced is an unreliable channel... by default reliable packets are sequenced in ENet and CANNOT be unsequenced... ENet however provides a flag called ENET_PACKET_FLAG_UNSEQUENCED  you can use to make a channel both unreliable AND un-sequenced.

Assuming the name doesn't lie, it's safe to assume that under the hood Message.Ordered simply passes no flags to the enet_packet_create function.

Link to comment
Share on other sites

11 minutes ago, jen said:

That's stupidly complicated for a "simple and robust network communication layer". I have a perfectly working network system using a different library and I have no further interest in ENet, so I won't comment any further I'll leave it to you guys to sort your problem out.

It's not really complicated... that's just kind of the point I was making, it's easy if you READ the enet documentation.. it's hard when it's hidden behind Leadwerks abstractions and undocumented...

No flags = Unreliable, sequenced.

Unsequenced flag = Unreliable, unsequenced.

Reliable flag = Reliable, sequenced.
The documentation makes it very clear.

ENet is EXACTLY what it says it is, a low-level networking API... if you want to build a networking API into the engine it should be a higher-level design.

  • Upvote 1
Link to comment
Share on other sites

  • 2 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...