I want to make a sandbox tycoon but I don’t know how to give players automaticly a plot.
Can anyone help me?
i tried this:
local players = game:GetService(“Players”)
local plot = workspace.Plots
local function Findplot(plr)
local plotChildren = plots:GetChildren()
for i, plt in pairs(plotChildren) do
if plt then
if plt.Plot.Owner.Valau ~= nil then
print("Owner Found")
else
local pltNm = plt.Name
game.ReplicatedStorage.Events.ClientPlot:FireClient(plr,pltNm)
plt.Plot.Owner.Value = plr
break
end
end
end
This belongs in #help-and-feedback:scripting-support. Please do read the category guidelines and make sure it is in the correct category. Forum feedback isn’t the place for it.
The category also isn’t meant for spoonfeeding code, so please after you move it, show any existing code or methods you have tried.
All you need to do is whenever a player joins, find an empty plot and assign it to them.
First we need to detect if a player joins, we can use the PlayerAdded event from Players then fire a function.
local Players = game:GetService("Players")
local function FindPlot(Plr)
end
Players.PlayerAdded:Connect(FindPlot) -- Runs the function FindPlot when the player joins
Now we need to loop through all of the plots and check to see if it available, if it is available then we can assign that plot to the player.
local Players = game:GetService("Players")
local function FindPlot(Plr)
local AllPlots = workspace.Plots:GetChildren()
for index = 1, #AllPlots do
if #AllPlots[index].Owner.Value == 0 then -- Plot is empty
AllPlots[index].Owner.Value = Plr.Name
game.ReplicatedStorage.Events.ClientPlot:FireClient(Plr, AllPlots[index].Name)
break
end
end
end
Players.PlayerAdded:Connect(FindPlot) -- Runs the function FindPlot when the player joins
What you originally did wrong
if plt.Plot.Owner.Valau ~= nil then
Assuming that the Owner value is a string value, it will never be nil only an empty string (""), you can test this for yourself by trying to set a string value to nil - it will error because the value would never be nil, it would always find a player.
To check that the string is empty, you can either check the length is 0 using the # operator (this is what I did above) or check the string is equal to "". You also made a typo spelling Value Valau.
plt.Plot.Owner.Value = plr
Here you are setting the string value to a UserData value. To set it to the players name you need to add .Name to the end so it looks like this: plt.Plot.Owner.Value = plr.Name
Oh, you are using an ObjectValue instead of a StringValue. That is fine however the script I wrote will need some minor changes.
local Players = game:GetService("Players")
local function FindPlot(Plr)
local AllPlots = workspace.Plots:GetChildren()
for index = 1, #AllPlots do
if not (AllPlots[index].Owner.Value) then -- Plot is empty
AllPlots[index].Plot.Owner.Value = Plr
game.ReplicatedStorage.Events.ClientPlot:FireClient(Plr, AllPlots[index].Name)
break
end
end
end
Players.PlayerAdded:Connect(FindPlot) -- Runs the function FindPlot when the player joins
Check to see if the Owner value is changing, if it is then my script is working perfectly. I am not sure what you are wanting to do on the client side - that is up to you.
Just that module, a model in workspace with models as its children for each plot (needs primarypart), and then you’d need a serverscript such as:
--[!] local
local function create(obj)
obj = Instance.new(obj)
return function (props)
for prop, val in next, props do
obj[prop] = val
end
return obj
end
end
--[!] Init Events
local remotes = create "Folder" {
Parent = game:GetService('ReplicatedStorage');
Name = "Remotes";
}
local Events = {
-- any other events you need
toClients = create "RemoteEvent" {
Parent = remotes;
Name = "toClients";
};
}
--[!] Init handlers
local StorageHandler = nil -- your data storage handler
local BuildHandler = require(game:GetService('ServerStorage').Modules.BuildHandler).new(StorageHandler, Events) -- change the path to where the module is
--[!] Set up your client->server events here
-- stuff stuff stuff
--[!] Player handling
local PlayerAdded = (function (Player)
BuildHandler:assignPlot(Player) -- assign our plot
Player.CharacterAdded:connect(function (Character)
-- do stuff with character
end) do
if Player.Character then
-- do stuff with character
end
end
end)
game.Players.PlayerAdded:connect(PlayerAdded) do
-- do stuff with the player
for _, Player in next, game.Players:GetChildren() do
PlayerAdded(Player)
end
end
game.Players.PlayerRemoving:connect(function (Player)
BuildHandler:unassignPlot(Player) -- remove our plot
end)
--[!] Closing handler
game.OnClose = (function ()
if not game:GetService("RunService"):IsStudio() then
-- do stuff when we close
end
end)
--[!] Main runtime
game:GetService("RunService").Heartbeat:connect(function (deltaTime)
-- do our runtime stuff
end)
It’s a great attempt but there are several issues. I’ve added comments and fixed your script so you can see what you did wrong:
local players = game:GetService("Players") -- you used ” characters, needs to be the normal quotation characters
local plot = workspace.Plots
local function FindPlot(plr)
local plotChildren = plots:GetChildren()
for i, plt in pairs(plotChildren) do
if plt then
--> You were checking to see if it wasn't nil, but we only care if it's nil so we can give the player a new plot
if plt.Plot.Owner.Value == nil then --> You spelled it 'valau' instead of 'Value'
local pltNm = plt.Name
game.ReplicatedStorage.Events.ClientPlot:FireClient(plr, pltNm)
plt.Plot.Owner.Value = plr
break
end
end
end
end
players.PlayerAdded:Connect(FindPlot)
--[!!!] We also need to remove that old plot once a player leaves
local function RemovePlot(plr)
local plotChildren = plots:GetChildren()
local plot
for i, plt in pairs(plotChildren) do
if plt then
--> Find the plot our player used
if plt.Plot.Owner.Value == plr then
plot = plt
break
end
end
end
if plot then
--> Remove everything the player added to the plot and clear it up for the new person
--> Once we've done that, we can reset the plot owner value
plot.Plot.Owner.Value = nil
end
end
players.PlayerRemoved:Connect(RemovePlot)