its just easier with them. it makes it look less complex, however your not wrong, you can just do it without functions
do
Material = totype(part.Material.Name)
its just easier with them. it makes it look less complex, however your not wrong, you can just do it without functions
do
Material = totype(part.Material.Name)
which one?
to make them understand that you cant save parts with
Setasync(part)
thats why its mentioned
Dictionaries take up more space than a usual table, consider doing something like this instead.
function makeSaveableColor3(color3)
return {color3.R, color3.G, color3.B};
end
function makeColor3FromSaved(savedColor3)
return Color3.new(table.unpack(savedColor3));
end
ook thanks for suggesting ill use that next time
(lucky that i didnt use [“s”] for dictionaries as they take up much more space)
I have a partsaver that saves parts based off of their properties, all you have to do is pcall through all 400+ properties to see which it has and store the property name that succeeded as well as the value. This way you can save pretty much anything and everything with no errors. Also I would avoid using a table for a datastore because it takes up more characters, if you are saving high volumes of data that can slow things down.
Instead do table.concat() and use string.split() to seperate it out again to save usage.
Also to get the properties back to be usable like as vector3 e.c.t, i just pcall when im setting the property to see if it it is the correct type.
oh yeah but i still needed to mention it. dosent change the fact that its not good to put it there
why should i remove that to make people still think that
Setasync(part)
can save part.
actually, i think thats the good time to use dictionaries because pcalls arent efficient at all.
pcalls should only be used for web calls and datastores.
i might be wrong tho.
local MyData = game:GetService("DataStoreService"):GetDataStore("MyData")
local Players = game:GetService("Players")
local Part = workspace.Part
Players.PlayerRemoving:Connect(function(player)
local DataTable = {
X = Part.Position.X;
Y = Part.Position.Y;
Z = Part.Position.Z
}
MyData:UpdateAsync(player.UserId, function() return DataTable end)
end)
Players.PlayerAdded:Connect(function(player)
local SavedData = MyData:GetAsync(player.UserId)
if SavedData ~= nil then
Part.Position = Vector3.new(SavedData.X, SavedData.Y, SavedData.Z)
else
print("Data is nil")
end
end)
This is an example of how I save position, color, etc. And works really well.
But your idea is great too.
This looks like my tutorial mentioned by some player here
Just a correction:
Basically, RDBMS is the format used by huge companies like Roblox, UTF-8 is not a format
Note that, UTF-8 means a non-instance, or a value which is not an object
Its not a format for any data store, and 90% of the games of roblox which we see are objects
UI, blocks and scripts all of these are instances
Now you cannot save these directly, they are instances, not non-instances
And you need a primary key to save a data in a table of DataStore in Roblox
So, you need to make them into data which can be saved in data stores, which is a non-instance or UTF-8 characters
Sorry, but using too many functions is really a bad idea @regexman
And in my opinion what @ElVaranCubico_YT said was correct
Below is an example, why functions for saving is hard
Example 1 (Functions):
local function getmaterial(instance)
local stringtoreturn = tostring(instance.Material)
return stringtoreturn
end
local table = {
["Material"] = getmaterial(instance)
}
Both the methods work, but a 1 line script is better than a 4 line script
Example 2 (Normal):
local table = {
["Material"] = tostring(instance.Material)
}
See how easy it is
I’m not telling what you explained was wrong, but I’m just suggesting you to mention an easy way
i included it later in the step 1
Ok, ive used people’s suggestions that improved my tutorial thanks to @Deadwoodx
there might be a mistake in a tutorial, please quote so if you find one
How exactly would I use this to save the player’s position? I’ve attempted it with this method but I’ve obviously done it wrong.
Here is my code:
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("Position")
game.Players.PlayerAdded:Connect(function(plr)
local Character = plr.Character or plr.CharacterAdded:Wait()
local Root = Character:WaitForChild("HumanoidRootPart")
Position = {X = Root.CFrame.X, Y = Root.CFrame.Y, Z = Root.CFrame.Z}
local RetreveData = DataStore:GetAsync("plr") or nil
if RetreveData ~= nil then
Root.CFrame = CFrame.new(RetreveData.X, RetreveData.Y, RetreveData.Z)
end
end)
game.Players.PlayerRemoving:Connect(function()
DataStore:SetAsync("plr", Position)
end)
Thanks!
you should
char:SetPrimaryPartCFrame() instead
and save the humanoidrootpart position as vector3 not cframe
char:SetPrimaryPartCFrame(CFrame.new(Vector3.new(retrieveddata.X,retrieveddata.Y,retrieeveddata.Z)))
I’m not really good at datastore but… Aren’t you doing GetAsync(“plr”)? For what I’ve read on an article about it, you have to put the player.UserId, and you are just getting the data from the key “plr” (UserId is a key).
Try replacing "plr"
with plr
, actually, use plr.UserId
i think he just did it as a test. he isnt releasing it in a game i think.
okay, ill send you my old script that works, heres the script
local position = game:GetService("DataStoreService"):GetDataStore("PlayerPositions")
game.Players.PlayerAdded:Connect(function(plr)
local char = plr.Character or plr.CharacterAdded:Wait()
char:WaitForChild("Humanoid")
char:WaitForChild("HumanoidRootPart")
-- load position if data exists
local retrieveddata = position:GetAsync(plr.UserId) or nil
if retrieveddata ~= nil then
char:SetPrimaryPartCFrame(CFrame.new(Vector3.new(table.unpack(retrieveddata))))
print("Set primary part cframe")
end
task.wait(2)
while true do
print("Saving data")
position:SetAsync(plr.UserId,{char.HumanoidRootPart.Position.X,char.HumanoidRootPart.Position.Y,char.HumanoidRootPart.Position.Z})
task.wait(10)
end
end)