Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why am I not able to compare leaderstats with a local script?

I'm currently trying to make a pet shop GUI in my simulator game. I have a pet and this code works in the local script in the text button:

local pet = game.ReplicatedFirst.Part:Clone()
local plr = game.Players.LocalPlayer

script.Parent.MouseButton1Click:Connect(function()
		pet.Parent = plr.Character
end)

I'm trying to the script so that you need at least one "strength" (leaderstat) for this script to run. This is what I tried but it doesn't seem to work:

local pet = game.ReplicatedFirst.Part:Clone()
local plr = game.Players.LocalPlayer

script.Parent.MouseButton1Click:Connect(function()
	if  player.leaderstats.rebirths.Value >= 1 then
		pet.Parent = plr.Character
	end
end)

Can anyone help me?

1 comment

0

do you have more than one 'Part' in replicatedFirst?

1 answer

✓ Accepted answer

This is longer than I expected, so here's the uncopylocked game with a free BASIC follow pet script and a notification module.

Alright, while I don't know your exact problem because you haven't provided any output information; I can try and deduce what is wrong and explain how you can move forward and secure your code in the process to help save you from major headaches regarding the client-server model in ROBLOX.

Objects that you put in ReplicatedFirst run, well, absolutely first. You don't store storage objects there. As the contents of ReplicatedFirst replicate to the client before anything else in the game. it is ideal for creating loading GUIs or tutorials. In your case, a pet model does not meet this criteria, so it shouldn't be there. ReplicatedStorage is where you can store references to objects that need to be "Replicated" to the client. Both the client and server can see these objects. In your case however, unless you need to access this model from the client to show in a Viewport for instance, your pet models can be placed in ServerStorage, away from prying eyes. This also helps with lag, as anything placed in ReplicatedStorage will be replicated to the player.

*NEVER TRUST THE CLIENT to do anything regarding sanity checks that are going to give them leverage. The client is a liar, anything they say can and will be used against you. *

Think of me as bank teller and you as the customer. If you told me you had 1million dollars to withdraw, would I just give it to you or would I look you up in the database first? I'm not going to trust you to tell me what you have; I'm going to verify your balance and I'm going to verify you are who you say you are.

When you are asking the player if they enough rebirths to unlock the pet, all a player has to do is change their leaderstats, which can be done very easily. Instead, what you can and should do is keep this check, but then also fire a RemoteEvent to the server that checks again and handles the rest on the server.

LocalScript in your GUI

local LocalPlayer = game.Players.LocalPlayer
local leaderstats = LocalPlayer:WaitForChild("leaderstats")
local rebirths = leaderstats:WaitForChild('rebirths')
local button = script.Parent

local PetGiverEvent = game:GetService("ReplicatedStorage"):WaitForChild('PetGiver')
local NotificationEvent = game:GetService("ReplicatedStorage"):WaitForChild('Notification')

NotificationEvent.OnClientEvent:Connect(function(msg)
	print ( msg ) 
end)

button.MouseButton1Down:Connect(function()
	if rebirths.Value >= 100 then
		PetGiverEvent:FireServer('Dragon') 
	end
end)

Script in ServerScriptService


local PetStorage = game:GetService('ServerStorage').Pets
local RemoteEvent = game:GetService("ReplicatedStorage").PetGiver
local NotificationModule = require ( script.Notification )
local Pets = {
	['Dragon'] = { Pet = PetStorage:WaitForChild("Dragon"), Cost = 100 } 
}

local PlayerPets = {}

local function Assign(Player, newPet)
	-- Delete old assigned pet to make way for new pet
	if PlayerPets[Player.Name] then 
		PlayerPets[Player.Name]:Destroy()
	end
	-- Get previous pet name or newPet from Pets
	local Pet = newPet and Pets[newPet].Pet:Clone() or Pets[PlayerPets[Player.Name].Name].Pet:Clone()
	-- Give pet
	Pet.Parent = Player.Character
	-- Assign pet
	PlayerPets[Player.Name] = Pet
	-- SetNetworkOwner erorrs if Parent doesn't exist yet
	repeat wait() until Player.Character
	Pet.PrimaryPart:SetNetworkOwner(Player)
end

RemoteEvent.OnServerEvent:Connect(function(PlayerWhoFired, PetName)
	assert(PetName, 'Provide a PetName')
	assert(typeof(PetName) == 'string', 'PetName has to be a string!')
	local MatchingKey = Pets[PetName]
	-- is the pet even real? Client could have lied
	if Pets[PetName] then 
		local leaderstats = PlayerWhoFired:FindFirstChild("leaderstats")
		local rebirths = leaderstats and leaderstats:FindFirstChild("rebirths")
		-- Are our rebirths actually >= to the requirement? 
		if rebirths then 
			if rebirths.Value >= MatchingKey.Cost then 
				-- They are, assign the new pet.
				Assign(PlayerWhoFired, PetName)
			else
				-- Are not, notify client they lost the battle
				NotificationModule.Message(PlayerWhoFired, "You don't have enough")
			end		
		end
	else
		-- Pet isn't real
		NotificationModule.Message(PlayerWhoFired, 'That pet does not exist')
	end
end)

game.Players.PlayerAdded:Connect(function(Player)
	script.leaderstats:Clone().Parent = Player
	Player.CharacterAdded:Connect(function(character)
		-- give them their pet each time they respawn
		if PlayerPets[Player.Name] then
			Assign(Player)
		end
	end)
end)

game.Players.PlayerRemoving:Connect(function(Player)
	-- clean up referance 
	PlayerPets[Player.Name] = nil
end)

4 comments

0

Thank you so much!

0

Azarth there is one problem, the pet sometimes gets stuck in the ground when you spawn/buy it.

0

Make sure CanCollide is off on the parts.

0

I did

This discussion is preserved as it was. New answers, comments, and votes are closed.