← All guides
Guide 4

Build your first tower defense

Enemies walk along a path toward your base, and a tower shoots the closest one.

Free60 minutes · Beginner · Roblox Studio
1
Step 1 / 8

Set up the place

  1. Open Roblox Studio, click New Experience and choose the Baseplate template.
  2. In Explorer hover over Workspace, click + and add a Folder. Name it Path.
  3. Add a second Folder to Workspace and name it Enemies. Leave it empty. Enemies will appear in it during the game.

More detail

  • The Baseplate template is in the list of templates on the start screen.
  • When you click +, type the word Folder to find it quickly. Rename a folder with F2.
  • The names must be exactly Path and Enemies, with a capital first letter. The scripts look for these names.
  • On a Mac, use the Cmd key every time this guide says Ctrl.
This step does not work for me

Check these three things first

  • The name of every part and script is exactly as in the guide, with the same capital letters.
  • The script sits inside the right object. Look at the label above the code box.
  • Open the Output window from the Window menu. Red text shows the script and the line with the problem.

Still stuck? Write to us →

2
Step 2 / 8

Build the path

  1. Add a Part. Set Size to 6, 1, 6, turn on Anchored and drag it into the Path folder. Name it 1.
  2. Duplicate it with Ctrl+D and move the copy about 30 studs away. Name it 2.
  3. Repeat until you have 5 parts named 1, 2, 3, 4 and 5. Place them so the route has a few turns.
  4. Enemies will go from 1 to 2 to 3 and so on, in a straight line between each pair.

More detail

  • To put a part into the folder, drag its name in Explorer onto the name Path.
  • A copy made with Ctrl+D is already inside the Path folder. You only have to move it and rename it.
  • The names are just the numbers: 1, 2, 3, 4, 5. No letters and no spaces.
  • Leave the parts lying on the floor. Enemies float 2 studs above them.
Common mistake. Skipping a number. If part 3 is missing, the enemies stop at part 2 and the script shows an error.
This step does not work for me

Check these three things first

  • The name of every part and script is exactly as in the guide, with the same capital letters.
  • The script sits inside the right object. Look at the label above the code box.
  • Open the Output window from the Window menu. Red text shows the script and the line with the problem.

Still stuck? Write to us →

3
Step 3 / 8

Create the enemy

  1. Add a Part. Set Shape to Ball and Size to 3, 3, 3, and make it red. Turn on Anchored, turn off CanCollide and name it Enemy.
  2. Hover over Enemy, click + and add an IntValue. Name it Health and set its Value to 3.
  3. Drag Enemy into ServerStorage. It is now a template. The game will make copies of it.

More detail

  • Shape is a list in Properties. Click it and choose Ball.
  • CanCollide is a checkbox in Properties. Without the tick, players and other parts pass through the enemy.
  • When you click +, type IntValue to find it. Click the new IntValue, then change Name to Health and Value to 3 in Properties.
  • After you drag Enemy into ServerStorage, it is gone from the Viewport. That is correct.
Tip. The enemy is anchored because a script moves it. Anchored parts ignore gravity and pushes.
This step does not work for me

Check these three things first

  • The name of every part and script is exactly as in the guide, with the same capital letters.
  • The script sits inside the right object. Look at the label above the code box.
  • Open the Output window from the Window menu. Red text shows the script and the line with the problem.

Still stuck? Write to us →

4
Step 4 / 8

Build the base

  1. Add a big Part at the end of the path, next to part 5. Turn on Anchored and name it Base.
  2. Hover over Base, click + and add an IntValue. Name it Health and set its Value to 10.
  3. Add a BillboardGui to Base with Size {0, 200}, {0, 50} and StudsOffset 0, 8, 0. Add a TextLabel into it with Size {1, 0}, {1, 0} and TextScaled on.
  4. Add a Script to Base and paste this code.
Base > Script
local base = script.Parent
local health = base.Health
local label = base.BillboardGui.TextLabel

local function update()
	if health.Value > 0 then
		label.Text = "Base: " .. health.Value
	else
		label.Text = "Game over"
	end
end

health.Changed:Connect(update)
update()

What each part does

  • Changed runs every time the Health value changes.
  • The update function writes the new number onto the label above the base.
  • When Health reaches 0, the label shows Game over and the Waves script stops sending enemies.

More detail

  • A size of 10, 10, 10 is a good base. Any color works.
  • The Health of the base is a different object from the Health of the enemy. Each one sits inside its own part.
  • For Size and StudsOffset, type the numbers exactly as shown, with the brackets and commas, and press Enter.
  • To test: press F5. The label above the base shows Base: 10.
This step does not work for me

Check these three things first

  • The name of every part and script is exactly as in the guide, with the same capital letters.
  • The script sits inside the right object. Look at the label above the code box.
  • Open the Output window from the Window menu. Red text shows the script and the line with the problem.

Still stuck? Write to us →

5
Step 5 / 8

Send the waves

  1. Hover over ServerScriptService, click + and add a Script. Name it Waves.
  2. Delete the line that is already there and paste this code.
  3. Press Play. Every 3 seconds a red ball appears at part 1 and moves along the path. When it reaches the end, the base loses 1 health.
ServerScriptService > Waves
local TweenService = game:GetService("TweenService")
local ServerStorage = game:GetService("ServerStorage")

local path = workspace:WaitForChild("Path")
local enemies = workspace:WaitForChild("Enemies")
local base = workspace:WaitForChild("Base")
local SPEED = 8

local function walk(enemy)
	for i = 2, #path:GetChildren() do
		local target = path[tostring(i)].Position + Vector3.new(0, 2, 0)
		local distance = (target - enemy.Position).Magnitude
		local info = TweenInfo.new(distance / SPEED, Enum.EasingStyle.Linear)
		local tween = TweenService:Create(enemy, info, {Position = target})
		tween:Play()
		tween.Completed:Wait()
		if not enemy.Parent then return end
	end

	base.Health.Value = math.max(0, base.Health.Value - 1)
	enemy:Destroy()
end

while base.Health.Value > 0 do
	task.wait(3)

	local enemy = ServerStorage.Enemy:Clone()
	enemy.Position = path["1"].Position + Vector3.new(0, 2, 0)
	enemy.Parent = enemies
	task.spawn(walk, enemy)
end

What each part does

  • Clone makes a copy of the Enemy template from ServerStorage.
  • The walk function moves the enemy to each path part in order. distance / SPEED keeps the speed the same on long and short stretches.
  • task.spawn lets every enemy walk on its own, so the loop can keep sending new ones.

More detail

  • The script opens in a new tab. Click inside the code, press Ctrl+A and then Ctrl+V to replace everything.
  • Enemies appear inside the Enemies folder while the game runs. You can watch them in Explorer.
  • With no tower yet, every enemy reaches the base. After 10 enemies the label shows Game over and no more enemies come.
  • Red text about a missing name in Output means a path part or a folder has the wrong name.
This step does not work for me

Check these three things first

  • The name of every part and script is exactly as in the guide, with the same capital letters.
  • The script sits inside the right object. Look at the label above the code box.
  • Open the Output window from the Window menu. Red text shows the script and the line with the problem.

Still stuck? Write to us →

6
Step 6 / 8

Build the tower

  1. Add a Part near a turn in the path. Set Size to 4, 8, 4, turn on Anchored and name it Tower.
  2. Add a Script to Tower and paste this code.
  3. Press Play. Once a second the tower hits the closest enemy in range. The enemy flashes white, and after 3 hits it disappears.
Tower > Script
local tower = script.Parent
local enemies = workspace:WaitForChild("Enemies")
local RANGE = 25
local DAMAGE = 1

while true do
	task.wait(1)

	local target = nil
	local closest = RANGE
	for _, enemy in ipairs(enemies:GetChildren()) do
		local distance = (enemy.Position - tower.Position).Magnitude
		if distance < closest then
			target = enemy
			closest = distance
		end
	end

	if target then
		target.Health.Value -= DAMAGE
		if target.Health.Value <= 0 then
			target:Destroy()
		else
			target.Color = Color3.new(1, 1, 1)
			task.wait(0.1)
			target.Color = Color3.fromRGB(255, 60, 60)
		end
	end
end

What each part does

  • The loop measures the distance from the tower to every enemy and remembers the closest one.
  • RANGE is how far the tower can reach. DAMAGE is how much health one hit removes.
  • When Health reaches 0, Destroy removes the enemy.

More detail

  • Put the tower 8 to 12 studs from the path. The range is 25 studs in every direction.
  • One tower takes 3 seconds for one enemy, and a new enemy comes every 3 seconds. So one tower can hold the path only if the enemies stay in range long enough.
  • The white flash lasts a tenth of a second. Look closely to see it.
  • For a second tower, select Tower and press Ctrl+D, then move the copy. The script comes with it.
Tip. A tower works best next to a turn, because enemies stay in range longer there.
This step does not work for me

Check these three things first

  • The name of every part and script is exactly as in the guide, with the same capital letters.
  • The script sits inside the right object. Look at the label above the code box.
  • Open the Output window from the Window menu. Red text shows the script and the line with the problem.

Still stuck? Write to us →

7
Step 7 / 8

Test and balance

  1. Press F5 and watch a few waves.
  2. If no enemy ever reaches the base, the game is too easy. If the base loses all its health quickly, it is too hard.
  3. Balance it with three numbers: the wait time in Waves, the Health value of the enemy and the DAMAGE of the tower.
  4. Press Shift+F5 to stop. If something fails, open the Output window from the Window menu and read the red text.

More detail

  • Change only one number at a time, then play again. Otherwise you do not know which change helped.
  • The wait time is the number in task.wait(3) near the end of the Waves script. A smaller number sends enemies faster.
  • The enemy's Health is in ServerStorage, inside Enemy. The tower's DAMAGE is at the top of the Tower script.
  • A good first goal: the base should survive two minutes with two towers.
This step does not work for me

Check these three things first

  • The name of every part and script is exactly as in the guide, with the same capital letters.
  • The script sits inside the right object. Look at the label above the code box.
  • Open the Output window from the Window menu. Red text shows the script and the line with the problem.

Still stuck? Write to us →

8
Step 8 / 8

Publish it

  1. Choose File → Publish to Roblox. Give the game a name and a short description.
  2. On the Creator Hub website open your game and fill in the Maturity questionnaire.
  3. Set the game to Public and send the link to a friend.

More detail

  • The first time you publish, Studio asks for a name and a description. Click Create.
  • Creator Hub is the website create.roblox.com. Sign in with the same account and click your game in the list.
  • Roblox may ask for more before a game can be public, for example an age check on the account. The page tells you what is missing.
  • If you are under 18, do this step together with a parent.
Tip. Show the game to a friend and ask one question: was it too easy or too hard? Then change one number and test again.
This step does not work for me

Check these three things first

  • The name of every part and script is exactly as in the guide, with the same capital letters.
  • The script sits inside the right object. Look at the label above the code box.
  • Open the Output window from the Window menu. Red text shows the script and the line with the problem.

Still stuck? Write to us →

Now change it yourself

  • Add a second tower with a short range and DAMAGE 2.
  • Make the waves faster over time. Hint: keep the wait time in a variable and make it a little smaller after every enemy.
  • Give the base 20 health and make every enemy remove 2.