Table of Contents

Class SpeedHackDetector

Namespace
CodeStage.AntiCheat.Detectors
Assembly
Build.dll

Allows detecting Cheat Engine's speed hack (and maybe some other speed hack tools) usage.

[AddComponentMenu("Code Stage/Anti-Cheat Toolkit/Speed Hack Detector")]
[DisallowMultipleComponent]
[HelpURL("https://docs.codestage.net/actk/manual/detectors.html#speed-hack-detector")]
public class SpeedHackDetector : ACTkDetectorBase<SpeedHackDetector>
Inheritance
object
Object
Component
Behaviour
MonoBehaviour
SpeedHackDetector
Inherited Members

Remarks

Add it to any GameObject as usual or through the GameObject > Create Other > Code Stage > Anti-Cheat Toolkit menu to get started.
You can use detector completely from inspector without writing any code except the actual reaction to cheating.

Avoid using detectors from code at the Awake phase.

// Basic usage - start detection with callback
void Start()
{
    SpeedHackDetector.StartDetection(OnSpeedHackDetected);
}

private void OnSpeedHackDetected()
{
    Debug.Log("Speed hack detected!");

    // Get detailed detection info
    Debug.Log($"Detection details: {SpeedHackDetector.Instance.LastDetectionInfo}");

    // Handle the detection - ban player, show warning, etc.
}
// Advanced usage with custom settings
void Start()
{
    // Start with custom interval, max false positives, and cooldown
    SpeedHackDetector.StartDetection(OnSpeedHackDetected, 0.5f, 5, 30);
}

private void OnSpeedHackDetected()
{
    Debug.Log("Speed hack detected!");
    // Your response logic here
}
// Using SpeedHackProofTime for reliable timers
void Update()
{
    // Use SpeedHackProofTime instead of Time.time for reliable timing
    float deltaTime = SpeedHackProofTime.deltaTime;
    float time = SpeedHackProofTime.time;

    // Your game logic using reliable timers
    transform.Translate(Vector3.forward * deltaTime * speed);
}
// Safely changing timeScale without triggering false positives
void PauseGame()
{
    // Use SetTimeScale instead of Time.timeScale = 0
    SpeedHackDetector.SetTimeScale(0f);
    Debug.Log("Game paused safely");
}

void ResumeGame()
{
    SpeedHackDetector.SetTimeScale(1f);
}

// For third-party assets that need to change timeScale
void AllowThirdPartyTimeScale()
{
    // Allow any timeScale changes for 5 seconds
    SpeedHackDetector.AllowAnyTimeScaleFor(5f);
}

Fields

ComponentName

public const string ComponentName = "Speed Hack Detector"

Field Value

string

coolDown

Amount of sequential successful checks before clearing internal false positives counter.
Set 0 to disable Cool Down feature.

[Tooltip("Amount of sequential successful checks before clearing internal false positives counter.\nSet 0 to disable Cool Down feature.")]
public int coolDown

Field Value

int

interval

Time (in seconds) between detector checks.

[Tooltip("Time (in seconds) between detector checks.")]
public float interval

Field Value

float

maxFalsePositives

Maximum false positives count allowed before registering speed hack.

[Tooltip("Maximum false positives count allowed before registering speed hack.")]
public byte maxFalsePositives

Field Value

byte

threshold

Allowed speed multiplier threshold. Do not set to too low values (e.g. 0 or 0.00*) since there are timer fluctuations on different hardware.

[Tooltip("Allowed speed multiplier threshold. Do not set to too low values (e.g. 0 or 0.00*) since there are timer fluctuations on different hardware.")]
[Range(0.05, 5)]
public float threshold

Field Value

float

Properties

LastDetectionInfo

Holds detailed information about latest triggered detection.

public SpeedHackDetectionInfo LastDetectionInfo { get; }

Property Value

SpeedHackDetectionInfo

Remarks

Provides information about which detection source triggered the speed hack detection (environment ticks, realtime ticks, DSP, or timeScale changes).

TimeJumpThreshold

Time jump threshold in seconds. Detects suspicious backward or forward time jumps exceeding this value.

public int TimeJumpThreshold { get; set; }

Property Value

int

UseDsp

Controls whether to use DSP Timer to catch speed hacks in sandboxed environments (like WebGL, VMs, etc.).

public bool UseDsp { get; set; }

Property Value

bool

Remarks

Uses AudioSettings.dspTime under the hood, which can catch some extra speed hacks in sandboxed environments but can potentially cause false positives on some hardware due to way too high sensitivity. ⚠️ Warning: Use at your peril!

WatchTimeScale

Controls whether to watch Time.timeScale for unauthorized changes.

public bool WatchTimeScale { get; set; }

Property Value

bool

Remarks

When enabled, the detector will monitor for unauthorized changes to Time.timeScale. Use SetTimeScale() method to safely change timeScale without triggering false positives. ⚠️ Warning: May cause false positives if you change timeScale without using the provided API.

Methods

AddToSceneOrGetExisting()

Creates new instance of the detector at scene if it doesn't exists. Make sure to call NOT from Awake phase.

public static SpeedHackDetector AddToSceneOrGetExisting()

Returns

SpeedHackDetector

New or existing instance of the detector.

AllowAnyTimeScale()

Immediately allows any timeScale changes until StopAllowingAnyTimeScale() is called.

public static void AllowAnyTimeScale()

Remarks

Useful when third-party assets need to change timeScale directly for an indefinite period.

AllowAnyTimeScaleFor(float)

Temporarily allows any timeScale changes for the specified duration.

public static void AllowAnyTimeScaleFor(float durationSeconds)

Parameters

durationSeconds float

Duration in real-time seconds to allow any timeScale changes.

Remarks

Useful when third-party assets need to change timeScale directly.

Dispose()

Stops and completely disposes detector component.

public static void Dispose()

Remarks

On dispose Detector follows 2 rules:

  • if Game Object's name is "Anti-Cheat Toolkit Detectors": it will be automatically destroyed if no other Detectors left attached regardless of any other components or children;
  • if Game Object's name is NOT "Anti-Cheat Toolkit Detectors": it will be automatically destroyed only if it has neither other components nor children attached;

SetTimeScale(float)

Safely changes Time.timeScale without triggering false positives in timeScale detection.

public static void SetTimeScale(float newTimeScale)

Parameters

newTimeScale float

New timeScale value to set.

Remarks

Use this method instead of directly setting Time.timeScale when timeScale detection is enabled.

StartDetection()

Starts speed hack detection for detector you have in scene.

public static SpeedHackDetector StartDetection()

Returns

SpeedHackDetector

Remarks

Make sure you have properly configured detector in scene with autoStart disabled before using this method.

StartDetection(Action)

Starts speed hack detection with specified callback.

public static SpeedHackDetector StartDetection(Action callback)

Parameters

callback Action

Method to call after detection.

Returns

SpeedHackDetector

Remarks

If you have detector in scene make sure it has empty Detection Event.
Creates a new detector instance if it doesn't exists in scene.

StartDetection(Action, float)

Starts speed hack detection with specified callback using passed interval.

public static SpeedHackDetector StartDetection(Action callback, float interval)

Parameters

callback Action

Method to call after detection.

interval float

Time in seconds between speed hack checks. Overrides interval property.

Returns

SpeedHackDetector

Remarks

If you have detector in scene make sure it has empty Detection Event.
Creates a new detector instance if it doesn't exists in scene.

StartDetection(Action, float, byte)

Starts speed hack detection with specified callback using passed interval and maxFalsePositives.

public static SpeedHackDetector StartDetection(Action callback, float interval, byte maxFalsePositives)

Parameters

callback Action

Method to call after detection.

interval float

Time in seconds between speed hack checks. Overrides interval property.

maxFalsePositives byte

Amount of possible false positives. Overrides maxFalsePositives property.

Returns

SpeedHackDetector

Remarks

If you have detector in scene make sure it has empty Detection Event.
Creates a new detector instance if it doesn't exists in scene.

StartDetection(Action, float, byte, int)

Starts speed hack detection with specified callback using passed interval, maxFalsePositives and coolDown.

public static SpeedHackDetector StartDetection(Action callback, float interval, byte maxFalsePositives, int coolDown)

Parameters

callback Action

Method to call after detection.

interval float

Time in seconds between speed hack checks. Overrides interval property.

maxFalsePositives byte

Amount of possible false positives. Overrides maxFalsePositives property.

coolDown int

Amount of sequential successful checks before resetting false positives counter. Overrides coolDown property.

Returns

SpeedHackDetector

StopAllowingAnyTimeScale()

Stops allowing any timeScale changes if AllowAnyTimeScale() was called.

public static void StopAllowingAnyTimeScale()

StopDetection()

Stops detector. Detector's component remains in the scene. Use Dispose() to completely remove detector.

public static void StopDetection()

TriggerDetection()

Manually triggers cheating detection and invokes assigned events.

[ContextMenu("Trigger detection")]
public void TriggerDetection()