Okay, sorry it took me a while to respond, I’ve been busy the past few days. (Also sorry for the essay long scripts)
The system first starts with the PlayerDatabase Script in ServerScriptService
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local database = DataStoreService:GetDataStore("PlayerDatabase")
local data = {}
local function LoadData(player)
local success = nil
local playerData = nil
local attempt = 1
repeat
success, playerData = pcall(function()
return database:GetAsync(player.UserId)
end)
attempt += 1
if not success then
warn(playerData)
task.wait()
end
until success or attempt == 3
if success then
print("Connection success")
if not playerData then
print("New player ["..player.Name.."], giving default data")
playerData = {
["Yen"] = 0,
["OwnedTools"] = {},
["HotbarTools"] = {},
["OffHandTool"] = {},
["HotbarSize"] = 2,
["Inventory"] = {},
["Affiliation"] = "Tokyo-3 Citizen",
}
else
print(playerData.OwnedTools[1])
end
data[player.UserId] = playerData
else
warn("Unable to get data for player"..player.UserId)
player:Kick("There was a problem getting your data")
end
end
Players.PlayerAdded:Connect(LoadData)
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()
end
until success or attempt == 3
if success then
print("["..player.Name.."] Data saved successfully")
else
warn("Unable to save data for"..player.Name.." "..player.UserId)
end
else
warn("No session data for"..player.Name.." "..player.UserId)
end
end
ReplicatedStorage.Remotes.DeleteData.OnServerEvent:Connect(function(player)
data[player.UserId] = nil
database:RemoveAsync(player.UserId)
player:Kick("Data Deleted")
end)
Players.PlayerRemoving:Connect(function(player)
SaveData(player)
data[player.UserId] = nil
end)
ReplicatedStorage.Remotes.SaveData.OnServerEvent: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)
ReplicatedStorage.Remotes.GetData.OnServerInvoke = function(player)
return data[player.UserId]
end
This script should just initialize the individual data for each player and create functions related to that data.
Next is the ToolModule which handles data related to the weapons in game.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local equipment = ReplicatedStorage:WaitForChild("Equipment")
local ToolModule = {}
local ToolData = {
["Karambit Progressive Knife"] = {
["Name"] = "Karambit Progressive Knife",
["ToolId"] = 1,
["Model"] = equipment:WaitForChild("Karambit Progressive Knife")
}
}
function ToolModule.addToolToPlayer(toolId)
local playerData = ReplicatedStorage.Remotes.GetData:InvokeServer()
for i, tool in ipairs(ToolData) do
if tool.ToolId == toolId then
if not table.find(playerData.OwnedTools, tool) then
table.insert(playerData.OwnedTools, tool)
ReplicatedStorage.Remotes.SaveData:FireServer()
end
end
end
end
return ToolModule
This should just create the data for each future weapon and tool in game (only K Prog Knife exists right now). It should also be able to add the name for the weapon in the player’s OwnedTools table for later access.
This script is just in a part in workspace that allows the player to “collect” the weapon.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local proximityPrompt = script.Parent:WaitForChild("ProximityPrompt")
proximityPrompt.Triggered:Connect(function(player)
ReplicatedStorage.Remotes.AddTool:FireClient(player, 1)
end)
This next one is in StarterPlayerScripts
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ToolModule = require(ReplicatedStorage:WaitForChild("ToolModule"))
ReplicatedStorage.Remotes.AddTool.OnClientEvent:Connect(function(toolId)
ToolModule.addToolToPlayer(toolId)
end)
Then this script is inside of the PlayerGui for the equip menu
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ToolModule = require(ReplicatedStorage:WaitForChild("ToolModule"))
local player = game.Players.LocalPlayer
local function updateMenu()
print("WAdadwad")
local playerData = ReplicatedStorage.Remotes.GetData:InvokeServer()
local ownedTools = playerData.OwnedTools
print(ownedTools[1])
for i, tool in pairs(ownedTools) do
print(tool.Name)
print("Awdad")
if not script.Parent.EquipContainer:FindFirstChild(tool.Name) then
local newButton = script.Template:Clone()
local model = tool.Model:Clone()
newButton.Parent = script.Parent.EquipContainer
newButton.Name = tool.Name
newButton.Visible = true
model.Parent = newButton.Viewport
model.CFrame = newButton.Viewport.HandleAnchor.CFrame
end
end
end
ReplicatedStorage.Remotes.UpdateMenu.Event:Connect(function()
updateMenu()
end)
What happens is that after giving the player default data and then interacting with the part that fires the AddTool event, when the updateMenu function is called in the equip menu, the first print is seen just fine but then the second print on line 10 is printed as “nil”.
Opening the game again loads the player data just fine however the print on line 41 in the PlayerDatabase script also prints out as “nil”.
Again, sorry for the big heaps of code. I am not an expert programmer so this could be a simple solution that I oversighted, but I think it would be better to get a fresh perspective on my work.