Making this script more server oriented?

Hello, I’ve made this script to manage the text on a sign although it has gotten inefficient as when new players join they have to update the text for it to show for them. Any help or suggestions on making this more server oriented will help.

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

local EditEvent = ReplicatedStorage.Events:FindFirstChild("EditEvent")
local UpdateText = ReplicatedStorage.Events:FindFirstChild("UpdateText")
local PromptEvent = ReplicatedStorage.Events:FindFirstChild("PromptEvent")
local ResetSignEvent = ReplicatedStorage.Events:FindFirstChild("ResetSignEvent")

local Sign = game.Workspace:FindFirstChild("Sign")
local SignText = Sign.Structure.Signs.TextSign.SurfaceGui:FindFirstChild("Text")

local EditPrompt = Sign.Structure.Prompt:FindFirstChild("Edit")
local EditFrame = Players.LocalPlayer.PlayerGui.Edit:FindFirstChild("Frame")

local Apply = EditFrame:FindFirstChild("Apply")
local Text = EditFrame:FindFirstChild("Text")

ResetSignEvent.OnClientEvent:Connect(function()
	SignText.Text = "Your Text Here"
end)

PromptEvent.OnClientEvent:Connect(function(EditPrompt, Value)
	EditPrompt.Enabled = Value
end)

EditEvent.OnClientEvent:Connect(function()
	EditFrame:TweenPosition(UDim2.new(0.5, 0, 0.5, 0), "Out", "Sine", 0.5, true)
end)

Apply.MouseButton1Down:Connect(function()
	UpdateText:FireServer(Text.Text)
end)

local function HandleTextUpdate(Owner, NewText)
	if Owner and NewText then
		SignText.Text = NewText
		if Owner == Players.LocalPlayer then
			EditFrame:TweenPosition(UDim2.fromScale(0.5,-1), "Out", "Sine", 0.5, true)
			EditPrompt.Enabled = true
		end
	end
end

UpdateText.OnClientEvent:Connect(HandleTextUpdate)

Could you please describe more briefly about your goal?

Basically a player claims a sign and edits the text on it, however more events are needed to display edits globally and new players won’t see the current text when they join.

Any errors appearing in the output?

They aren’t any errors, it just requires more resources when managing the text locally so I’m looking to make it more simple by running it through a server script.

The OP said there’s no problems in this code, just to reformat it as server sided.

Oh. My bad. :man_facepalming:

Why are you only displaying the text on the client and not inserting the new text on the server instead?

This is the problem. New players won’t see the new updated text because this event was never fired until they did something. Of course, you can make it so that when this local script runs, you fire this remote event, but I prefer doing the text on the server instead.

I know this is the problem, but I’m not sure how I could manage the text with the server.

Literally just set the text on the sign on the server? Your function is doing the same thing.

I should’ve put more context, the update text event is used to filter the text the user inputs.

update the text from server, using the remote updatetext

filter text on server → check if sign is owned by the player who fired the event → check text length → update text on sign

You could’ve DMed me if this script was causing you issues, either way here I am.

Server:

-- Recycled code from the last post

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local ChatService = game:GetService("Chat")

local Sign = game.Workspace:FindFirstChild("Sign")
local SignText = Sign:GetAttribute("Text")
if not SignText then
  Sign:SetAttribute("Text", "Your default text here")
end

local UpdateText = ReplicatedStorage.Events:FindFirstChild("UpdateText")

local OwnerValue = nil -- Add this in again, teehee..

local function HandleTextRequest(Player, Text)
  if typeof(Text) ~= "string" then warn(("invalid type for argument #2 in HandleTextRequest, expected string; got %s"):format(typeof(Text))) return; end

	local Status, FilteredText = pcall(function()
    return ChatService:FilterStringAsync(SignText, Player, Player)
  end) -- pcall returns both "success" and "return"/"errormsg"
  -- "success" is a boolean indicating if it ran
  -- "return"/"errormsg" is self explanatory
  if Status then
    Sign:SetAttribute("Text", FilteredText)
    -- You may be able to entirely remove the fireallclients call
    -- With the client I wrote
		UpdateText:FireAllClients(OwnerValue, FilteredText)
  end
end

UpdateText.OnServerEvent:Connect(HandleTextRequest)

And then the Client:

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

local EditEvent = ReplicatedStorage.Events:FindFirstChild("EditEvent")
local UpdateText = ReplicatedStorage.Events:FindFirstChild("UpdateText")
local PromptEvent = ReplicatedStorage.Events:FindFirstChild("PromptEvent")
local ResetSignEvent = ReplicatedStorage.Events:FindFirstChild("ResetSignEvent")

local Sign = game.Workspace:FindFirstChild("Sign")
local SignText = Sign.Structure.Signs.TextSign.SurfaceGui:FindFirstChild("Text")

local EditPrompt = Sign.Structure.Prompt:FindFirstChild("Edit")
local EditFrame = Players.LocalPlayer.PlayerGui.Edit:FindFirstChild("Frame")

local Apply = EditFrame:FindFirstChild("Apply")
local Text = EditFrame:FindFirstChild("Text")

ResetSignEvent.OnClientEvent:Connect(function()
	SignText.Text = "Your Text Here"
end)

PromptEvent.OnClientEvent:Connect(function(EditPrompt, Value)
	EditPrompt.Enabled = Value
end)

EditEvent.OnClientEvent:Connect(function()
	EditFrame:TweenPosition(UDim2.new(0.5, 0, 0.5, 0), "Out", "Sine", 0.5, true)
end)

Apply.MouseButton1Down:Connect(function()
	UpdateText:FireServer(Text.Text)
end)

Sign:GetAttributeChangedSignal("Text"):Connect(function()
  local Temp = Sign:GetAttribute("Text")
  if Temp and typeof(Temp) == "string" then
    SignText.Text = Temp;
  end
end) -- If this works, just remove the FireAllClients call
-- Actually, no, I won't remove this cause I'm tired but
-- you need that call for the EditPrompt, unless you use
-- your PromptEvent remote.

local function HandleTextUpdate(Owner, NewText)
	if Owner and NewText then
		--SignText.Text = NewText
    -- if the above doesn't work, let me know.
		if Owner == Players.LocalPlayer then
			EditFrame:TweenPosition(UDim2.fromScale(0.5,-1), "Out", "Sine", 0.5, true)
			EditPrompt.Enabled = true
		end
	end
end

UpdateText.OnClientEvent:Connect(HandleTextUpdate)

Let me know if this works, if it doesn’t, if it sorta works, etc.

Edit: Going to sleep at the time of this edit, it is 11:57 PM CST. GN.

1 Like