Skip to content

Client SDK Reference

The Client SDK runs within LocalScript environments (such as StarterPlayerScripts or UI controllers). It automatically captures client hardware, network latency, and frame rates while providing methods to track UI flows, client errors, and gameplay milestones.



Boots the client-side telemetry engine. Calling .init() multiple times returns the same singleton instance.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local AnalyticsModule = require(ReplicatedStorage.AnalyticsModule)
local AnalyticsClient = AnalyticsModule.init()
  1. Connects to the secure server communication bridge (RemoteEvent).
  2. Waits 1 second for the workspace CurrentCamera to initialize, then captures screen resolution and hardware profile.
  3. Attaches a RenderStepped frame sampler to monitor client FPS.
  4. Hooks ScriptContext.Error to forward uncaught client script exceptions.
  5. Hooks UserInputService.InputBegan to manage active playtime vs. AFK state.

Dispatches a custom client telemetry event to the server across the rate-limited network bridge.

AnalyticsClient:track(eventName: string, data: { [string]: any }?, category: string?): ()
Parameter Type Required Default Description
eventName string Yes — Unique event identifier (max 64 characters).
data { [string]: any }? No {} Key-value dictionary containing event attributes (max 32 keys).
category string? No "custom" Event classification. Must be one of: "custom", "performance", "error", "session", "spatial".
-- Inside StarterPlayerScripts/UIAnalytics.client.luau
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local AnalyticsClient = require(ReplicatedStorage.AnalyticsModule).init()
local shopButton = script.Parent:WaitForChild("ShopButton") :: TextButton
shopButton.Activated:Connect(function()
AnalyticsClient:track("ShopOpened", {
sourceButton = "HUD_BottomBar",
currentLevel = 12,
})
end)
AnalyticsClient:track("OnboardingStepCompleted", {
stepIndex = 2,
stepName = "EquippedFirstSword",
durationSeconds = 18.4,
})

The Client SDK executes four automated collectors in the background:

Fires once shortly after join (ClientDemographics):

{
"name": "ClientDemographics",
"category": "demographics",
"data": {
"platform": "PC",
"inputDevice": "KeyboardMouse",
"viewportWidth": 1920,
"viewportHeight": 1080,
"networkPingMs": 42,
"locale": "en_us",
"accountAgeDays": 384
}
}
  • Platform Detection: Distinguishes between "PC", "Mobile", "Tablet" (viewport shortest dimension $\ge 600$), "Console", "VR", and "Unknown".
  • Input Type: Detects "KeyboardMouse", "Touch", "Gamepad", and "VR".
  • Ping: Measures round-trip network ping via Player:GetNetworkPing().

Every 10 seconds, the SDK calculates rolling performance metrics across RenderStepped frames (ClientPerformanceSnapshot):

{
"name": "ClientPerformanceSnapshot",
"category": "performance",
"data": {
"fps": 58,
"avgFrameTimeMs": 17.2
}
}

Intercepts unhandled client-side runtime errors (ClientRuntimeError) and transmits the error message and callstack to the server for centralized monitoring:

{
"name": "ClientRuntimeError",
"category": "error",
"data": {
"errorMessage": "Players.iiRealistic_Dev.PlayerGui.HUD:42: attempt to index nil with 'Text'",
"stackTrace": "PlayerGui.HUD.LocalScript:42\nReplicatedStorage.Controllers.UI:15",
"scriptName": "PlayerGui.HUD.LocalScript"
}
}

Monitors UserInputService.InputBegan. Whenever user input is detected, an activity ping (PlayerActivityPing) is dispatched (throttled to a maximum of once every 30 seconds) to notify the server that the player is actively engaged.


Because client events travel across a Roblox RemoteEvent, the server enforces strict validation rules to safeguard against exploiters:

Constraint Limit Violation Action
Token-Bucket Rate Limit 10 burst capacity, 5 refill/sec Events dropped silently if exceeded
Event Name Length Maximum 64 characters Event rejected
Payload Key Count Maximum 32 entries Excess keys truncated
Key Length Maximum 32 characters Invalid keys dropped
String Value Length Maximum 256 characters Values exceeding cap dropped
Allowed Value Types string, number, boolean Functions, Instances, and Tables stripped