We use cookies only to manage your session — no third-party tracking or advertising. Learn more in our Privacy Policy.

RoLearn

Unlock Pro features

DISCOVER
Back to Guidance

RoLearn SDK Quickstart for Roblox: Ship Your First Event in 5 Minutes

Guide
May 24, 2026
7 min
RoLearn SDK Team
SDK
Roblox
Quickstart
Lua

This guide gets a Roblox experience sending its first event to the RoLearn SDK in under five minutes. We will not cover what RoLearn is, why you would want analytics in your game, or how the broader platform works — those live in the SDK overview. The point of this page is to copy four things into Studio and see your first event appear in the dashboard. If you have an existing analytics pipeline, the patterns here also map onto how RoLearn coexists alongside whatever you have today.

Prerequisites (one minute)

  • A Roblox place you can publish to (saved place, doesn't need to be live).
  • A RoLearn account on any plan (the SDK works on the free SDK tier — see pricing).
  • An SDK ingest key in the format rk_live_…. Generate one from the Brand Workspace's Experiences tab (per-experience key, recommended) or from your team API keys (team-wide, also works). The raw key is shown exactly once at issuance — copy it immediately to your Roblox Studio's Game Settings → Security → Variables panel as a service variable, not into the script itself.

Step 1 — Paste the SDK ModuleScript

The Roblox SDK is a single-file ModuleScript. DownloadRoLearnSDK.lua from the downloads page (Roblox tab), then in Studio:

  1. Open the Explorer panel.
  2. Right-click ReplicatedStorage → Insert Object → ModuleScript. Name it RoLearnSDK.
  3. Paste the file contents in. The script is self-contained — no dependencies, no Wally, no Rojo required.

The ModuleScript should not be in ServerScriptService even though the SDK runs server-side. Keeping it in ReplicatedStorage matches the pattern most Roblox analytics libraries use and avoids name collisions with your own server scripts.

Step 2 — Initialize the SDK from a server script

Create a regular Script (not a LocalScript) inside ServerScriptService and paste the following. Replace the API key with the one you generated above:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SDK = require(ReplicatedStorage:WaitForChild("RoLearnSDK"))

SDK.init({
    api_key  = "rk_live_REPLACE_ME",
    endpoint = "https://rolearn.dev/api/sdk/events",
    game_id  = tostring(game.PlaceId),
})

That is the entire integration. The SDK will now:

  • Auto-emit a session_start event every time a player joins, including their resolved country code.
  • Auto-emit a session_end event with session duration when they leave.
  • Auto-batch events and POST them to the ingest endpoint every 10 seconds (configurable via flush_every).
  • Auto-capture performance snapshots and crash reports if you leave the defaults on.
  • Auto-hook gamepass and developer product purchases if you pass auto_hook_marketplace = true.
If you only ever paste those two snippets, RoLearn will populate DAU, retention cohorts, geo, and session-length analytics on the SDK dashboard without you writing a single custom event. The next step adds richer signal, but it is optional. Many studios run on auto-instrumentation alone for the first month while they figure out what they want to track.

Step 3 — Send a custom event

Custom events are the unit of intentional instrumentation. They let you measure flows that matter to your specific game: level completion, character class selection, daily quest claims, whatever drives your design decisions. The signature:

SDK.track(eventType, payload, player)

A realistic example — fired when a player completes a level:

SDK.track("level_complete", {
    level     = 5,
    score     = 1840,
    duration  = 92,    -- seconds
    result    = "win",
}, player)

The third argument player is the standard Roblox Player instance. Passing it lets the SDK attach the player's identity, country, and platform automatically — you do not passplayer_id in the payload. If the event is not player-scoped (a server-wide event, a scheduled tick), omit the third argument and the SDK will emit it without a player_id.

Step 4 — Publish and verify

Publish the place and join it as a regular player. Within 10–30 seconds, the events should land. Two places to verify:

  1. SDK Event Explorer (in the RoLearn web app, under SDK → Events). Filter by your game_id — you should see your session_start within seconds of joining and your level_complete within the next flush window.
  2. SDK Dashboard. DAU populates by the next nightly rollup (09:00 UTC by default), so the dashboard view is not the right place to verify the first event — use the Event Explorer for that.

If nothing arrives within 60 seconds, the four most common causes are:

  • API key typo. The key must start with rk_live_ and be exactly the value shown at issuance. Trailing whitespace from a copy-paste is the most common silent failure.
  • HttpService disabled. The Roblox SDK uses HttpService internally. Game Settings → Security → "Allow HTTP Requests" must be on.
  • Test in Studio vs published place. Studio play-solo sessions are filtered out by default on the dashboard (because they would otherwise dominate DAU during development). Use a published place to verify, or check the Event Explorer which includes Studio events.
  • Per-experience key scoped to the wrong game_id. If you generated a per-experience key from the Brand Workspace, it is bound to the place_id you configured there. If you are testing on a different place, either use a team-wide key or generate one for the new place.

Optional — the four config knobs worth knowing

The defaults are deliberately tuned for the common case. The four knobs you might tune in production:

SDK.init({
    api_key                   = "rk_live_…",
    endpoint                  = "https://rolearn.dev/api/sdk/events",
    game_id                   = tostring(game.PlaceId),

    flush_every               = 10,    -- seconds between batches (min 2)
    batch_max                 = 50,    -- events per HTTP request
    auto_hook_marketplace     = true,  -- track gamepass + devproduct buys
    auto_capture_performance  = true,  -- periodic FPS / memory snapshots
    auto_capture_crashes      = true,  -- Lua errors captured + stack-traced

    before_send = function(event)
        -- Strip any PII you accidentally include in custom payloads
        if event.payload and event.payload.email then
            event.payload.email = nil
        end
        return event
    end,
})
  • flush_every: lower for snappier dashboards (good for live-ops moments), higher to reduce HTTP overhead. Default 10s is fine for nearly everyone.
  • auto_hook_marketplace: when on, every gamepass and developer-product purchase emits a purchase event automatically with SKU + price. You do not need to write your own purchase tracking.
  • auto_capture_performance: emits periodic FPS / memory / device snapshots. The SDK dashboard's Performance view depends on these.
  • before_send: a last-line PII guard. Runs synchronously before every event leaves the client. Return nil to drop the event entirely.

What to track first (and what to skip)

New SDK integrations frequently over-instrument in the first week and the dashboard becomes noise. A defensible starting set:

  1. Don't track: session start/end, country, device, purchases — all of these are auto-instrumented. Tracking them manually causes duplicate counts.
  2. Do track first: the 3-5 events that map to your game's core funnel. For a tycoon: first_purchase,shop_opened, prestige. For a fighter:queue_entered, match_completed,character_unlocked. Five events, named consistently, beats fifty events named inconsistently.
  3. Add later: level/wave granularity, A/B test assignment events, social events (party join, friend invite). Add them when you have a specific question to answer with them, not preemptively.

For deeper patterns on event naming, payload shape, and funnel design, see the Custom Event Tracking Patterns guide. For a brand-activation-specific event set (zone enter / exit / equip / share), see the brand-specific events on the SDK integration reference.

Where to go next