Author Topic: 3.25 Released  (Read 26528 times)

Rak'kar

  • Administrator
  • Hero Member
  • *****
  • Posts: 6895
  • Karma: 291
    • View Profile
    • RakNet
Re: 3.25 Released
« Reply #15 on: July 29, 2008, 11:44:16 AM »
My last edit does basically that, but is even less aggressive. You'd hit the 1 second delay by random chance once every 50 hours more or less, at 30 sends per second the entire time. You can get it out of source control if you want.

gjaegy

  • Jr. Member
  • **
  • Posts: 76
  • Karma: 1
    • View Profile
Re: 3.25 Released
« Reply #16 on: July 29, 2008, 11:59:36 AM »
In your edit I see you have 50ms for the first retry... ? or maybe I don't see which edit you talk about ?

Rak'kar

  • Administrator
  • Hero Member
  • *****
  • Posts: 6895
  • Karma: 291
    • View Profile
    • RakNet
Re: 3.25 Released
« Reply #17 on: July 29, 2008, 12:40:17 PM »
Code: [Select]
internalPacket->timesSent++;
if (ackPingSum==0 || internalPacket->timesSent>4)
internalPacket->nextActionTime = time + (RakNetTimeNS)1000000;
else if (internalPacket->timesSent==2)
internalPacket->nextActionTime = time + (RakNetTimeNS)50000 + (ackPingSum>>7);
else if (internalPacket->timesSent==3)
internalPacket->nextActionTime = time + (RakNetTimeNS)100000 + (ackPingSum>>7);
else // if (internalPacket->timesSent==4)
internalPacket->nextActionTime = time + (RakNetTimeNS)200000 + (ackPingSum>>6);

The first resend also does time + (RakNetTimeNS)50000 + (ackPingSum>>7);

gjaegy

  • Jr. Member
  • **
  • Posts: 76
  • Karma: 1
    • View Profile
Re: 3.25 Released
« Reply #18 on: July 29, 2008, 04:13:39 PM »
Yes, this is what I mean.

I think having ping x 2 or ping x 4 for the first (and maybe second as well) retry would be much safer (at least in my specific case) than 50ms + ping x 2.

What about having this configurable ? You could for instance have a RAKNET_AVOID_FLOODING flag or parameter or whatever that switches between two different levels of flooding prevention.

Oliver Smith

  • Full Member
  • ***
  • Posts: 173
  • Karma: 7
  • Oliver Smith
    • View Profile
    • Oliver's blog
Re: 3.25 Released
« Reply #19 on: July 29, 2008, 04:17:02 PM »
I noticed in BtStream.cpp::ReverseBytesInPlace you changed

Code: [Select]
BitSize_t i;
for (i=0; i < length; i++)
to
Code: [Select]
BitSize_t i;
for (i=0; i < (length>>1); i++)

you're only reversing half the data? is "length" in Bits, Bytes or Words?


- Oliver

Rak'kar

  • Administrator
  • Hero Member
  • *****
  • Posts: 6895
  • Karma: 291
    • View Profile
    • RakNet
Re: 3.25 Released
« Reply #20 on: July 29, 2008, 06:37:26 PM »
Yes, this is what I mean.

I think having ping x 2 or ping x 4 for the first (and maybe second as well) retry would be much safer (at least in my specific case) than 50ms + ping x 2.

What about having this configurable ? You could for instance have a RAKNET_AVOID_FLOODING flag or parameter or whatever that switches between two different levels of flooding prevention.

Edit: What do you think of this:

first resend: 15 milliseconds + 2 * ping
second resend: 100 milliseconds + 2 * ping
third resend: 200 milliseconds + 4 * ping
fourth + resends: 1 second
« Last Edit: July 29, 2008, 07:01:36 PM by Rak'kar »

Rak'kar

  • Administrator
  • Hero Member
  • *****
  • Posts: 6895
  • Karma: 291
    • View Profile
    • RakNet
Re: 3.25 Released
« Reply #21 on: July 29, 2008, 06:39:17 PM »
Bytes. It was a bug before to go through the whole list. To reverse a list, you have to swap half the total elements.

I noticed in BtStream.cpp::ReverseBytesInPlace you changed

Code: [Select]
BitSize_t i;
for (i=0; i < length; i++)
to
Code: [Select]
BitSize_t i;
for (i=0; i < (length>>1); i++)

you're only reversing half the data? is "length" in Bits, Bytes or Words?


- Oliver

gjaegy

  • Jr. Member
  • **
  • Posts: 76
  • Karma: 1
    • View Profile
Re: 3.25 Released
« Reply #22 on: July 30, 2008, 02:21:07 AM »
You are a hard negotiator ;)

As I said, I have never had any issue with flooding, and my application needs to get the packets as soon as possible (reliable as well) so personally I would prefer having no constant time at all (at least for the fist and second retry, i.e. 99.99% of the cases)...

But you are the only decision maker  :-\
« Last Edit: July 30, 2008, 02:24:11 AM by gjaegy »

Rak'kar

  • Administrator
  • Hero Member
  • *****
  • Posts: 6895
  • Karma: 291
    • View Profile
    • RakNet
Re: 3.25 Released
« Reply #23 on: July 30, 2008, 11:08:27 AM »
Update: What I've checked in should work pretty well.

The first two tries should cover 99.96% of datagrams, in which case there is no delay beyond what is absolutely necessary.
The third try uses a base of 50 milliseconds, and 3X your ping.
After that it's 1 second apart.

Using the loopback it transfers 32 megabits per second at 2.5% packetloss due to system buffer overruns.

Code: [Select]
// First try is immediate
// Second try will be
// 15 milliseconds for system variance
// Twice your ping for RTT
// 1/4 your ping for normal transit fluctuations
internalPacket->nextActionTime = time + (RakNetTimeNS)15000 + (ackPingSum>>7) + (ackPingSum>>10);

Code: [Select]
if (ackPingSum==0 || internalPacket->timesSent>=3)
{
// Fourth and subsequent tries will be one second apart, to avoid flooding the other system on periods of long unresponsiveness
internalPacket->nextActionTime = time + (RakNetTimeNS)1000000;
}
else if (internalPacket->timesSent==2)
{
// Third try will be
// 50 milliseconds for system variance
// Three times your ping
internalPacket->nextActionTime = time + (RakNetTimeNS)50000 + (ackPingSum>>7) + (ackPingSum>>8);
}

Oliver Smith

  • Full Member
  • ***
  • Posts: 173
  • Karma: 7
  • Oliver Smith
    • View Profile
    • Oliver's blog
Re: 3.25 Released
« Reply #24 on: July 30, 2008, 01:48:06 PM »
Agh - I can see why ^- these ping-related changes are good for shoebox games but how do they translate to situations where players have a broad spectrum of variable pings, as in an MMO. We see pings in the range from 30ms to 780ms. However, more importantly, we still have 6% of our playerbase using dialup (my friends at Blizzard tell me they have roughly about the same).

Unless your game is generating a ridiculous amount of bandwidth then for most of the time, the connection is largely idle; maybe you send 10-20 fairly small packets every second. But every now and again you are going to have chat messages, status updates, etc, going on, and every now and again these are going to occur in a short enough space of time to interact with the Thread Sleep Timer and cause a temporary, artificial spike in ping. On a very low-latency connection this spike can easily be more than double the running ping. If you have a running ping of 20ms with spikes of 60ms, your average isn't going to come out anywhere near the 30ms that would prevent Raknet sending spurious retransmits.

Remember: Ping is a Round Trip Time. A -> B -> A. Under Raknet you have the additional interaction with the Sleep Timer...

A -> Sleep Timer at A -> send -> Sleep Timer at B -> Raknet at B -> acknowledge -> Sleep Timer at B -> send -> Sleep Timer at A -> A

(I could be wrong about this: do ping acks go out in the same sleep-cycle as they are received, Kevin? Or do you read off the wire /after/ sending all outstanding packets?)

Would it help if Raknet rounded all ping times up to the next modulo of the Thread Sleep Timer when using them in the average-ping calculation, and then rounded the average ping up to the next modulo of the Thread Sleep Timer? That way you'd be saying "I won't decide to retransmit before the other end has had chance to do a full sleep cycle".

"Making sure the packets arrive as soon as possible" is not entirely compatible with "making sure packets arrive in a smooth and timely fashion" which is what you really want. Being too quick off the mark to retransmit data means that other data gets delayed.

I suspect it might be helpful to use a less aggressive default time-based retransmit policy with prioritization based on acknowledgements.

Lets say I send 10 packets, average ping 40ms

T+000ms Packet 1 sent
T+011ms Packet 2 sent
T+022ms Packet 3 sent
T+033ms Packet 4 sent
T+040ms Packet 1 ack'd
T+044ms Packet 5 sent
T+051ms Packet 2 ack'd
T+055ms Packet 6 sent
T+062ms ack for packet 3 does not arrive
T+066ms Packet 7 sent
T+073ms ack for packet 4 does not arrive
T+077ms Packet 8 sent
T+084ms Packet 5 ack'd

At this point, packets 3 and 4 are outstanding an ack. They may have arrived at the far end and they are avgPing * 1.5 overdue. That's a good time to retransmit.

On the other hand, consider if at T+084 we didn't receive an ACK - we don't know for sure, yet, that the other end isn't receiving our packets. Yes, there may be congestion occurring, but increasing our send rate (by adding retransmits to the outgoing packets) is not the solution, since it may make the congestion worse. Infact, this is a great way to cause your users to get disco'd in a bunch of normal operating scenarios, such as another application grabbing the network connection -- Adobe and Sun's auto-updaters are terrible for this.

That said, it might be useful if Raknet had the ability to inject a small, stand-alone ping packet when it thinks packetloss is occurring. Think of it as a "pinched" test - like dropping a penny down a vacuum cleaner hose to see if it's blocked.

If the ack for packet 5 is properly in-sequence (i.e. the packet is sequential to the last packet received) then the client can tell that there is packet -loss or -reordering occurring on the client->server connection. If the ack had a bit indicating "in sequence" and it received the #5 ack out of sequence then it could tell that server->client loss/reordering is occurring.
« Last Edit: July 30, 2008, 01:56:31 PM by Oliver Smith »

Rak'kar

  • Administrator
  • Hero Member
  • *****
  • Posts: 6895
  • Karma: 291
    • View Profile
    • RakNet
Re: 3.25 Released
« Reply #25 on: July 30, 2008, 02:03:14 PM »
RakNet's ping already accounts for the thread sleep timer. The ping is continuously recalculated to be current. Pings are data the same as other sends, but have higher priorities.

You're right about the ping. The first retransmit ought to be about 1.5 times.

gjaegy

  • Jr. Member
  • **
  • Posts: 76
  • Karma: 1
    • View Profile
Re: 3.25 Released
« Reply #26 on: July 31, 2008, 02:36:01 AM »
I understand you guys are right for normal games over the internet.

However, I use Raknet on a small gigabit LAN, linking about 10 PCs together. I only send a few packets per second. Keyframes for my objects are sent every second using reliable packets.

So in my case, even 50ms >> ping, this is why what appears to be a very small change, actually beneficial in most of the cases, makes me feel a bit nervous in my situation.

OvermindDL1

  • Anti-Spam Moderator
  • Hero Member
  • ****
  • Posts: 855
  • Karma: 40
  • Programmer
    • View Profile
    • OvermindDL1's Site
Re: 3.25 Released
« Reply #27 on: July 31, 2008, 05:36:30 AM »
But a dropped packet would also be very rare on such a network (if the router is half-decent), so it is not a situation that would be encountered often...

gjaegy

  • Jr. Member
  • **
  • Posts: 76
  • Karma: 1
    • View Profile
Re: 3.25 Released
« Reply #28 on: August 04, 2008, 02:45:14 AM »
You are certainly right, however I don't want to rely on this assumption for my software. Because of the wide range of hardware used by different customers I prefer being sure of what the software does, and I prefer if it does it properly on a bad condition network.

I might be paranoid, but it turned that being realistic (developing for the worst case scenario) is less problematic than being optimistic. I think you can't disagree with that...

OvermindDL1

  • Anti-Spam Moderator
  • Hero Member
  • ****
  • Posts: 855
  • Karma: 40
  • Programmer
    • View Profile
    • OvermindDL1's Site
Re: 3.25 Released
« Reply #29 on: August 04, 2008, 02:51:50 AM »
If you want something more reliable then a packet switching network, you could always use a direct stream over RS232 or a LPT port. :P