Chat Shop Commands

I have been working on my new game and I was just wondering how I could go about making chat commands for a shop, like “!buy coil” and it would buy it after popping a little “Are you sure you want to purchase this item?”. So basically all it does is make a notification show on screen asking if you want to buy the item.

I want to try to make a table of different items you can buy, all with different prices, and also a command gui that you can open with “!gui” or something like that.

I’m very new to stuff like this so I have no idea how to make any of it, especially the notifications, I do not know how to trigger an event or anything like that.

2 Likes

You can use Player.Chatted to detect when the player chats and what message he sent. You would then compare the Message string to whatever your command is. E.g if Message == "!buy coil" then → from there just clone or tween a UI onto the players screen with an option to close the UI or to purchase. If they click purchase → then detect or charge them whatever the fee is and give them the item.

https://developer.roblox.com/en-us/api-reference/event/Player/Chatted

1 Like

That doesn’t completely solve my problem, but that’s very helpful! Would I just make it a normal script and put it in the Workspace? or would I have to make it something else in a different place?

1 Like

This would be a script, preferably in ServerScriptService:

-- Services --
local PS = game:GetService("Players");

-- Chat Function --
function PlayerJoined(Player)
	Player.Chatted:Connect(function(Msg) -- This fires whenever a player types a message. Msg = the original message the player sent
		print(Player.Name.." has said: "..Msg);

		if string.lower(Msg) == "!buy coil" then -- First we make the message all lowercase using string.lower then we see if they said !buy coil.
			warn(Player.Name.." is attempting to buy a coil!");
			-- Give the UI or give them the coil, etc
		elseif string.lower(Msg) == "poop" then -- You can use elseif statements to do something else if the first statement wasn't met!
			warn("Now "..Player.Name.." is pooping");
			-- Do something else here
		end;
	end);
end;

-- Connections --
PS.PlayerAdded:Connect(PlayerJoined);

for _, Player in ipairs(PS:GetPlayers()) do -- Incase player loads in before this script runs (this really only happens in studio)
	task.spawn(PlayerJoined, Player);
end;

This is just a simple way to detect when a player chats and how to compare their message to another string. As for the GUI part, simply create a physical GUI → clone it into the players PlayerGui → do whatever you need to on the client.

1 Like

Thank you so much this really kickstarted the process! Now that I have the script, I already made the notification, by adding this script in:
local c = script.Notif:Clone() c.Parent = Player.PlayerGui
all I need now is to figure out how to make that notification actually give the player a tool.

1 Like

You would need to create a local script. You can just leave it inside the Notif GUI you made. You would then need to reference the purchase/close buttons. Create a MouseButton1Click connection:

https://developer.roblox.com/en-us/api-reference/event/GuiButton/MouseButton1Click

After that you would need to fire a remote using RemoteEvents and have the server give the item.

1 Like

Yeah I have all of that I do not know if I set it up right though,

game:GetService("StarterGui"):SetCore("SendNotification", { Title = "Purchase"; Text = "Are you sure you want to purchase an blank ($100)"; Icon = ""; Duration = 300; Button1 = "Yes"; Button2 = "No"; })

Obviously there is a new line in between every semi-colon.

1 Like

You would have to supply the callback function for the notification. This post has an example of how to apply it:

You would then do what you did for the chat script and have an if statement that compares the result:

function bindable.OnInvoke(response) -- code taken from the above post
    if response == "Yes" then
        -- Fire a remote to the server to give the coil
    else
        -- Player selected no, therefore do nothing
    end
    print(response .. " chosen")
end
2 Likes

what would the bindable mean? and where would it go? it comes up as an unknown global for me

1 Like

Bindable is an actual instance object, its used to send data between same type scripts (such as server to server or local to local). Could you send the current code block you have?

1 Like

Here you go (need a couple more letters for this to send in):

Notif1 - Roblox Studio 1_21_2022 11_47_14 PM (2)

the duration is meant to be 5 minutes long, and the (300) is meant for the amount of credits needed.

1 Like

Duration represents how long the notification will remain on the players screen. I do not recommend having on screen for longer then 10 seconds. You don’t want the player to be flooded with notifications that don’t disappear for like 5 minutes. If they haven’t made a selection in like 10 seconds then just assume they don’t want to purchase.

-- This is just the same script from the forum post just slightly edited

    local SG = game:GetService("StarterGui");
	local Bind = Instance.new("BindableFunction");

	function Bind.OnInvoke(Reponse)
		if Reponse == "Yes" then
			print("fire remote to server to give coil");
		else
			print("player canceled the purchase");
		end;
	end;

	SG:SetCore("SendNotification", {
		Title = "Purchase";
		Text = "Are you sure you want to purchase an AK-47 (300)";
		Icon = "";
		Duration = 10; -- Don't leave it for 300 seconds, if the player hasn't selected anything in like 10 seconds then assume they didn't want to purchase. Don't want to flood their screen with notifications forever.
		Button1 = "Yes";
		Button2 = "No";
		
		Callback = Bind;
	});

1 Like

see this topic of mine

1 Like

thanks, I probably would have changed the duration after some major trial and error :grinning_face_with_smiling_eyes:, so is there an easy way for me to identify the player?

1 Like

Also that is a very nice post!

1 Like

Its quite easy for any local scripts. All you have to do is:

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

Local player only exist on the client, trying to define local player in a server script won’t work and will result in an error. So what you would want to do is create a RemoteEvent → when the player chats the right command, fire that remote for the client that sent the chat message → have the players client listen for that event and then post the purchase notification (the one we did above) → once the player makes a selection you then fire the same remote and this time have the server listen for that event → have the server give the desired item.

1 Like

thank you

1 Like

Alright I used that thanks for the reassurance!

1 Like

I was trying to make the game just clone it out of the server storage folder, and just put it in the players backpack. Is that not efficient or something?

also I don’t know what happened but for some reason the server script will not let me clone the notification gui into the player’s PlayerGui… heres what the code looks like, its just your base code:

local PS = game:GetService("Players");

function PlayerJoined(Player)
	Player.Chatted:Connect(function(Msg)
		if string.lower(Msg) == "!buy AK-47" then
			local c = script.Notif1:Clone()
			c.Parent = Player.PlayerGui
		end;
	end);
end;

PS.PlayerAdded:Connect(PlayerJoined);

for _, Player in ipairs(PS:GetPlayers()) do
	task.spawn(PlayerJoined, Player);
end;
1 Like

Since we are making the message lowercase, the if statement won’t be met since AK is capital. Just change it to ak-47 instead of AK-47.

1 Like