數據存儲

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

DataStoreService 允許您存儲需要在會話之間持久化的數據,例如玩家的物品或技能點。數據存儲在每個遊戲中都是一致的,因此遊戲中的任何地方都可以訪問和更改相同的數據,包括不同伺服器上的地方。

如果您想為數據存儲添加細粒度的權限控制並在 Studio 或 Roblox 伺服器之外訪問它們,您可以使用 數據存儲的開放雲 API

要通過 Creator Hub 查看和監控遊戲中的所有數據存儲,請使用 數據存儲管理器

對於需要頻繁更新或訪問的臨時數據,請使用 內存存儲

啟用 Studio 訪問

默認情況下,在 Studio 中測試的遊戲無法訪問數據存儲,因此您必須首先啟用它們。在 Studio 中訪問數據存儲對於實時遊戲來說可能是危險的,因為 Studio 訪問與客戶端應用程序相同的數據存儲。為了避免覆蓋生產數據,請不要為實時遊戲啟用此設置。相反,請為遊戲的單獨測試版本啟用它。

要在 已發布 的遊戲中啟用 Studio 訪問:

  1. 打開 Studio 的 文件體驗設置 窗口。
  2. 導航到 安全性
  3. 啟用 啟用 Studio 訪問 API 服務 切換。
  4. 點擊 保存

訪問數據存儲

要在遊戲中訪問數據存儲:

  1. DataStoreService 添加到伺服器端的 Script 中。
  2. 使用 GetDataStore() 函數並指定您想要使用的數據存儲的名稱。如果數據存儲不存在,Studio 在您第一次保存遊戲數據時會創建一個。
local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")

創建數據

數據存儲本質上是一個字典,類似於 Luau 表。每個值都有一個唯一的 來索引,例如用戶的唯一 Player.UserId 或遊戲促銷的命名字符串。

用戶數據鍵
3125060850
35167597920
50530609278000
促銷數據鍵
ActiveSpecialEventSummerParty2
ActivePromoCodeBONUS123
CanAccessPartyPlacetrue

要創建新條目,調用 SetAsync() 並提供鍵名和一個值。

local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")
local success, errorMessage = pcall(function()
gameStore:SetAsync("User_1234", 50)
end)
if not success then
print(errorMessage)
end

更新數據

要更改數據存儲中任何存儲的值,調用 UpdateAsync() 並提供條目的鍵名和一個回調函數,該函數定義了您希望如何更新條目。此回調接受當前值並根據您定義的邏輯返回新值。如果回調返回 nil,則寫入操作將被取消,值不會更新。

local DataStoreService = game:GetService("DataStoreService")
local nicknameStore = DataStoreService:GetDataStore("Nicknames")
local function makeNameUpper(currentName)
local nameUpper = string.upper(currentName)
return nameUpper
end
local success, updatedName = pcall(function()
return nicknameStore:UpdateAsync("User_1234", makeNameUpper)
end)
if success then
print("大寫名稱:", updatedName)
end

設置與更新

使用設置快速更新特定鍵。SetAsync() 函數:

  • 如果兩個伺服器同時嘗試設置相同的鍵,可能會導致數據不一致
  • 只計入寫入限制

使用更新來處理多伺服器嘗試。UpdateAsync() 函數:

  • 在進行任何更改之前,從最後更新它的伺服器讀取當前鍵值
  • 由於在寫入之前進行讀取,因此速度較慢
  • 計入讀取和寫入限制

讀取數據

要讀取數據存儲條目的值,調用 GetAsync() 並提供條目的鍵名。

local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")
local success, currentGame = pcall(function()
return gameStore:GetAsync("User_1234")
end)
if success then
print(currentGame)
end

增量數據

要在數據存儲中增量一個整數,調用 IncrementAsync() 並提供條目的鍵名和一個數字以改變值。IncrementAsync() 是一個方便的函數,讓您避免調用 UpdateAsync() 並手動增量整數。

local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")
local success, newGame = pcall(function()
return gameStore:IncrementAsync("Player_1234", 1)
end)
if success then
print(newGame)
end

刪除數據

要刪除條目並返回與鍵相關聯的值,調用 RemoveAsync()

local DataStoreService = game:GetService("DataStoreService")
local nicknameStore = DataStoreService:GetDataStore("Nicknames")
local success, removedValue = pcall(function()
return nicknameStore:RemoveAsync("User_1234")
end)
if success then
print(removedValue)
end

元數據

與鍵相關聯的元數據有兩種類型:

  • 服務定義:默認的只讀元數據,例如最近的更新時間和創建時間。每個對象都有服務定義的元數據。
  • 用戶定義:用於標記和分類的自定義元數據。使用 DataStoreSetOptions 對象和 SetMetadata() 函數定義。

要管理元數據,擴展 SetAsync()UpdateAsync()GetAsync()IncrementAsync()RemoveAsync() 函數。

  • SetAsync() 接受可選的第三和第四個參數:

    • 一個 UserIds 的表。這可以幫助跟踪和刪除內容版權和知識產權。

    • 一個 DataStoreSetOptions 對象,您可以使用 SetMetadata() 函數定義自定義元數據。

      local DataStoreService = game:GetService("DataStoreService")
      local gameStore = DataStoreService:GetDataStore("PlayerGame")
      local setOptions = Instance.new("DataStoreSetOptions")
      setOptions:SetMetadata({["GameElement"] = "Fire"})
      local success, errorMessage = pcall(function()
      gameStore:SetAsync("User_1234", 50, {1234}, setOptions)
      end)
      if not success then
      print(errorMessage)
      end
  • GetAsync()IncrementAsync()RemoveAsync() 返回 DataStoreKeyInfo 對象中的第二個值。這個第二個值包含服務定義的屬性和函數,用於獲取用戶定義的元數據。

    local DataStoreService = game:GetService("DataStoreService")
    local gameStore = DataStoreService:GetDataStore("PlayerGame")
    local success, currentGame, keyInfo = pcall(function()
    return gameStore:GetAsync("User_1234")
    end)
    if success then
    print(currentGame)
    print(keyInfo.Version)
    print(keyInfo.CreatedTime)
    print(keyInfo.UpdatedTime)
    print(keyInfo:GetUserIds())
    print(keyInfo:GetMetadata())
    end
  • UpdateAsync() 的回調函數在 DataStoreKeyInfo 對象中接受一個額外的參數,該參數描述當前鍵的狀態。它返回修改後的值、與 UserIds 相關聯的鍵和鍵的元數據。

    local DataStoreService = game:GetService("DataStoreService")
    local nicknameStore = DataStoreService:GetDataStore("Nicknames")
    local function makeNameUpper(currentName, keyInfo)
    local nameUpper = string.upper(currentName)
    local userIDs = keyInfo:GetUserIds()
    local metadata = keyInfo:GetMetadata()
    return nameUpper, userIDs, metadata
    end
    local success, updatedName, keyInfo = pcall(function()
    return nicknameStore:UpdateAsync("User_1234", makeNameUpper)
    end)
    if success then
    print(updatedName)
    print(keyInfo.Version)
    print(keyInfo.CreatedTime)
    print(keyInfo.UpdatedTime)
    print(keyInfo:GetUserIds())
    print(keyInfo:GetMetadata())
    end

有關定義元數據的限制,請參見 元數據限制

有序數據存儲

默認情況下,數據存儲不會對其內容進行排序。如果您需要以有序的方式獲取數據,例如在持久的排行榜統計中,請調用 GetOrderedDataStore() 而不是 GetDataStore()

local DataStoreService = game:GetService("DataStoreService")
local characterAgeStore = DataStoreService:GetOrderedDataStore("CharacterAges")

有序數據存儲支持與默認數據存儲相同的基本功能,以及獨特的 GetSortedAsync() 函數。這會根據特定的排序順序、頁面大小和最小/最大值檢索 多個排序鍵

以下示例將角色數據按降序排序為三個條目的頁面,然後循環遍歷頁面並輸出每個角色的名稱和年齡。

local DataStoreService = game:GetService("DataStoreService")
local characterAgeStore = DataStoreService:GetOrderedDataStore("CharacterAges")
-- 填充有序數據存儲
local characters = {
Mars = 19,
Janus = 20,
Diana = 18,
Venus = 25,
Neptune = 62
}
for char, age in characters do
local success, errorMessage = pcall(function()
characterAgeStore:SetAsync(char, age)
end)
if not success then
print(errorMessage)
end
end
-- 按降序將數據排序為每頁三個條目
local success, pages = pcall(function()
return characterAgeStore:GetSortedAsync(false, 3)
end)
if success then
while true do
-- 獲取當前(第一)頁
local entries = pages:GetCurrentPage()
-- 遍歷頁面上的所有鍵值對
for _, entry in entries do
print(entry.key .. " : " .. tostring(entry.value))
end
-- 檢查是否已到達最後一頁
if pages.IsFinished then
break
else
print("----------")
-- 進入下一頁
pages:AdvanceToNextPageAsync()
end
end
end

讀取多個條目

要在單個請求中讀取多個 有序數據存儲 條目,請調用 BatchGetAsync() 並提供一個鍵的數組。這是一次性讀取條目的批量對應函數,使用 GetAsync()

BatchGetAsync() 返回一個字典,將每個請求的鍵映射到一個具有 value 字段的表。不存在的鍵將從字典中省略,因此在讀取其值之前請確認鍵是否存在。

您請求的每個鍵都計算為一次讀取請求,因此對 N 個鍵的單次調用計算為對有序數據存儲的 N 次請求 讀取限制

以下示例在單個請求中讀取三個玩家的分數,然後循環遍歷鍵並輸出每個存在的分數。

local DataStoreService = game:GetService("DataStoreService")
local playerScores = DataStoreService:GetOrderedDataStore("PlayerScores")
local keys = {"Player_123", "Player_456", "Player_789"}
local success, results = pcall(function()
return playerScores:BatchGetAsync(keys)
end)
if success then
for _, key in keys do
local entry = results[key]
if entry then
print(key .. " : " .. tostring(entry.value))
else
print(key .. " 沒有保存的條目")
end
end
end
©2026 Roblox Corporation、Roblox、Roblox 標誌及 Powering Imagination 是我們在美國及其他國家地區的部分註冊與未註冊商標。