Leaderstats is not a valid member of Player "player.alabamalover90001"

One sec… is this script inside like a part?

yes it is inside a part, it used to be a script, but i tried a local script but it didnt work, i’ll still use a normal script if it works.

Here I have a solution for you, just give me a second to test it out.

Oh wait a minute. This isn’t even that complicated. In your leaderstats script, make a condition if the player’s muscle thing value is greater than the amount you want it then the part’s can collide property is false.

I tested this code out in studio and it works perfectly.

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	local musclestuff = Instance.new("IntValue", leaderstats)
	musclestuff.Name = "MuscleCash"
	musclestuff.Value = 0
	if musclestuff.Value >= 10000 then
		game.Workspace.Part.CanCollide = false
		print("False")
	else
		print("Not enough")
	end
end)

Now, if you wanted to make these local, then you would want to use a remote event. Make a remote event inside replicated storage and then make a local script inside starter player scripts, and then type this code.

leaderstats script:

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	local musclestuff = Instance.new("IntValue", leaderstats)
	musclestuff.Name = "MuscleCash"
	musclestuff.Value = 0
	if musclestuff.Value >= 10000 then
		game.ReplicatedStorage.RemoteEvent:FireClient(player)
		print("False")
	else
		print("Not enough")
	end
end)

local script:

game.ReplicatedStorage.RemoteEvent.OnClientEvent:Connect(function()
	game.Workspace.Part.CanCollide = false
end)

Sorry for the long post but hope this helped you with your problem!

I tried the exact same thing as you did basically.

Basically, but I feel like you should use this method, especially because what you are doing currently isn’t working.

This is exactly the reason why your current code is failing though. Need to see that code.

1 Like

try this
game.Players.PlayerAdded:Connect(function(player)
if player:WaitForChild(“leaderstats”).MusclarCash.Value >= 10000 then
script.Parent.CanCollide = false
else
script.Parent.CanCollide = true
end
end)

The problem is that since it says “PlayerAdded”, it would only be available if you joined whilst having over 10000 value, it wouldn’t be available if you joined before you had 10000 value and just reached 10000 value, you should make it so you’d make a loop where it’ll see if the player will have more or less than 10000 or equal.

Also “MusclarCash”? You probably mispelled it, anyways fix your other scripts and answer people’s common sense questions so you’d get it finished rq.

So basically, my leaderstats script is a datastore + leaderstats, maybe that’s why, I don’t know.

local DService = game:GetService("DataStoreService"):GetDataStore("Game")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local MusclarCash = Instance.new("NumberValue")
	MusclarCash.Parent = leaderstats
	MusclarCash.Name = "MusclarCash"
	
	local Strength = Instance.new("NumberValue")
	Strength.Parent = leaderstats
	Strength.Name = "Strength"
	
	local Rebirths = Instance.new("NumberValue")
	Rebirths.Parent = leaderstats
	Rebirths.Name = "Rebirths"
	
	local debounce = Instance.new("BoolValue")
	debounce.Parent = player
	debounce.Name = "Debounce"
	
	if player.leaderstats.MusclarCash.Value >= 10000 then
		game.Workspace.GymDoor.CanCollide = false
		game.Workspace.GymDoor.Anchored = true
	else
		game.Workspace.GymDoor.CanCollide = true
	end
	
	local key = "user-"..player.UserId
	
	local storedItems = DService:GetAsync(key)
	
	if storedItems then
		MusclarCash.Value = storedItems[1]
		Strength.Value = storedItems[2]
		Rebirths.Value = storedItems[3]
	else
		local items = {MusclarCash.Value, Strength.Value, Rebirths.Value}
		
		DService:SetAsync(key, items)
	end
end)


game.Players.PlayerRemoving:Connect(function(player)
	local items = {player.leaderstats.MusclarCash.Value, player.leaderstats.Strength.Value, player.leaderstats.Rebirths.Value}
	
	local key = "user-"..player.UserId
	
	DService:SetAsync(key, items)
end)

I put it above the data store.

While in testing mode check to see if the values are inside a “leaderstats” folder inside the player (In Players). If there is all the data then your leaderstats will not be the problem, if in case it is the problem make sure you didn’t miss-spell anything.

Also maybe add and load the key before the statement:
take the "if player.leaderstats.MusclarCash.Value >= 10000 then
and put it under the “game.players.playerremoving” ( I meant after the entire thing so put it under the end).

erm, I could see that, and yes the leaderstats are still included in players, it is created before the if statement.

if the PlayerAdded event is working half the time, i suggest reading this post:

It isn’t working at all, I would try ChildAdded but I’m not sure about that instance.

Well by the looks of it you might be asking for something before its even loaded, pcall (to check if there was success) could be used to detect if its got the data, though I’m not a complete expert on pcall, it could be a sort of backup solution in case it fails.

hm, have you tried turning the PlayerAdded function into a local function?

local function playerAdded(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local MusclarCash = Instance.new("NumberValue")
	MusclarCash.Parent = leaderstats
	MusclarCash.Name = "MusclarCash"
	
	local Strength = Instance.new("NumberValue")
	Strength.Parent = leaderstats
	Strength.Name = "Strength"
	
	local Rebirths = Instance.new("NumberValue")
	Rebirths.Parent = leaderstats
	Rebirths.Name = "Rebirths"
	
	local debounce = Instance.new("BoolValue")
	debounce.Parent = player
	debounce.Name = "Debounce"
	
	if player.leaderstats.MusclarCash.Value >= 10000 then
		game.Workspace.GymDoor.CanCollide = false
		game.Workspace.GymDoor.Anchored = true
	else
		game.Workspace.GymDoor.CanCollide = true
	end
	
	local key = "user-"..player.UserId
	
	local storedItems = DService:GetAsync(key)
	
	if storedItems then
		MusclarCash.Value = storedItems[1]
		Strength.Value = storedItems[2]
		Rebirths.Value = storedItems[3]
	else
		local items = {MusclarCash.Value, Strength.Value, Rebirths.Value}
		
		DService:SetAsync(key, items)
	end
end)

game.Players.PlayerAdded:Connect(function(player)
       spawn(function() playerAdded(player) end) -- playerAdded is the local function and the parameter inside it is the player
end) -- spawn could possibly fix your issue

There are few errors in your latest script:

  1. You are checking if MusclarCash’s Value is greater than 10k before even loading player data from the DataStore, so it will be 0 by Default (I believe.) So what you should do instead is load the data first and then run your check.

I made the small change on this script here:

local DService = game:GetService("DataStoreService"):GetDataStore("Game")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local MusclarCash = Instance.new("NumberValue")
	MusclarCash.Parent = leaderstats
	MusclarCash.Name = "MusclarCash"
	
	local Strength = Instance.new("NumberValue")
	Strength.Parent = leaderstats
	Strength.Name = "Strength"
	
	local Rebirths = Instance.new("NumberValue")
	Rebirths.Parent = leaderstats
	Rebirths.Name = "Rebirths"
	
	local debounce = Instance.new("BoolValue")
	debounce.Parent = player
	debounce.Name = "Debounce"
	
	local key = "user-"..player.UserId
	
	local storedItems = DService:GetAsync(key)
	
	if storedItems then
		MusclarCash.Value = storedItems[1]
		Strength.Value = storedItems[2]
		Rebirths.Value = storedItems[3]
	else
		local items = {MusclarCash.Value, Strength.Value, Rebirths.Value}
		
		DService:SetAsync(key, items)
	end

        --Moved this if statement down here:
       if player.leaderstats.MusclarCash.Value >= 10000 then
		game.Workspace.GymDoor.CanCollide = false
		game.Workspace.GymDoor.Anchored = true
	else
		game.Workspace.GymDoor.CanCollide = true
	end
end)


game.Players.PlayerRemoving:Connect(function(player)
	local items = {player.leaderstats.MusclarCash.Value, player.leaderstats.Strength.Value, player.leaderstats.Rebirths.Value}
	
	local key = "user-"..player.UserId
	
	DService:SetAsync(key, items)
end)

Mm. So what you’re encountering is a race condition. The code you put forth is running ahead of leaderstats being created which results in the error because leaderstats doesn’t exist to that code yet: additionally, LocalScripts don’t run in the workspace if you were hoping to locally disable collisions with your special door. Doing it from the server would enable the room for everyone if someone with sufficient cash joined.

When working with PlayerAdded, I always recommend storing it in a function which you later have listen to PlayerAdded as well as run for any players who were in the game before the script finished connecting to PlayerAdded. As for creating leaderstats, you should avoid parenting the folder until you’ve created and parented the other stats values as well.

You can manage your door with a LocalScript in PlayerScripts which will change the collision based on the current cash and then remove the collision handler from the data loading script.

local Player = game:GetService("Players").LocalPlayer

-- We can assume MuscularCash exists when leaderstats does
local Leaderstats = Player:WaitForChild("leaderstats")
local MuscularCash = Leaderstats.MuscularCash

local GymDoor = workspace:WaitForChild("GymDoor")

local CASH_FOR_GYM = 10000

local function valueChanged(newValue)
    GymDoor.CanCollide = (newValue >= CASH_FOR_GYM)
end

MuscularCash.Changed:Connect(valueChanged)
valueChanged(MuscularCash.Value)

And your server script requires a few changes as well, particularly in the realm not only of the way you handle your PlayerAdded function but also how you’re managing your DataStores as well. Always remember to use pcall when working with DataStores so you can account for service failures.

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")

local PlayerData = DataStoreService:GetDataStore("Game")

-- These should not be saved if encountered during saving
local SESSION_VALUES = {"Debounce"}

-- We don't want to overwrite and cause data loss if DataStoreService is down
local shouldNotSave = {}

-- Handy utility function to serialise player data for saving
local function folderToDictionary(folder)
    local dictionary = {}

    for _, stat in ipairs(folder:GetChildren()) do
        if not table.find(SESSION_VALUES, stat.Name) then
            if stat:IsA("Folder") then
                dictionary[stat.Name] = folderToDictionary(stat)
            else
                dictionary[stat.Name] = stat.Value
            end
        end
    end

    return dictionary
end

local function playerAdded(player)
    local playerKey = "user-" .. player.UserId

    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"

    local muscularCash = Instance.new("IntValue")
    muscularCash.Name = "MuscularCash"
    muscularCash.Parent = leaderstats -- Never parent first!

    local strength = Instance.new("IntValue")
    strength.Name = "Strength"
    strength.Parent = leaderstats

    local rebirths = Instance.new("IntValue")
    rebirths.Name = "Rebirths"
    rebirths.Parent = leaderstats

    local debounce = Instance.new("BoolValue")
    debounce.Name = "Debounce"
    debounce.Parent = player

    -- No need to save data if the player has none, catch it in PlayerRemoving
    local success, data = pcall(PlayerData.GetAsync, PlayerData, playerKey)
    if success then
        if data then
            for key, value in pairs(data) do
                local stat = leaderstats:FindFirstChild(key)
                if stat then
                    stat.Value = value
                end
            end
        end
    else
        shouldNotSave[player] = true
        warn("Data could not be loaded for key " .. playerKey .. " - " .. data)
    end

    leaderstats.Parent = player
end

local function playerRemoving(player)
    local playerKey = "user-" .. player.UserId
    local leaderstats = player:FindFirstChild("leaderstats")
    -- Done this way to account for failed loads and to make data
    -- easier to browse: for example, via a plugin, or code.
    if leaderstats and not shouldNotSave[player] then
        local data = folderToDictionary(leaderstats)
        local success, result = pcall(PlayerData.SetAsync, PlayerData, playerKey, data)
        if not success then
            warn("Failed to save for key " .. playerKey .. " - " .. result)
        end
    end
    shouldNotSave[player] = nil
end

Players.PlayerAdded:Connect(playerAdded)
Players.PlayerRemoving:Connect(playerRemoving)
for _, player in ipairs(Players:GetPlayers()) do
    playerAdded(player)
end

This is the exact problem!

It was printing I didn’t have enough because my data didn’t load!