• Hello
Search Results for

    Show / Hide Table of Contents

    Universal - Game Time - Monitor (Pro)

    Many games use Time.deltaTime for movement and cooldowns. A speed hack can make that clock run too fast, too slow, or stop. AntiCheat measures the real speed of that clock.

    Walkthrough: Protecting against speedhacks.

    Monitor

    GameTimeMonitor (namespace GUPS.AntiCheat.Monitor.Time) compares Unity's clock with real time. It sends a GameTimeStatus to its listeners.

    Why not use another clock in the game

    A speed hack such as Cheat Engine Speedhack does not edit your scripts. It scales the clocks the game can read. Then UnityEngine.Time, DateTime.UtcNow, Stopwatch, and Environment.TickCount all lie by the same amount. Comparing two of them shows nothing.

    This monitor uses a real-time clock that those tools cannot easily fake. About every 100 ms it compares that clock with Time.realtimeSinceStartupAsDouble. Unity's real-time clock is used on purpose. It is not limited by Time.maximumDeltaTime. It is not changed by Time.timeScale. A hitch, a scene load, or slow motion does not look like a cheat.

    Status

    The monitor sends a GameTimeStatus:

    public struct GameTimeStatus : IWatchedSubject
    {
        // Classified deviation of Unity's clock from real time.
        public ETimeDeviation Deviation { get; }
    
        // Elapsed Unity time divided by elapsed real time over the monitor window. 1.0 = real speed, 2.0 = twice as fast.
        public float SpeedFactor { get; }
    }
    
    • Deviation: How SpeedFactor compares with the tolerance you set.
    • SpeedFactor: How fast Unity's clock is running. 1 is normal. 2 is twice as fast. The detector uses this to correct protected time.

    The monitor does not report Time.fixedDeltaTime. The detector checks the physics step itself.

    Deviation uses this enum:

    public enum ETimeDeviation : byte
    {
        None = 0,       // No deviation detected.
        Stopped = 1,    // Time has effectively stopped.
        SlowedDown = 2, // Time is running slower than expected.
        SpeedUp = 3     // Time is running faster than expected.
    }
    

    Lifecycle and timing

    • The reference clock starts in OnStart. It stops in OnStop and OnDestroy. It runs in the background. It does not keep the game process alive.
    • The monitor looks at the reference every frame in OnUpdate. It only stores a sample when the reference moved since the last frame. Samples arrive about every 100 ms. Each sample is a pair: Unity time moved, and real time moved.
    • The last 10 samples are kept. That is about one second. Once the window is full, every new sample sends a GameTimeStatus. SpeedFactor is Unity time divided by real time. Listeners get about ten reports per second. The window keeps sliding. It is not cleared after a report.
    • A difference is reported when SpeedFactor is far enough from 1. How far is the tolerance. Stopped is reported when Unity's clock did not move at all.
    • If the reference clock does not tick for 1000 rendered frames, but Unity's clock keeps moving, the monitor reports SpeedUp right away. It does not wait for the window. Frames are counted instead of Unity time. A speed hack does not add frames, so it cannot fake this path.
    • The window resets when the monitor starts, when it resumes, when the app gets focus, and when it leaves pause. Unity's clock may or may not move while the app is in the background. Samples from before and after that gap are not compared.

    Configuration

    There is one Inspector field:

    • Tolerance Factor (toleranceFactor, range 0.05 to 1, default 0.25, a good range is 0.15 to 0.3): How far Unity's speed may drift from real time. 0.25 reports 1.25x and faster, or 0.75x and slower. The real-time clock can overshoot by a few percent. That makes Unity look a little fast. Do not go below 0.1.

    What the monitor detects and what it does not

    • Detects speed hacks that change the clocks the game can read. Cheat Engine Speedhack works this way. It also detects a memory edit of Unity's clock, and a frozen reference clock.
    • Does not detect changes to Time.timeScale. Pause and slow motion are normal. A protected timeScale is not part of this version.
    • Does not detect a tool that slows the whole computer, not just the game. The reference clock slows with it.

    Supported platforms

    The monitor works on every platform. WebGL has no background thread, so the reference falls back to DateTime.UtcNow. A speed hack that also changes the browser clock can fool that fallback. Protection is weaker there.

    Requirements

    There are no extra requirements.

    How to use

    Add GameTimeMonitor as a child of the AntiCheat-Monitor. Pair it with GameTimeCheatingDetector.

    Add the component

    Add GameTimeMonitor from GUPS.AntiCheat.Monitor.Time. A child of the monitor is the best place.

    Add the GameTimeMonitor component.

    Read the status in code

    You can also listen yourself. Subscribe returns an IDisposable. Dispose it when you want to stop.

    using System;
    using GUPS.AntiCheat.Core.Watch;
    using GUPS.AntiCheat.Monitor.Time;
    using UnityEngine;
    
    public class GameTimeStatusLogger : MonoBehaviour, IObserver<IWatchedSubject>
    {
        private void Start()
        {
            var monitor = GetComponentInChildren<GameTimeMonitor>();
            monitor.Subscribe(this);
        }
    
        public void OnNext(IWatchedSubject subject)
        {
            if (subject is GameTimeStatus status)
            {
                Debug.Log($"Deviation: {status.Deviation}, Speed: {status.SpeedFactor:0.00}x");
            }
        }
    
        public void OnError(Exception error) { }
        public void OnCompleted() { }
    }
    

    Detect a speed hack

    To decide if the report is cheating, use the Game Time Cheating Detector.

    In This Article
    Back to top GuardingPearSoftware documentation