Chat Shop Commands

I don’t really understand – why not use a shop GUI with an open/close button, and handle the verification of the purchase on the server? Using chat commands seems to overcomplicate this purpose and doesn’t seem very productive for a consumer, not to mention it would be easier to accomplish the former. Is there a reason for this choice in design?

1 Like

It just looks cool to me. That is the entire reason.

But seriously I just do not want to make a shop since there is not downtime at all inside the game, and I just want there to be a notification since it looks cool, instead of a giant box on your screen.

1 Like

That seems to have fixed it.

Also about that.

I scripted that inside of the little notification ‘if else’ statement. Did not seem to work at all (Also as of this edit I’m going to go eat)

if Reponse == "Yes" then
		if plr.leaderstats.Cash.Value >= 300 then
			plr.leaderstats.Cash.Value = plr.leaderstats.Cash.Value - 300
			local c = SS.Weapons["AK-47"]:Clone()
			c.Parent = plr.Backpack
		end	
	else
		print("Player canceled the purchase");
	end;
1 Like

It would be better to have an ID system of sorts and utilize a RemoteFunction to determine whether the player purchased the weapon or not.
For example,

local Weapons = {
    ["AK-47"] = 47, -- Weapon name, price of weapon
}

local function RetrieveWeaponData(Arg)
    for WeaponName, Price in pairs(Weapons) do
        if WeaponName:lower():find(Arg) == 1 then
            return WeaponName, Price
        end
    end
    return nil, nil
end
...

local Arg = Msg:lower():match("%!buy (%w+)")
if Arg then
    local WeaponName, _ = GetWeaponData(Arg)
    if WeaponName then
        local NewNotif = script.Notification:Clone()
        NewNotif.WantedWeapon.Value = Weapon
        NewNotif.TextLabel.Text = "Are you sure you want to buy [" .. Weapon .. "] ?"
        NewNotif.Parent = Player.PlayerGui
    end
end
...

PurchaseWeapon.OnServerInvoke = function(Player, WeaponName)
    local WeaponName, Price = GetWeaponData(WeaponName)
    -- Verify purchase on server, and give the specified weapon
end
1 Like

That seems like a smart idea although it looks extremely confusing and

Notifications don’t work like that

That notification system seems fine to me. Simply clone the notification parent it to the player’s PlayerGui folder somewhere (so that it’s correctly rendered onto the screen) and then modify the shown GuiObjects accordingly (alter text, images etc.).

Sorry, went to bed.

The reason why its not working is because you need to give the item on the Server not the client. To do this you would have to use RemoteEvent and/or RemoteFunctions.

So right click on replicatedStorage → insert a new object (aka a remoteEvent) → name that remote whatever you want → define that remote in your notification script → have it FireServer() when player buys an item → server listens for the event → server gives item

Do I need to make a separate event for every single item?

No, what you want to do is pass arguments to differentiate between task you want to do.

E.g on the client you might have something like:

local Remote = game:GetService("ReplicatedStorage").MyRemote

Remote:FireServer("AK-47", 1235) -- we can send arguments!!

On the server script you would do:

local Remote = game:GetService("ReplicatedStorage").MyRemote

Remote.OnServerEvent:Connect(function(Player, WeaponName, RandomNumbers)

print(Player, WeaponName, RandomNumbers)

end)

I’m on mobile so there may be typos and bad formatting.

So the only arguments you really want to be passing to the server is the name of the item the player purchased. The server will then use that name to search a folder to get said item. You then can deduct whatever cash and give the item.

So your telling me I just fire the server with the item the player wants to buy, and then have a server script handle the fired event?

Yes. All the client is going to do is fire the remote and provide the name of the item. The server will handle the rest (such as finding the item, giving it, and deducting points).

Like this?

local Remote = game:GetService("ReplicatedStorage").Purchase
local Folder = game:GetService("ServerStorage").Weapons

Remote.OnServerEvent:Connect(function(Player, Weapon)
	print(Player, Weapon)
	local c = Folder:FindFirstChild(Weapon):Clone()
	c.Parent = Player.BackPack
end)

Also here is what my Notification Script looks like now:

if Reponse == "Yes" then
		if plr.leaderstats.Cash.Value >= 300 then
			plr.leaderstats.Cash.Value = plr.leaderstats.Cash.Value - 300
			RS.Purchase:FireServer("AK-47")
		end	
	else
		print("Player canceled the purchase");
	end;
if plr.leaderstats.Cash.Value >= 300 then
			plr.leaderstats.Cash.Value = plr.leaderstats.Cash.Value - 300

Move this part to the server for security and replication reasons. Security cause an exploiter can just fire the remote directly and get a free tool and what i mean by replication is that when you update a value on the client. The server won’t see it. So even if you’re deducting 300 cash from the player on the client. In reality the player will still have his 300 cash.

Ok I’ll just make it an argument while firing the server, would that be alright? like:

RS.Purchase:FireServer("AK-47", 300)

I don’t think you should make it an argument as exploiters can still fire the remote and just set the value to 0. Basically giving them a free weapon.

A simple alternative would be to store an IntValue called “Cost” inside the actual weapon. Then just get the cost on the server.

E.g

Remote.OnServerEvent:Connect(function(Player, Weapon)
	print(Player, Weapon)
	local GetWeapon = Folder:FindFirstChild(Weapon)

local Cost = GetWeapon:FindFirstChild("Cost").Value

-- do your check where you see if the player has enough
-- if they do then deduct the points and give the weapon
	GetWeapon:Clone().Parent = Player.BackPack
end)

I made a little IntValue inside of my Tool

local Remote = game:GetService("ReplicatedStorage").Purchase
local Folder = game:GetService("ServerStorage").Weapons

Remote.OnServerEvent:Connect(function(Player, Weapon)
	print(Player, Weapon)
	local Price = Folder:FindFirstChild(Weapon).Cost.Value
	if Player.leaderstats.Cash.Value >= Price then
		Player.leaderstats.Cash.Value = Player.leaderstats.Cash.Value - Price
	local c = Folder:FindFirstChild(Weapon):Clone()
		c.Parent = Player.BackPack
	end
end)

That’s what it looks like now

Skimmed over it and so far so good. Test it out in studio.

It worked! I did BackPack instead of Backpack, but I fixed it and it worked!