Island Assignment Script

Hello! I’m making a simulator game and each person is going to have their own little island. On the main area there is a teleport button that when clicked, a GUI pops with the option to teleport to your island or someone else’s. My only problem is I am struggling on making the script(s) that assign each player their own island upon joining the game. I have managed to make a script that assigns each player a number in a table that will be shown below on what it exactly does, but I’m at a road block and need some help.

-------Setups-------
place = {Vector3.new(0,0,0),Vector3.new(0,0,0),Vector3.new(0,0,0),Vector3.new(0,0,0),Vector3.new(0,0,0),Vector3.new(0,0,0),Vector3.new(0,0,0),Vector3.new(0,0,0),Vector3.new(0,0,0),Vector3.new(0,0,0),Vector3.new(0,0,0),Vector3.new(0,0,0)}
owners = {0,0,0,0,0,0,0,0,0,0,0,0}
busy = false --interaction failsafe

local players = game:GetService("Players")

-------Functions-------
local function update()
	busy = false
	print(busy)
	print(owners)
end

local function onPlayerAdded(player) 
	busy = true
	local temp = {}
	local i
	table.move(owners,1,12,1,temp)
	i = table.find(temp,0) 
	table.remove(temp,i)
	table.insert(temp,i,player.UserId)
	table.clear(owners)
	table.move(temp,1,12,1,owners)
	update()
end

local function onPlayerRemoved(player)
	busy = true
	local temp = {}
	local i
	table.move(owners,1,12,1,temp)
	i = table.find(temp,player.UserId)
	table.remove(temp,i)
	table.insert(temp,i,0)
	table.clear(owners)
	table.move(temp,1,12,1,owners)
	update()
end

-------Events-------
players.PlayerAdded:Connect(onPlayerAdded)

players.PlayerRemoving:Connect(onPlayerRemoved)

-------Random-------


On the image above, when a player leaves it sets the number they were assigned to as 0.

If you know how I can connect this to the system I’m looking to make or if you have a better way of doing it, please let me know!

1 Like

Every time the player creates an island (or claims his one, idk) assign the number that you give to the player the island. Currently you have a table where you store those ids from the players. I would make a dictionary where I set the player as the key and the value is the id.

When the player leaves then save this id to a datastore. When the same player joins again, then retrieve the datastore and find the Island by it’s id and teleport him/her to his/her island.

You can make a table of islands then when a player joins if there is an open island then assign the UserId to the island in the table

local Islands = {Add Islands Here}
local Owned = {}

for i,v in pairs(Islands) do
Owned[v] = 1
end

local function GetOpenIsland()
 
local Island = nil

for i,v in pairs(Owned) do
 
if v == 1 then Island = v end

 end

return Island

end

game.Players.PlayerAdded:Connect(function(player)
 
local Island = GetOpenIsland()

if Island then
 
 Owned[Island] = player.UserId
 
 --Do what you want with the island


end

end)


game.Players.PlayerRemoving:Connect(function(player)

for i,v in pairs(Owned) do
 
 if v == player.UserId then
  
  v = 1
  break

 end
end


end)

Sorry if the formatting is a bit off it’s a bit hard in the devforums code bit

1 Like

Thank you for the script but if you don’t mind could I ask a couple questions about how it works? Like, how would I put the islands in the “local Islands = {}” area. Would I have to make a bunch of these: local island1 = game.workspace.Island1, etc or is there another way. Also wdym by “Do what you want with the island”, like what can I do in there?

1 Like

For the 1st question if you have a folder for the islands then you can just do
local Islands = folder:GetChildren() otherwise then yes you would have to do local Islands - {game.Workspace.Island1,game.Workspace.Island2, etc...}

For the 2nd question I mean like teleport the player, or set the island value somewhere else

2 Likes

I tried to reply when you first posted, but my internet went off, and I only just got it back on.
So here is something I typed up.
Maybe it will help you.

Place File:
Island Spawn.rbxl (110.6 KB)

image

--capture our little hut scenery
local Hut = workspace:WaitForChild("Hut")
Hut.Parent = nil

--get a list for connections
local ConnectionList = {}

local ColorList = {Color3.new(1, 0, 0),Color3.new(0, 0.666667, 0),Color3.new(0, 0.333333, 1),Color3.new(0.333333, 0, 1)
	,Color3.new(1, 1, 1),Color3.new(0.0784314, 0.0784314, 0.0784314),Color3.new(1, 0.333333, 0),Color3.new(1, 1, 0)
}

--get a list of the islands
local IslandList = workspace:WaitForChild("Islands"):GetChildren()
--assign a color to each island
for n = 1,#IslandList do
	IslandList[n]:SetAttribute("IslandColor",ColorList[n])
end


local busy = false

function FindIslandByUserId(id)
	for _,i in pairs(IslandList) do
		if i:GetAttribute("UserId") == id then
			return i
		end
	end
end

function onCharacterAdded(character)
	--spawn to our island
	local player = game.Players:GetPlayerFromCharacter(character)
	if player then
		local island = FindIslandByUserId(player.UserId)
		if island then
			local spawnPad = island:WaitForChild("Spawn")
			local hrp = character:WaitForChild("HumanoidRootPart")
			local humanoid = character:WaitForChild("Humanoid")
			while character.Parent ~= workspace do task.wait() end
			character:PivotTo(spawnPad.CFrame+Vector3.new(0,7,0))
		end
	end
end

function onPlayerAdded(player)
	--this sets the player tag IsLoaded to show that we have found our way to this function and do not need to call this again in the loop at the bottom
	player:SetAttribute("IsLoaded",true)
	
	
	--Wait until not busy and find empty island
	while busy do task.wait() end
	busy = true
	local island = FindIslandByUserId(nil)
	if not island then 
		busy = false
		error("Not Enough Empty Islands") 
		return	
	end
	--set this islands PlayerId to the players PlayerId
	island:SetAttribute("UserId",player.UserId)
	busy = false
	

	--give the island a hut
	local hut = Hut:Clone()
	hut.PrimaryPart.Color = island:GetAttribute("IslandColor")
	hut:PivotTo(island:WaitForChild("Mountain").CFrame + Vector3.new(0,5.2,0))
	hut.Parent = island
	
	
	--handle connections for character added
	if player.Character then --catches any character that might have been created before this script created the event handler
		ConnectionList[player.UserId] = player.CharacterAdded:Connect(onCharacterAdded)
		onCharacterAdded(player.Character)		
	else
		ConnectionList[player.UserId] = player.CharacterAdded:Connect(onCharacterAdded) 
	end
end

function onPlayerRemoved(player)
	--remove hut and mark island as empty
	local island = FindIslandByUserId(player.UserId)
	if island then
		local hut = island:FindFirstChild("Hut")
		if hut then hut:Destroy() end
		island:SetAttribute("UserId",nil)
	end
	
	
	--cleanup connections
	if ConnectionList[player.UserId] then
		ConnectionList[player.UserId]:Disconnect()
		ConnectionList[player.UserId] = nil
	end 
end

game.Players.PlayerAdded:Connect(onPlayerAdded)
game.Players.PlayerRemoving:Connect(onPlayerRemoved)


--catches a player that might have connected before this script could finish setting up event handlers
for _,player in pairs(game.Players:GetPlayers()) do
	if not player:GetAttribute("IsLoaded") then
		onPlayerAdded(player)
	end
end

image

--get button
local HomeButton = script.Parent:WaitForChild("Button")
local ButtonTemplate = HomeButton:Clone()

function FindIslandByUserId(id)
	for _,i in pairs(workspace:WaitForChild("Islands"):GetChildren()) do
		if i:GetAttribute("UserId") == id then
			return i
		end
	end
end

function onButtonClicked(button)
	local id = button:GetAttribute("UserId")
	local island = FindIslandByUserId(id)
	if island then
		local character = game.Players.LocalPlayer.Character
		local spawnPad = island:WaitForChild("Spawn")
		local hrp = character:WaitForChild("HumanoidRootPart")
		local humanoid = character:WaitForChild("Humanoid")
		while character.Parent ~= workspace do task.wait() end
		character:PivotTo(spawnPad.CFrame+Vector3.new(0,7,0))
	end
end

HomeButton:SetAttribute("UserId",game.Players.LocalPlayer.UserId)
HomeButton.MouseButton1Click:Connect(function() onButtonClicked(HomeButton) end)

--setup event
local ButtonList = {}

function CreateButtons()
	for _,i in pairs(ButtonList) do
		if i[2] then i[2]:Disconnect() end
		if i[1] then i[1]:Destroy() end 
	end
	ButtonList = {}
	for _,i in pairs(workspace:WaitForChild("Islands"):GetChildren()) do
		local player = game.Players:GetPlayerByUserId( i:GetAttribute("UserId"))
		if player and player ~= game.Players.LocalPlayer then
			local button = ButtonTemplate:Clone()
			button.Text = player.Name
			button.Name = player.Name
			button.Parent = script.Parent:WaitForChild("ScrollingFrame")
			local connection = button.MouseButton1Click:Connect(function() onButtonClicked(button) end)
			table.insert(ButtonList{button,connection})
		end
	end
end

for _,i in pairs(workspace.Islands:GetChildren()) do
	i:GetAttributeChangedSignal("UserId"):Connect(function()
		CreateButtons()
	end)
end

1 Like

Ohh alright perfect, I do have them in a folder. I don’t want them to teleport there as I have a separate GUI for that but if I wanted to specify the location of the islands (where the players would spawn) based on the numbers, how can I do that?

I checked it out and it looks good, the only thing is I don’t want players to spawn there right away, I want there to be a GUI where they can spawn at any island but they have permissions to only edit their island.

I wasn’t trying to write up a complete system for you, that’s not the purpose of these forums.

It was just an example of how you can manage players owning an island when they log in, and how you can keep track of that and relay that information to the client where your spawn gui would be.

Yeah ik, I was just trying to understand the script. Like they system you made or got, does it clarify who is the owner of the island and the location of the islands?

Nvm, Imma just try and figure it out. If I can’t I will ask for help

It gets the children of the Island directory when a player joins, and if the model of the island does not have an attribute called “UserId”, then it creates that attribute and assigns the player’s UserId to its value.

So basically each island has an attribute saying the player who owns it.

If we want to find the island a player owns, we loop through the islands, and check for a match of the players UserId, and the value of the islands “UserId” attribute.

Since this attribute is set on the server, it is replicated to the islands on the client.
So the client can check by looping through the islands and seeing who owns them to generate a spawn list or ownership list, or the client script can set an event to fire when an islands UserId attribute changes.

Thank you!! This has really helped me out! Only thing that isn’t working is the part where it’s supposed to show the buttons to go to the other players islands.

I probably left something out, like parenting them or something. I couldn’t test it much as it was late when I made it. However, I’m sure you can get the idea of what I was trying to do.

The client loops through the islands and listens for an event to change on the island model’s UserId attribute.

When that changes, it rebuilds the teleport list, by assigning a button with text of the player name who owns each island by the UserId

Okay, so it works on the link that you sent me but it’s not working when I transferred it to my game and made a couple edits. Here is everything, are you able to spot anything that may be wrong with it?

local script

--get button
local HomeButton = script.Parent.Parent:WaitForChild("Button")
local ButtonTemplate = HomeButton:Clone()
local text = script.Parent.Parent

function FindIslandByUserId(id)
	for _,i in pairs(workspace.Builds:WaitForChild("Islands"):GetChildren()) do
		if i:GetAttribute("UserId") == id then
			return i
		end
	end
end

local player = game.Players.LocalPlayer
text.Text = player.Name

function onButtonClicked(button)
	local id = button:GetAttribute("UserId")
	local island = FindIslandByUserId(id)
	if island then
		local character = game.Players.LocalPlayer.Character
		local spawnPad = island:WaitForChild("Spawn")
		local hrp = character:WaitForChild("HumanoidRootPart")
		local humanoid = character:WaitForChild("Humanoid")
		while character.Parent ~= workspace do task.wait() end
		character:PivotTo(spawnPad.CFrame+Vector3.new(0,7,0))
	end
end

HomeButton:SetAttribute("UserId",game.Players.LocalPlayer.UserId)
HomeButton.MouseButton1Click:Connect(function() onButtonClicked(HomeButton) end)

--setup event
local ButtonList = {}

function CreateButtons()
	for _,i in pairs(ButtonList) do
		if i[2] then i[2]:Disconnect() end
		if i[1] then i[1]:Destroy() end 
	end
	ButtonList = {}
	for _,i in pairs(workspace.Builds:WaitForChild("Islands"):GetChildren()) do
		local player = game.Players:GetPlayerByUserId( i:GetAttribute("UserId"))
		if player and player ~= game.Players.LocalPlayer then
			local button = ButtonTemplate:Clone()
			button.Text = player.Name
			button.Name = player.Name
			button.Parent = script.Parent.Parent.Parent.Parent:WaitForChild("ScrollingFrame")
			local connection = button.MouseButton1Click:Connect(function() onButtonClicked(button) end)
			table.insert(ButtonList{button,connection})
			print(ButtonList)
		end
	end
end

for _,i in pairs(workspace.Builds.Islands:GetChildren()) do
	i:GetAttributeChangedSignal("UserId"):Connect(function()
		CreateButtons()
	end)
end

Server Script

--get a list for connections
local ConnectionList = {}

local ColorList = {Color3.new(1, 0, 0),Color3.new(0, 0.666667, 0),Color3.new(0, 0.333333, 1),Color3.new(0.333333, 0, 1)
	,Color3.new(1, 1, 1),Color3.new(0.0784314, 0.0784314, 0.0784314),Color3.new(1, 0.333333, 0),Color3.new(1, 1, 0)
}

--get a list of the islands
local IslandList = workspace.Builds:WaitForChild("Islands"):GetChildren()
--assign a color to each island
for n = 1,#IslandList do
	IslandList[n]:SetAttribute("IslandColor",ColorList[n])
end


local busy = false

function FindIslandByUserId(id)
	for _,i in pairs(IslandList) do
		if i:GetAttribute("UserId") == id then
			return i
		end
	end
end


function onPlayerAdded(player)
	--this sets the player tag IsLoaded to show that we have found our way to this function and do not need to call this again in the loop at the bottom
	player:SetAttribute("IsLoaded",true)


	--Wait until not busy and find empty island
	while busy do task.wait() end
	busy = true
	local island = FindIslandByUserId(nil)
	if not island then 
		busy = false
		error("Not Enough Empty Islands") 
		return	
	end
	--set this islands PlayerId to the players PlayerId
	island:SetAttribute("UserId",player.UserId)
	busy = false


	--handle connections for character added
	if player.Character then --catches any character that might have been created before this script created the event handler
		ConnectionList[player.UserId] = player.CharacterAdded:Connect(onCharacterAdded)
		onCharacterAdded(player.Character)		
	else
		ConnectionList[player.UserId] = player.CharacterAdded:Connect(onCharacterAdded) 
	end
end

function onPlayerRemoved(player)
	
	
	--cleanup connections
	if ConnectionList[player.UserId] then
		ConnectionList[player.UserId]:Disconnect()
		ConnectionList[player.UserId] = nil
	end 
end

game.Players.PlayerAdded:Connect(onPlayerAdded)
game.Players.PlayerRemoving:Connect(onPlayerRemoved)


--catches a player that might have connected before this script could finish setting up event handlers
for _,player in pairs(game.Players:GetPlayers()) do
	if not player:GetAttribute("IsLoaded") then
		onPlayerAdded(player)
	end
end

Lmk if anything doesn’t look right

It looks like you put the client script inside of a button, its designed to run outside of the buttons, maybe in as a child of the TeleportGui, or the Frame under that.

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