Magazyny danych to usługa, której możesz użyć do zapisywania i ładowania trwałych danych gracza w różnych sesjach gracza. Przechowują one ważne informacje, takie jak postęp gracza lub inwentarz, i pozwalają na ich odzyskanie, gdy gracz następnym razem dołączy do twojej gry. Bez magazynów danych gracz straciłby cały swój postęp za każdym razem, gdy opuściłby grę.
Istnieją dwa typy magazynów danych: standardowe i uporządkowane. Ten samouczek wykorzystuje standardowe magazyny danych, które przechowują dane, takie jak liczby, ciągi znaków i tabele, które nie muszą być klasyfikowane ani sortowane.
Używając pliku samouczek magazynów danych Gold Rush - Start .rbxl jako punktu wyjścia oraz pliku samouczek magazynów danych Gold Rush - Complete .rbxl jako odniesienia, ten samouczek daje ci podstawy potrzebne do zapisania postępu gracza i stworzenia bardziej spójnych gier, w tym wskazówki dotyczące:
- Zapisywania i ładowania ilości złota, które gracz zebrał.
- Aktualizacji interfejsu użytkownika, aby wyświetlić inwentarz złota gracza.
- Automatycznego zapisywania inwentarza złota gracza co 30 sekund.
- Zapisywania pozycji gracza, gdy opuszcza grę.
- Przywracania pozycji gracza, gdy ponownie dołącza do gry.
Na koniec tego samouczka powinieneś mieć dwa skrypty z magazynami danych w ServerScriptService:
- Zaktualizowany skrypt GoldManager, który śledzi, ładuje i automatycznie zapisuje złoto gracza.
- Zaktualizowany skrypt PositionManager, który zapisuje pozycję gracza, gdy opuszcza grę i przywraca jego pozycję, gdy wraca do gry.

Włącz dostęp Studio do usług API
Magazyny danych nie są przechowywane lokalnie na twoim urządzeniu, więc twoja gra polega na komunikacji serwerowej z backendem Roblox w celu ich użycia. Domyślnie Studio ogranicza tę komunikację, aby zapobiec nadużyciom lub przypadkowemu użyciu. Dostęp do usług API w Studio jest wyłączony, aż wyraźnie go włączysz, aby upewnić się, że tylko zaufane gry mogą czytać i zapisywać na serwerach backendu Roblox.
Aby włączyć dostęp Studio do usług API, aby móc używać magazynów danych:
- Otwórz plik samouczek magazynów danych Gold Rush - Start .rbxl w Studio i stwórz lokalną kopię.
- Z powrotem w Studio, przejdź do Plik ⟩ Ustawienia doświadczenia ⟩ Bezpieczeństwo.
- Włącz Włącz dostęp Studio do usług API.
- Zapisz swoje zmiany.
Utwórz standardowy magazyn danych
Podczas tworzenia magazynu danych należy zawsze wywołać DataStoreService z serwerowego Script. Jest to ważne, ponieważ:
- Roblox blokuje wszystkie dostęp do magazynów danych z klienta, aby tylko serwer miał pozwolenie na dostęp i modyfikowanie trwałych danych gracza.
- Skrypty po stronie serwera działają w scentralizowanym środowisku, co zapewnia, że dane odczytywane i zapisywane w twoim magazynie danych są dokładne i ważne.
- Ponieważ skrypty po stronie klienta działają na urządzeniu gracza, każdy gracz mógłby potencjalnie wykorzystać grę i ukraść lub nadpisać dane innych graczy, jeśli klient miałby dostęp do twoich magazynów danych.
Należy również nadać swojemu magazynowi danych unikalną nazwę, aby uporządkować swoje dane i zapobiec ich zachodzeniu lub konfliktom w różnych magazynach danych. W tym samouczku magazyn danych, który zapisuje i przechowuje inwentarz złota gracza, nazywa się PlayerGold.
Aby utworzyć magazyn danych PlayerGold:
Otwórz istniejący skrypt GoldManager w ServerScriptService.

Na górze skryptu, po innych usługach, zainicjalizuj DataStoreService i wywołaj GetDataStore z napisem "PlayerGold".
local DataStoreService = game:GetService("DataStoreService")local goldStore = DataStoreService:GetDataStore("PlayerGold")
Zapisz i załaduj dane gracza
Magazyny danych składają się z kluczy, które identyfikują dane, oraz wartości, które przechowują dane.
| Klucz | Wartość | |
|---|---|---|
| Opis | Klucz to unikalny identyfikator, którego możesz użyć do uzyskania dostępu do konkretnego elementu danych. Klucze pozwalają ci uporządkować swoje dane, abyś mógł łatwo je zarządzać i debugować. | Wartość to faktyczne dane, które chcesz zapisać lub załadować, takie jak inwentarz gracza lub jego ustawienia. Wartości pozwalają ci przechowywać postęp między sesjami, a także odzyskiwać dane gracza następnym razem, gdy dołączy do twojej gry. |
| Dozwolone formaty | Mogą być tylko ciągami znaków. | Mogą być liczbami, ciągami znaków, wartościami logicznymi lub tabelami. |
| Przykłady | "Player_A", "TopScore", "GameSetting" | 100, "Level_5", true, {gold = 100, level = 5} |
W tym samouczku kluczem jest userId gracza, a wartością jest ilość złota, które zebrał. Aby użyć tego klucza i wartości do zapisywania i ładowania danych gracza:
W skrypcie GoldManager dodaj funkcję pomocniczą o nazwie saveGold, aby zapisać złoto gracza w magazynie danych PlayerGold.
local function saveGold(userId, value)local success, err = pcall(function()-- `userId` to unikalny identyfikator gracza-- `value` to ilość złota do zapisania dla tego graczagoldStore:SetAsync(userId, value)end)end- OPTIONALDodaj ostrzeżenie do saveGold, które wydrukuje identyfikator gracza i komunikat o błędzie. Choć nie jest to obowiązkowe, ten krok jest dobrą praktyką, aby łatwiej debugować, jeśli twoja funkcja nie powiedzie się.local function saveGold(userId, value)local success, err = pcall(function()-- `userId` to unikalny identyfikator gracza-- `value` to ilość złota do zapisania dla tego graczagoldStore:SetAsync(userId, value)end)if not success thenwarn("[BŁĄD ZAPISU] Nie udało się zapisać złota dla", userId, ":", err)endend
Zmodyfikuj zdarzenie onPlayerAdded, aby załadować złoto gracza, gdy ten po raz pierwszy dołączy do gry. Zaktualizowana funkcja onPlayerAdded:
- Próbuje załadować zawartość wewnątrz magazynu danych PlayerGold. Zwraca albo zapisane złoto gracza, albo wartość 0, jeśli gracz nie ma żadnego złota lub nie grał wcześniej w tę grę.
- Dostarcza ci log debugowy, aby pomóc ci łatwiej debugować swój kod. Ten log debugowy zawiera zapisane złoto gracza, lub komunikat o błędzie, jeśli onPlayerAdded nie może uzyskać dostępu do magazynu danych.
- Aktualizuje interfejs użytkownika, aby wyświetlić zapisane złoto gracza na jego ekranie.
local function onPlayerAdded(player)local userId = player.UserIdlocal success, storedGold = pcall(function()return goldStore:GetAsync(userId)end)if success thenlocal currentGold = storedGold or 0playerGold[userId] = currentGolduiEvent:FireClient(player, {gold = currentGold,doTween = false,showAlert = not success})elseuiEvent:FireClient(player, { showAlert = true })warn("Nie można załadować złota dla", player.Name)endendZmodyfikuj zdarzenie onPlayerRemoving, aby wywołać funkcję saveGold, którą stworzyłeś wcześniej i zapisać złoto gracza, gdy opuszcza grę.
local function onPlayerRemoving(player)local userId = player.UserIdif playerGold[userId] thensaveGold(userId, playerGold[userId])endend
Automatyczne zapisywanie danych gracza
Automatyczne zapisywanie danych gracza to dobra praktyka, ponieważ chroni gracza przed utratą jego danych. Jeśli zapisujesz dane gracza tylko wtedy, gdy opuszcza grę za pomocą onPlayerRemoving, możesz stracić jego najnowszy postęp, gdy nieoczekiwanie rozłączy się z serwerem.
Aby automatycznie zapisać dane gracza:
Utwórz nową stałą, aby określić, jak często chcesz, aby twoja gra automatycznie zapisywała dane gracza. Stała jest zmienną, której wartość nie zmienia się podczas działania gry. Możesz użyć tej stałej, aby odwołać się do interwału autosave w całym swoim skrypcie i łatwo dostosować frekwencję autosavingu.
-- Ta liczba jest w sekundachlocal AUTOSAVE_INTERVAL = 30Dodaj coroutine autosave do istniejącej funkcji onPlayerAdded, aby utworzyć pętlę w tle, która działa, gdy gracz jest w grze. Coroutine to funkcja, która działa asynchronicznie; może wstrzymać się w pewnych punktach, wznowić tam, gdzie skończyła, i działać równolegle z innymi częściami twojego skryptu, nie blokując ich.
W tym skrypcie tło autosave coroutine czeka na liczbę sekund w twojej stałej AUTOSAVE_INTERVAL, a następnie wywołuje funkcję saveGold, którą stworzyłeś wcześniej.
coroutine.wrap(function()while player.Parent dotask.wait(AUTOSAVE_INTERVAL)if playerGold[userId] thenprint("[AUTOSAVE] Zapisuję", playerGold[userId], "złota dla", player.Name)saveGold(userId, playerGold[userId])endendend)()
Zapisz i załaduj pozycję gracza
Aby zapisać pozycję gracza, należy pracować z jego Character, a nie z obiektem Player. Character gracza reprezentuje jego fizyczny model w świecie 3D i ma współrzędne dla swojej obecnej pozycji i orientacji, podczas gdy obiekt Player reprezentuje tylko konto użytkownika.
Ponieważ magazyny danych mogą przechowywać tylko podstawowe typy danych, takie jak liczby, ciągi znaków i tabele, nie możesz bezpośrednio przechować złożonych obiektów, takich jak wartości Vector3 lub CFrame. Aby zapisać pozycję gracza, musisz podzielić ją na trzy oddzielne liczby (współrzędne X, Y i Z) i zapisać je osobno. Podczas ładowania pozycji później możesz odbudować Vector3 za pomocą zapisanych współrzędnych.
Aby zapisać i załadować pozycję postaci:
Otwórz istniejący skrypt PositionManager w ServerScriptService.
Na górze skryptu zainicjalizuj DataStoreService i wywołaj GetDataStore z napisem "PlayerPosition".
local DataStoreService = game:GetService("DataStoreService")local positionStore = DataStoreService:GetDataStore("PlayerPosition")Dodaj funkcję pomocniczą o nazwie savePosition, która przyjmuje userId gracza i pozycję Vector3. Ponieważ nie możesz bezpośrednio zapisać wartości Vector3, skonwertuj pozycję na tabelę z liczbami X, Y, Z.
local function savePosition(player, position)local userId = player.UserIdlocal success, err = pcall(function()positionStore:SetAsync(userId, {position.X, position.Y, position.Z})end)end- OPTIONALDodaj ostrzeżenie do savePosition, które wydrukuje komunikat o błędzie i nazwę gracza, dla którego nie udało się zapisać pozycji. Choć nie jest to obowiązkowe, ten krok jest dobrą praktyką, aby łatwiej debugować, jeśli twoja funkcja nie powiedzie się.local function savePosition(player, position)local userId = player.UserIdlocal success, err = pcall(function()positionStore:SetAsync(userId, {position.X, position.Y, position.Z})end)if not success thenwarn("Nie można zapisać pozycji dla", player.Name, ":", err)endend
Dodaj kolejną funkcję pomocniczą o nazwie loadPosition, aby załadować zapisane współrzędne dla gracza w magazynie danych PlayerPosition. Użyj PivotTo, aby przywrócić pozycję postaci w świecie. Ponieważ zapisane położenie gracza zwracane jest jako tabela, musisz odbudować Vector3, a następnie przekształcić go w CFrame, aby przenieść postać.
local function loadPosition(userId, character)local userId = player.UserIdlocal success, savedCoords = pcall(function()return positionStore:GetAsync(userId)end)if success and savedCoords thenlocal pos = Vector3.new(savedCoords[1], savedCoords[2], savedCoords[3])print("Przywrócono pozycję dla", player.Name)character:PivotTo(CFrame.new(pos))elseif not success thenwarn("Nie można załadować pozycji dla", player.Name)endendZmodyfikuj zdarzenie onPlayerAdded, aby zainicjować logikę pozycji dla każdego gracza, który dołącza do twojej gry. W zaktualizowanej funkcji onPlayerAdded:
- CharacterAdded wywołuje loadPosition, aby przywrócić ostatnią znaną lokalizację postaci, gdy postać gracza się pojawia.
- CharacterRemoving wywołuje savePosition, aby zapisać bieżącą pozycję postaci gracza, jeśli zostanie usunięta z gry.
- GetPivot uzyskuje dokładną lokalizację postaci w świecie w momencie jej usunięcia.
local function onPlayerAdded(player)local userId = player.UserIdplayer.CharacterAdded:Connect(function(character)loadPosition(player, character)end)player.CharacterRemoving:Connect(function(character)local pos = character:GetPivot().PositionsavePosition(player, pos)end)endPlayer.PlayerAdded:Connect(onPlayerAdded)
Końcowy kod
Zobacz poniższe fragmenty kodu dla kompletnych skryptów GoldManager i PositionManager. Możesz je wkleić i uruchomić bezpośrednio w pliku samouczek zapisywania danych Gold Rush - Start .rbxl w Studio.
GoldManager
-- Pobierz usługi
-- Pobierz usługi
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")
local DataStoreService = game:GetService("DataStoreService")
-- Zdalne zdarzenie do aktualizacji interfejsu użytkownika
local uiEvent = ReplicatedStorage:WaitForChild("UIEvent")
-- Magazyn danych do zapisywania złotych kawałków gracza
local goldStore = DataStoreService:GetDataStore("PlayerGold")
-- Tabela do przechowywania kawałków złota gracza w jednej sesji
local playerGold = {}
-- Stałe
local GOLD_VALUE = 10 -- Ile wart jest każdy kawałek złota
local GOLD_REGEN_DELAY = 2 -- Opóźnienie przed respawnowaniem kawałka (w sekundach)
local AUTOSAVE_INTERVAL = 30 -- Jak często kawałki gracza są zapisywane (w sekundach)
-- Funkcja do obsługi zbierania kawałka złota przez gracza
local function processGoldTouch(chunk, player)
-- Ukryj kawałek, gdy gracz go zbierze
chunk.Parent = nil
-- Dodaj kawałek do sesyjnego wyniku złota gracza
local userId = player.UserId
playerGold[userId] = (playerGold[userId] or 0) + GOLD_VALUE
print(player.Name, "ma teraz", playerGold[userId], "złota")
-- Aktualizuj interfejs użytkownika, aby odzwierciedlić nowy wynik złota w tej sesji
uiEvent:FireClient(player, {
gold = playerGold[userId],
doTween = true,
showAlert = false
})
-- Poczekaj chwilę, a następnie respawnuj kawałek złota, który został właśnie zebrany
task.delay(GOLD_REGEN_DELAY, function()
chunk.Parent = workspace.GoldChunks
end)
end
-- Przejdź przez wszystkie części oznaczone jako "Gold" i połącz je z wykrywaniem dotyku
for _, chunk in ipairs(CollectionService:GetTagged("Gold")) do
chunk.Touched:Connect(function(otherPart)
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if player then
processGoldTouch(chunk, player)
end
end)
end
-- Funkcja do zapisywania złota gracza w magazynie danych
local function saveGold(player, value)
local userId = player.UserId
local success, err = pcall(function()
goldStore:SetAsync(userId, value)
end)
if not success then
warn("Nie można zapisać złota dla", player.Name, ":", err)
end
end
-- Funkcja do obsługi przyłączania gracza do gry
local function onPlayerAdded(player)
local userId = player.UserId
print(player.Name, "dołączył do gry")
-- Spróbuj załadować złoto gracza z magazynu danych
local success, storedGold = pcall(function()
return goldStore:GetAsync(userId)
end)
if success then
-- Ustaw obecny wynik złota sesji, korzystając z wartości magazynu danych dla gracza
local currentGold = storedGold or 0
playerGold[userId] = currentGold
-- Zaktualizuj interfejs użytkownika za pomocą wartości magazynu danych dla gracza
uiEvent:FireClient(player, {
gold = currentGold,
doTween = false,
showAlert = false
})
print("Załadowano", currentGold, "złota dla", player.Name)
else
-- Powiadom gracza, że jego złoto nie mogło zostać załadowane
uiEvent:FireClient(player, { showAlert = true })
warn("Nie można załadować złota dla", player.Name)
end
-- Rozpocznij korutynę autosave, aby zapisywać złoto gracza co 30 sekund
coroutine.wrap(function()
while player.Parent do
task.wait(AUTOSAVE_INTERVAL)
if playerGold[userId] then
saveGold(player, playerGold[userId])
print("Autosave", playerGold[userId], "złota dla", player.Name)
end
end
end)()
end
-- Funkcja do obsługi opuszczania gry przez gracza
local function onPlayerRemoving(player)
local userId = player.UserId
print(player.Name, "opuścił grę")
-- Sprawdź, czy złoto gracza było śledzone
if playerGold[userId] then
-- Zapisz złoto gracza w magazynie danych przed opuszczeniem
saveGold(player, playerGold[userId])
end
end
-- Połącz zdarzenia dołączania i opuszczania gracza
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)
PositionManager
-- Pobierz usługi
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
-- Magazyn danych do zapisywania pozycji gracza
local positionStore = DataStoreService:GetDataStore("PlayerPosition")
-- Funkcja do zapisywania pozycji gracza jako tabeli {X, Y, Z}
local function savePosition(player, position)
local userId = player.UserId
local success, err = pcall(function()
positionStore:SetAsync(userId, {position.X, position.Y, position.Z})
end)
if not success then
warn("Nie można zapisać pozycji dla", player.Name, ":", err)
end
end
-- Funkcja do ładowania ostatniej zapisanej pozycji gracza i przenoszenia jego postaci
local function loadPosition(player, character)
local userId = player.UserId
local success, savedCoords = pcall(function()
return positionStore:GetAsync(userId)
end)
if success and savedCoords then
local pos = Vector3.new(savedCoords[1], savedCoords[2], savedCoords[3])
print("Przywrócono pozycję dla", player.Name)
character:PivotTo(CFrame.new(pos))
elseif not success then
warn("Nie można załadować pozycji dla", player.Name)
end
end
-- Funkcja do obsługi przyłączania gracza do gry
local function onPlayerAdded(player)
local userId = player.UserId
-- Spróbuj załadować pozycję gracza, gdy jego postać się pojawi
player.CharacterAdded:Connect(function(character)
loadPosition(player, character)
end)
-- Zapisz pozycję gracza, gdy jego postać zostanie usunięta
player.CharacterRemoving:Connect(function(character)
local pos = character:GetPivot().Position
savePosition(player, pos)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)