Tower Defense - Tower Placement issues

Hello,

The things I am attempting to achieve is when you click a button on the players interface it gets the tower from the towers folder to place down to the location of where your mouse is at.

The problem I am getting is not being able to have it work, when I click the buttons nothing work.

Solutions I have tried so far is attempting to use ChatGPT, my brain, devforum, and youtube. (I am not using a tutorial)

MainScript:

-- local PhysicsService = game:GetService("PhysicsService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Commands = require(script.AdminCommands)
local EntityHandler = require(script.EntityHandler)

local Slot1 = ReplicatedStorage.Towers.Tower1
local BaseHealth = game.Workspace.Data.Health
local Players = game:GetService("Players")

local ProtectedUsers = {"1vp78z", "painfuljeffkiller1", "evilqueen6554"}

local Prefix = "/"
local AdministratorsID = {
	1027251890
}

local AdministratorsUser = {
	"Roblox",
}

game.Players.PlayerAdded:Connect(function(Player)
	for i, v in pairs(game.Players:GetPlayers()) do
		if table.find(ProtectedUsers, v.Name) then
			--Allow
		elseif not table.find(ProtectedUsers, v.Name) then
			Player:Kick("You are not whitelisted to join the game!")
		end
	end	
	
	Player.CharacterAdded:Connect(function(Character)
		for i,object in ipairs(Character:GetDescendants()) do
			if object:IsA("BasePart") then
				PhysicsService:SetPartCollisionGroup(object, "Player")
			end
		end
	end)
	local Cash = Instance.new("IntValue", Player)
	Cash.Name = "Cash"
	Cash.Value = 10000
	
	Player.Chatted:Connect(function(msg)
		for i, v in pairs(AdministratorsID) do
			if Player.UserId == v then
				local split = msg:split(" ")
				local firedCommand = split[1]:split(Prefix)

				if Commands[firedCommand[2]] then
					local arguments = split
					table.remove(arguments, 1)
					Commands[firedCommand[2]](Player, table.unpack(arguments))
				end
			end
		end
	end)

	Player.Chatted:Connect(function(msg)
		for i, v in pairs(AdministratorsUser) do
			if Player.Name == v then
				local split = msg:split(" ")
				local firedCommand = split[1]:split(Prefix)

				if Commands[firedCommand[2]] then
					local arguments = split
					table.remove(arguments, 1)
					Commands[firedCommand[2]](Player, table.unpack(arguments))
				end
			end
		end
	end)
end)

spawn(function()
	while true do
		wait(1)
		if BaseHealth.Value <= 0 then
			warn("The base's health has hit 0, returning players to lobby!")
		end
	end
end)

local function placeTower(player, position)
	local newTower = Slot1:Clone()
	newTower.Position = position
	newTower.Parent = workspace.Towers
end

game.ReplicatedStorage.Remotes.PlaceTower.OnServerInvoke = placeTower

image

Firstly, I already see a security issue. You shouldn’t use a mixture of UserID and Usernames for protected features. Stick with UserID as it is the most secure form of identification. If it works, then keep it, but I’d rather stay on the safe side.
Secondly, game.Players should be replaced with Players. (You’ve defined it above, but never used it?)
Same goes with the game.ReplicatedStorage at the bottom. Replace it with ReplicatedStorage.
Never access a service directly. It is prone to issues if it is renamed by someone else, or isn’t loaded.
You’ve connected to the same event twice. Don’t do this, you can easily just place both for loops in the same connection. But even better, just drop the for loop entirely and replace it with if AdministratorsID[Player.UserId] or AdministratorsUser[Player.Name] then

Next up is the most painful of all. I’m not even going to try and explain it as it’s midnight, but simply put, you’re using a deprecated feature in a while true do statement. Just replace it with

BaseHealth:GetPropertyChangedSignal("Value"):Connect(function()
    if BaseHealth.Value <= 0 then
        warn("The base's health has hit 0, returning players to lobby!")
    end
end)

This code will fire every time the health (Value of BaseHealth) changes, but will ignore all other properties (e.g. the Name property).
You can completely scrap the spawn() too, from what I see the script will still reach it.

Try these fixes first, then come back with any errors in the Output, or if the code still doesn’t work.

Hey! Finished Making my changes to the script (and removed the things I do not find ultimately important.

The issue I was having is not having anything work for when you want to place the tower down. I have no idea on how I will be able to code this into the game.

Do you know how I would be able to do that?

Also here is the new and updated script:

local PhysicsService = game:GetService("PhysicsService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local EntityHandler = require(script.EntityHandler)

local Slot1 = ReplicatedStorage.Towers.Tower1
local BaseHealth = game.Workspace.Data.Health
local Players = game:GetService("Players")

game.Players.PlayerAdded:Connect(function(Player)	
	Player.CharacterAdded:Connect(function(Character)
		for i,object in ipairs(Character:GetDescendants()) do
			if object:IsA("BasePart") then
				PhysicsService:SetPartCollisionGroup(object, "Player")
			end
		end
	end)
	local Cash = Instance.new("IntValue", Player)
	Cash.Name = "Cash"
	Cash.Value = 10000
end)

BaseHealth:GetPropertyChangedSignal("Value"):Connect(function()
	if BaseHealth.Value <= 0 then
		warn("The base's health has hit 0, returning players to lobby!")
	end
end)

if it plain not working? or is your code erroring? Because you have the function to placetower… so whats up?

not working entirely, I have no idea on how to code it to work. I’ve tried using gnome code (just for an example), chatgpt, dev forum, etc. I dont know how I get the UI to be pressed to be able to have your mouse hover at that spot, to then place it down. (I could just be tired but I have no idea)

okay, well utilize the mouse and mouse.hit and send that info to server when clicked (refer to roblox api for code documentation)

how I would make the mouse hover is perhaps have a base part at the bottom (or clone the entire tower) and constantly update its position every .stepped, updating its pos based on mouse.hit

like you said, gnomecode goes over this in a video:

any ideas. @Juicy_Fruit

30_charactersareneededsohi

problem with that is i dont know how i would integrate his code with mine. :sad:

it worked, awesome! ty!

30_chars

Just to add on, a remote function should only be used if you are returning a value to the client who initiated the invoke.

What you have here:

local function placeTower(player, position)
	local newTower = Slot1:Clone()
	newTower.Position = position
	newTower.Parent = workspace.Towers
end

game.ReplicatedStorage.Remotes.PlaceTower.OnServerInvoke = placeTower

is not really game breaking, you’re just using the wrong client-server communication.

Instead, you should use a Remote Event, it does the same exact thing except it is asynchronous communication between the client and the server. However, if you do plan on returning the “newTower” variable, then completely ignore what I said!

Hey! I got more issues with my tower defense game, can I get some help?

@Juicy_Fruit You got time to squash another bug?

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