ConnectionQuality.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // standalone, Unity-independent connection-quality algorithm & enum.
  2. // don't need to use this directly, it's built into Mirror's NetworkClient.
  3. using UnityEngine;
  4. namespace Mirror
  5. {
  6. public enum ConnectionQuality : byte
  7. {
  8. ESTIMATING, // still estimating
  9. POOR, // unplayable
  10. FAIR, // very noticeable latency, not very enjoyable anymore
  11. GOOD, // very playable for everyone but high level competitors
  12. EXCELLENT // ideal experience for high level competitors
  13. }
  14. public enum ConnectionQualityMethod : byte
  15. {
  16. Simple, // simple estimation based on rtt and jitter
  17. Pragmatic // based on snapshot interpolation adjustment
  18. }
  19. // provide different heuristics for users to choose from.
  20. // simple heuristics to get started.
  21. // this will be iterated on over time based on user feedback.
  22. public static class ConnectionQualityHeuristics
  23. {
  24. // convenience extension to color code Connection Quality
  25. public static Color ColorCode(this ConnectionQuality quality)
  26. {
  27. switch (quality)
  28. {
  29. case ConnectionQuality.POOR: return Color.red;
  30. case ConnectionQuality.FAIR: return new Color(1.0f, 0.647f, 0.0f);
  31. case ConnectionQuality.GOOD: return Color.yellow;
  32. case ConnectionQuality.EXCELLENT: return Color.green;
  33. default: return Color.gray; // ESTIMATING
  34. }
  35. }
  36. // straight forward estimation
  37. // rtt: average round trip time in seconds.
  38. // jitter: average latency variance.
  39. public static ConnectionQuality Simple(double rtt, double jitter)
  40. {
  41. if (rtt <= 0.100 && jitter <= 0.10) return ConnectionQuality.EXCELLENT;
  42. if (rtt <= 0.200 && jitter <= 0.20) return ConnectionQuality.GOOD;
  43. if (rtt <= 0.400 && jitter <= 0.50) return ConnectionQuality.FAIR;
  44. return ConnectionQuality.POOR;
  45. }
  46. // snapshot interpolation based estimation.
  47. // snap. interp. adjusts buffer time based on connection quality.
  48. // based on this, we can measure how far away we are from the ideal.
  49. // the returned quality will always directly correlate with gameplay.
  50. // => requires SnapshotInterpolation dynamicAdjustment to be enabled!
  51. public static ConnectionQuality Pragmatic(double targetBufferTime, double currentBufferTime)
  52. {
  53. // buffer time is set by the game developer.
  54. // estimating in multiples is a great way to be game independent.
  55. // for example, a fast paced shooter and a slow paced RTS will both
  56. // have poor connection if the multiplier is >10.
  57. double multiplier = currentBufferTime / targetBufferTime;
  58. // empirically measured with Tanks demo + LatencySimulation.
  59. // it's not obvious to estimate on paper.
  60. if (multiplier <= 1.15) return ConnectionQuality.EXCELLENT;
  61. if (multiplier <= 1.25) return ConnectionQuality.GOOD;
  62. if (multiplier <= 1.50) return ConnectionQuality.FAIR;
  63. // anything else is poor
  64. return ConnectionQuality.POOR;
  65. }
  66. }
  67. }