roblox-data

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

roblox-data

roblox-data

When to Use

适用场景

Use this skill when the task is mainly about Roblox data durability, shared cross-server state, or quota-aware coordination:
  • Designing persistent player saves, global config-like records, or other
    DataStoreService
    usage.
  • Choosing between standard data stores and ordered data stores.
  • Structuring save payloads, schema versions, migrations, and metadata.
  • Deciding when to use
    SetAsync()
    ,
    UpdateAsync()
    ,
    IncrementAsync()
    , or version APIs.
  • Designing ephemeral cross-server systems with
    MemoryStoreService
    .
  • Choosing between memory store queues, sorted maps, and hash maps.
  • Coordinating multiple servers with
    MessagingService
    .
  • Handling throttling, request budgets, retries, backoff, contention, and observability.
  • Reasoning about stale reads, cache behavior, idempotency, and multi-server correctness.
Do not use this skill when the task is mainly about:
  • Remote-event security, client-to-server validation, or general gameplay networking.
  • OAuth flows, API key setup, or general Open Cloud authentication.
  • Broad engine API lookup outside data services.
当任务主要涉及Roblox数据持久性、跨服共享状态或配额感知协调时使用本指南:
  • 设计玩家持久化存档、全局类配置记录或其他
    DataStoreService
    使用场景。
  • 在标准数据存储和有序数据存储之间做选型。
  • 设计存档载荷结构、schema版本、迁移方案和元数据。
  • 确定
    SetAsync()
    UpdateAsync()
    IncrementAsync()
    或版本API的使用时机。
  • 基于
    MemoryStoreService
    设计临时跨服系统。
  • 在内存存储队列、有序映射和哈希映射之间做选型。
  • 基于
    MessagingService
    实现多服务器协调。
  • 处理限流、请求预算、重试、退避、资源竞争和可观测性问题。
  • 处理陈旧读取、缓存行为、幂等性和多服务器正确性相关问题。

Decision Rules

不适用场景

  • Use standard data stores for durable cross-session data that can be represented as numbers, strings, booleans, tables, or buffers.
  • Use ordered data stores only when the stored value is numeric and the main requirement is persistent ranking or sorted retrieval.
  • Prefer storing one related object per durable key instead of scattering related fields across many durable keys.
  • Prefer
    UpdateAsync()
    when multiple servers might write the same key or when the new value depends on the current value.
  • Use memory stores for shared data that is frequent, temporary, or coordination-oriented and can expire.
  • Use a memory store hash map for keyed lookups and high fan-out across many keys.
  • Use a memory store sorted map when ordering matters or when you need range reads by sort key.
  • Use a memory store queue for ordered work processing, matchmaking queues, or claim-and-remove workflows.
  • Use
    MessagingService
    for short-lived broadcast signals, fan-out notifications, or wake-up coordination, not as the durable system of record.
  • If the task is mostly about remotes, replication to clients, or trust boundaries, hand off to
    roblox-networking
    .
  • If the task is mostly about general runtime structure or script placement, hand off to
    roblox-core
    .
  • If the task is mostly about member lookup, signatures, or class discovery, hand off to
    roblox-api
    .
  • If a request mixes in out-of-scope material, answer only the data-service portion and exclude the rest.
当任务主要涉及以下内容时请勿使用本指南:
  • 远程事件安全、客户端到服务端校验或通用游戏网络通信。
  • OAuth流程、API密钥配置或通用Open Cloud认证。
  • 数据服务之外的通用引擎API查询。

Instructions

决策规则

  1. Classify the state before choosing a service:
    • Durable across sessions.
    • Temporary but cross-server.
    • Broadcast-only coordination.
    • Numeric ranking versus arbitrary structured data.
  2. Choose the narrowest primitive that fits:
    • Standard data store for durable objects.
    • Ordered data store for durable numeric rankings.
    • Hash map for keyed ephemeral state.
    • Sorted map for ordered ephemeral state.
    • Queue for claim-and-process work items.
    • Messaging for notifications that can be regenerated from other state.
  3. For persistent saves, define a stable schema:
    • Keep one self-contained object per key when possible.
    • Include a schema version field inside the value.
    • Reserve migrations for load time or first write after load.
    • Keep keys, scopes, and store names short and predictable.
  4. Design writes for concurrency:
    • Prefer
      UpdateAsync()
      for contested keys.
    • Make callbacks deterministic and non-yielding.
    • Return
      nil
      to abort invalid updates.
    • Preserve existing metadata and user IDs when you do not intend to clear them.
  5. Design reads with cache behavior in mind:
    • Treat
      GetAsync()
      as locally cached for a short window.
    • Use uncached reads only when freshness matters enough to justify extra budget use.
    • Avoid reading immediately after writing from a different server unless the design accounts for staleness.
  6. Treat quotas as part of the design:
    • Check request budgets before bursty durable writes.
    • Batch related durable data into one object where it improves atomicity and budget use.
    • Keep memory-store TTLs as short as the use case allows.
    • Remove queue and sorted-map items promptly after processing.
  7. Design for retries and failure:
    • Wrap network calls in
      pcall()
      .
    • Retry transient failures with exponential backoff.
    • Add jitter or spreading when many servers may retry together.
    • Make retryable operations idempotent whenever possible.
  8. Use observability to close the loop:
    • Watch request counts, throttles, and quota usage for data stores.
    • Watch memory usage, request-unit usage, and throttle statuses for memory stores.
    • Use dashboards to confirm whether the bottleneck is global quota, per-key contention, or hot partitions.
  9. Use messaging as a coordination layer, not storage:
    • Publish compact events.
    • Re-read or update authoritative state in data or memory stores as needed.
    • Assume messages can be delayed or duplicated and make handlers safe.
  10. Keep guidance inside scope:
  • Focus on persistence, ephemeral shared state, quotas, and concurrency.
  • Do not drift into remote security, gameplay networking, or auth flows.
  • 标准数据存储适用于可表示为数字、字符串、布尔值、表或缓冲区的跨会话持久化数据。
  • 仅当存储值为数字类型,且核心需求是持久化排名或有序检索时,才使用有序数据存储。
  • 优先为每个持久化key存储一个关联对象,不要将关联字段分散到多个持久化key中。
  • 当多个服务器可能写入同一个key,或新值依赖当前值时,优先使用
    UpdateAsync()
  • 内存存储适用于高频、临时、面向协调且可过期的共享数据。
  • 内存哈希映射适用于key查询和多key高扇出场景。
  • 当需要排序能力或需要按排序key做范围读取时,使用内存有序映射。
  • 内存队列适用于有序工作处理、匹配队列或认领后移除的工作流。
  • MessagingService
    适用于短生命周期广播信号、扇出通知或唤醒协调,不可作为持久化记录系统。
  • 如果任务主要涉及远程调用、客户端同步或信任边界问题,转至
    roblox-networking
    指南。
  • 如果任务主要涉及通用运行时结构或脚本放置,转至
    roblox-core
    指南。
  • 如果任务主要涉及成员查询、签名或类发现,转至
    roblox-api
    指南。
  • 如果请求混合了超出范围的内容,仅回答数据服务相关部分,忽略其余内容。

Using References

使用指南

  • Open
    references/data-stores-guides.md
    for standard versus ordered data stores, core CRUD patterns, metadata, serialization, and save-shape decisions.
  • Open
    references/data-store-best-practices.md
    for durable schema layout, key organization, storage hygiene, and cleanup strategy.
  • Open
    references/versioning-listing-caching-limits-and-observability.md
    for version history, prefix listing, cache behavior, limits, request budgets, throttling, and dashboards.
  • Open
    references/memory-stores-guides.md
    for choosing between queues, sorted maps, and hash maps and for the core API patterns of each.
  • Open
    references/memory-store-best-practices-limits-and-observability.md
    for TTL strategy, sharding, partition pressure, request-unit budgeting, contention handling, and dashboards.
  • Open
    references/cross-server-messaging.md
    for topic design, publish-subscribe flow, and coordination patterns that pair messaging with durable or ephemeral state.
  • Open
    references/data-stores-vs-memory-stores-comparison.md
    when the first decision is which service class should own the data.
  1. 选型前先对状态做分类:
    • 跨会话持久化
    • 临时但跨服务器共享
    • 仅广播类协调
    • 数字排名类 vs 任意结构化数据
  2. 选择最贴合需求的最小能力原语:
    • 持久化对象使用标准数据存储
    • 持久化数字排名使用有序数据存储
    • 带key的临时状态使用哈希映射
    • 有序临时状态使用有序映射
    • 认领后处理的工作项使用队列
    • 可从其他状态重新生成的通知使用消息服务
  3. 持久化存档需要定义稳定的schema:
    • 尽可能每个key对应一个自包含对象
    • 存储值内部要包含schema版本字段
    • 迁移操作预留到读取时或读取后的首次写入时执行
    • key、scope和存储名称保持简短可预测
  4. 写入操作要做并发兼容设计:
    • 有竞争的key优先使用
      UpdateAsync()
    • 回调函数要保持确定性且不产生yield
    • 无效更新返回
      nil
      终止操作
    • 不需要清空元数据和用户ID时要保留原有值
  5. 读取操作要考虑缓存行为:
    • GetAsync()
      返回的值默认是短时间内的本地缓存
    • 仅当对新鲜度要求足够高,值得消耗额外预算时才使用无缓存读取
    • 除非设计已考虑陈旧性问题,否则避免在跨服务器写入后立即读取
  6. 配额要纳入设计考虑:
    • 突发持久化写入前要检查请求预算
    • 关联的持久化数据尽可能合并为单个对象,提升原子性和预算使用效率
    • 内存存储的TTL在业务允许的情况下尽可能短
    • 队列和有序映射的项处理完成后要及时移除
  7. 重试和故障处理设计:
    • 网络调用要用
      pcall()
      包裹
    • 瞬时故障使用指数退避重试
    • 多服务器可能同时重试时添加抖动或请求打散逻辑
    • 可重试操作尽可能保证幂等性
  8. 通过可观测性形成闭环:
    • 监控数据存储的请求数量、限流情况和配额使用情况
    • 监控内存存储的内存使用、请求单元消耗和限流状态
    • 通过仪表盘确认瓶颈是全局配额、单key竞争还是热分区
  9. 消息服务仅作为协调层,不作为存储层:
    • 发布紧凑的事件
    • 按需重新读取或更新数据存储/内存存储中的权威状态
    • 假设消息可能延迟或重复,处理逻辑要保证安全
  10. 指南使用要保持在范围内:
    • 聚焦于持久化、临时共享状态、配额和并发相关内容
    • 不要偏离到远程安全、游戏网络通信或认证流程相关内容

Checklist

参考文档

  • The state is classified as durable, ephemeral cross-server, or broadcast-only.
  • The chosen service matches the durability and ordering requirements.
  • Persistent keys use a stable schema with an explicit version field.
  • Durable writes use
    UpdateAsync()
    when contention is possible.
  • Ordered data stores are only used for numeric ranking data.
  • Cache behavior and stale-read risk are accounted for.
  • Request budgets, quotas, and throttling behavior are part of the design.
  • Memory-store TTLs are intentionally short and cleanup paths are explicit.
  • Queue items are removed after processing and sorted-map or hash-map items are pruned when stale.
  • Messaging is used for coordination, not as the system of record.
  • Retry logic uses
    pcall()
    plus backoff rather than tight loops.
  • No remote security, OAuth, or general API-lookup material is included.
  • 打开
    references/data-stores-guides.md
    查看标准与有序数据存储、核心CRUD模式、元数据、序列化和存档结构决策相关内容
  • 打开
    references/data-store-best-practices.md
    查看持久化schema布局、key组织、存储规范和清理策略相关内容
  • 打开
    references/versioning-listing-caching-limits-and-observability.md
    查看版本历史、前缀查询、缓存行为、限制、请求预算、限流和仪表盘相关内容
  • 打开
    references/memory-stores-guides.md
    查看队列、有序映射、哈希映射选型和各组件核心API模式相关内容
  • 打开
    references/memory-store-best-practices-limits-and-observability.md
    查看TTL策略、分片、分区压力、请求单元预算、竞争处理和仪表盘相关内容
  • 打开
    references/cross-server-messaging.md
    查看主题设计、发布订阅流程和消息服务与持久化/临时状态结合的协调模式相关内容
  • 当首要决策是确定数据归属的服务类型时,打开
    references/data-stores-vs-memory-stores-comparison.md

Common Mistakes

检查清单

  • Using
    SetAsync()
    on hot keys that multiple servers can write concurrently.
  • Splitting one durable player profile across many unrelated keys without a strong reason.
  • Using ordered data stores for structured blobs or metadata-heavy records.
  • Forgetting that
    GetAsync()
    can return a cached value for a few seconds.
  • Treating memory stores as durable storage.
  • Using a queue when random keyed access or scans would fit a hash map better.
  • Putting all hash-map traffic on one hot key and then hitting partition throttles.
  • Keeping long TTLs on temporary memory-store items and filling quota with stale data.
  • Using
    MessagingService
    as the only source of truth for recoverable state.
  • Retrying immediately on throttles or conflicts and causing coordinated retry storms.
  • 状态已分类为持久化、跨服临时或仅广播类
  • 选型的服务符合持久性和排序要求
  • 持久化key使用了带明确版本字段的稳定schema
  • 存在竞争可能的持久化写入使用了
    UpdateAsync()
  • 有序数据存储仅用于数字排名数据
  • 已考虑缓存行为和陈旧读取风险
  • 请求预算、配额和限流行为已纳入设计
  • 内存存储的TTL设置足够短,清理路径明确
  • 队列项处理完成后已移除,有序映射/哈希映射的陈旧项已清理
  • 消息服务仅用于协调,不作为记录系统
  • 重试逻辑使用
    pcall()
    加退避,而非紧循环
  • 未包含远程安全、OAuth或通用API查询相关内容

Examples

常见错误

Choose the right service

  • Player profile save: standard data store with one object per player key.
  • All-time coins leaderboard: ordered data store keyed by player identifier with numeric values.
  • Matchmaking pool: memory store queue.
  • Cross-server auction board with ranking: memory store sorted map.
  • Shared ephemeral room registry keyed by server id: memory store hash map.
  • Force a cache refresh workflow across servers: message plus data-store or memory-store re-read.
  • 多服务器可并发写入的热key使用
    SetAsync()
  • 无合理理由将单个玩家持久化档案拆分到多个无关key中
  • 有序数据存储用于结构化blob或元数据密集的记录
  • 忽略
    GetAsync()
    可能返回数秒内缓存值的特性
  • 将内存存储当作持久化存储使用
  • 随机key访问或扫描场景更适合哈希映射时,错误使用队列
  • 所有哈希映射流量都打到单个热key,触发分区限流
  • 临时内存存储项设置过长TTL,导致配额被陈旧数据占用
  • MessagingService
    被用作可恢复状态的唯一可信源
  • 限流或冲突时立即重试,导致协调重试风暴

Use
UpdateAsync()
for contested durable saves

示例

选择合适的服务

lua
local DataStoreService = game:GetService("DataStoreService")
local profileStore = DataStoreService:GetDataStore("PlayerProfiles")

local function saveCoins(userId, delta)
    return profileStore:UpdateAsync(("player/%d"):format(userId), function(current, keyInfo)
        current = current or {schemaVersion = 1, coins = 0}
        current.coins += delta
        return current, keyInfo:GetUserIds(), keyInfo:GetMetadata()
    end)
end
  • 玩家档案存档:标准数据存储,每个玩家key对应一个对象
  • 历史金币排行榜:有序数据存储,以玩家ID为key,存储值为数字类型
  • 匹配池:内存存储队列
  • 带排名的跨服拍卖板:内存存储有序映射
  • 以服务器ID为key的临时跨服房间注册表:内存存储哈希映射
  • 跨服务器强制刷新缓存工作流:消息 + 数据存储/内存存储重读

Use messaging to wake workers, not to hold state

有竞争的持久化存档使用
UpdateAsync()

lua
-- Publish: "queue has work"
-- Receiver: read the queue or map, then process authoritative state there.
lua
local DataStoreService = game:GetService("DataStoreService")
local profileStore = DataStoreService:GetDataStore("PlayerProfiles")

local function saveCoins(userId, delta)
    return profileStore:UpdateAsync(("player/%d"):format(userId), function(current, keyInfo)
        current = current or {schemaVersion = 1, coins = 0}
        current.coins += delta
        return current, keyInfo:GetUserIds(), keyInfo:GetMetadata()
    end)
end

消息服务用于唤醒工作者,而非存储状态

lua
-- Publish: "queue has work"
-- Receiver: read the queue or map, then process authoritative state there.