본문으로 건너뛰기
cccskills
무료GitHub에 공개

roblox-datastores

Persist player data in Roblox with DataStoreService: GetDataStore, GetAsync/ SetAsync/UpdateAsync/IncrementAsync wrapped in pcall, load-on-join and save-on-leave plus BindToClose, retries, and OrderedDataStore leaderboards. Use when saving or loading persistent data in a Roblox experience — when the user mentions DataStore, DataStoreService, GetAsync, SetAsync, UpdateAsync, save player data, or leaderboards. For general Luau scripting use roblox-luau.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(2)

  • SKILL.md7.5 KB
  • references/sessions-and-limits.md5.4 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Roblox DataStores

Persist data across sessions in Roblox with DataStoreService: loading on join, saving on leave and shutdown, safe updates, retries, and ordered stores for leaderboards. Server-side only.

When to use

  • Use to save/load player progress (coins, inventory, levels), build persistent leaderboards, or fix data loss, overwrites, and throttling.
  • Use when server code calls DataStoreService, GetDataStore, GetAsync, SetAsync, UpdateAsync, or GetOrderedDataStore.

When not to use: general scripting, services, remotes, the client/server split → roblox-luau. High-frequency temporary state (matchmaking, per-round) → memory stores (a different service). Engine-agnostic persistence theory → save-systems.

Core workflow

  1. Enable Studio access once. File → Game Settings → Security → Enable Studio Access to API Services (use a test place; Studio hits live data). DataStores work only from server Scripts, never LocalScripts.
  2. Get a store, then read/write by key. DataStoreService:GetDataStore("Name"); key per player is usually "Player_" .. player.UserId.
  3. Wrap every call in pcall. GetAsync/SetAsync/UpdateAsync are network calls that can fail; an unguarded failure errors the thread and risks data loss.
  4. Load on PlayerAdded, save on PlayerRemoving, and also BindToClose. A leaving player and a shutting-down server both need a final save.
  5. Prefer UpdateAsync for read-modify-write (multi-server safe) over SetAsync (blind overwrite). On a failed load, do not overwrite with defaults — abort the save so you don't wipe good data.
  6. Use OrderedDataStore for ranked data (leaderboards) via GetSortedAsync. Test by joining, changing data, rejoining, and confirming it persisted.

Patterns

1. Load on join (pcall-guarded)

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local store = DataStoreService:GetDataStore("PlayerData")

local DEFAULT = { Coins = 0, Level = 1 }

Players.PlayerAdded:Connect(function(player)
    local key = "Player_" .. player.UserId
    local ok, data = pcall(function()
        return store:GetAsync(key)
    end)

    if not ok then
        -- Load FAILED (network). Do not treat as a new player; flag so we never save
        -- over their real data with defaults.
        warn("Load failed for", player.Name, data)
        player:SetAttribute("DataLoaded", false)
        return
    end

    player:SetAttribute("DataLoaded", true)
    local profile = data or DEFAULT          -- nil == genuinely new player
    applyToLeaderstats(player, profile)
end)

2. Save with UpdateAsync (multi-server safe)

-- UpdateAsync reads the latest value, then writes what the callback returns.
-- The callback MUST NOT yield (no task.wait, no further Async calls inside it).
local function savePlayer(player)
    if player:GetAttribute("DataLoaded") == false then return end  -- never overwrite on a bad load
    local key = "Player_" .. player.UserId
    local newData = gatherDataFor(player)    -- a plain table of serializable values

    local ok, err = pcall(function()
        store:UpdateAsync(key, function(old)
            -- merge/decide here; return nil to cancel the write
            return newData
        end)
    end)
    if not ok then warn("Save failed for", player.Name, err) end
end

3. Save on leave AND on shutdown

Players.PlayerRemoving:Connect(savePlayer)

-- BindToClose runs when the server shuts down; save everyone still in.
-- It has a limited time budget, so save in parallel and yield until done.
game:BindToClose(function()
    local players = Players:GetPlayers()
    local remaining = #players
    if remaining == 0 then return end
    for _, player in players do
        task.spawn(function()
            savePlayer(player)
            remaining -= 1
        end)
    end
    while remaining > 0 do task.wait() end
end)

4. Retry with backoff (transient failures)

local function withRetry(fn, attempts)
    attempts = attempts or 3
    for i = 1, attempts do
        local ok, result = pcall(fn)
        if ok then return true, result end
        if i < attempts then task.wait(2 ^ i) end   -- 2s, 4s, ... backoff
    end
    return false
end

local ok, data = withRetry(function() return store:GetAsync(key) end)

5. Increment a counter

-- IncrementAsync is a convenience for integer read-modify-write (still wrap it).
local ok, newTotal = pcall(function()
    return store:IncrementAsync("Visits_" .. player.UserId, 1)
end)

6. Leaderboard with OrderedDataStore

local boards = DataStoreService:GetOrderedDataStore("Coins")

-- Write a player's score (call when it changes, not every frame).
pcall(function() boards:SetAsync("Player_" .. player.UserId, coins) end)

-- Read the top 10, descending.
local ok, pages = pcall(function()
    return boards:GetSortedAsync(false, 10)   -- ascending=false → highest first
end)
if ok then
    for rank, entry in ipairs(pages:GetCurrentPage()) do
        print(rank, entry.key, entry.value)   -- entry.value is the number
    end
end

Pitfalls

  • Unhandled failure wipes progress → always pcall Async calls; on a failed load, mark the session and refuse to save so defaults never overwrite real data.
  • SetAsync race between servers → two servers writing the same key can clobber each other. Use UpdateAsync for read-modify-write so each write sees the latest.
  • Yielding inside the UpdateAsync callback → the callback can't call task.wait or other Async functions; compute the new value beforehand and return it.
  • No BindToClose save → players in the server at shutdown lose unsaved progress; add game:BindToClose and wait for saves to finish within its budget.
  • Throttling / "too many requests" → respect per-key and per-minute limits; don't save on every value change. Batch and save on a timer / on leave. GetAsync is cached briefly, so immediate re-reads may be stale.
  • Storing non-serializable values → only JSON-serializable data persists: numbers, strings, booleans, and tables with string/number keys. Instances, Vector3, CFrame, and functions do not — serialize them to plain tables first.
  • Testing without API access → DataStores silently can't be used in Studio until Enable Studio Access to API Services is on (and they don't work from a LocalScript).
  • DataStoreKeyInfo is nil for ordered stores → OrderedDataStore doesn't support versioning/metadata; use a regular DataStore when you need those.

References

  • For session locking (preventing duplicate data across servers), versioning/ metadata with DataStoreSetOptions, ordered-store pagination (AdvanceToNextPageAsync), the key error codes and request limits, and Right-to-be-Forgotten compliance, read references/sessions-and-limits.md.

Related skills

  • roblox-luau — services, instances, events, and the server/client model.
  • save-systems — engine-agnostic serialization, slots, and migration.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Build a production behavior-tree runtime (Blackboard, action/condition leaves, sequence/selector/parallel composites, decorators) and a Utility AI system (response curves — linear, exponential, sigmoid, quadratic — considerations, and action evaluators), plus hybrid BT-drives-Utility agents. Use when implementing a reusable behavior-tree or utility-based decision system, or tuning enemy/NPC decisions beyond a simple FSM, or when the user mentions behavior tree, blackboard, decorator, selector, sequence, tick status, utility AI, response/scoring curve, or consideration. For choosing between FSM/BT/steering or for pathfinding, use game-ai; for Unreal's BehaviorTree/Blackboard assets, use unreal-behavior-trees.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

gamedev-skills/awesome-gamedev-agent-skills1.6천2026년 10월 9일 업데이트

Implement game audio practice — bus/mixer architecture and gain in decibels, ducking (sidechain), adaptive/dynamic music via layering and re-sequencing, SFX variation, and beat synchronization. Engine-neutral. Use when the user mentions audio mixing, audio buses, adaptive/dynamic music, ducking, SFX variation, music layers, or syncing gameplay to the beat.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

gamedev-skills/awesome-gamedev-agent-skills1.6천2026년 10월 9일 업데이트

bevy-ecs

무료

Structure a Bevy app around its Entity Component System: build the App with plugins, define Component/Resource types, write systems with Query/Res/Commands, filter and order systems, and use the Time resource for frame-rate-independent motion. Use when building or debugging a Bevy game in Rust — when the user mentions Bevy, ECS, App::new, add_systems, Query, Commands, components/systems, or a Cargo.toml depending on bevy.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

gamedev-skills/awesome-gamedev-agent-skills1.6천2026년 10월 9일 업데이트

Build game cameras that feel good — 2D follow with a deadzone, look-ahead, smoothing, and level-bounds clamping; 3D third-person orbit with collision and first-person look; plus multi-target framing and a shake hook. Engine-neutral techniques that pair with the engine's camera node and rigs like Unity Cinemachine or Godot Camera2D/PhantomCamera. Use when the user mentions camera follow, follow camera, deadzone, look-ahead, camera smoothing, camera bounds/ limits, third-person camera, orbit camera, first-person look, Cinemachine, or camera jitter.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

gamedev-skills/awesome-gamedev-agent-skills1.6천2026년 10월 9일 업데이트

card-game

무료

Build a card game: card data, deck/hand/discard zones, draw/shuffle/reshuffle, a turn structure, costs, and effect resolution. Use for a deckbuilder, TCG/CCG, or roguelike deckbuilder.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

gamedev-skills/awesome-gamedev-agent-skills1.6천2026년 10월 9일 업데이트

Plan, generate, source, normalize, and validate cohesive visual game assets. Use for art direction, style bibles, sprites, tilesets, backgrounds, UI art, icons, textures, concept art, or 3D asset briefs.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

gamedev-skills/awesome-gamedev-agent-skills1.6천2026년 10월 9일 업데이트

gamedev-skills의 스킬 모두 보기

이 스킬의 문제 신고