DataStoreService 允許您存儲需要在會話之間持久化的數據,例如玩家的物品或技能點。數據存儲在每個遊戲中都是一致的,因此遊戲中的任何地方都可以訪問和更改相同的數據,包括不同伺服器上的地方。
如果您想為數據存儲添加細粒度的權限控制並在 Studio 或 Roblox 伺服器之外訪問它們,您可以使用 數據存儲的開放雲 API。
要通過 Creator Hub 查看和監控遊戲中的所有數據存儲,請使用 數據存儲管理器。
對於需要頻繁更新或訪問的臨時數據,請使用 內存存儲。
啟用 Studio 訪問
默認情況下,在 Studio 中測試的遊戲無法訪問數據存儲,因此您必須首先啟用它們。在 Studio 中訪問數據存儲對於實時遊戲來說可能是危險的,因為 Studio 訪問與客戶端應用程序相同的數據存儲。為了避免覆蓋生產數據,請不要為實時遊戲啟用此設置。相反,請為遊戲的單獨測試版本啟用它。
要在 已發布 的遊戲中啟用 Studio 訪問:
- 打開 Studio 的 文件 ⟩ 體驗設置 窗口。
- 導航到 安全性。
- 啟用 啟用 Studio 訪問 API 服務 切換。
- 點擊 保存。
訪問數據存儲
要在遊戲中訪問數據存儲:
- 將 DataStoreService 添加到伺服器端的 Script 中。
- 使用 GetDataStore() 函數並指定您想要使用的數據存儲的名稱。如果數據存儲不存在,Studio 在您第一次保存遊戲數據時會創建一個。
local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")創建數據
數據存儲本質上是一個字典,類似於 Luau 表。每個值都有一個唯一的 鍵 來索引,例如用戶的唯一 Player.UserId 或遊戲促銷的命名字符串。
| 用戶數據鍵 | 值 |
|---|---|
| 31250608 | 50 |
| 351675979 | 20 |
| 505306092 | 78000 |
| 促銷數據鍵 | 值 |
| ActiveSpecialEvent | SummerParty2 |
| ActivePromoCode | BONUS123 |
| CanAccessPartyPlace | true |
要創建新條目,調用 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元數據
與鍵相關聯的元數據有兩種類型:
- 服務定義:默認的只讀元數據,例如最近的更新時間和創建時間。每個對象都有服務定義的元數據。
要管理元數據,擴展 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 thenprint(errorMessage)end
GetAsync()、IncrementAsync() 和 RemoveAsync() 返回 DataStoreKeyInfo 對象中的第二個值。這個第二個值包含服務定義的屬性和函數,用於獲取用戶定義的元數據。
- Version 屬性獲取鍵的版本。
- CreatedTime 屬性獲取鍵創建的時間,格式為自紀元以來的毫秒數。
- UpdatedTime 屬性獲取鍵最後更新的時間,格式為自紀元以來的毫秒數。
local DataStoreService = game:GetService("DataStoreService")local gameStore = DataStoreService:GetDataStore("PlayerGame")local success, currentGame, keyInfo = pcall(function()return gameStore:GetAsync("User_1234")end)if success thenprint(currentGame)print(keyInfo.Version)print(keyInfo.CreatedTime)print(keyInfo.UpdatedTime)print(keyInfo:GetUserIds())print(keyInfo:GetMetadata())endUpdateAsync() 的回調函數在 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, metadataendlocal success, updatedName, keyInfo = pcall(function()return nicknameStore:UpdateAsync("User_1234", makeNameUpper)end)if success thenprint(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