roblox-data
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseroblox-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 usage.
DataStoreService - Choosing between standard data stores and ordered data stores.
- Structuring save payloads, schema versions, migrations, and metadata.
- Deciding when to use ,
SetAsync(),UpdateAsync(), or version APIs.IncrementAsync() - 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()或版本API的使用时机。IncrementAsync() - 基于设计临时跨服系统。
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 when multiple servers might write the same key or when the new value depends on the current value.
UpdateAsync() - 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 for short-lived broadcast signals, fan-out notifications, or wake-up coordination, not as the durable system of record.
MessagingService - 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
决策规则
- Classify the state before choosing a service:
- Durable across sessions.
- Temporary but cross-server.
- Broadcast-only coordination.
- Numeric ranking versus arbitrary structured data.
- 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.
- 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.
- Design writes for concurrency:
- Prefer for contested keys.
UpdateAsync() - Make callbacks deterministic and non-yielding.
- Return to abort invalid updates.
nil - Preserve existing metadata and user IDs when you do not intend to clear them.
- Prefer
- Design reads with cache behavior in mind:
- Treat as locally cached for a short window.
GetAsync() - 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.
- Treat
- 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.
- 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.
- Wrap network calls in
- 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.
- 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.
- 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 for standard versus ordered data stores, core CRUD patterns, metadata, serialization, and save-shape decisions.
references/data-stores-guides.md - Open for durable schema layout, key organization, storage hygiene, and cleanup strategy.
references/data-store-best-practices.md - Open for version history, prefix listing, cache behavior, limits, request budgets, throttling, and dashboards.
references/versioning-listing-caching-limits-and-observability.md - Open for choosing between queues, sorted maps, and hash maps and for the core API patterns of each.
references/memory-stores-guides.md - Open for TTL strategy, sharding, partition pressure, request-unit budgeting, contention handling, and dashboards.
references/memory-store-best-practices-limits-and-observability.md - Open for topic design, publish-subscribe flow, and coordination patterns that pair messaging with durable or ephemeral state.
references/cross-server-messaging.md - Open when the first decision is which service class should own the data.
references/data-stores-vs-memory-stores-comparison.md
- 选型前先对状态做分类:
- 跨会话持久化
- 临时但跨服务器共享
- 仅广播类协调
- 数字排名类 vs 任意结构化数据
- 选择最贴合需求的最小能力原语:
- 持久化对象使用标准数据存储
- 持久化数字排名使用有序数据存储
- 带key的临时状态使用哈希映射
- 有序临时状态使用有序映射
- 认领后处理的工作项使用队列
- 可从其他状态重新生成的通知使用消息服务
- 持久化存档需要定义稳定的schema:
- 尽可能每个key对应一个自包含对象
- 存储值内部要包含schema版本字段
- 迁移操作预留到读取时或读取后的首次写入时执行
- key、scope和存储名称保持简短可预测
- 写入操作要做并发兼容设计:
- 有竞争的key优先使用
UpdateAsync() - 回调函数要保持确定性且不产生yield
- 无效更新返回终止操作
nil - 不需要清空元数据和用户ID时要保留原有值
- 有竞争的key优先使用
- 读取操作要考虑缓存行为:
- 返回的值默认是短时间内的本地缓存
GetAsync() - 仅当对新鲜度要求足够高,值得消耗额外预算时才使用无缓存读取
- 除非设计已考虑陈旧性问题,否则避免在跨服务器写入后立即读取
- 配额要纳入设计考虑:
- 突发持久化写入前要检查请求预算
- 关联的持久化数据尽可能合并为单个对象,提升原子性和预算使用效率
- 内存存储的TTL在业务允许的情况下尽可能短
- 队列和有序映射的项处理完成后要及时移除
- 重试和故障处理设计:
- 网络调用要用包裹
pcall() - 瞬时故障使用指数退避重试
- 多服务器可能同时重试时添加抖动或请求打散逻辑
- 可重试操作尽可能保证幂等性
- 网络调用要用
- 通过可观测性形成闭环:
- 监控数据存储的请求数量、限流情况和配额使用情况
- 监控内存存储的内存使用、请求单元消耗和限流状态
- 通过仪表盘确认瓶颈是全局配额、单key竞争还是热分区
- 消息服务仅作为协调层,不作为存储层:
- 发布紧凑的事件
- 按需重新读取或更新数据存储/内存存储中的权威状态
- 假设消息可能延迟或重复,处理逻辑要保证安全
- 指南使用要保持在范围内:
- 聚焦于持久化、临时共享状态、配额和并发相关内容
- 不要偏离到远程安全、游戏网络通信或认证流程相关内容
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 when contention is possible.
UpdateAsync() - 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 plus backoff rather than tight loops.
pcall() - No remote security, OAuth, or general API-lookup material is included.
- 打开查看标准与有序数据存储、核心CRUD模式、元数据、序列化和存档结构决策相关内容
references/data-stores-guides.md - 打开查看持久化schema布局、key组织、存储规范和清理策略相关内容
references/data-store-best-practices.md - 打开查看版本历史、前缀查询、缓存行为、限制、请求预算、限流和仪表盘相关内容
references/versioning-listing-caching-limits-and-observability.md - 打开查看队列、有序映射、哈希映射选型和各组件核心API模式相关内容
references/memory-stores-guides.md - 打开查看TTL策略、分片、分区压力、请求单元预算、竞争处理和仪表盘相关内容
references/memory-store-best-practices-limits-and-observability.md - 打开查看主题设计、发布订阅流程和消息服务与持久化/临时状态结合的协调模式相关内容
references/cross-server-messaging.md - 当首要决策是确定数据归属的服务类型时,打开
references/data-stores-vs-memory-stores-comparison.md
Common Mistakes
检查清单
- Using on hot keys that multiple servers can write concurrently.
SetAsync() - 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 can return a cached value for a few seconds.
GetAsync() - 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 as the only source of truth for recoverable state.
MessagingService - 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
UpdateAsync()示例
—
选择合适的服务
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()
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.