Best way to switch local script to server

heya! I’m helping someone with scripting and I somehow am also having trouble. they have this script which is similar to a roulette table:

local TweenService = game:GetService("TweenService")

local ScreenGui = script.Parent
local RouletteFrame = ScreenGui:WaitForChild("RouletteFrame")
local CoinStorage = RouletteFrame:WaitForChild("CoinStorage")
local RedLine = RouletteFrame:WaitForChild("RedLine")

local speed = math.random(50,100)
local slowDuration = math.random(7,15)
local spacing = 0
local function generatePattern()
	local pattern = {}
	math.randomseed(tick())
	local currentCoin = "Robux"
	local startingIndex = math.random(1, 14)
	for i = startingIndex, startingIndex + 33 do
		if (i - startingIndex) % 14 == 0 then
			table.insert(pattern, "Diamond")
		else
			table.insert(pattern, currentCoin)
		end
		if currentCoin == "Robux" then
			currentCoin = "Tix"
		else
			currentCoin = "Robux"
		end
	end
	return pattern
end





local function createCoins(pattern)
	local totalWidth = (#pattern - 1) * (136 + spacing) + CoinStorage:FindFirstChild(pattern[#pattern]).Size.X.Offset
	local startX = RouletteFrame.Size.X.Offset / 2 - totalWidth / 2

	for i, coinType in ipairs(pattern) do
		local coin = CoinStorage:FindFirstChild(coinType):Clone()
		coin.Position = UDim2.new(0, startX + (i - 1) * (136 + spacing), 0.5, -68)
		coin.Name = coinType .. "_" .. tostring(i)
		coin.Parent = RouletteFrame
	end
end

local function moveCoins()
	local fastDuration = math.random(3,7)
	local randomnumb = math.random(1,2)
	local deceleration = "."..randomnumb
	local frameWidth = RouletteFrame.Size.X.Offset

	local speed = math.random(50,100)
	local function moveOneStep()
		for _, coin in ipairs(RouletteFrame:GetChildren()) do
			if coin:IsA("ImageLabel") then
				local newPos = coin.Position.X.Offset - speed
				if newPos + 136 < 0 then
					newPos = newPos + (#generatePattern() * (136 + spacing))
				end
				coin.Position = UDim2.new(0, newPos, 0.5, -68)
			end
		end
		wait()
	end

	for _ = 1, fastDuration * 15 do
		moveOneStep()
	end

	local elapsedTime = 0
	while speed > 0 do -- gradually decrease speed to 0
		moveOneStep()
		elapsedTime = elapsedTime + 1/15
		speed = speed - deceleration * elapsedTime
	end
	moveOneStep() -- make sure the coins end up in the correct positions
end


local elapsedTime = 0
local function moveSlowly(dt)
	local elapsed = 0
	local totalTime = slowDuration

	local startPos = 0
	local endPos = -RouletteFrame.Size.X.Offset

	local deceleration = speed / (slowDuration * 15)

	while elapsed < totalTime do
		elapsed = elapsed + dt

		speed = speed - deceleration

		local newPos = startPos + ((elapsed / totalTime) * (endPos - startPos))

		for _, coin in ipairs(RouletteFrame:GetChildren()) do
			if coin:IsA("ImageLabel") then
				if newPos + 136 < 0 then
					newPos = newPos + (#generatePattern() * (136 + spacing))
				end
				coin.Position = UDim2.new(0, newPos, 0.5, -68)
			end
		end

		wait()
	end
end

local function determineWinner()
	local coins = RouletteFrame:GetChildren()
	local redLineX = RedLine.AbsolutePosition.X
	for _, coin in ipairs(coins) do
		if coin:IsA("ImageLabel") then
			local coinLeft = coin.AbsolutePosition.X
			local coinRight = coinLeft + coin.AbsoluteSize.X
			if redLineX >= coinLeft and redLineX <= coinRight then

				return coin.Name
			end
		end
	end
	return nil
end


local function createTimer(duration)
	local TimerLabel = Instance.new("TextLabel")
	TimerLabel.Size = UDim2.new(0, 100, 0, 50)
	TimerLabel.Position = UDim2.new(0.5, -50, 0, 20)
	TimerLabel.Parent = ScreenGui
	TimerLabel.Text = tostring(duration)
	TimerLabel.Font = Enum.Font.SourceSansBold
	TimerLabel.TextSize = 24
	TimerLabel.BackgroundTransparency = 1
	while true do
		for i = duration, 0, -1 do
			TimerLabel.Text = tostring(i)
			wait(1)
		end

		-- Remove any existing coins
		for _, coin in ipairs(RouletteFrame:GetChildren()) do
			if coin:IsA("ImageLabel") then
				coin:Destroy()
			end
		end

		local coins = generatePattern()
		createCoins(coins)
		moveCoins(coins)

		local winner = determineWinner()
		if winner then
			print("Winner is: " .. winner) 
			script.Parent.TextLabel.Text = winner
			break
		end
	end

	-- Cleanup
	TimerLabel:Destroy()
end

script.Parent.testold.MouseButton1Click:Connect(function()
	createTimer(.00000001)
end)

and i am not quite sure how to set it up in the server to prevent exploiters from changing it.
the largest challenge for us was globally changing the gui across all clients.

is someone able to help us with some tips or general info?

2 Likes

To fix the gui problem, you can just have a remote event that fires to all clients and changes the gui on the client. The client
receives the remote event and changes the gui.

yes we are aware of that method, but we do not know how to implement that into the way we change the GUI in the script.

Man, this entire thing was made for local.

1 Like

I’m pretty sure that putting that as a server script in the gui can work because server scripts can change gui too

I honestly didn’t think of that! good thinking. But another problem with that is that the GUI should be the same for everyone. multiple players = multiple uis = multiple scripts = multiple pattern seeds yada yada yeah.

would creating the seed and determining a winner within a server script in serverscriptservice and using a bindable function to connect to all the other scripts work? I am honestly not quite sure how bindable functions work as I have never tried anything with them surprisingly.

Bindable functions are like remote events but for server scripts. But I have a very dumb idea, what if you made a dummy gui that the local script updates and have a server script constantly update the player gui by replacing it. It really dumb…

1 Like

TBH that would work if it wasnt so easy to stress out roblox. its not “dumb” its just not optimized. it would definitely work.

I think the only way is to have the remote event fire all clients and pass a argument that specifies what gui the client should change.

so bindable functions wouldnt work?

No because bindable function only work server to server

? The main reason we’re trying to switch to server is so that it is the same globally and it is secured from exploiters

this worked AAGAGAHAGAGAGAGAGAHAHAHAHAGA

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.