Hey, I’m currently working on creating a gamepass system similar to one Roblox Bedwars uses for kits. Currently, I have two gamepasses. One of them increases your JumpHeight and the other one increases your WalkSpeed. Similarly to Bedwars, there is a Gui that allows you to select which “kit,” in this case, gamepass you would like to use. So far, I have eight remote events in ReplicatedStorage which allow this system to work.
The problems:
-
One issue is that players can select and use multiple gamepasses simultaneously, whereas they should only be able to utilize the perks of one gamepass at a time, similar to the setup in Bedwars. For instance, if a player chooses the speed gamepass option in the GUI, they should not be able to equip the jump boost gamepass unless they first unequip the speed gamepass. This is the intended behavior, but currently, players can use both gamepasses simultaneously if they have purchased them. (I have considered using BoolValues to check if one of the gamepasses is equipped, but I realize exploiters could likely change the values with ease)
-
I am by no means a scripter, but I do have a decent amount of knowledge on it. Enough to be able to script most of the functionality in my games. I could be wrong, but eight remote events for one system seems like an excessive and likely unecessary amount. Is there a way to make this code a bit more efficient?
-
Is this script vulnerable to exploits? Can an exploiter compromise this script with ease? If so, how do I make it more secure? I don’t know what exploiters are capable of as I have never exploited myself. Am I putting too much trust in the client?
I know this post is asking for a lot but even if you can’t help with all three of those things, just helping with one of them would be a major help.
Explorer:
Gui → StarterGui
SpeedScript (Server) → ServerScriptService
JumpScript (Server) → ServerScriptService
SpeedLocalScript (Client) → Gui
JumpLocalScript (Client) → Gui
Remotes → ReplicatedStorage
The script and Gui are prototypes. I am trying to get the basic coding for a much more complex system. (So don’t mind how poor quality the UI is)
I will show you the server sprint script and client sprint script. The scripts for jumping are exactly the same, just with different names for remotes and a few value changes. If you would also like to see the jump scripts or have any other questions, please ask.
Any help is much appreciated, thank you!
UI:
Speed script (Server)
--Variables
local eventFolder = game:GetService("ReplicatedStorage"):WaitForChild("GamepassEvents")
local speedEvent = game:GetService("ReplicatedStorage"):WaitForChild("GamepassEvents").SpeedGamepass
local speedAcceptEvent = game:GetService("ReplicatedStorage"):WaitForChild("GamepassEvents").SpeedAccepted
local speedDeclineEvent = game:GetService("ReplicatedStorage"):WaitForChild("GamepassEvents").SpeedDeclined
local unequipSpeed = game:GetService("ReplicatedStorage"):WaitForChild("GamepassEvents").UnequipSpeed
local id = 195581571
local normSpeed = 16
local speed = 32
--MarketplaceService
game:GetService("MarketplaceService").PromptGamePassPurchaseFinished:Connect(function(plr, ido, purchased)
if purchased and ido == id then
print("Player owns the gamepass")
end
end)
game.Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(game.Players[char.Name].UserId, id) then
print("Player owns the gamepass")
end
end)
end)
--Gamepass functionality
local function equipSpeed(player)
--Confirm player has gamepass
if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId, 195584369) then
--Gives the player speed and makes changes to the UI on the client.
player.Character.Humanoid.WalkSpeed = speed
speedAcceptEvent:FireClient(player)
else
--Changes UI on the client.
speedDeclineEvent:FireClient(player)
end
end
--Removes the speed
local function unEquipSpeed(player)
player.Character.Humanoid.WalkSpeed = normSpeed
end
speedEvent.OnServerEvent:Connect(equipSpeed)
unequipSpeed.OnServerEvent:Connect(unEquipSpeed)
Speed script (Client)
--Variables
local eventFolder = game:GetService("ReplicatedStorage"):WaitForChild("GamepassEvents")
local speedEvent = game:GetService("ReplicatedStorage"):WaitForChild("GamepassEvents").SpeedGamepass
local speedAcceptEvent = game:GetService("ReplicatedStorage"):WaitForChild("GamepassEvents").SpeedAccepted
local speedDeclineEvent = game:GetService("ReplicatedStorage"):WaitForChild("GamepassEvents").SpeedDeclined
local unequipSpeed = game:GetService("ReplicatedStorage"):WaitForChild("GamepassEvents").UnequipSpeed
local jumpButton = script.Parent.Parent.JumpEquip
local button = script.Parent
local declineWarning = script.Parent.Parent.DeclineWarning
local mainGui = script.Parent.Parent
equipped = false
--Runs when the player presses the "Equip" button
button.MouseButton1Click:Connect(function()
if equipped == false then
equipped = true
speedEvent:FireServer()
else
--Unequips and removes speed on the server
button.Text = "Equip"
unequipSpeed:FireServer()
equipped = false
end
end)
local function accepted()
--Player has the gamepass
button.Text = "Equipped"
button.BackgroundColor = BrickColor.new(0.027451, 0.286275, 1)
end
local function declined()
--Player doesn't have the gamepass
button.BackgroundColor = BrickColor.new(1, 0, 0)
--Warning label tells player they must purachase the gamepass
declineWarning.Visible = true
end
speedAcceptEvent.OnClientEvent:Connect(accepted)
speedDeclineEvent.OnClientEvent:Connect(declined)