How to make this script work without rejoining

Please help me doing this script work without rejoining

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		if game.MarketplaceService:PlayerOwnsAsset(player,12866752) then
			character.Humanoid.WalkSpeed = 25
		end
	end)
end)

I’m not a big time scripter so I’m not sure if this would work, but try rephrasing the script to something like:


game.Players.PlayerAdded:Connect(function(player)

local owner = false

if game:GetService(“MarketplaceService”):UserOwnsGamePassAsync(player.UserId, 12866752) then 
owner = true

player.CharacterAdded:Connect(function(character)
if owner == true then character.Humanoid.WalkSpeed = 25
end
end
end)
end)

I eyeballed this script so I’m not 100% certain if it will fix your issue, but it should work.

That script will give everyone 25 walkspeed if 1 player owns the gamepass. You should move the owner variable inside the playerAdded event.

2 Likes

Alright, thanks for letting me know, it’s 2 am so I can’t think properly. :sweat_smile:

Currently you’re just checking whether they have it when they join. Give them the walk speed when you have confirmed that they have bought it.

This script checks when a child is added to a workspace (for example character when it respawns or joins) and so it would check in players if the child’s name that was added could be found. If it is then it checks the rest.

I wrapped “PlayerOwnsAsset” in pcall function to prevent script breaking, since sometimes Roblox’s API’s are down. Keep in mind that this script could be improved if your checking more then one asset.

Hope it helps!

local AssetId = 1088037915
local AssetName = "Frightful Blade of Bone"

local MarketplaceService = game:GetService("MarketplaceService")
local PlayerOwnsAsset = MarketplaceService.PlayerOwnsAsset

workspace.ChildAdded:Connect(function(child)
	local player = game.Players:FindFirstChild(child.Name)
	if player then
		local success, doesPlayerOwnAsset = pcall(PlayerOwnsAsset, MarketplaceService, player, AssetId)
		if doesPlayerOwnAsset then
			print(player.Name .. " owns " .. AssetName)
		else
			print(player.Name .. " doesn't own " .. AssetName)
		end
	end
end)

Instead of this I suggest the following:

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		while wait(.1) do
			if game.MarketplaceService:PlayerOwnsAsset(player,12866752) then
				character.Humanoid.WalkSpeed = 25
				break
			end
		end
	end)
end)

This is the general logic you want to use

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

local Bought = false

Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		if MarketplaceService:PlayerOwnsAsset(Player, 12866752) or Bought == true then
			Character.Humanoid.WalkSpeed = 25
		end
	end)
end)

Pretty sure MarketplaceService caches the result of what it finds the first time, so if the Player purchases the asset after they join, it will continue to return that they do not have it. The alternative to this is prompting the purchase in-game. When they buy the asset in-game (however you want to manage that) tick the Bought variable to true so the Player can immediately reap the benefits.

Quick notes from some of the other solutions/replies.

A pcall should be used for the PlayerOwnsAsset function. You want to be able to prevent HTTP errors.
Don’t use loops for this, all of it can be done with events.
Don’t fire an event when a child is added to workspace - PlayerAdded and CharacterAdded exist for a reason and if you’re only looking for new Character’s spawning, just use those.

You are using playerownsasset incorrectry…
instead, use MarketplaceService | Documentation - Roblox Creator Hub.