slowpoker/Assets/Mirror/Core/ConnectionQuality.cs

75 lines
3.2 KiB
C#
Raw Permalink Normal View History

2024-10-17 17:23:05 +03:00
// 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;
}
}
}