KorvayneGuides
SDK reference

Korvayne Runtime SDK reference

The technical reference for integrating the public C ABI directly or through engine wrappers. Use this after the drop-in quickstart is working.

Windows x64C ABIEngine wrappers

Integration modes

ModeWhat it doesUse when
Drop-inShip anticheat.dll, anticheat.lic, and anticheat.ini; load the DLL once at startup.You want baseline sensors and local logs with minimal game changes.
Cooperative APICall the public C exports or an engine wrapper for context, telemetry tokens, ValueGuard, SaveGame protection, and aim reports.You need player/session attribution, protected values, protected saves, or behavior reports.

Package layout

sdk/include/anticheat.h     Public C API
sdk/bin/anticheat.dll       Runtime DLL and drop-in entry
sdk/lib/anticheat.lib       MSVC import library
sdk/anticheat.ini.example   Example config
backend-kit/                Schemas and endpoint examples
samples/ue5/                Unreal wrapper
samples/unity/              Unity wrapper
tools/KorvayneConfigurator  Config UI
tools/KorvayneDropper       File placement helper

Lifecycle

AC_Init verifies the license, adopts the callback and flags, then starts the background sensor threads. It is idempotent and safe to call early.

ac_config cfg = {0};
cfg.cb = OnKorvayneDetection;
cfg.user = MyContext;
cfg.scan_interval_ms = 500;
cfg.flags = AC_FLAG_VALUEGUARD_RESTORE;
cfg.license = NULL; // load anticheat.lic next to the game executable

int rc = AC_Init(&cfg);
FunctionPurpose
AC_Init(const ac_config*)Arms sensors and starts the scan thread.
AC_Tick()Optional cheap per-frame checks. Useful for cooperative integrations.
AC_Shutdown()Stops SDK threads before process shutdown or controlled unload.
AC_Version()Returns the runtime version string for support and logs.

Detection callback

The callback runs on an SDK background thread, not your game thread. Keep it cheap and thread-safe.

typedef void (*ac_detection_cb)(const ac_detection* det, void* user);

typedef struct {
    const char* sensor;
    ac_severity severity;
    float confidence;
    const char* message;
    unsigned long long detail;
} ac_detection;
  • Copy strings if you need to keep them. Pointers are valid only during the callback.
  • Do not perform file or network I/O directly inside the callback.
  • Do not call AC_* functions from inside the callback.
  • Queue evidence to your game thread or telemetry worker.
SeverityMeaning
AC_SEV_INFOStartup, license, or status event.
AC_SEV_LOWWeak signal. Log only.
AC_SEV_MEDCorroborating signal. Review with context.
AC_SEV_HIGHHigh-confidence tamper evidence.
AC_SEV_CRITEnforcement event.

Runtime context

Context setters copy non-secret game/session data used by telemetry and access checks. Set them after login or session creation, and rotate the telemetry token when your backend issues a new one.

FunctionUse
AC_SetGameIdStable game identifier.
AC_SetEnvironmentproduction, staging, or similar.
AC_SetIdentityProviderPlatform or account source, such as steam.
AC_SetPlayerIdStudio player/account ID.
AC_SetSessionIdLogin, match, or server session ID.
AC_SetPlatformUserIdPlatform user identifier.
AC_SetGameBuildBuild/version string.
AC_SetTelemetryTokenShort-lived backend-issued token. Not a static secret.

The backend JSON contract is documented in Telemetry event payload, including required fields, optional fields, and schema files.

ValueGuard API

ValueGuard protects stable 4-byte values owned by the game. Legitimate writes should go through the write-through setter so the runtime value and shadow value stay in sync.

AC_GuardFloat("player.health", &CurrentHP);
AC_SetGuardedFloat(&CurrentHP, NewHP);
AC_UnguardFloat(&CurrentHP);
Function groupPurpose
AC_GuardU32, AC_GuardI32, AC_GuardFloatRegister a value address and display name.
AC_SetGuardedU32, AC_SetGuardedI32, AC_SetGuardedFloatPreferred legitimate write path. Updates value and shadow together.
AC_NoteLegit, AC_NoteLegitI32, AC_NoteLegitFloatFallback after legacy direct writes. Prefer setters when possible.
AC_Unguard, AC_UnguardI32, AC_UnguardFloatStop guarding before the address becomes invalid.

SaveGame API

SaveGame protection wraps serialized save bytes with a signed envelope before writing and verifies that envelope before loading. The game owns serialization and recovery behavior.

const char* ctx = "player=studio-123;slot=campaign-1;schema=2";
int rc = AC_ProtectSaveFile("profile.ksave", saveBytes, saveLen, ctx);
unsigned outLen = 0;
unsigned char out[1024 * 1024];
int rc = AC_VerifySaveFile("profile.ksave", ctx, out, sizeof(out), &outLen);
if (rc == AC_SAVE_OK) {
    Deserialize(out, outLen);
}
Function groupPurpose
AC_ProtectSaveBuffer, AC_VerifySaveBufferProtect or verify save bytes when the engine handles file I/O.
AC_ProtectSaveFile, AC_VerifySaveFileProtect or verify a save file on disk.
AC_SaveResultNameConvert SaveGame return codes into readable names for logs and wrappers.
ReturnMeaning
AC_SAVE_OKProtection or verification succeeded.
AC_SAVE_BUFFER_TOO_SMALLOutput buffer is too small for the verified plain payload.
AC_SAVE_TAMPEREDEnvelope, payload, or context verification failed. Reject the load.
AC_SAVE_UNLICENSEDThe runtime is not armed under a valid license.
AC_SAVE_DISABLED[SaveGameProtection] enabled = 0.

See SaveGame protection for context-binding, config, Unity, Unreal, and telemetry guidance.

Behavior API

Behavior reports are optional cooperative signals. Drop-in mode cannot know where a player aimed, when a target became visible, or whether a shot had line of sight. The SDK does not read mouse input, target positions, or visibility state by itself. The game must send that context after a local human player's shot.

AC_ReportAim(
    aimSpeedPerMs,
    reactionMs,
    hadLineOfSight ? 1 : 0,
    hit ? 1 : 0
);
ArgumentMeaning
aimSpeedPerMsCrosshair or view-angle movement speed immediately before the shot. Use one consistent unit across your game.
reactionMsApproximate milliseconds between target acquisition/visibility and firing.
hadLineOfSight1 if the local player had valid line of sight when the shot was resolved.
hit1 if the shot hit a player or protected target.

How to produce the values

ValueSimple integration sourceNotes
aimSpeedPerMsStore the local camera/control rotation from the previous weapon tick and compare it to the rotation at shot time.Approximate is fine. Keep the same unit and calculation across builds so baselines stay comparable.
reactionMsWhen a valid enemy first becomes visible or targetable, store a timestamp. On shot, subtract that timestamp.If the game does not track acquisition yet, pass a conservative large value until it does.
hadLineOfSightReuse the same line trace, raycast, or server hit-validation result your weapon already uses.Do not invent a second visibility system only for the SDK; mismatches create noisy reports.
hitUse the final local hit result after the weapon has resolved the shot.Only report shots fired by the local human player.

Safe fallback: if a game cannot calculate one of these values yet, leave shot reports disabled instead of sending guesses every frame. The other anti-cheat sensors still work without this API.

  1. Call it once per resolved shot, not every frame.
  2. Only report the local human player. Do not report bots, remote replicated players, spectators, or replay playback.
  3. Start with behavior_response = report until normal gameplay has been observed.
  4. Correlate behavior events with server-side match data before strong punishment.

What the runtime checks

The built-in checks are intentionally simple advisory heuristics, not automatic full-match aim analysis. They only run when the game calls AC_ReportAim.

EvidenceCurrent conditionSeverity
AimSnaphit = 1 and aimSpeedPerMs > 8.0medium
TriggerbotThree hit shots with 0 < reactionMs < 60. The counter resets after a normal reaction above 120ms.medium
Wallhackhit = 1 and hadLineOfSight = 0high

Telemetry categorizes those events as aim_behavior, controlled by [TelemetryEvents] aim_behavior and [Enforcement] behavior_response. Keep them report-only until the studio has compared the events with normal gameplay and server-side match data.

Engine wrappers

Unreal and Unity teams should normally use wrapper code instead of calling raw C exports directly from gameplay scripts.

  • Unreal: startup plugin/module loads the DLL and exposes Blueprint-friendly nodes.
  • Unity: KorvayneManager, KorvayneProtectedFloat, and KorvayneProtectedInt wrap native calls safely.

Return codes and flags

ReturnMeaning
0SDK armed successfully.
-1Bad arguments.
-2Thread startup failed.
-3Unlicensed, expired, malformed, or invalid license. SDK does not arm.
FlagMeaning
AC_FLAG_VALUEGUARD_RESTORERestore guarded values on out-of-band writes.
AC_FLAG_TERMINATE_ON_TAMPERAllow local termination on confirmed high-confidence evidence.
AC_FLAG_EJECT_ON_READERSeparate aggressive reader-only override. With the reader entitlement, unsigned read-only external readers can close the protected game even without AC_FLAG_TERMINATE_ON_TAMPER.