Scenario Roblox Data logo

Scenario Roblox Data

OrganizationPopular
scenario-labs
scenario-roblox-data

Use when a Roblox game saves or loads player data, or when players report data not saving, lost progress, rollbacks, duplicated items or a purchase granted twice. Triggers: DataStoreService, UpdateAsync, SetAsync, BindToClose, ProfileStore, ProfileService, DataStore2, session locking, data schema or migration, Developer Product ProcessReceipt, player trading, OrderedDataStore leaderboards, MemoryStore, MessagingService, TeleportService and reserved servers, DataStore budgets and throttling (errors 301 to 306), 'You must publish this place to the web to access DataStore', and testing data code in an unpublished place.

Overview

Publisherscenario-labs
Repositoryskills
Skill namescenario-roblox-data
Stars
1.2K
Forks
144
Bundled files
17
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 17 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by scenario-labs on GitHub. Read the source before you install it.

Installation

Install the Scenario Roblox Data AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/scenario-labs/skills/tree/main/skills/game-engines/roblox/scenario-roblox-data
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/scenario-labs/skills.git /tmp/skills
mkdir -p .claude/skills
cp -r /tmp/skills/skills/game-engines/roblox/scenario-roblox-data .claude/skills/scenario-roblox-data
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Scenario Roblox Data in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Scenario Roblox Data on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Scenario Roblox Data is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Roblox Data and Backend

Roblox Studio (October 2026 build) on macOS, driven through the scenario-roblox-expert toolkit.

Expert level here means the data layer stays correct when a server crashes, a write fails after it landed, or two servers want the same player. Prove those cases against a simulated multi-server backend before any published test, because an unpublished place cannot reach DataStores at all.

If a sibling skill named here is missing from your available skills, load it with skill_get (Scenario MCP) or ask the user to install it (https://github.com/scenario-labs/skills#install); unattended, proceed from tool schemas and flag the gap.

REQUIRED BACKGROUND: scenario-roblox-expert (channels, review loop, toolkit, current-Roblox traps).

Stance (the expert delta)

  1. Session locks stop duplication, UpdateAsync alone does not. One ProfileStore profile per player holds the lock (loleris, ProfileStore docs). UpdateAsync is safer than SetAsync only when the transform reads the old value (Suphi Kaner, 00:04:43).
  2. A failed write may have landed. Read with UseCache = false before redoing it (Roblox best practices). Put an operation id inside the value so a repeat is a no-op [added]. With 30% of writes failing after they landed, naive retries stored 39 for 30 operations in the mock run.
  3. Retries on one key stay in order. A late retry of an old value overwrites newer data (Roblox best practices). KeyQueue serializes per key.
  4. A purchase is granted once and confirmed saved. Log each PurchaseId in the profile. Return PurchaseGranted only when LastSavedData holds it (Rileybytes, 00:29:08; Roblox purchasing doc). Every other path returns NotProcessedYet.
  5. Migrate before Reconcile. Reconcile copies the template's SchemaVersion into old data, and the migration is skipped [added, proven against the real ProfileStore].
  6. Old servers never save newer data. During an update, old and new servers run side by side. Refuse a higher SchemaVersion, release the lock untouched, and kick [added]. Publish every place of a multi-place game together (CJ_Oyer, 00:27:33).
  7. Two profiles never save atomically. Editing both without a yield protects memory only (loleris). Escrow both sides, then let one trade-log record decide [added]. Without escrow a crash between the two saves duplicated a Shield and lost a Sword.
  8. Test against an injected store. Write the data code so DataStoreService can be swapped for MockDataStore and run several simulated servers with the unmodified ProfileStore [added].

Establish first

  • Published, and Studio API access on? Unpublished: every DataStore call throws, so test with mocks. Published with access on: Studio writes live keys, so use a separate test experience (Roblox docs) or ProfileStore.Mock.
  • What persists where. Player state goes in one profile. Leaderboards use an OrderedDataStore. Matchmaking and short-lived shared state use MemoryStore. Announcements use MessagingService.
  • Trading, Developer Products, multi-place? Each adds a stage below.
  • Peak CCU, players per server, profile size. Feed rbx_data.budget.
  • Data already live? Then keys and store names are frozen; every change becomes a migration step.

Defaults: ProfileStore at the pinned commit, store PlayerData, key Player_<UserId>, a SchemaVersion field, a 100-entry PurchaseIds log.

Procedure

Modules live in scripts/agentkit/data/ and have no requires. Inline them with rbx_data.run(studio, code, dm, data=[...]), or build them into a place with rbx_data.build_place(dir). Full code and results: procedures.md.

  1. Probe the environment. Goal: know which services answer here. How: rbx_data.probe_services(studio, "Edit"), then "Server" in a playtest. GATE: the error texts are recorded, and the store choice (real or mock) follows from them.
  2. Design the schema. Goal: a profile that saves as-is and grows safely. How: DataCheck.report(template) and a maxed sample, DataCheck.key(key, {userId}). GATE: zero error findings, size under 25% of 4,194,304 characters, and a JSON round trip equal to the input.
  3. Plan the budget. Goal: no throttling at peak. How: rbx_data.budget(players, ccu, kb, saves_per_min). GATE: ok is true at peak CCU, and the per-key writes per minute cover autosave plus purchases.
  4. Wire sessions. Goal: one owner per profile. How: PlayerData runs StartSessionAsync with Cancel, kicks on nil, then AddUserId, migrate, Reconcile, a kick on OnSessionEnd, and EndSession on leave. GATE: the sessions suite passes, and a playtest shows the profile loaded with DataStoreState "NoAccess".
lua
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ProfileStore = require(ServerStorage.Packages.ProfileStore)
local PlayerData = require(ServerStorage.DataKit.PlayerData)
local Migrate = require(ServerStorage.DataKit.Migrate)

local data = PlayerData.new({
	ProfileStore = ProfileStore,
	Players = Players,
	storeName = "PlayerData",
	template = { SchemaVersion = 2, Coins = 0, Inventory = {}, PurchaseIds = {} },
	migrate = Migrate.new({
		latest = 2,
		steps = {
			-- v1 kept owned items as an array of names; v2 counts them by id.
			[2] = function(d: any)
				d.Inventory = d.Inventory or {}
				for _, item in ipairs(d.Items or {}) do
					d.Inventory[item] = (d.Inventory[item] or 0) + 1
				end
				d.Items = nil
			end,
		},
	}),
})
data:Start()
  1. Version the schema. Goal: old data upgrades once. How: Migrate.new{latest, steps}, one fixture per old version. GATE: the schema suite passes, including the Reconcile trap and the "newer" refusal.
  2. Grant purchases. Goal: exactly one grant per PurchaseId. How: Receipts.new{getProfile, isPresent, handlers}; assign ProcessReceipt in one script. GATE: the receipts suite passes with ghost writes, crashes and server changes.
  3. Raw stores. Goal: leaderboards, counters and logs that survive retries. How: KeyQueue.new(store) with an op id in the value and a verify function. GATE: the keyqueue suite passes.
  4. Trades. Goal: no item created or lost by a crash. How: Trade.paidTradingAllowed for both players (PolicyService IsPaidItemTradingAllowed, fail closed), Trade.new{log = KeyQueue.new(tradeLogStore)}, trade:Recover(profile) in onLoaded. GATE: the trade suite passes at every crash stage.
  5. Teleports. Goal: parties arrive together. How: SafeTeleport.new{TeleportService}, TeleportParty for groups. GATE: the teleport suite passes against the fake service; a real teleport needs a published experience.
  6. Audit. Goal: no known mistake left in the code. How: DataAudit.place(game) in Edit, or rbx_data.py audit place.rbxl offline. GATE: zero error findings outside test fixtures.
  7. Operate. Rollbacks with PlayerData:Restore (ProfileStore VersionQuery), final edits in OnLastSave, RTBF templates with rbx_data.rtbf_config: procedures 13 to 15.
  8. Prove and report. Run the offline suites, then the same suites in Studio Edit through rbx_run, then the playtest checks. List what still needs a published place.

Numbers

ValueRelative to
Server read or write: 60 + 40 x players per minutePer server, default, tunable
Experience read 300 + 40 x CCU, write 300 + 20 x CCU per minuteWhole experience, shared with Open Cloud
UpdateAsync, so every ProfileStore save, spends 1 read and 1 writeBoth budgets
Per key: write 4 MB per minute, read 25 MB per minuteRounded up to whole KB per request
Value 4,194,304 characters; key, name, scope 50Per key
Queue of 30 per request type, then errors 301 to 306Per server
GetAsync cache 4 sPer data store instance
One version kept per key per UTC hour, 30 days after overwritePer key
Storage 500 MB + 1 MB x lifetime usersCompressed latest versions
ProfileStore autosave 300 s, steal 40 s, assume dead 630 sPinned source; assume dead compares os.time() across servers
ProfileStore first retry 5 s, then every 10 sWhile another server holds the lock
Profile load over 5 sTreat as a bug (loleris)
BindToClose budget 30 sPer server shutdown
MessagingService message 1 kBPer publish

Quality gates

  • run_offline.sh: all Lune suites pass, rbx_check reports zero errors in kit, place and snippets.
  • run_live.py: the same suites pass in Studio Edit, and the playtest checks pass.
  • DataAudit: zero error findings outside fixtures.
  • Console: one "[ProfileStore]: Roblox API services unavailable" line in an unpublished playtest, and no save errors.
  • Published test experience (later): two real servers hand a player over in under 5 s.

Common mistakes

MistakeSymptomFix
SetAsync on PlayerRemoving, no lockRollbacks, duplicated items after server hopsProfileStore through PlayerData
Key from player.NameData lost after a renamePlayer_<UserId>
Reconcile before migrationOld fields stranded, new fields emptyMigrate first
Retry by recalling the same writeCounters too highOp id in the value, KeyQueue
PurchaseGranted before the savePaid but not granted after a crashReceipts
Handler that yieldsGrant applied twiceHandlers run on a copy and must not yield
Two profile saves as a tradeItems duplicated or lostTrade with escrow
GetDataStore outside pcallScript errors at startup in StudioProbe inside pcall, then fall back to the mock
Awaiting MessagingService in an unpublished playtestThread hangsCall it in task.spawn
Retrying a teleport with ShouldReserveServerParty split across serversReserve once, reuse the access code
Editing a ModuleScript's Source in Edit, then requiring it againThe old code keeps runningReplace the module with a Clone first

Handoffs

  • From scenario-roblox-architecture: where the data service lives and how systems read it.
  • From scenario-roblox-monetization: product ids and amounts. Back: the Receipts handler table.
  • From scenario-roblox-networking: validated trade and shop requests. Back: Trade and inventory calls.
  • To scenario-roblox-ui and scenario-roblox-gameplay: values exposed as Attributes or signals, never raw profiles.
  • To scenario-roblox-performance: shutdown timing and update publishing.
  • To scenario-roblox-tooling: the Lune suites for CI.
  • To scenario-roblox-luau: types for the template.

Current Roblox notes

  • DataStore limits became experience-wide on 2026-07-29; old answers quote 60 + 10 x players and a 6 s cooldown, both gone.
  • Storage limits are enforced from 2026-04-09.
  • HttpService:JSONEncode encodes NaN and infinity as tagged objects since 2026-03-10, and drops sparse and mixed entries silently (live test).
  • ProfileService is unsupported; use ProfileStore. DataStore2 is legacy.
  • ReserveServerAsync replaces ReserveServer.
  • Studio API access: File > Experience Settings > Security > Enable Studio Access to API Services, published games only.
  • Studio budgets do not follow the server formulas: a one-player playtest read 585.

References

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Scenario Roblox Data AI skill do?

Use when a Roblox game saves or loads player data, or when players report data not saving, lost progress, rollbacks, duplicated items or a purchase granted twice. Triggers: DataStoreService, UpdateAsync, SetAsync, BindToClose, ProfileStore, ProfileService, DataStore2, session locking, data schema or migration, Developer Product ProcessReceipt, player trading, OrderedDataStore leaderboards, MemoryStore, MessagingService, TeleportService and reserved servers, DataStore budgets and throttling (errors 301 to 306), 'You must publish this place to the web to access DataStore', and testing data co...

Why use Scenario Roblox Data on TypingMind?

Because you install it once and use it with any model. Scenario Roblox Data is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Scenario Roblox Data in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/scenario-labs/skills/tree/main/skills/game-engines/roblox/scenario-roblox-data. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Scenario Roblox Data?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Scenario Roblox Data?

As many as you like. As long as a model supports skills, you can use Scenario Roblox Data with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Scenario Roblox Data AI skill free?

Yes. It is published on GitHub by scenario-labs under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇