save-systems
Skill2 starsChanged 29 days agoMITView on GitHub
Engine-agnostic save-system design (what to persist, schema versioning, a migration chain, defensive loading, backups), adapted for Roblox DataStores with ProfileStore session locking. Use when designing or changing a Roblox player profile, adding, renaming or removing saved fields, bumping dataVersion, writing or testing migrations, deciding what to store vs recompute, handling saves from a newer server during a rolling update, or debugging lost or corrupted player data. It does not replace the roblox-lessons data.md facts, which win on any conflict.
5 other projects use a version of this.
Adopted by
Most recently taken up by
- gamedev-skills/awesome-gamedev-agent-skillstheir own version, first seen Oct 23, 2026
- jammyfu/open-game-skillstheir own version, first seen Oct 11, 2026
- ukanwat/aaabenchtheir own version, first seen Aug 15, 2026
- ukanwat/overtimetheir own version, first seen Aug 15, 2026
- ukanwat/selfstartertheir own version, first seen Aug 15, 2026
Other versions5 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 5
- gamedev-skills/awesome-gamedev-agent-skills★ 6.4ksame name
- ukanwat/aaabench★ 399same name
- ukanwat/overtime★ 399same name
- ukanwat/selfstarter★ 399same name
- jammyfu/open-game-skills★ 12same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository19 other files it gives its agents.
- template/CLAUDE.mdCLAUDE.md
- roblox-lessonsSkill
- audio-designSkill
- game-feelSkill
- game-ui-uxSkill
- level-designSkill
- roblox-creator-store-security-auditSkill
- roblox-dataSkill
- roblox-debugging-bugfixSkill
- roblox-devSkill
- roblox-monetizationSkill
- roblox-networkingSkill
- roblox-publish-checklistSkill
- roblox-release-operationsSkill
- roblox-security-economySkill
- roblox-securitySkill
- roblox-studio-mcpSkill
- roblox-to-issuesSkill
- roblox-toolingSkill
The file
We split this skill into the rules it gives an agent
4 rules. 0 are common, 2 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 5 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 19
No Instances, Vector3, CFrame or Color3: store numbers and strings.
- Distinctive: line 20
No tables mixing array and string keys, and no sparse arrays.
- Distinctive: line 21
No NaN or infinity.
- Very specific: line 30
Run Migrate(data, DATA_VERSION) on a deep copy.
“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Save systems
Where this conflicts with the roblox-lessons skill, roblox-lessons wins. Read roblox-lessons references/data.md first.
A save is a serialized snapshot of authoritative state that outlives the code that wrote it. The hard parts are choosing what to save, never losing it to a bad write, and loading old saves after you ship an update.
On Roblox
- No files: DataStores, through ProfileStore. Session locking stops two servers overwriting each other during fast server hops. ProfileStore auto-saves, saves on leave and on shutdown, and does the atomic read-modify-write for you. Don't hand-roll
GetAsync/SetAsync. - One table per player (
profile.Data), mutated only by the server through one service API. The client never writes saves; it only displays what the server sends. - Never rename the DataStore to change the format. A new name is a new, empty store, and everyone loses their progress. Migrate instead.
- Studio uses its own store (
NAME .. "_Studio"), so playtests never touch live players. Guard Studio conveniences withRunService:IsStudio(). - Format limits: values must be JSON-encodable.
- No Instances,
Vector3,CFrameorColor3: store numbers and strings. - No tables mixing array and string keys, and no sparse arrays.
- No NaN or infinity.
- There is a per-key size limit of about 4 MB.
- No Instances,
- Backups: DataStores keep previous versions of a key for a limited time (
ListVersionsAsync,GetVersionAsync), which is your rollback path. The Open Cloud API can read a live entry to confirm what was really saved.
Workflow
- Decide the authoritative state. Save data (ids, counts, levels, flags), never Instances or object references. Rebuild the world from data on load.
- Stamp
dataVersionin the template from day one. - Load pipeline:
- Run
Migrate(data, DATA_VERSION)on a deep copy.Steps[v]upgrades v to v+1; run each inpcall. - Replace the live data only if every step succeeds.
- Then
Reconcile()to fill new template fields. - Then validate (ids still exist in content, numbers sane).
- Run
- Outcomes:
currentormigrated: load normally.newer(an old server during a rolling update),missingSteporfailed: leave the save untouched, end the session and kick with "please rejoin".- Reset only pre-launch dev saves below a declared baseline, never live ones.
- Bump
DATA_VERSIONtogether withSteps[old]. A spec should fail until every version from the baseline up has a step. Keep old steps forever. - Store, don't derive. Save choices and progress, and recompute derived values (income totals, multipliers) on load, so a formula change in a patch can't desync saves.
- Verify:
- Spec the migration chain against fixture saves from each shipped version.
- Playtest with Studio API access on: save, rejoin, and confirm the state matches.
local function Migrate(data, target, steps)
local v = data.dataVersion or 0
if v > target then return "newer", data end
if v == target then return "current", data end
if v < BASELINE then return "reset", nil end
local copy = deepCopy(data)
while v < target do
local step = steps[v]
if not step then return "missingStep", data end
if not pcall(step, copy) then return "failed", data end
v += 1
copy.dataVersion = v
end
return "migrated", copy
endPitfalls
- Renaming the store, or wiping on a version mismatch.
- Loading a newer save with older code, which silently drops unknown fields on the next write.
- Migrations that mutate the live table and fail halfway.
- Saving Roblox datatypes or Instances, which are dropped or rejected on write.
- Mixed or sparse tables. Key by
tostring(id). - Content removed in a patch (an item id) that crashes the load. Drop or substitute it during validation.
- Trusting the client with any saved value.
- Studio playtests writing to the live store.
References
references/versioning-and-migration.md: the version field, the migration chain and its rules, backups and rollback, format constraints, a load-time validation checklist, and store vs recompute.
Related: roblox-lessons (data.md, monetization.md for purchase-receipt dedupe stored in the save).
Adapted from awesome-gamedev-agent-skills (Apache-2.0). Modified; see SOURCE.md.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

