Launch context#
Every time the Gamearly launcher starts your game, it sets a group of GAMEARLY_*
environment variables on your game's process. Together they describe how the launch was
authorized: who the player is, whether we could verify them right now, and if not, why not.
They are plain, individual environment variables — not a JSON blob — so reading any one of them is a single line in any engine, with no parsing.
Read this first
Only GAMEARLY_LAUNCH_TOKEN is authoritative: it is cryptographically signed and verified
by our servers. Every other variable is advisory. They are unsigned text, and anyone can
set them by hand before running your executable.
Use them to decide user experience and to understand why a token is missing. Never use them, on their own, to grant access to anything you care about.
Always present#
| Variable | Values | Meaning |
|---|---|---|
GAMEARLY_LAUNCHER |
1 |
Gamearly started this process. If this variable is absent, the launcher was not involved at all. |
GAMEARLY_CONTEXT_VERSION |
1 |
Version of this variable set. Ignore values you don't recognize; we only bump it if the meaning of an existing variable changes. |
GAMEARLY_ENV |
production / staging / local |
Which Gamearly environment launched you. |
GAMEARLY_GAME_ID |
integer | Your game id. |
GAMEARLY_TOKEN_STATUS |
see table below | Whether a token was issued, and if not, why. |
GAMEARLY_ACCESS_STATE |
ok / unknown |
ok if we have confirmed this player's access online — now, or on a previous launch. |
GAMEARLY_ONLINE |
1 / 0 / unknown |
Whether the machine had connectivity at launch. |
Present when we know them#
| Variable | Values | Meaning |
|---|---|---|
GAMEARLY_LAUNCH_TOKEN |
signed JWT | The launch token. Present only when GAMEARLY_TOKEN_STATUS=ok. |
GAMEARLY_TOKEN_EXPIRES_AT |
unix seconds | When the token stops verifying. |
GAMEARLY_USER_ID |
uuid | The Gamearly user. Set whenever we know who is signed in — including when no token could be issued. Advisory until confirmed by /launch_tokens/verify. |
GAMEARLY_LAST_VERIFIED_AT |
unix seconds | The last time we confirmed this player's access online, for this channel. Absent if we never have. |
GAMEARLY_INSTALLATION_ID |
uuid | Stable id for this install on this device. Occasionally absent in the first few seconds after the launcher starts. |
GAMEARLY_CHANNEL_ID |
string | The build channel launched — main, demo, DLC, beta … |
GAMEARLY_BUILD_ID |
string | The exact build. |
GAMEARLY_BUILD_VERSION |
e.g. 1.4.2 |
Version string of that build. |
GAMEARLY_LAUNCHER_VERSION |
e.g. 1.8.2 |
The launcher's own version. |
Token status values#
| Value | Meaning | Recommended handling |
|---|---|---|
ok |
A token is attached. | Verify it server-side. |
offline |
The machine has no connectivity, so we couldn't request one. | Apply your offline policy — see the grace period in Enforcement. |
server_error |
Gamearly was reachable but failed. | Treat exactly like offline. Never punish a player for our outage. |
auth_expired |
The player's Gamearly session expired. | Treat like offline. You may prompt them to sign in to Gamearly. |
not_entitled |
Gamearly says this player does not own this channel. | The one status worth refusing even if you're lenient about offline. |
no_channel |
Launch metadata was incomplete. Should not happen. | Treat like unknown. |
unknown |
Unclassified failure. | Treat like offline. |
GAMEARLY_LAUNCH_TOKEN is set only for ok. For every other status there is no token to
verify — the status is telling you why.
The distinction that matters most#
GAMEARLY_LAUNCHER is set -> Gamearly started your game.
Read GAMEARLY_TOKEN_STATUS to learn how much we could verify.
GAMEARLY_LAUNCHER is absent -> Your executable was started directly: from Explorer, from a
copied folder, by a script, or by another launcher. None of
the guarantees on this page apply.
Worked examples#
You have a token; verify it and enforce fully.
GAMEARLY_LAUNCHER=1
GAMEARLY_CONTEXT_VERSION=1
GAMEARLY_ENV=production
GAMEARLY_GAME_ID=42
GAMEARLY_TOKEN_STATUS=ok
GAMEARLY_ACCESS_STATE=ok
GAMEARLY_ONLINE=1
GAMEARLY_LAUNCH_TOKEN=eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...
GAMEARLY_TOKEN_EXPIRES_AT=1755865260
GAMEARLY_USER_ID=8a8c0198-6e85-4fa3-8c7f-9f6d43bcb8b2
GAMEARLY_LAST_VERIFIED_AT=1755865200
GAMEARLY_INSTALLATION_ID=2b1f9c44-77e3-4a0e-9d31-6c8a5f2e10bd
GAMEARLY_CHANNEL_ID=chn_9f3a21
GAMEARLY_BUILD_ID=bld_7c41de
GAMEARLY_BUILD_VERSION=1.4.2
GAMEARLY_LAUNCHER_VERSION=1.8.2
No token exists to verify, but you know who they are and when we last confirmed their access — five days ago here. Under a 14-day grace window, let them play.
GAMEARLY_LAUNCHER=1
GAMEARLY_CONTEXT_VERSION=1
GAMEARLY_ENV=production
GAMEARLY_GAME_ID=42
GAMEARLY_TOKEN_STATUS=offline
GAMEARLY_ACCESS_STATE=ok
GAMEARLY_ONLINE=0
GAMEARLY_USER_ID=8a8c0198-6e85-4fa3-8c7f-9f6d43bcb8b2
GAMEARLY_LAST_VERIFIED_AT=1755432000
GAMEARLY_INSTALLATION_ID=2b1f9c44-77e3-4a0e-9d31-6c8a5f2e10bd
GAMEARLY_CHANNEL_ID=chn_9f3a21
GAMEARLY_BUILD_ID=bld_7c41de
GAMEARLY_BUILD_VERSION=1.4.2
GAMEARLY_LAUNCHER_VERSION=1.8.2
We were online and we asked; the answer was no. Note GAMEARLY_ACCESS_STATE=unknown and the
absence of GAMEARLY_LAST_VERIFIED_AT — we have never confirmed access for this player.
This is the case to refuse.
GAMEARLY_LAUNCHER=1
GAMEARLY_CONTEXT_VERSION=1
GAMEARLY_ENV=production
GAMEARLY_GAME_ID=42
GAMEARLY_TOKEN_STATUS=not_entitled
GAMEARLY_ACCESS_STATE=unknown
GAMEARLY_ONLINE=1
GAMEARLY_USER_ID=8a8c0198-6e85-4fa3-8c7f-9f6d43bcb8b2
GAMEARLY_INSTALLATION_ID=2b1f9c44-77e3-4a0e-9d31-6c8a5f2e10bd
GAMEARLY_CHANNEL_ID=chn_9f3a21
GAMEARLY_BUILD_ID=bld_7c41de
GAMEARLY_BUILD_VERSION=1.4.2
GAMEARLY_LAUNCHER_VERSION=1.8.2
Someone opened your .exe from Explorer, or copied the install folder to a machine that has
no Gamearly. There is nothing at all:
(no GAMEARLY_* variables are set)
Reading it#
Call GamearlyLaunch.Init() early, e.g. in a bootstrap MonoBehaviour.Awake.
using System;
using UnityEngine;
public static class GamearlyLaunch {
public static bool ViaLauncher { get; private set; }
public static string Token { get; private set; }
public static string TokenStatus { get; private set; }
public static string UserId { get; private set; }
public static long LastVerified { get; private set; } // unix seconds, 0 = never
public static bool IsOnline { get; private set; }
public static bool HasToken => !string.IsNullOrEmpty(Token);
static string Env(string key) => Environment.GetEnvironmentVariable(key);
public static void Init() {
ViaLauncher = Env("GAMEARLY_LAUNCHER") == "1";
Token = Env("GAMEARLY_LAUNCH_TOKEN");
TokenStatus = Env("GAMEARLY_TOKEN_STATUS") ?? "unknown";
UserId = Env("GAMEARLY_USER_ID");
IsOnline = Env("GAMEARLY_ONLINE") == "1";
long.TryParse(Env("GAMEARLY_LAST_VERIFIED_AT"), out long lastVerified);
LastVerified = lastVerified;
// Never block boot here. Gate online features on the VERIFIED result instead.
Debug.Log($"[Gamearly] launcher={ViaLauncher} tokenStatus={TokenStatus}");
}
// Send Token to YOUR backend, which calls
// POST https://api.gamearly.com/v1/launch_tokens/verify with your X-Api-Key.
}
For example in your GameInstance init.
const bool bViaLauncher =
FPlatformMisc::GetEnvironmentVariable(TEXT("GAMEARLY_LAUNCHER")) == TEXT("1");
const FString Token = FPlatformMisc::GetEnvironmentVariable(TEXT("GAMEARLY_LAUNCH_TOKEN"));
const FString Status = FPlatformMisc::GetEnvironmentVariable(TEXT("GAMEARLY_TOKEN_STATUS"));
if (!bViaLauncher) {
UE_LOG(LogTemp, Log, TEXT("[Gamearly] Direct launch; continuing (fail-open)."));
} else if (Token.IsEmpty()) {
UE_LOG(LogTemp, Log, TEXT("[Gamearly] No token (%s); applying offline policy."), *Status);
} else {
// POST Token to YOUR backend -> it calls .../launch_tokens/verify.
// Gate online services on the result.
}
func _ready():
var via_launcher := OS.get_environment("GAMEARLY_LAUNCHER") == "1"
var token := OS.get_environment("GAMEARLY_LAUNCH_TOKEN")
var status := OS.get_environment("GAMEARLY_TOKEN_STATUS")
# token may be empty (offline, or a direct launch) — never abort here.
# Verify server-side and gate only online features.