數據存儲

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

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

如果您希望對數據存儲添加精細的權限控制並在 Studio 或 Roblox 伺服器之外訪問它們,您可以使用 Open Cloud APIs for data stores

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

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

啟用 Studio 訪問

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

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

  1. 打開 Studio 的 File ⟩ Experience Settings 窗口。
  2. 轉到 Security
  3. 啟用 Enable Studio Access to API Services 切換開關。
  4. 單擊 Save

訪問數據存儲

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

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

local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")

創建數據

數據存儲本質上是一個字典,類似於 Luau 表。每個值在數據存儲中都有一個唯一的 key 索引,例如用戶的唯一 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("Uppercase Name:", updatedName)
end

Set vs update

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

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

使用 update 處理多伺服器嘗試。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
©2026 Roblox Corporation、Roblox、Roblox 標誌及 Powering Imagination 是我們在美國及其他國家地區的部分註冊與未註冊商標。