Server API Reference
The AnalyticsModule server API is the primary interface for collecting telemetry, tracking economy transactions, monitoring server health, querying retention cohorts, and managing event dispatch pipelines.
Table of Contents
Section titled “Table of Contents”- Lifecycle & Initialization
- Event Tracking
- Badges & Progression
- Economy & Monetization
- Player Retention & Cohorts
- Server Diagnostics & Health
- Pipeline & Exporters
Lifecycle & Initialization
Section titled “Lifecycle & Initialization”AnalyticsModule.init
Section titled “AnalyticsModule.init”Initializes the analytics engine with user configuration. If already initialized, returns the existing singleton instance. When called from a client context (RunService:IsClient()), automatically redirects to the Client SDK.
AnalyticsModule.init(config: AnalyticsConfig?): AnalyticsInstanceParameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
config |
AnalyticsConfig? |
No | Optional configuration table overriding engine defaults. |
Returns
Section titled “Returns”| Type | Description |
|---|---|
AnalyticsInstance |
The active singleton analytics manager. |
Example
Section titled “Example”local ReplicatedStorage = game:GetService("ReplicatedStorage")local AnalyticsModule = require(ReplicatedStorage.AnalyticsModule)
local Analytics = AnalyticsModule.init({ debugMode = true, flushIntervalSeconds = 15, autoTrackDemographics = true,})Analytics:Flush
Section titled “Analytics:Flush”Forces an immediate synchronous-style flush of the in-memory buffer queue to all registered exporters.
Analytics:Flush(): ()- Flushes are invoked automatically by the background worker at
flushIntervalSecondsand upon server shutdown insidegame:BindToClose. - Call this method before executing operations where pending events must be dispatched immediately (e.g. before triggering a teleport).
Example
Section titled “Example”-- Manually flush all queued telemetry before teleporting a groupAnalytics:Flush()TeleportService:TeleportPartyAsync(placeId, players)Event Tracking
Section titled “Event Tracking”Analytics:TrackEvent
Section titled “Analytics:TrackEvent”Dispatches a custom telemetry event into the pipeline. If a Player instance is supplied, automatically enriches the event with their UserId and active SessionId.
Analytics:TrackEvent(player: Player?, eventName: string, data: { [string]: any }?): ()Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
player |
Player? |
No | Optional player associated with the action. If nil, the event is logged as a server-level action. |
eventName |
string |
Yes | Alphanumeric identifier for the event (e.g. "BossDefeated", "DialogueSkipped"). |
data |
{ [string]: any }? |
No | Dictionary of custom key-value pairs (strings, numbers, booleans, nested dictionaries). |
Dispatched Event Structure
Section titled “Dispatched Event Structure”{ "name": "BossDefeated", "category": "custom", "timestamp": 1727790000, "userId": 12345678, "sessionId": "4a7f05b3-3a9d-4762-b91c-7f516a249d41", "data": { "bossId": "Dragon_01", "difficulty": "Hard", "rewardsGranted": 3 }}Example
Section titled “Example”Analytics:TrackEvent(player, "CraftingCompleted", { recipeId = "IronSword", successRate = 0.95, materialsConsumed = { "IronOre", "Wood" },})Analytics:Increment
Section titled “Analytics:Increment”Convenience wrapper to increment a named numeric metric counter. Formats the internal event name as Metric_<metricName> with { incrementBy = amount }.
Analytics:Increment(metricName: string, amount: number?, tags: { [string]: any }?): ()Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
metricName |
string |
— | The metric to increment (e.g. "CoinsMined", "PortalsOpened"). |
amount |
number? |
1 |
Amount to add to the counter. Defaults to 1. |
tags |
{ [string]: any }? |
{} |
Optional metadata tags for grouping or cohort filtering. |
Example
Section titled “Example”-- Increment gold mined metric by 25 with biome tagAnalytics:Increment("GoldMined", 25, { biome = "CrystalCaverns" })Analytics:StartTimer
Section titled “Analytics:StartTimer”Measures the elapsed execution time of an operation or gameplay phase. Returns a stop callback function that finishes the timer, calculates the elapsed time in seconds, dispatches a Timer_<timerName> event, and returns the duration.
Analytics:StartTimer(player: Player?, timerName: string): () -> numberParameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
player |
Player? |
No | Optional player performing the timed action. |
timerName |
string |
Yes | Identifier for the action (e.g. "DungeonGeneration", "RoundDuration"). |
Returns
Section titled “Returns”| Type | Description |
|---|---|
() -> number |
Callback function. Calling this function concludes the measurement and returns the elapsed time in seconds (rounded to 2 decimal places). |
Example
Section titled “Example”local stopTimer = Analytics:StartTimer(player, "MatchDuration")
-- Later when the match concludes:local elapsedSeconds = stopTimer()print(string.format("Match lasted %.2f seconds", elapsedSeconds))Analytics:TrackSpatial
Section titled “Analytics:TrackSpatial”Records coordinates $(X, Y, Z)$ alongside custom metadata. Coordinates are automatically rounded to 1 decimal place to optimize compression and facilitate spatial aggregation.
Analytics:TrackSpatial(player: Player?, eventName: string, position: Vector3, data: { [string]: any }?): ()Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
player |
Player? |
No | Optional player associated with the location. |
eventName |
string |
Yes | Name of the spatial event (e.g. "ChestDiscovered", "TrapTriggered"). |
position |
Vector3 |
Yes | World space 3D vector. |
data |
{ [string]: any }? |
No | Additional contextual metadata. |
Example
Section titled “Example”local chestPosition = chestModel:GetPivot().PositionAnalytics:TrackSpatial(player, "SecretFound", chestPosition, { secretTier = "Mythic", zone = "TempleRuins",})Badges & Progression
Section titled “Badges & Progression”Analytics:AwardBadge
Section titled “Analytics:AwardBadge”Safely awards a Roblox badge to a player. Automatically verifies ownership first using BadgeService:UserHasBadgeAsync to prevent duplicate API calls, catches network exceptions, and records progression telemetry.
Analytics:AwardBadge(playerOrUserId: Player | number, badgeId: number): (boolean, boolean, string?)Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
playerOrUserId |
Player | number |
Yes | Either a live Player instance or their numeric UserId. |
badgeId |
number |
Yes | Roblox Badge ID. |
Returns
Section titled “Returns”| Position | Type | Description |
|---|---|---|
| 1 | boolean |
callOk: true if the engine call succeeded without error. |
| 2 | boolean |
wasAwarded: true if the badge was newly awarded; false if already owned or call failed. |
| 3 | string? |
errorMessage: Error description if the call failed or user already owned badge. |
Example
Section titled “Example”local ok, awarded, err = Analytics:AwardBadge(player, 212456789)if awarded then print("Player earned a new badge!")elseif not ok then warn("Failed to award badge: " .. tostring(err))endAnalytics:RecordBadgeAward
Section titled “Analytics:RecordBadgeAward”Manual recording hook for projects utilizing their own custom BadgeService wrapper.
Analytics:RecordBadgeAward(userId: number, badgeId: number, success: boolean, errorMessage: string?): ()Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
userId |
number |
Yes | Numeric player user ID. |
badgeId |
number |
Yes | Roblox Badge ID. |
success |
boolean |
Yes | Whether the badge was successfully granted. |
errorMessage |
string? |
No | Error message if the award failed. |
Analytics:GetBadgeAwardCount
Section titled “Analytics:GetBadgeAwardCount”Returns the total number of times a specific badge has been successfully awarded by this server.
Analytics:GetBadgeAwardCount(badgeId: number): numberAnalytics:GetTotalBadgesAwarded
Section titled “Analytics:GetTotalBadgesAwarded”Returns the aggregate count of all badges awarded across this server instance.
Analytics:GetTotalBadgesAwarded(): numberEconomy & Monetization
Section titled “Economy & Monetization”Analytics:RecordEconomySource
Section titled “Analytics:RecordEconomySource”Tracks virtual currency or items granted to a player (quest payouts, daily rewards, leveling gifts, loot drops).
Analytics:RecordEconomySource( playerOrUserId: Player | number, currency: string, amount: number, itemType: string?, itemId: string?): ()Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
playerOrUserId |
Player | number |
Yes | Target player instance or user ID. |
currency |
string |
Yes | Currency name (e.g. "Gold", "Gems"). |
amount |
number |
Yes | Amount of currency added. |
itemType |
string? |
No | Source category (e.g. "QuestReward", "DailyLogin"). |
itemId |
string? |
No | Source identifier (e.g. "Quest_204"). |
Analytics:RecordEconomySink
Section titled “Analytics:RecordEconomySink”Tracks virtual currency or items spent by a player (store purchases, weapon upgrades, cosmetic unlocks).
Analytics:RecordEconomySink( playerOrUserId: Player | number, currency: string, amount: number, itemType: string?, itemId: string?): ()Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
playerOrUserId |
Player | number |
Yes | Target player instance or user ID. |
currency |
string |
Yes | Currency name (e.g. "Gold", "Gems"). |
amount |
number |
Yes | Amount of currency spent. |
itemType |
string? |
No | Sink category (e.g. "WeaponUpgrade", "ShopItem"). |
itemId |
string? |
No | Sink identifier (e.g. "Sword_Tier3"). |
Player Retention & Cohorts
Section titled “Player Retention & Cohorts”Retention methods require
enableRetentionTracking = true(default:true) in your configuration.
Analytics:IsNewPlayer
Section titled “Analytics:IsNewPlayer”Returns whether a player is visiting the game for the first time in their account history.
Analytics:IsNewPlayer(playerOrUserId: Player | number): booleanExample
Section titled “Example”Players.PlayerAdded:Connect(function(player) -- Allow retention record to initialize task.wait(0.5) if Analytics:IsNewPlayer(player) then print(player.Name .. " is a brand new player! Showing tutorial...") TutorialManager:Start(player) endend)Analytics:GetTotalVisits
Section titled “Analytics:GetTotalVisits”Returns the player’s total lifetime visit count across all game sessions.
Analytics:GetTotalVisits(playerOrUserId: Player | number): numberAnalytics:GetLifetimePlaytimeSeconds
Section titled “Analytics:GetLifetimePlaytimeSeconds”Returns the total cumulative playtime (in seconds) across all previous and current sessions for this player.
Analytics:GetLifetimePlaytimeSeconds(playerOrUserId: Player | number): numberAnalytics:GetAveragePlaytimeSeconds
Section titled “Analytics:GetAveragePlaytimeSeconds”Calculates the average session length in seconds across all sessions completed on this server.
Analytics:GetAveragePlaytimeSeconds(): numberServer Diagnostics & Health
Section titled “Server Diagnostics & Health”Analytics:GetServerUptimeSeconds
Section titled “Analytics:GetServerUptimeSeconds”Returns the uptime of the current server in seconds since startup.
Analytics:GetServerUptimeSeconds(): numberAnalytics:GetServerHealth
Section titled “Analytics:GetServerHealth”Returns a live diagnostics snapshot of server memory, concurrency, and performance.
Analytics:GetServerHealth(): ServerHealthSnapshot?Snapshot Fields
Section titled “Snapshot Fields”type ServerHealthSnapshot = { serverJobId: string, placeId: number, placeVersion: number, uptimeSeconds: number, playerCount: number, peakPlayerCount: number, memoryUsageMb: number, averageHeartbeatFps: number, timestamp: number,}Pipeline & Exporters
Section titled “Pipeline & Exporters”Analytics:Use
Section titled “Analytics:Use”Registers middleware into the synchronous event dispatch pipeline. Middleware functions can mutate event attributes or drop events by returning nil.
Analytics:Use(middleware: (event: TelemetryEvent) -> TelemetryEvent?): ()Example
Section titled “Example”-- Enrich all events with the game environmentAnalytics:Use(function(event) event.data.environment = "Production" return eventend)
-- Drop spammy eventsAnalytics:Use(function(event) if event.name == "RedundantPing" then return nil -- Event dropped end return eventend)Analytics:AddExporter
Section titled “Analytics:AddExporter”Registers a telemetry exporter implementing the IExporter interface.
Analytics:AddExporter(exporter: IExporter): ()Example
Section titled “Example”local DiscordExporter = require(ServerScriptService.Exporters.DiscordExporter)Analytics:AddExporter(DiscordExporter.new(webhookSecret))