DataStoreService cho phép bạn lưu trữ dữ liệu cần phải tồn tại giữa các phiên, như các vật phẩm trong kho của người chơi hoặc điểm kỹ năng. Kho dữ liệu nhất quán theo trò chơi, vì vậy bất kỳ nơi nào trong trò chơi cũng có thể truy cập và thay đổi cùng một dữ liệu, bao gồm cả các nơi trên các máy chủ khác nhau.
Nếu bạn muốn thêm kiểm soát quyền truy cập chi tiết cho các kho dữ liệu của mình và truy cập chúng bên ngoài Studio hoặc các máy chủ Roblox, bạn có thể sử dụng Open Cloud APIs cho kho dữ liệu.
Để xem và theo dõi tất cả các kho dữ liệu trong một trò chơi thông qua Trung tâm Tạo nội dung, hãy sử dụng Trình quản lý Kho Dữ liệu.
Đối với dữ liệu tạm thời mà bạn cần cập nhật hoặc truy cập thường xuyên, hãy sử dụng kho nhớ.
Bật quyền truy cập Studio
Theo mặc định, các trò chơi được thử nghiệm trong Studio không thể truy cập kho dữ liệu, vì vậy bạn phải bật chúng trước. Việc truy cập kho dữ liệu trong Studio có thể nguy hiểm cho các trò chơi đang hoạt động vì Studio truy cập cùng một kho dữ liệu như ứng dụng khách. Để tránh ghi đè dữ liệu sản xuất, không bật cài đặt này cho các trò chơi đang hoạt động. Thay vào đó, hãy bật nó cho một phiên bản thử nghiệm riêng biệt của trò chơi.
Để bật quyền truy cập Studio trong một trò chơi đã xuất bản:
- Mở cửa sổ Tệp ⟩ Cài đặt Trải nghiệm của Studio.
- Điều hướng đến Bảo mật.
- Bật công tắc Bật quyền truy cập Studio vào API Services.
- Nhấp vào Lưu.
Truy cập kho dữ liệu
Để truy cập một kho dữ liệu bên trong một trò chơi:
- Thêm DataStoreService vào một Script phía máy chủ.
- Sử dụng hàm GetDataStore() và chỉ định tên của kho dữ liệu mà bạn muốn sử dụng. Nếu kho dữ liệu không tồn tại, Studio sẽ tạo một cái khi bạn lưu dữ liệu trò chơi lần đầu tiên.
local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")Tạo dữ liệu
Một kho dữ liệu về cơ bản là một từ điển, tương tự như một bảng Luau. Một khóa duy nhất chỉ mục mỗi giá trị trong kho dữ liệu, như Player.UserId duy nhất của người dùng hoặc một chuỗi có tên cho một chương trình khuyến mãi trò chơi.
| Khóa dữ liệu người dùng | Giá trị |
|---|---|
| 31250608 | 50 |
| 351675979 | 20 |
| 505306092 | 78000 |
| Khóa dữ liệu khuyến mãi | Giá trị |
| ActiveSpecialEvent | SummerParty2 |
| ActivePromoCode | BONUS123 |
| CanAccessPartyPlace | true |
Để tạo một mục mới, gọi SetAsync() với tên khóa và một giá trị.
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)
endCập nhật dữ liệu
Để thay đổi bất kỳ giá trị nào đã lưu trong một kho dữ liệu, gọi UpdateAsync() với tên khóa của mục và một hàm callback xác định cách bạn muốn cập nhật mục đó. Hàm callback này nhận giá trị hiện tại và trả về một giá trị mới dựa trên logic mà bạn xác định. Nếu hàm callback trả về nil, thao tác ghi sẽ bị hủy và giá trị sẽ không được cập nhật.
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("Tên viết hoa:", updatedName)
endĐặt vs cập nhật
Sử dụng set để nhanh chóng cập nhật một khóa cụ thể. Hàm SetAsync():
- Có thể gây ra sự không nhất quán dữ liệu nếu hai máy chủ cố gắng đặt cùng một khóa cùng một lúc
- Chỉ tính vào giới hạn ghi
Sử dụng update để xử lý các nỗ lực đa máy chủ. Hàm UpdateAsync():
- Đọc giá trị khóa hiện tại từ máy chủ đã cập nhật nó lần cuối trước khi thực hiện bất kỳ thay đổi nào
- Chậm hơn vì nó đọc trước khi ghi
- Tính vào cả giới hạn đọc và ghi
Đọc dữ liệu
Để đọc giá trị của một mục kho dữ liệu, gọi GetAsync() với tên khóa của mục.
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)
endTăng dữ liệu
Để tăng một số nguyên trong một kho dữ liệu, gọi IncrementAsync() với tên khóa của mục và một số cho biết bao nhiêu để thay đổi giá trị. IncrementAsync() là một hàm tiện lợi cho phép bạn tránh gọi UpdateAsync() và tự động tăng số nguyên.
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)
endXóa dữ liệu
Để xóa một mục và trả về giá trị liên quan đến khóa, gọi 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)
endSiêu dữ liệu
Có hai loại siêu dữ liệu liên quan đến các khóa:
- Được xác định bởi dịch vụ: Siêu dữ liệu chỉ đọc mặc định, như thời gian cập nhật gần nhất và thời gian tạo. Mỗi đối tượng đều có siêu dữ liệu được xác định bởi dịch vụ.
- Được xác định bởi người dùng: Siêu dữ liệu tùy chỉnh để gán thẻ và phân loại. Được xác định bằng cách sử dụng đối tượng DataStoreSetOptions và hàm SetMetadata().
Để quản lý siêu dữ liệu, mở rộng các hàm SetAsync(), UpdateAsync(), GetAsync(), IncrementAsync(), và RemoveAsync().
SetAsync() chấp nhận các tham số tùy chọn thứ ba và thứ tư:
Một bảng của UserIds. Điều này có thể giúp theo dõi và loại bỏ bản quyền nội dung và tài sản trí tuệ.
Một đối tượng DataStoreSetOptions, nơi bạn có thể xác định siêu dữ liệu tùy chỉnh bằng cách sử dụng hàm 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(), và RemoveAsync() trả về một giá trị thứ hai trong đối tượng DataStoreKeyInfo. Giá trị thứ hai này chứa cả thuộc tính được xác định bởi dịch vụ và các hàm để lấy siêu dữ liệu được xác định bởi người dùng.
- Hàm GetMetadata() lấy siêu dữ liệu được xác định bởi người dùng mà bạn đã truyền vào SetAsync() thông qua SetMetadata().
- Thuộc tính Version lấy phiên bản của khóa.
- Thuộc tính CreatedTime lấy thời gian khóa được tạo, được định dạng dưới dạng số mili giây kể từ epoch.
- Thuộc tính UpdatedTime lấy thời gian lần cuối khóa được cập nhật, được định dạng dưới dạng số mili giây kể từ epoch.
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())endHàm callback của UpdateAsync() nhận một tham số bổ sung trong đối tượng DataStoreKeyInfo mô tả trạng thái hiện tại của khóa. Nó trả về giá trị đã sửa đổi, các khóa liên quan đến UserIds, và siêu dữ liệu của khóa.
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
Để biết giới hạn khi định nghĩa siêu dữ liệu, xem giới hạn siêu dữ liệu.
Kho dữ liệu có thứ tự
Theo mặc định, các kho dữ liệu không sắp xếp nội dung của chúng. Nếu bạn cần lấy dữ liệu theo cách có thứ tự, như trong thống kê bảng xếp hạng bền vững, hãy gọi GetOrderedDataStore() thay vì GetDataStore().
local DataStoreService = game:GetService("DataStoreService")
local characterAgeStore = DataStoreService:GetOrderedDataStore("CharacterAges")Các kho dữ liệu có thứ tự hỗ trợ cùng các chức năng cơ bản như các kho dữ liệu mặc định, cộng với hàm duy nhất GetSortedAsync(). Hàm này lấy nhiều khóa đã sắp xếp dựa trên một thứ tự sắp xếp cụ thể, kích thước trang, và giá trị tối thiểu/tối đa.
Ví dụ sau sắp xếp dữ liệu nhân vật thành các trang với ba mục, mỗi mục theo thứ tự giảm dần, sau đó lặp qua các trang và xuất tên và tuổi của mỗi nhân vật.
local DataStoreService = game:GetService("DataStoreService")
local characterAgeStore = DataStoreService:GetOrderedDataStore("CharacterAges")
-- Điền kho dữ liệu có thứ tự
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
-- Sắp xếp dữ liệu theo thứ tự giảm dần thành các trang ba mục mỗi trang
local success, pages = pcall(function()
return characterAgeStore:GetSortedAsync(false, 3)
end)
if success then
while true do
-- Lấy trang hiện tại (trang đầu tiên)
local entries = pages:GetCurrentPage()
-- Lặp qua tất cả các cặp khóa-giá trị trên trang
for _, entry in entries do
print(entry.key .. " : " .. tostring(entry.value))
end
-- Kiểm tra xem đã đến trang cuối cùng chưa
if pages.IsFinished then
break
else
print("----------")
-- Tiến đến trang tiếp theo
pages:AdvanceToNextPageAsync()
end
end
endĐọc nhiều mục
Để đọc nhiều mục kho dữ liệu có thứ tự trong một yêu cầu duy nhất, gọi BatchGetAsync() với một mảng các khóa. Đây là đối tác theo lô để đọc các mục một lần với GetAsync().
BatchGetAsync() trả về một từ điển ánh xạ mỗi khóa yêu cầu đến một bảng với trường value. Các khóa không tồn tại sẽ bị loại bỏ khỏi từ điển, vì vậy hãy xác nhận rằng một khóa có mặt trước khi đọc giá trị của nó.
Mỗi khóa bạn yêu cầu tính là một yêu cầu đọc, vì vậy một cuộc gọi duy nhất cho N khóa tính là N yêu cầu chống lại giới hạn đọc của kho dữ liệu có thứ tự.
Ví dụ sau đọc ba điểm số của người chơi trong một yêu cầu duy nhất, sau đó lặp qua các khóa và xuất mỗi điểm số tồn tại.
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 .. " không có mục đã lưu")
end
end
end