Zone doesnt work at start of game

The zone control script has the function or event whatever its called GetPropertyChangedSignal but the first time when the game starts up freshly it doesn’t change the text of the textlabel when ZoneType value changes.

Zone System Script:

local ZoneOdds = require(game:GetService("ServerStorage"):WaitForChild("ZoneOdds"))

local function ChooseZone()
	
	local totalChance = 0

	for Zone,Odds in pairs(ZoneOdds) do

		totalChance = totalChance + Odds

	end

	local roll = math.random() * totalChance

	local accumulatedChance = 0

	for Zone,Odds in pairs(ZoneOdds) do

		accumulatedChance = accumulatedChance + Odds

		if roll <= accumulatedChance then

			return Zone

		end

	end

	return nil
	
end

local function SetZonePos()
	
	local xMin = math.min(-93.75,93.75)
	
	local xMax = math.max(-93.75,93.75)
	
	local zMin = math.min(-93.75,93.75)
	
	local zMax = math.max(-93.75,93.75)
	
	return CFrame.new(math.random(xMin,xMax),8,math.random(zMin,zMax))
	
end

local Zone = game:GetService("ReplicatedStorage"):WaitForChild("Zone")

while true do
	
	local ChosenZone = ChooseZone()
	
	if not workspace:FindFirstChild("Zone") then
		
		Zone.Parent = workspace
		
	end
	
	workspace.Zone.Type.Value = ChosenZone
	
	workspace.Zone:PivotTo(SetZonePos())
	
	for secs = 10,0,-1 do
		
		if math.clamp(secs,41,60) == secs then
			
			workspace.Zone.ZoneInfoUI.Holder.ZoneDuration.TextColor3 = Color3.fromRGB(76, 229, 112)
			
		elseif math.clamp(secs,21,40) == secs then
			
			workspace.Zone.ZoneInfoUI.Holder.ZoneDuration.TextColor3 = Color3.fromRGB(255, 149, 1)
			
		elseif math.clamp(secs,0,20) == secs then

			workspace.Zone.ZoneInfoUI.Holder.ZoneDuration.TextColor3 = Color3.fromRGB(255, 6, 81)
			
		end
		
		workspace.Zone.ZoneInfoUI.Holder.ZoneDuration.Text = tostring(secs)
		
		task.wait(1)
		
	end
	
end

Zone Control (This is the issue):

local ZoneModule = require(game:GetService("ReplicatedStorage"):WaitForChild("ZoneModule"))

local Container = script.Parent:WaitForChild("Detector")

local ZoneDetector = ZoneModule.new(Container)

local Border = script.Parent:WaitForChild("Border")

local ZoneType = script.Parent:WaitForChild("Type")

local PlayersInZone = {}

local ZoneInfoUI = script.Parent:WaitForChild("ZoneInfoUI")

local ZoneNameDisplay = ZoneInfoUI:WaitForChild("Holder"):WaitForChild("ZoneName")

local ZoneCapacityDisplay = ZoneInfoUI:WaitForChild("Holder"):WaitForChild("ZoneCapacity")

local MaxCapacity = 3

ZoneType:GetPropertyChangedSignal("Value"):Connect(function()
	
	table.clear(PlayersInZone)
	
	ZoneCapacityDisplay.Text = #PlayersInZone .. "/" .. tostring(MaxCapacity)
	
	if ZoneType.Value == "Safe Zone" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(76, 229, 112)

	elseif ZoneType.Value == "Heal Zone" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(68, 203, 99)

	elseif ZoneType.Value == "2x Damage" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(235, 78, 0)

	elseif ZoneType.Value == "4x Damage" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(214, 68, 0)

	end
	
end)

ZoneDetector.playerEntered:Connect(function(plr)
	
	if #PlayersInZone < 3 then
		
		table.insert(PlayersInZone, plr.Name)
		
		ZoneCapacityDisplay.Text = tostring(#PlayersInZone) .. "/" .. tostring(MaxCapacity)
		
		if #PlayersInZone == 3 then
			
			Border.CanCollide = true
			
		end
		
	end
	
end)

ZoneDetector.playerExited:Connect(function(plr)
	
	table.remove(PlayersInZone, table.find(PlayersInZone, plr.Name))
	
	ZoneCapacityDisplay.Text = tostring(#PlayersInZone) .. "/" .. tostring(MaxCapacity)
	
	if #PlayersInZone < 3 then

		if Border.CanCollide == true then
			
			Border.CanCollide = false
			
		end

	end

end)
1 Like

It is waiting for a “change”.

So is there a “change” when the game loads.

so what should i change? I am confused

I am not sure what ZoneType is in your game.

Here is an example (using a StringValue in Workspace)

local ZoneType = game.Workspace:WaitForChild("Type") -- StringValue



function ZoneTypeChanged()

	print("Hello")

end
ZoneType.Changed:Connect(ZoneTypeChanged) -- when changed

ZoneTypeChanged() -- when script first loaded

task.wait(4)

ZoneType.Value = "Two"

task.wait(4)

ZoneType.Value = "Three"

Your script only executes when ZoneType actually “changes” from whatever it is.

The sample above calls the function when the script loads, and when the value changes.

1 Like

ZoneType is a string value that is changed depend on the zone so for ex: 2x damage or 4x damage or safe zone or heal zone

So the following structure may solve your problem:

function ZoneTypeChanged()
	print("Hello")
end
ZoneType.Changed:Connect(ZoneTypeChanged) -- when changed
ZoneTypeChanged() -- when script first loaded
1 Like

The problem is with this piece of code. I don’t know why it doesn’t fire everytime the value is changed.

ZoneType:GetPropertyChangedSignal("Value"):Connect(function()

That is why I changed it to be:

ZoneType.Changed:Connect(function()

I don’t remember the difference, but GetPropertyChangedSignal is unreliable for Instance value changes (like a StringValue).

Here is a good write up on when to use GetPropertyChangedSignal.

1 Like

Why is it unreliable for instance changes?

You will need to run “propertychanged” function once when player enters the game, as players would enter the game (even the first one), after the zone has already been chosen by server.

local function OnZoneChaged()
	
	table.clear(PlayersInZone)
	
	ZoneCapacityDisplay.Text = #PlayersInZone .. "/" .. tostring(MaxCapacity)
	
	if ZoneType.Value == "Safe Zone" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(76, 229, 112)

	elseif ZoneType.Value == "Heal Zone" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(68, 203, 99)

	elseif ZoneType.Value == "2x Damage" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(235, 78, 0)

	elseif ZoneType.Value == "4x Damage" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(214, 68, 0)

	end
	
end
--connect here
ZoneType:GetPropertyChangedSignal("Value"):Connect(OnZoneChanged)

-- force run once on joining
OnZoneChanged()

Hope this helps.

EDIT:
But as Oof said, while this would work, it should be probably handled via a remote event fired from server to all clients. PropertyChanged signals should be reserved for internal communication (server-server or local - same client local).

Because that has been my experience.

When I use ValueBases (like a StringValue) I use StringValue.Changed:Connect(function()

The writeup above mentions the same… “however Changed is specially adapted for ValueBases”

So ur saying instead of me using the function getpropertychangedsignal I should use a remote event to fire every time the zone changes?

What do you mean for base values

I am saying to change you script from:

ZoneType:GetPropertyChangedSignal("Value"):Connect(function()

	table.clear(PlayersInZone)

	ZoneCapacityDisplay.Text = #PlayersInZone .. "/" .. tostring(MaxCapacity)

	if ZoneType.Value == "Safe Zone" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(76, 229, 112)

	elseif ZoneType.Value == "Heal Zone" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(68, 203, 99)

	elseif ZoneType.Value == "2x Damage" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(235, 78, 0)

	elseif ZoneType.Value == "4x Damage" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(214, 68, 0)

	end

end)

To be:

local function ZoneTypeChanged()
	
	table.clear(PlayersInZone)

	ZoneCapacityDisplay.Text = #PlayersInZone .. "/" .. tostring(MaxCapacity)

	if ZoneType.Value == "Safe Zone" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(76, 229, 112)

	elseif ZoneType.Value == "Heal Zone" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(68, 203, 99)

	elseif ZoneType.Value == "2x Damage" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(235, 78, 0)

	elseif ZoneType.Value == "4x Damage" then

		ZoneNameDisplay.Text = ZoneType.Value

		ZoneNameDisplay.TextColor3 = Color3.fromRGB(214, 68, 0)

	end
end
ZoneType.Changed:Connect(ZoneTypeChanged) -- use .Changed to connect a function
ZoneTypeChanged() -- run the function when the script first loads (becasue there is no "change" to trigger the function)

The reason is that .Changed work better with the StringValue and because you need to run the function when the script loads (your original problem).