You don’t need pcalls, and you can use the same data store.
Creator Hub - Store
Discover millions of assets made by the Roblox community to accelerate any creation task.
You don’t need pcalls, and you can use the same data store.
My script is erroring.
Error message: 17:42:42.322 - ServerScriptService.save_script:92: attempt to index nil with ‘Get’
Other messages:
17:42:47.663 - Data store main was not saved as it was not updated.
Both messages happen at the same time.
DataStore2 = require(game:GetService("ServerScriptService").DataStore2)
ServerStorage = game:GetService("ServerStorage")
Players = game:GetService("Players")
default_omega_coins, default_likes, default_wins = 0, 0, 0
default_bunker_terrain_position = {
CFrame.new(26.927, -33.383, -435.507),
CFrame.new(26.927, 23.365, -572.788),
CFrame.new(164.479, 23.365, -434.153),
CFrame.new(-110.625, 23.365, -435.236),
CFrame.new(25.844, 23.365, -297.955)
}
default_bunker_terrain_size = {
Vector3.new(277.27, 8.143, 277.27),
Vector3.new(277.27, 108.309, 2.708),
Vector3.new(2.166, 108.309, 274.562),
Vector3.new(2.166, 108.309, 272.396),
Vector3.new(275.104, 108.309, 2.166)
}
default_bunker_terrain_rotation = {
CFrame.Angles(0, 0, 0),
CFrame.Angles(0, 0, 0),
CFrame.Angles(0, 0, 0),
CFrame.Angles(0, 0, 0),
CFrame.Angles(0, 0, 0)
}
default_bunker_materials = {
"Mud",
"Rock",
"Rock",
"Rock",
"Rock"
}
default_object_name, default_object_position, default_object_rotation = {}, {}, {}
DataStore2.Combine("main", "Wins", "Ωmega Coins", "Likes", "object_name", "object_position", "object_rotation", "terrain-position", "terrain_rotation", "terrain_size", "terrain_materials")
Players.PlayerAdded:Connect(function(Player)
winsStore = DataStore2("Wins", Player)
coinStore = DataStore2("Ωmega Coins", Player)
likesStore = DataStore2("Likes", Player)
objectnameStore = DataStore2("object_name", Player)
objectpositionStore = DataStore2("object_position", Player)
objectrotationStore = DataStore2("object_rotation", Player)
terrainpositionStore = DataStore2("terrain-position", Player)
terrainrotationStore = DataStore2("terrain_rotation", Player)
terrainsizeStore = DataStore2("terrain_size", Player)
terrainmaterialsStore = DataStore2("terrain_materials", Player)
local leaderstats = Instance.new("Folder") do
leaderstats.Name = "leaderstats"
end
local wins = Instance.new("IntValue") do
wins.Name = "Wins"
wins.Parent = leaderstats
end
local omega_coins = Instance.new("IntValue") do
omega_coins.Name = "Ωmega $"
omega_coins.Parent = leaderstats
end
local likes = Instance.new("IntValue") do
likes.Name = "Likes"
likes.Parent = leaderstats
end
leaderstats.Parent = Player
function save_to_model(folder_name, target_location, CFrameoffset, pos,size,rot,mat)
local newMap = ServerStorage.empty_map:Clone() do
newMap.Name = folder_name
end
local terrain = newMap.terrain:WaitForChild("cubes")
for i, v in pairs(terrainmaterialsStore:Get(default_bunker_materials)) do
local Part = Instance.new("Part") do
Part.Name = v
Part.CFrame = pos[i]
Part.Size = size[i]
Part.Parent = terrain
end
end
newMap.Parent = target_location
end
end)
save_to_model("MrGuyROBLOX's Dungeon", game.Workspace.maps, 0, 0, 0, terrainpositionStore:Get(default_bunker_terrain_position), terrainsizeStore:Get(default_bunker_terrain_size), terrainrotationStore:Get(default_bunker_terrain_rotation,terrainmaterialsStore)) -- test function
Edit: Solved.
What is line 92?
Hi, this probably has been asked before but how would I use a plugin like Crazyman32’s Datastore Editor to edit people’s datastores saved in the default format of DataStore2?
If you search “datastore editor datastore2” you should have found this: Does CrazyMan's DataStore Editor work for DataStore2? - #6 by MFCmaster1234.
Hi, is it possible to use OrderedDataStores with this module?
I believe you need to use your own separate ordered data stores:
It works BUT, you need to use a seperate datastore as @Grargror said and doesn’t need to be that complicated:
https://gyazo.com/b72c32cc287523776ee3c8ebe471bafd
There is also a tutorial on how to create leaderboards if you need to, its in community resources I think.
My currency gui works but doesn’t update when I respawn do you know why?
replicatedStorage.UpdateClientCurrency.OnClientEvent:Connect(function(amount)
script.Parent.Text = "B$" .. amount
end)
Im currently trying to save a players play time. The problem is, it does not seem to save whatever I try. Lemme explain how my system looks. As soon as the player joins, os.time() is saved in a dictonary under the players UserId. The dictionary should look like this: {983190238 = 931290831902}
(Numbers aren’t correct). Next thing Im doing is connecting a Players.PlayerRemoving
event. This simply subtracts the join time value from os.time(). My script looks like this:
local Players = game:GetService("Players")
local SStorage = game:GetService("ServerStorage")
local Modules = SStorage:WaitForChild("Modules")
local DataStore2 = require(Modules.DataStore2)
local JoinTimes = {}
DataStore2.Combine("Data","Coins","PlayTime")
local function LoadLeaderstats(Player)
local PlayTimeData = DataStore2("PlayTime",Player)
JoinTimes[Player.UserId] = os.time()
local PlayTime = Instance.new("IntValue")
PlayTime.Name = "PlayTime"
PlayTime.Parent = Player
PlayTime.Value = PlayTimeData:Get(0)
end
local function OnPlayerRemoving(Player)
if JoinTimes[Player.UserId] then
local PlayTime = os.time() - JoinTimes[Player.UserId]
local PlayTimeData = DataStore2("PlayTime",Player)
JoinTimes[Player.UserId] = nil
PlayTimeData:Get()
PlayTimeData:Increment(PlayTime)
print(PlayTimeData:Get())
end
end
Players.PlayerAdded:Connect(LoadLeaderstats)
Players.PlayerRemoving:Connect(OnPlayerRemoving)
What I assume is that this is a timing problem, as DataStore2 probably also connects to a PlayerRemoving event. I still dont want to do something like:
while wait(1) do
PlayTimeData:Increment(1)
end
Did I make any mistakes in my code or is what I assume right? If so, is there another way to cope with this?
By the way, I would like to thank you for the effort you put into writing the module. It really helps me to prevent data loss (till now) and spares me the effort to write my own one.
Thanks in advance
Nova_MrRoyal
I’m not sure you completely understand DataStore2. Why are you storing a dictionary of the player’s user ID? The PlayTime
data store is exclusive to the player, that’s why you pass player
to the DataStore2 function in the first place. You should refactor this so it just saves the number.
I got a question, is it compatible if i placed in LeaderboardV3.
if kills.Value == kills +1 then
local e = DataStore2("points",humanoid)
e:Increment(100)
print(“Leaderboard script version 3.00 loaded”)
local ServerScriptService = game:GetService(“ServerScriptService”)
local DataStore2 = require(ServerScriptService.DataStore2)
function onPlayerEntered(newPlayer)
local stats = Instance.new("IntValue")
stats.Name = "leaderstats"
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
local kills = Instance.new("IntValue")
kills.Name = "Kills"
kills.Value = 0
local deaths = Instance.new("IntValue")
deaths.Name = "Deaths"
deaths.Value = 0
kills.Parent = stats
deaths.Parent = stats
points.Parent = stats
-- VERY UGLY HACK
-- Will this leak threads?
-- Is the problem even what I think it is (player arrived before character)?
while true do
if newPlayer.Character ~= nil then break end
wait(5)
end
local humanoid = newPlayer.Character.Humanoid
humanoid.Died:connect(function() onHumanoidDied(humanoid, newPlayer) end )
-- start to listen for new humanoid
newPlayer.Changed:connect(function(property) onPlayerRespawn(property, newPlayer) end )
stats.Parent = newPlayer
end
function Send_DB_Event_Died(victim, killer)
– killer may be nil
local killername = “no one”
if killer ~= nil then killername = killer.Name end
print("DIED EVENT: ", victim.Name, " KILLED by ", killername)
if shared["deaths"] ~= nil then
shared["deaths"](victim, killer)
print("SENT DB DEATH EVENT")
end
end
function Send_DB_Event_Kill(killer, victim)
print("KILL EVENT. ", killer.Name, " BLOXXED ", victim.Name)
if shared[“kills”] ~= nil then
shared[“kills”](killer, victim)
print(“SENT DB KILL EVENT”)
end
end
function onHumanoidDied(humanoid, player)
local stats = player:findFirstChild(“leaderstats”)
if stats ~= nil then
local deaths = stats:findFirstChild(“Deaths”)
deaths.Value = deaths.Value + 1
-- do short dance to try and find the killer
local killer = getKillerOfHumanoidIfStillInGame(humanoid)
Send_DB_Event_Died(player, killer)
handleKillCount(humanoid, player)
end
end
function onPlayerRespawn(property, player)
– need to connect to new humanoid
if property == "Character" and player.Character ~= nil then
local humanoid = player.Character.Humanoid
local p = player
local h = humanoid
humanoid.Died:connect(function() onHumanoidDied(h, p) end )
end
end
function getKillerOfHumanoidIfStillInGame(humanoid)
– returns the player object that killed this humanoid
– returns nil if the killer is no longer in the game
-- check for kill tag on humanoid - may be more than one - todo: deal with this
local tag = humanoid:findFirstChild("creator")
-- find player with name on tag
if tag ~= nil then
local killer = tag.Value
if killer.Parent ~= nil then -- killer still in game
return killer
end
end
return nil
end
function handleKillCount(humanoid, player)
local killer = getKillerOfHumanoidIfStillInGame(humanoid)
if killer ~= nil then
local stats = killer:findFirstChild("leaderstats")
if stats ~= nil then
local kills = stats:findFirstChild("Kills")
local points = stats:findFirstChild("Points")
if killer ~= player then
kills.Value = kills.Value + 1
points.Value = points.Value +1
if kills.Value == kills +1 then
local e = DataStore2("points",humanoid)
e:Increment(100)
end
else
kills.Value = kills.Value - 0
end
Send_DB_Event_Kill(killer, player)
end
end
end
game.Players.ChildAdded:connect(onPlayerEntered)
Hello, just wanted to ask if I’m understanding this correctly:
local ValueStore = DataStore2(Data, Player)
local Value = ValueStore:Get()
return Value[Data], Value, ValueStore -- Gets the value from data (a table)
local AchievementStore, Value, ValueStore = DataHandler.GrabData("DataThingy", Player, "Data thing from table")
AchievementStore["Data thing from table"] = true -- sets to true
ValueStore:Set(Value) -- Sets/saves it?
AchievementsStore:Get(DataTable["The data table"]) -- Is found inside main/playeradded, gets data from table?
Or is this wrong/a better way of doing so?
You need to set value, not the data store itself.
Is there a way for me to see the total length of the jsonencoded DATA table when I’m using this module? I want to see how much storage i’m using right now.
Here’s my post.
You should refactor this so it just saves the number.
I’m unsure what you mean. I think I am saving a number. I want to save a player’s play time. Therefore I need 2 times, namely JoinTime and LeaveTime, to calculate how long the player played. After that I’m increasing the current play time of the player by the time I calculated. It still does not seem to save,altough I can’t find a mistake.
My explanation in the post linked above might be misleading Is there something wrong in my code?
You’re saving a table with the player’s user id. You should just save a number.
I have recieved a message from roblox “Right To Erasure” meaning that I have to erase a player’s data from my datastores.
Is there a way to do this through datastore2?
I’ve read posts saying you can use a plugin Crazyman has made;
Discover millions of assets made by the Roblox community to accelerate any creation task.
Will this affect or conflict with any data saved by datastore2? I know Datastore2 internally uses normal datastores but I want to be sure.
For anyone dealing with GDPR, I believe this script I whipped up will work. Put this in your command bar then use
clear(userId, name)
(also in the command bar) to clear someone’s data.
Saw this post a bit too late, this has worked!
I am new to using Datastore2.
there is a function - Increment(value, defaultValue)
My question is, what is this default value used for; if when a player joins their value is set to the value defined by :Get(defaultValue) making the Increment() function’s defaultValue redundant?
Or is that defaultValue actually the default value to increment the value with when no Increment(Value) parameter is specified?