Add Tixfall to your game

The SDK is one ModuleScript that runs on your game's server. It reports when players finish your tasks, and sends analytics (sessions, purchases, your own events) to your dashboard. Players never see it.

1. Install

  1. Add your game on the dashboard, then open its Setup tab and create a key. It starts with spk_ and is shown once.
  2. In Studio, create a ModuleScript called Tixfall in ServerScriptService and paste the downloaded file into it.
  3. Turn on File → Experience Settings → Security → Allow HTTP Requests.
  4. In Creator Dashboard → your experience → Secrets, add a secret named tixfall_partner_key with your key as the value. Set its domain to tixfall.com.
    Set up before we were called Tixfall? Your spawnpoint_partner_key secret keeps working; when you update the SDK, just change that secret's domain to tixfall.com.
  5. Require it once from a server Script so sessions start being tracked:
Luau
-- ServerScriptService/StartTixfall (a Script)
local Tixfall = require(game.ServerScriptService.Tixfall)
Never put the key in a script. Secrets can only be read by your game's servers, so exploiters can't steal it.

Publish and join your game once. When a server starts, the SDK checks your setup and writes one line to the server's Output: [Tixfall] connected: Your Game is …, or a line starting with [Tixfall] SETUP: that says exactly what to fix. Your game's Setup tab ticks off each step as it starts working, so you can follow along there.

2. Tasks

Tasks are the goals players earn rewards for. You suggest them when you add your game, and each one has an ID like win_round. When a player finishes one, call Complete from your server code:

Luau
local Tixfall = require(game.ServerScriptService.Tixfall)

-- wherever your game decides someone won
local function onRoundWon(player)
    Tixfall.Complete(player, "win_round")
end

-- reaching a level
if newLevel >= 10 then
    Tixfall.Complete(player, "level_10")
end

It's safe to call as often as you like. Each task pays a player once, and only if they came from Tixfall.

What makes a task count

  • The player pressed Play on your game in the Tixfall hub.
  • They're in a live session of your game (the SDK tracks this for you).
  • They didn't finish it faster than the task's minimum time. Finishing impossibly fast is treated as cheating, and that player's rewards are frozen for review.
  • They haven't reached the most one player can earn from your game. That limit is set by Tixfall and covers all your tasks together.

Come-back tasks

Some tasks, like "Come back tomorrow and play 10 minutes", are never reported by your game. Tixfall sees the player's sessions, and pays the task itself when they come back on the right day and have played long enough in total. You don't add any code for these. They show up in your task list marked as come-back tasks, and only Tixfall sets them up.

3. Playtime tasks

For "play for N minutes" tasks, one line does it. A player's time adds up across sessions, so leaving and coming back doesn't reset it, and the hub shows them a timer.

Luau
Tixfall.TrackPlaytime(5, "play_5m")

Keep your task list in your game

You don't have to edit tasks on this site too. List them once in your game when the server starts, and Tixfall follows the list: new tasks appear on your dashboard, and a task you stop listing turns off. A new task starts unpaid until Tixfall sets what it pays.

Luau
Tixfall.DefineTasks({
  { id = "play_10m", label = "Play for 10 minutes", minutes = 10, playMinutes = 10 },
  { id = "win_round", label = "Win a round", minutes = 2 },
  { id = "return_d2", label = "Come back tomorrow and play 10 minutes", minutes = 10, returnDay = 1 },
})
  • minutes is the fastest a real player could finish it. For a come-back task it's how long they have to play once it opens (their sessions add up).
  • playMinutes makes the SDK complete the task for you once the player has played that long in total (their time adds up across sessions), so you don't need TrackPlaytime.
  • returnDay makes it a come-back task (1 is tomorrow, 6 is day 7). Tixfall pays those itself, so don't call Complete for them.

4. Analytics

These are tracked automatically once the module is required:

  • Sessions: when each player joins and leaves, and how long they played.
  • Game pass purchases, with the Robux price.
  • Which tracking link a new player came in through. Make links on your game's Links tab, one for each place you share your game, and your dashboard shows which one brings players who stay and pay.

Developer products are bought through your own ProcessReceipt. Wrap it and every sale is counted with what the player really paid. Your function runs exactly as before, and a sale only counts when it returns PurchaseGranted:

Luau
MarketplaceService.ProcessReceipt = Tixfall.WrapReceipt(function(receipt)
    -- give the item and save it, as you do now
    return Enum.ProductPurchaseDecision.PurchaseGranted
end)

Levels and rounds

Anything a player starts and then finishes or fails. Each one counts the attempt and how many seconds it took, and a player who leaves in the middle is sent as stage_quit, so you can see where people rage quit.

Luau
Tixfall.Progression(player, "start", "World 1-3")
Tixfall.Progression(player, "complete", "World 1-3", { score = 1200 })
Tixfall.Progression(player, "fail", "World 1-3", { cause = "lava" })

Tutorial steps

Each step is sent once per player. Your Insights tab shows how many new players reach each one in their first session, and which step loses the most.

Luau
Tixfall.Onboarding(player, "joined")
Tixfall.Onboarding(player, "first_jump")
Tixfall.Onboarding(player, "first_win")

Your currencies

Call these on every pickup and purchase if you like. They're added up between uploads, so a busy game sends one total per player, currency and source instead of thousands of tiny events.

Luau
Tixfall.Earn(player, "Coins", 50, "quest")
Tixfall.Spend(player, "Coins", 200, "sword")

Player properties

Up to 3 things about a player you want to compare by, like their class, team or whether they're VIP. They're added to every event that player sends afterwards, so Insights can tell you when one group behaves differently.

Luau
Tixfall.SetProperty(player, "class", "Mage")
Tixfall.SetProperty(player, "vip", true)

Custom events

Anything else you want counted is a custom event. They show up in your dashboard's Events tab:

Luau
Tixfall.Track(player, "boss_killed", { boss = "Yeti", seconds = 94 })
Tixfall.Track(player, "tutorial_done")
  • Event names are lowercase letters, numbers and _, up to 40 characters.
  • Up to 12 properties per event: numbers, true/false, or text (up to 120 characters).
  • Events are sent in batches every 15 seconds, so they appear on your dashboard a few seconds late.
  • If Tixfall can't be reached, events wait and go out with the next upload (up to 5,000) instead of being lost.

While you build, Tixfall.Configure({ debug = true }) prints every event to the Output as it's recorded, and Tixfall.Flush() sends everything waiting straight away, for example before you teleport players to another place.

5. Anti-cheat

Optional server-side movement checks. A flag never kicks or punishes anyone in your game. It only freezes that player's Tixfall rewards until we review it, and it shows up in your Anti-cheat tab.

Luau
Tixfall.AntiCheat({
    maxSpeed = 120, -- studs a second running along the ground, held for over a second
    maxAirTime = 8, -- seconds hanging in the air without coming down
    exempt = function(player)
        -- return true while your own game holds this player in the air
        return player:GetAttribute("BeingCarried") == true
    end,
})

Already ignored for you: jumps and flings (anyone falling isn't flying), ragdolls, seats, ladders, swimming, and players welded to anchored parts. Low gravity gives players more air time automatically. Use exempt for anything else your game does, like cranes, grabs or cutscenes.

6. Control

Run your game from the dashboard's Control tab while it's live: message every player, kick, ban and unban, shut down one server or all of them, flip settings, and press buttons for your own commands. It works as soon as your game has this SDK. Kick, ban and shut down are also on the Live tab and on each player's page.

Live settings

A value you can change without publishing. Every server gets the new value within seconds.

Luau
local DOUBLE_COINS = Tixfall.Setting("double_coins", false, { label = "Double coins" })

Tixfall.OnSetting("double_coins", function(on)
    -- runs now with the current value, and again each time you change it
end)

-- or read it whenever you need it
if Tixfall.Get("double_coins") then
    coins *= 2
end

The type comes from the default: true/false, a number or text. Numbers can have min and max. Reset a setting on the dashboard and it goes back to the default in your code.

Your own commands

A button on your dashboard that runs your code. Tixfall never sends code to your game: it can only run what you register.

Luau
Tixfall.Command("give_coins", {
    label = "Give coins",
    params = {
        { name = "player", type = "player" },
        { name = "amount", type = "number" },
    },
}, function(args)
    Coins.Add(args.player, args.amount)
    return "gave " .. args.amount -- shown on the dashboard
end)

Param types: player (arrives as the Player, and the command runs on the server they're in), number, text, boolean, and choice with options = { ... }. Add optional = true to leave one blank. Return false, "why" or throw an error and the dashboard shows it as failed.

How it reaches your game

Roblox servers can't be called from outside, so each server asks Tixfall for work: every 3 seconds while someone has the Control or Live tab open, every 20 seconds otherwise. Bans use Roblox's own ban list, so they cover every server and alt accounts. To turn Control off for a game, call Tixfall.Configure({ control = false }).

7. Experiments

Try a change on some of your players before giving it to everyone. On the dashboard's Experiments tab, pick a live setting and a value to try. A share of players get it (B) and the rest keep the normal value (A). Tixfall compares what each group does from then on: coming back the next day, minutes played, Robux spent and how many pay.

Read the setting with the player, where the player meets it:

Luau
Tixfall.Setting("sword_price", 100, { label = "Sword price" })

-- when the player opens the shop
local price = Tixfall.Get("sword_price", player)

The first read for a player puts them in the test, so only players who saw the change are counted. Each player is placed by their user id, so they get the same version on every server and every visit. Without a test running, it returns the normal value. OnSetting and Get(key) without a player always give the normal value.

Reading the results

A result needs at least 50 players in each group. A test is called clear when a difference that big would happen by luck less than 1 time in 20 (p < 0.05). Before that it says "not yet" or "too early". When B wins, Give everyone B makes it the setting's value for every player. You get an alert when a test has a clear result. Up to 5 tests can run at once, one per setting.

8. Testing

Studio can't read your experience's secrets, so by default the SDK sends nothing from Studio and prints what it would send instead, like [Tixfall] task win_round for YourName.

Test your key from Studio

  1. In Studio, open File → Experience Settings → Security → Local Secrets and add the same secret: tixfall_partner_key, your key, domain tixfall.com.
  2. Press Play and open View → Output. You'll see [Tixfall] connected, or what to fix.
  3. Finish one of your tasks in the playtest. The Output says whether that task id is one of your tasks, and your Setup tab shows it too. A typo like win_rnd is caught here instead of quietly never paying.

Nothing from Studio is paid or counted in your analytics: Studio only checks in. To see every analytics event while you test, set the workspace attribute TixfallDebug to true.

After you publish, join your game once. Its first server checks in and your Setup tab turns green within a few seconds.

Troubleshooting

Every problem the SDK can spot is written to the server's Output (in a live game: press F9 in the game and open the Server tab). Each line starts with [Tixfall].

The Output saysFix
HTTP requests are offTurn on File → Experience Settings → Security → Allow HTTP Requests, then publish again.
no secret called tixfall_partner_keyAdd the secret in Creator Dashboard → your experience → Secrets. The name has to match exactly.
the secret's domain has to be …Edit the secret and set its domain to tixfall.com.
Tixfall didn't accept the keyThe key was deleted or pasted wrong. Make a new key on your Setup tab and paste it as the secret's value.
this key belongs to …, a different experienceEvery game has its own key. Use the one from this game's Setup tab.
"…" isn't one of this game's tasksThe id in Tixfall.Complete doesn't match a task. Check the spelling against your Setup tab; ids are lowercase, like win_round.
these tasks are waiting for Tixfall to set what they payNothing to fix. New tasks start unpaid until we review them.
No [Tixfall] lines at allThe module isn't required from a server Script. Check it's in ServerScriptService and that a Script (not a LocalScript) requires it.

Questions

  • Do I have to wait for approval to see analytics? No. Your dashboard fills in as soon as your game checks in. Approval only decides when your tasks appear in the hub and start paying.
  • Does it slow my game down? No. It runs on the server, sends events in batches every 15 seconds, and never waits on Tixfall before your code carries on.
  • What if Tixfall is down? Your game keeps working. Task reports and events are retried, and nothing in your game waits for an answer.
  • My experience has several places. Add the module to each place that has players. They share the one key, because secrets belong to the experience.

9. Reference

CallWhat it does
Complete(player, taskId)The player finished a task. Paid once per player.
TrackPlaytime(minutes, taskId)Completes the task once the player has played that many minutes in total, across sessions.
DefineTasks(list)Sends your task list to Tixfall when the server starts, so the game is the one place you edit tasks.
Progress(player, taskId, value, target, unit)Tells the hub how far a player is toward a task, like 6 / 10 levels. It only changes what the hub shows; nothing is paid from it. TrackPlaytime and playMinutes already send a timer for you (use the unit "time" and seconds for your own, and the hub shows it as 4:30 / 10:00).
Track(player, name, props?)A custom analytics event.
Progression(player, status, stage, props?)A level, round or quest: "start", "complete" or "fail". Counts attempts and seconds, and sends stage_quit if the player leaves in the middle.
Onboarding(player, step)A tutorial step, sent once per player as onboard_step.
Earn(player, currency, amount, source?)
Spend(player, currency, amount, item?)
Your own currencies coming in and going out, added up between uploads.
SetProperty(player, key, value)Up to 3 things about a player, added to each of their events. nil removes one.
WrapReceipt(fn)Wraps your ProcessReceipt so every granted developer product sale is counted with the Robux paid.
Purchase(player, robux, productId?)A developer product sale by hand, if you don't use WrapReceipt.
Setting(key, default, options?)A value you change from the Control tab while the game runs. Returns its value now. Options: label, description, min, max.
Get(key)
OnSetting(key, fn)
A setting's value right now, or a function that runs now and on every change.
Get(key, player)The value for one player. While the setting has a test running, some players get the value being tried; the first read counts them in the test.
Command(name, options, fn)A button on the Control tab that runs fn(args). Options: label, description, params.
Configure(options)debug = true prints every event; flushEvery is the seconds between uploads (5 to 60); live = false stops the Live tab reports; control = false turns the Control tab off for this game.
Flush()Sends everything waiting now. Use it before teleporting players away.
AntiCheat(options?)Turns on the speed and fly checks.
VERSIONThe SDK's version. Your Setup tab says when a newer one is out.

10. Data and privacy

The SDK sends Roblox user IDs, usernames, and the events described above: the ones it records itself and the ones your game reports. Nothing else about players is collected. Raw events are kept for 90 days, and you can download your game's events as a CSV from the dashboard at any time.

11. Read the source

You don't have to take our word for any of this. The SDK is one readable file with no hidden code, and every request it makes goes through a single function, so you can check exactly what leaves your game before you add it. Read Tixfall.lua.

It's source-available, not open source: you can read it, audit it, change it for your game and use it with Tixfall, but not copy it into another product or use it with another service. Read the licence.