I have tried to fix this script, but i cannot.
It is the primary script which maintains most server side stuff.
I tried to make an DataStore handler, but it returns nil.
Code:
local rep = game:GetService("ReplicatedStorage")
local DrawingData = game:GetService("DataStoreService"):GetDataStore("DrawingData")
rep.SendToRandom.OnServerEvent:Connect(function(plr,data)
end)
rep.LoadFromDatastore.OnServerInvoke = function(plr,...)
local success,gotten =pcall(DrawingData.SetAsync,DrawingData,...)
if not success then
gotten = {}
warn("Failure with DataStore get, replacing with placeholder.")
end
return gotten
end
rep.SaveToDatastore.OnServerInvoke =function(plr,data:string)
local a = {DrawingData:GetAsync("GM")}
local gotten = tonumber(a[1])
DrawingData:SetAsync(tostring(gotten + 1),data)
DrawingData:SetAsync("GM",tostring(gotten + 1))
return gotten + 1
end
Output:
Failure with DataStore get, replacing with placeholder.
Saving works, and loading should work.
But, loading doesn't.
Looks like you're using SetAsync and GetAsync without actual UserId to store it to, you should save and load the data to a UserId unless the data is meant to be accessed by everyone (which I do NOT recommend).
From what I can tell you are trying to save data for individual players, but you are storing their data or their data I suppose to a singular DataStore, which will only make it more difficult for the game to load once it is prompted to load again.
Here is what I wrote based on what I believe you are trying to accomplish
local rep = game:GetService("ReplicatedStorage")
local DrawingData = game:GetService("DataStoreService"):GetDataStore("DrawingData")
rep.LoadFromDatastore.OnServerInvoke = function(plr,...)
local success, response = pcall(function(...)
return DrawingData:SetAsync(plr.UserId, ...)
end, ...)
if success ~= true or type(response) ~= "table" or table.getn(response) == 0 then
return {}, type(response) == "string" and warn(response)
end
return response
end
rep.SaveToDatastore.OnServerInvoke =function(plr, data)
local success, response = pcall(function()
return DrawingData:GetAsync(plr.UserId)
end)
if success ~= true or type(response) ~= "table" or table.getn(response) == 0 then
response = {}
end
table.insert(response, data)
local success, response
while success ~= true do
success, response = pcall(function()
return DrawingData:SetAsync(plr.UserId, response)
end)
if success ~= true then
warn(response)
end
end
end
Related
When I try and save a table (encoded into a json format) through SetAsync, it provides me with this error:
"ServerScriptService.InventoryService.main:59: attempt to index number with 'SetAsync' - Server"
I have encoded the table with HTTP:JSONEncode() and I decode it when its read again.
heres an example of the table:
{
["A"] = {
["x"] = 98,
["y"] = "xyz",
["z"] = 15
},
["B"] = {
["c"] = "XYZ",
["d"] = 0, 0, 0,
["e"] = "22",
["f"] = "xyz"
}
}
Here is the Sample code
local Datastore = game:GetService("DataStoreService")
local RunService = game:GetService('RunService')
local HTTP = game:GetService('HttpService')
local item_data = Datastore:GetDataStore("Items")
local function save(Player:Player)
local item_data = {} --contains data created by the user
local savedata = {}
--PLAYER_DATA--
if savedata[Player] == "ERR" then return end
local suc, err = pcall(function()
player_data:SetAsync(Player.UserId, savedata)
end)
if err then
warn("Unable to save data for"..Player.Name,err)
end
--ITEM_DATA--
if item_data[Player] == "ERR" then return end
local suc, err = pcall(function()
local item_json = HTTP:JSONEncode(item_data)
itemdata:SetAsync(Player.UserId,item_json)
end)
if err then
warn("Unable to save data for "..Player.Name,err)
end
end
game.Players.PlayerAdded:Connect(function(Player)
local suc, err = pcall(function()
data = player_data:GetAsync(Player.UserId) or "0"
itemdata = HTTP:JSONDecode(item_data:GetAsync(Player.UserId) or "0")
itemdata = HTTP:JSONDecode(itemdata)
end)
if suc then
savedata[Player] = data
else
savedata[Player] = "ERR"
warn("Error fetching "..Player.Name.."'s data.",err)
end
end)
game.Players.PlayerRemoving:Connect(function(Player)
save(Player)
end)
game:BindToClose(function() -- (only needed inside Studio)
print('BindToClose')
if RunService:IsStudio() then -- (only needed inside Studio)
wait(3) -- this will force the "SetAsync" above to complete
end
end)
Thanks in advance, any help is really appreciated!
itemdata = HTTP:JSONDecode(item_data:GetAsync(Player.UserId) or "0")
itemdata = HTTP:JSONDecode(itemdata)
Not sure why you decode it twice here but take a look at or "0". That means itemdata might end up as 0
itemdata:SetAsync(Player.UserId,item_json)
And here you try to call it. That's why it complains about calling a number.
I assume you meant to use item_data, which is a DataStore. Please use more descriptive names here to avoid such confusion :)
I'm trying to make a DB and I'm still in testing phrase, but it doesn't work.
Basically the error is, I want it so if I type: ModuleScript:GetDB("salvage").Set("key", "value"), it would return a value, but it doesn't due to an error.
Any help is highly appreciated.
Error:
Photo
Server Script:
local ModuleScript = require(game.ServerStorage.ModuleScript)
game.Players.PlayerAdded:Connect(function(p)
p.Chatted:Connect(function(msg)
if msg == "t" then
print("lol")
print(ModuleScript:GetDB("salvage"))
ModuleScript:GetDB("salvage").Set("key", "value")
end
end)
end)
Module script:
--Variables
local dss = game:GetService("DataStoreService")
-- Tables
local greenwich = {}
local dbFunctions = {}
--Functions
function greenwich:GetDB(name)
local db = dss:GetDataStore(name)
local new = {}
new.store = db
coroutine.resume(coroutine.create(function()
for k, v in ipairs(dbFunctions) do
new[k] = function(...)
local args = { ... }
v(new.store, unpack(args))
end
end
end))
print(new.store.Name, name)
return new
end
function dbFunctions:Set(store, key, value)
print(value)
return value
end
--Returning everything.
return greenwich
Thanks in advance.
ModuleScript:GetDB("salvage") returns new which does not have a field Set so you cannot call ModuleScript:GetDB("salvage").Set("key", "value)
Set is a field of dbFunctions. You run a generic for loop over it using the ipairs iterator. dbFunctions is not a seqence, hence ipairs does not work for it. Use pairs instead.
I wanted it to teleport to a private server but it wont teleport and it doesn't show any errors.
Here's the code:
local TeleportService = game:GetService("TeleportService")
local Players = {}
local GamePlayers = game:GetService("Players")
local IsTeleporting = false
local PlayersAllowed = script.Parent.Lobby.Teleporter.MaxPlayers
local function Teleport()
if #Players > 0 then
local TeleportPlayers = {}
for i = 1, #Players do
local I = i
if game.Players:FindFirstChild(Players[i]) then
table.insert(TeleportPlayers, GamePlayers:FindFirstChild(Players[i]))
TransitionEvent:FireClient(GamePlayers:FindFirstChild(Players[i]))
else
table.remove(Players, i)
end
end
wait(0.5)
IsTeleporting = true
pcall(function()
TeleportService:TeleportPartyAsync(TeleportID, TeleportPlayers)
end)
wait(0.5)
IsTeleporting = false
end
end
Any help would be appreciated!
it doesn't show any errors.
pcall(function()
print("function called")
error("an error occurred!")
print("this will not be reached")
end)
This will print "function called". Nothing else. No error shown.
From the Lua 5.4 Reference Manual:
pcall (f [, arg1, ยทยทยท])
Calls the function f with the given arguments in protected mode. This
means that any error inside f is not propagated; instead, pcall
catches the error and returns a status code. Its first result is the
status code (a boolean), which is true if the call succeeds without
errors. In such case, pcall also returns all results from the call,
after this first result. In case of any error, pcall returns false
plus the error object. Note that errors caught by pcall do not call a
message handler.
Check pcall's return values to see if the function ran successfully.
Compare your code to Roblox's example:
local Players = game:GetService("Players")
local TeleportService = game:GetService("TeleportService")
local placeId = 0 -- replace
local playerList = Players:GetPlayers()
local success, result = pcall(function()
return TeleportService:TeleportPartyAsync(placeId, playerList)
end)
if success then
local jobId = result
print("Players teleported to "..jobId)
else
warn(result)
end
So im new to data storing on roblox from tutorials this is what I have come up with I use prints to figure out everything runs fine just on the player removing function when its supposed to save the data it always returns nil and dosent save ive tried over and over can someone explain to me what im doing wrong?
ive tried changing multiple things for about two days now I just want to figure this out.
game.Players.PlayerRemoving:connect(function(plyr)
succsess, err = pcall(function()
if succsess then
local ttt = plyr.PlayerGui:findFirstChild("SavedSpot")
savespot:SetAsync(plyr.UserId.."-SaveNumber",ttt.Value)
print("Saved")
else
warn(err)
print("No Save")
end
playersleft = playersleft - 1
be:Fire()
end)
end)
the player enters the game the data tries to load if the player has never played the data returns nil and makes the value 1 I have separate code in a block when you touch it to set the value to two when the person leaves e.g. the player removing function I want it to save the value two and then load it when the player enters again my only error message I receive is nil
heres the full code incase you need it
local ds = game:GetService("DataStoreService")
local savespot = ds:GetDataStore("Spot")
local timesplyd = ds:GetDataStore("TimesPlayed")
local playersleft = 0
print("starting")
game.Players.PlayerAdded:connect(function(plyr)
playersleft = playersleft + 1
print("Loading")
plyr.CharacterAdded:connect(function(char)
repeat wait() until plyr.PlayerGui:findFirstChild("SavedSpot")
repeat wait() until char:findFirstChild("Humanoid")
local sss = plyr.PlayerGui:findFirstChild("SavedSpot")
local ss
print("Loaded")
local tp
su,er = pcall(function()
ss = savespot:GetAsync(plyr.UserId.."-SaveNumber")
if su then
print("Loaded")
elseif er then
print(er)
end
end)
if ss ~= nil then
sss.Value = ss
print(ss)
else
sss.Value = 1
print("1111111111111111111")
end
end)
end)
local be = Instance.new("BindableEvent")
game.Players.PlayerRemoving:connect(function(plyr)
succsess, err = pcall(function()
if succsess then
local ttt = plyr.PlayerGui:findFirstChild("SavedSpot")
savespot:SetAsync(plyr.UserId.."-SaveNumber",ttt.Value)
print("Saved")
else
warn(err)
print("No Save")
end
playersleft = playersleft - 1
be:Fire()
end)
end)
game:BindToClose(function()
be.Event:Wait()
end)
Make sure you're running the code in a Script and not a LocalScript.
Also, you probably shouldn't try to check if there was no errors from inside the pcall statement. Also, SetAsync is supposed to return nil.
success, err = pcall(function()
local ttt = plyr.PlayerGui:findFirstChild("SavedSpot")
savespot:SetAsync(plyr.UserId .. "-SaveNumber", ttt.Value)
end)
if(success) then
print("Saved successfully!")
else
print("Save error!")
warn(err)
end
I'm trying to make a datastore and change the value of player data, but I am having an issue getting the script to run the function. I will paste the code I'm having issues with and mark the lines giving errors. I apologize for any rookie mistakes, this'll be my first time programming a game with Lua and on Roblox. I think it may be an issue with how I call the statName and how a statName of "Wheat" isn't there, but I don't know how to call it otherwise, or why it isn't there.
This is the relevant stuff from the modulescript:
function PlayerStatManager:ChangeStat(player, statName, value)
local playerUserId = "Player_" .. player.UserId
assert(typeof(sessionData[playerUserId][statName]) == typeof(value), "ChangeStat error: types do not match") <--this line
if typeof(sessionData[playerUserId][statName]) == "number" then
sessionData[playerUserId][statName] = sessionData[playerUserId][statName] + value
else
sessionData[playerUserId][statName] = value
end
end
-- Function to add player to the 'sessionData' table
local function setupPlayerData(player)
local playerUserId = "Player_" .. player.UserId
local data
local success, err = pcall(function()
playerData:UpdateAsync(playerUserId, function(playerData)
data = playerData
end)
end)
if success then
if data then
-- Data exists for this player
sessionData[playerUserId] = data
else
-- Data store is working, but no current data for this player
sessionData[playerUserId] = {Money=0, Wheat=0, Silo=0, Feeders=0, Chickens=0}
end
else
warn("Cannot set up data for player!")
end
end
This is the relevant stuff from the script using the modulescript:
local SrvrStats = require(game.ServerStorage.moduleScript)
SrvrStats:ChangeStat(player, 'Wheat', playerWheat.Value) <-- this line
Try This:
local PlayerStatManager = {}
PlayerStatManager.ChangeStat = function(player, statName, value)
local playerUserId = "Player_" .. player.UserId
assert(typeof(sessionData[playerUserId][statName]) == typeof(value), "ChangeStat error: types do not match") <--this line
if typeof(sessionData[playerUserId][statName]) == "number" then
sessionData[playerUserId][statName] = sessionData[playerUserId][statName] + value
else
sessionData[playerUserId][statName] = value
end
end
-- Function to add player to the 'sessionData' table
PlayerStatManager.setupPlayerData = PlayerStatManager(player)
local playerUserId = "Player_" .. player.UserId
local data
local success, err = pcall(function()
playerData:UpdateAsync(playerUserId, function(playerData)
data = playerData
end)
end)
if success then
if data then
-- Data exists for this player
sessionData[playerUserId] = data
else
-- Data store is working, but no current data for this player
sessionData[playerUserId] = {Money=0, Wheat=0, Silo=0, Feeders=0, Chickens=0}
end
else
warn("Cannot set up data for player!")
end
end
return PlayerStatManager