aha
This commit is contained in:
74
Assets/Mirror/Core/ConnectionQuality.cs
Normal file
74
Assets/Mirror/Core/ConnectionQuality.cs
Normal file
@ -0,0 +1,74 @@
|
||||
// standalone, Unity-independent connection-quality algorithm & enum.
|
||||
// don't need to use this directly, it's built into Mirror's NetworkClient.
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mirror
|
||||
{
|
||||
public enum ConnectionQuality : byte
|
||||
{
|
||||
ESTIMATING, // still estimating
|
||||
POOR, // unplayable
|
||||
FAIR, // very noticeable latency, not very enjoyable anymore
|
||||
GOOD, // very playable for everyone but high level competitors
|
||||
EXCELLENT // ideal experience for high level competitors
|
||||
}
|
||||
|
||||
public enum ConnectionQualityMethod : byte
|
||||
{
|
||||
Simple, // simple estimation based on rtt and jitter
|
||||
Pragmatic // based on snapshot interpolation adjustment
|
||||
}
|
||||
|
||||
// provide different heuristics for users to choose from.
|
||||
// simple heuristics to get started.
|
||||
// this will be iterated on over time based on user feedback.
|
||||
public static class ConnectionQualityHeuristics
|
||||
{
|
||||
// convenience extension to color code Connection Quality
|
||||
public static Color ColorCode(this ConnectionQuality quality)
|
||||
{
|
||||
switch (quality)
|
||||
{
|
||||
case ConnectionQuality.POOR: return Color.red;
|
||||
case ConnectionQuality.FAIR: return new Color(1.0f, 0.647f, 0.0f);
|
||||
case ConnectionQuality.GOOD: return Color.yellow;
|
||||
case ConnectionQuality.EXCELLENT: return Color.green;
|
||||
default: return Color.gray; // ESTIMATING
|
||||
}
|
||||
}
|
||||
|
||||
// straight forward estimation
|
||||
// rtt: average round trip time in seconds.
|
||||
// jitter: average latency variance.
|
||||
public static ConnectionQuality Simple(double rtt, double jitter)
|
||||
{
|
||||
if (rtt <= 0.100 && jitter <= 0.10) return ConnectionQuality.EXCELLENT;
|
||||
if (rtt <= 0.200 && jitter <= 0.20) return ConnectionQuality.GOOD;
|
||||
if (rtt <= 0.400 && jitter <= 0.50) return ConnectionQuality.FAIR;
|
||||
return ConnectionQuality.POOR;
|
||||
}
|
||||
|
||||
// snapshot interpolation based estimation.
|
||||
// snap. interp. adjusts buffer time based on connection quality.
|
||||
// based on this, we can measure how far away we are from the ideal.
|
||||
// the returned quality will always directly correlate with gameplay.
|
||||
// => requires SnapshotInterpolation dynamicAdjustment to be enabled!
|
||||
public static ConnectionQuality Pragmatic(double targetBufferTime, double currentBufferTime)
|
||||
{
|
||||
// buffer time is set by the game developer.
|
||||
// estimating in multiples is a great way to be game independent.
|
||||
// for example, a fast paced shooter and a slow paced RTS will both
|
||||
// have poor connection if the multiplier is >10.
|
||||
double multiplier = currentBufferTime / targetBufferTime;
|
||||
|
||||
// empirically measured with Tanks demo + LatencySimulation.
|
||||
// it's not obvious to estimate on paper.
|
||||
if (multiplier <= 1.15) return ConnectionQuality.EXCELLENT;
|
||||
if (multiplier <= 1.25) return ConnectionQuality.GOOD;
|
||||
if (multiplier <= 1.50) return ConnectionQuality.FAIR;
|
||||
|
||||
// anything else is poor
|
||||
return ConnectionQuality.POOR;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user