I’m currently trying to remake the data system my tower defense game uses with ProfileStore and I was wondering if this is correct? I’m still new to how this module works so I would appreciate any help!!
New Datastore Script:
local profileStore = require(game.ReplicatedStorage.Modules.ProfileStore)
local runService = game:GetService("RunService")
local badgeService = game:GetService("BadgeService")
local marketPlaceService = game:GetService("MarketplaceService")
local dataStoreService = game:GetService("DataStoreService")
local oldDatabase = dataStoreService:GetDataStore("dataTest")
local PROFILE_TEMPLATE = {
Coins = 50,
Level = 1,
XP = 0,
RequiredXP = 100,
Inventory = {
SelectedTowers = {"Bowsman X1"},
OwnedTowers = {"Bowsman X1"},
OwnedSkins = {},
SelectedSkins = {},
},
Triumphs = 0,
Losses = 0,
}
local PlayerStore = profileStore.New("PlayerStore", PROFILE_TEMPLATE)
local function migratePlayerData(userId)
local success, oldData = pcall(function()
return oldDatabase:GetAsync(tostring(userId))
end)
if success and oldData then
print("Old data found for userId:", userId)
local newData = {
Coins = oldData.Stars or PROFILE_TEMPLATE.Coins,
Level = oldData.Level or PROFILE_TEMPLATE.Level,
XP = oldData.Exp or PROFILE_TEMPLATE.XP,
RequiredXP = oldData.RequiredExp or PROFILE_TEMPLATE.RequiredXP,
Inventory = {
SelectedTowers = oldData.SelectedTowers or PROFILE_TEMPLATE.Inventory.SelectedTowers,
OwnedTowers = oldData.OwnedTowers or PROFILE_TEMPLATE.Inventory.OwnedTowers,
OwnedSkins = oldData.OwnedSkins or PROFILE_TEMPLATE.Inventory.OwnedSkins,
SelectedSkins = oldData.SelectedSkins or PROFILE_TEMPLATE.Inventory.SelectedSkins,
},
Triumphs = oldData.Triumphs or PROFILE_TEMPLATE.Triumphs,
Losses = oldData.Losses or PROFILE_TEMPLATE.Losses,
}
local profile = PlayerStore:StartSessionAsync(`{userId}`, {
Cancel = function()
return false
end,
})
if profile then
profile.Data = newData
profile:Reconcile()
profile:EndSession()
print("Data migrated successfully for userId:", userId)
else
warn("Failed to start session for userId:", userId)
end
else
print("No old data found for userId:", userId)
end
end
game.Players.PlayerAdded:Connect(function(player)
local userId = player.UserId
migratePlayerData(userId)
end)
Old Datastore Script:
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local BadgeService = game:GetService("BadgeService")
local markeetplace = game:GetService("MarketplaceService")
local database = DataStoreService:GetDataStore("dataTest")
local towers = require(ReplicatedStorage:WaitForChild("TowerShop"))
local MAX_SELECTED_TOWERS = 6
local data = {}
local function givetower(player, tower)
local playerData = data[player.UserId]
if not table.find(playerData.OwnedTowers, tower) then
table.insert(playerData.OwnedTowers, tower)
else
return
end
end
--Load the player's data.
local function LoadData(player)
local success = nil
local playerData = nil
local attempt = 1
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
repeat
success, playerData = pcall(function()
return database:GetAsync(player.UserId)
end)
attempt += 1
if not success then
warn(playerData)
task.wait(1)
end
until success or attempt == 3
if success then
print("Connection Success!")
if not playerData then
print("New player, giving default data")
playerData = {
["Stars"] = 50,
["SelectedTowers"] = {"Bowsman X1"},
["OwnedTowers"] = {"Bowsman X1"},
["Level"] = 0,
["Exp"] = 0,
["RequiredExp"] = 100,
["Triumphs"] = 0,
["Losses"] = 0,
["OwnedSkins"] = {},
["SelectedSkins"] = {}
}
end
data[player.UserId] = playerData
if player.Name=="RoboNinjaYTpl" then
playerData = {
["Stars"] = 9999999,
["SelectedTowers"] = {"Bowsman X1"},
["OwnedTowers"] = {"Bowsman X1"},
["Level"] = 0,
["Exp"] = 0,
["RequiredExp"] = 100,
["Triumphs"] = 0,
["Losses"] = 0,
["OwnedSkins"] = {},
["SelectedSkins"] = {}
}
data[player.UserId]=playerData
end
if not data[player.UserId]["Level"] then
data[player.UserId]["Level"] = 1
data[player.UserId]["Exp"] = 0
data[player.UserId]["RequiredExp"] = 100
end
if not data[player.UserId]["Triumphs"] then
data[player.UserId]["Triumphs"] = 0
data[player.UserId]["Losses"] = 0
end
if not data[player.UserId]["SelectedSkins"] then
data[player.UserId]["SelectedSkins"] = {}
data[player.UserId]["OwnedSkins"] = {}
end
if player.Name=="devvres" then
data[player.UserId].Stars=10000000
table.insert(data[player.UserId].OwnedSkins, "Devvres Sub Machine")
table.insert(data[player.UserId].OwnedSkins, "Sheep Boomboxer")
table.insert(data[player.UserId].OwnedSkins, "Bighead Mercenary")
table.insert(data[player.UserId].OwnedSkins, "10 Hour Executor")
table.insert(data[player.UserId].OwnedSkins, "Arctic Frost Shooter")
--table.insert(data[player.UserId].OwnedSkins, "Deadeye?")
--table.insert(data[player.UserId].OwnedSkins, "Bowsman?")
end
if string.lower(player.Name)=="roboninjaytplacc2" then
data[player.UserId].Stars=10000000
end
if player.Name == "NOKIA23716" then
data[player.UserId].Stars=100000
end
if player.Name=="devvingRN" then
data[player.UserId].Stars=100000
end
if player.Name=="realcixors" then
data[player.UserId].Stars=32323232
table.insert(data[player.UserId].OwnedSkins, "Sheep Boomboxer")
table.insert(data[player.UserId].OwnedSkins, "Devvres Sub Machine")
table.insert(data[player.UserId].OwnedSkins, "Arctic Frost Shooter")
table.insert(data[player.UserId].OwnedSkins, "Bowsman?")
end
if player.Name=="raelgoob" then
data[player.UserId].Stars=10000000
table.insert(data[player.UserId].OwnedSkins, "Devvres Sub Machine")
table.insert(playerData.OwnedTowers, "Bloxxer X1")
table.insert(data[player.UserId].OwnedSkins, "10 Hour Executor")
table.insert(data[player.UserId].OwnedSkins, "Deadeye?")
table.insert(data[player.UserId].OwnedSkins, "Bowsman?")
end
while task.wait() and data[player.UserId] do
if data[player.UserId]["Level"] and data[player.UserId]["Exp"] and data[player.UserId]["RequiredExp"] then
if playerData.Exp >= playerData.RequiredExp then
playerData.Exp = playerData.Exp - playerData.RequiredExp
playerData.Level += 1
playerData.RequiredExp = 155 + (playerData.Level * 1.5)
end
else
wait(playerData.Level and playerData.Exp and playerData.RequiredExp)
if playerData.Exp >= playerData.RequiredExp then
playerData.Exp = playerData.Exp - playerData.RequiredExp
playerData.Level += 1
playerData.RequiredExp = 155 + (playerData.Level * 1.5)
end
end
end--]]
if BadgeService:UserHasBadgeAsync(player.UserId, 2153889525) then -- Replace with your badge Id
if not table.find(playerData.OwnedTowers, "Deadeye X1") then
table.insert(playerData.OwnedTowers, "Deadeye X1")
end
end
if BadgeService:UserHasBadgeAsync(player.UserId, 1032409634298595) then -- Replace with your badge Id
if not table.find(playerData.OwnedSkins, "Bighead Mercenary") then
table.insert(playerData.OwnedSkins, "Bighead Mercenary")
else
print("this player has bighead skin!!")
end
end
if BadgeService:UserHasBadgeAsync(player.UserId, 3803315976370583) then -- Replace with your badge Id
if not table.find(playerData.OwnedTowers, "Bloxxer X1") then
table.insert(playerData.OwnedTowers, "Bloxxer X1")
end
end
if BadgeService:UserHasBadgeAsync(player.UserId, 3803315976370583) then -- Replace with your badge Id
if not table.find(playerData.OwnedTowers, "Bloxxer X1") then
table.insert(playerData.OwnedTowers, "Bloxxer X1")
end
end
-- if BadgeService:UserHasBadgeAsync(player.UserId, 2153788838) or player.UserId == 1090530019 then -- Replace with your badge Id
-- if not table.find(data[player.UserId].OwnedSkins, "10 Hour Executor") then
-- table.insert(data[player.UserId].OwnedSkins, "10 Hour Executor")
-- end
--end
if BadgeService:UserHasBadgeAsync(player.UserId, 703372011984396) then -- Replace with your badge Id
if not table.find(playerData.OwnedSkins, "Deadeye?") then
table.insert(playerData.OwnedSkins, "Deadeye?")
end
if not table.find(playerData.OwnedSkins, "Bowsman?") then
table.insert(playerData.OwnedSkins, "Bowsman?")
end
end
if markeetplace:UserOwnsGamePassAsync(player.UserId, 138357039) then -- Replace with your badge Id
if not table.find(playerData.OwnedSkins, "Deadeye?") and not table.find(playerData.OwnedSkins, "Bowsman?") then
table.insert(playerData.OwnedSkins, "Deadeye?")
table.insert(playerData.OwnedSkins, "Bowsman?")
end
end
if markeetplace:UserOwnsGamePassAsync(player.UserId, 663320679) then -- Replace with your badge Id
if not table.find(playerData.OwnedTowers, "Vulcan X1") then
table.insert(playerData.OwnedTowers, "Vulcan X1")
end
end
if player.UserId == 171709662 or player.UserId == 2465383027 or player.UserId == 954079762 then -- Replace with your badge Id
if not table.find(playerData.OwnedSkins, "Sheep Boomboxer") then
table.insert(playerData.OwnedSkins, "Sheep Boomboxer")
end
end
local CoinStats = Instance.new("NumberValue")
CoinStats.Name = "Coins"
CoinStats.Value = playerData.Stars
CoinStats.Parent = leaderstats
local winStats = Instance.new("NumberValue")
winStats.Name = "🏆Triumphs🏆"
winStats.Value = playerData.Triumphs
winStats.Parent = leaderstats
local loseStats = Instance.new("NumberValue")
loseStats.Name = "💀Losses💀"
loseStats.Value = playerData.Losses
loseStats.Parent = leaderstats
--local levelStats = Instance.new("IntValue")
--levelStats.Name = "Level"
--levelStats.Value = playerData.Level
--levelStats.Parent = leaderstats
else
warn("Unable to get data for player ", player.UserId)
player:Kick("There was an issue retrieving your data.")
end
end
Players.PlayerAdded:Connect(function(player)
LoadData(player)
end)
--Save the players data
local function SaveData(player)
if data[player.UserId] then
local success = nil
local playerData = nil
local attempt = 1
repeat
success, playerData = pcall(function()
return database:UpdateAsync(player.UserId, function()
return data[player.UserId]
end)
end)
attempt += 1
if not success then
warn(playerData)
task.wait(1)
end
until success or attempt == 3
if success then
print("Data Saved!")
else
warn("Unable to save data for player ", player.UserId, " :(")
end
else
warn("No session data for ", player.UserId)
end
end
Players.PlayerRemoving:Connect(function(player)
SaveData(player)
data[player.UserId] = nil
end)
game:BindToClose(function()
if not RunService:IsStudio() then
for index, player in pairs(Players:GetPlayers()) do
task.spawn(function()
SaveData(player)
end)
end
else
print("Shutting down inside studio.")
end
end)
local function getItemStatus(player,itemName,skin)
local playerData=data[player.UserId]
if not skin then
if table.find(playerData.SelectedTowers, itemName) then
return "Equipped"
elseif table.find(playerData.OwnedTowers, itemName) then
return "Owned"
else
return "For Sale"
end
else
local can=true
for i, skin in pairs(playerData.SelectedSkins) do
if skin and skin.Name then
if skin.Name==itemName then
can=false
return "Equipped"
end
end
end
if can then
if table.find(playerData.OwnedSkins,itemName) then
return "Owned"
else
return "For Sale"
end
end
end
end
ReplicatedStorage.InteractItem.OnServerInvoke = function(player, itemName,skin,iscrate,crateprice)
ReplicatedStorage.InteractGui:FireClient(player)
local shopItem = towers[itemName]
if skin then
shopItem=require(ReplicatedStorage.SkinShop)[itemName]
end
local playerData = data[player.UserId]
if shopItem and playerData then
local status = getItemStatus(player, itemName,skin)
if not skin then
if status == "For Sale" and shopItem.Price <= playerData.Stars then
-- purchase
playerData.Stars -= shopItem.Price
table.insert(playerData.OwnedTowers, shopItem.Name)
local BadgeID = 0
if game:GetService("BadgeService"):UserHasBadgeAsync(player.UserId,BadgeID) then
print("Gave tower!")
end
elseif status == "Owned" then
-- equip the tower
table.insert(playerData.SelectedTowers, shopItem.Name)
if #playerData.SelectedTowers > MAX_SELECTED_TOWERS then
table.remove(playerData.SelectedTowers, 1)
end
elseif status == "Equipped" then
-- unselect the tower (if more than 1 selected)
if #playerData.SelectedTowers > 0 then
--print(playerData.SelectedTowers)
local towerToRemove = table.find(playerData.SelectedTowers, itemName)
table.remove(playerData.SelectedTowers, towerToRemove)
end
end
else
if iscrate then
if tonumber(crateprice)<=playerData.Stars then
playerData.Stars -= tonumber(crateprice)
table.insert(playerData.OwnedSkins, shopItem.Name)
end
else
if status == "For Sale" and shopItem.Price <= playerData.Stars then
-- purchase
playerData.Stars -= shopItem.Price
table.insert(playerData.OwnedSkins, shopItem.Name)
local BadgeID = 0
if game:GetService("BadgeService"):UserHasBadgeAsync(player.UserId,BadgeID) then
print("Gave tower!")
end
elseif status == "Owned" then
-- equip the tower
for i, skin in pairs(playerData.SelectedSkins) do
if skin.Name and skin.Tower then
if skin.Tower==shopItem.Tower then
playerData.SelectedSkins[skin.Name]=nil
end
end
end
playerData.SelectedSkins[shopItem.Name]={
["Name"]=shopItem.Name,
["Tower"]=shopItem.Tower,
}
elseif status == "Equipped" then
-- unselect the tower (if more than 1 selected)
for i, skin in pairs(playerData.SelectedSkins) do
if skin.Name and skin.Tower then
if skin.Tower==shopItem.Tower then
playerData.SelectedSkins[skin.Name]=nil
end
end
end
end
end
end
return playerData
else
warn("Tower/player data does not exist")
end
return false
end
--ReplicatedStorage.GetData.OnServerInvoke = function(player)
-- return data[player.UserId]
--end
ReplicatedStorage.GetData.OnServerInvoke = function(playerthing:Player, desired:boolean, desiredplayer:Player)
if desired == false then
return data[playerthing.UserId]
elseif desired == true then
return data[desiredplayer.UserId]
end
end
ReplicatedStorage.GetLevelData.OnInvoke = function(player)
return data[player.UserId]
end