1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- // 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;
- }
- }
- }
|