§ How to · with Picoo
How to make a Roblox tower defense game (with AI)
By Sametcan Tasgiran, Founder & Developer·Published ·Updated
A Roblox tower defense game needs five pieces: tower placement, wave spawner, enemy pathing, currency drops on kill, and an upgrade UI. Ask Picoo for a tower defense game and it writes these for your map; the example below has 5 tower archetypes and 3 enemy types.
Example build: 11 files · 390 lines. Per-team economy, wave-based progression.
5 tower archetypes
Sniper (long range, slow), Cannon (AoE, medium), Machine Gun (fast, short), Sentry (chains lightning), Frost (slows enemies). Each has placement cost and 3 upgrade tiers.
Wave spawner
Configurable wave table — count, enemy mix, spawn interval. Starts on first tower placed. Auto-advances to next wave after kill count met.
Enemy pathing
PathfindingService generates path on map load. Enemies follow waypoints. Pathing recomputes if a tower blocks the existing path (configurable).
Currency drops
Each kill drops cash equal to enemy bounty. Player's earned cash funds new towers. Wave completion bonus added at end of each wave.
Upgrade UI
Click tower → upgrade panel shows next tier stats and cost. Tier 3 max. Sell button refunds 75% of total invested.
Endless mode
After wave 30, infinite scaling — each wave 15% stronger than the last. Leaderboard tracks farthest wave reached.
Example output from a build like this
11 files in this example. Picoo writes this code for your prompt, so file names and sizes vary.
ServerScriptService/TowerManager.lua
Tower placement, targeting, attack timing
ServerScriptService/WaveSpawner.lua
Wave progression, enemy spawn timing
ServerScriptService/EnemyManager.lua
Enemy spawn, path follow, death
ServerScriptService/EconomyManager.lua
Cash tracking, bounty drops
ReplicatedStorage/Modules/TowerConfig.lua
Per-tower stats
ReplicatedStorage/Modules/WaveConfig.lua
Wave-by-wave enemy mix
ReplicatedStorage/Remotes/PlaceTower
Client → server place
ReplicatedStorage/Remotes/UpgradeTower
Upgrade request
StarterGui/TowerShopUI.lua
Tower selection panel
StarterGui/UpgradePanel.lua
Upgrade + sell UI
StarterGui/WaveHUD.lua
Current wave + cash display
Sample output: ServerScriptService/TowerManager.lua
--!strict
-- ServerScriptService/TowerManager.lua (Picoo · excerpt)
local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TowerConfig = require(ReplicatedStorage.Modules.TowerConfig)
local EnemyManager = require(script.Parent.EnemyManager)
local function pickTarget(tower: Model, range: number): Model?
local pos = tower.PrimaryPart.Position
local closest, closestDist = nil, range
for _, enemy in ipairs(EnemyManager:getActive()) do
local d = (enemy.PrimaryPart.Position - pos).Magnitude
if d < closestDist then closest, closestDist = enemy, d end
end
return closest
end
local function tickTower(tower: Model)
local towerType = tower:GetAttribute("TowerType") :: string
local tier = tower:GetAttribute("Tier") :: number
local config = TowerConfig[towerType].tiers[tier]
while tower.Parent do
local target = pickTarget(tower, config.range)
if target then
EnemyManager:damage(target, config.damage)
-- Spawn projectile/effect handled by client via attribute change
tower:SetAttribute("LastFire", os.clock())
end
task.wait(config.fireRate)
end
end
CollectionService:GetInstanceAddedSignal("Tower"):Connect(function(t)
task.spawn(tickTower, t)
end)Building a Roblox tower defense game
Tower defense is one of Roblox's highest-revenue genres — Tower Defense Simulator alone has billions of visits. The pattern that makes a TD game work: clean tower placement, predictable enemy pathing, satisfying upgrade feedback, and waves that scale faster than your defense. The example below covers the whole pattern.
In this example the build is 11 files. The 5 tower archetypes cover the canonical roles: Sniper (single high damage), Cannon (AoE), Machine Gun (high DPS short range), Sentry (chain lightning), Frost (slow). Each has 3 upgrade tiers with linear stat scaling. Players learn the meta naturally — which towers counter which enemies — without you having to write a tutorial.
The wave spawner reads from WaveConfig.lua, a table of waves with enemy mix and spawn interval. Wave 1 might be 10 weak enemies. Wave 20 mixes fast runners with tanky bosses. The example ships a default progression; you tune the table for your difficulty curve.
Enemy pathing uses PathfindingService from spawn point to base. Pathing computes once at map load and caches the waypoints. If a player walls off the path with towers, the system recomputes — or rejects the placement, depending on whether you allow maze building. This is one config flag.
The upgrade UI is the engagement layer. Clicking a tower shows its current tier, next tier preview, and cost. Tier 3 max with a 'maxed' indicator. Sell refunds 75% of total invested. The cash flow is the core loop: kill enemies → earn cash → upgrade towers → kill harder enemies. Endless mode kicks in at wave 30 with 15% per-wave scaling, so progression continues indefinitely for players who want it.
See more on the Luau generator, the AI Luau script writer, the 3D model generator and the game builder, read how Picoo compares with ChatGPT, or browse the full blog.
Frequently asked
How do I add a new tower type?+
Add an entry to TowerConfig.lua with tiers table (damage, range, fireRate, cost per tier). TowerManager picks it up automatically. The visual model goes in ReplicatedStorage/TowerModels with the same name.
Can multiple players co-op?+
Yes. In this example the default is shared cash + shared towers (true co-op). Configurable to per-player cash with shared towers. Server tracks who placed each tower for kill credit.
What about boss enemies between waves?+
WaveConfig entries can include 'isBoss = true' on enemies. Boss enemies use a different model, have 10x HP, and pay 50x bounty. Spawn timing is staggered (one boss per wave at the end).
How does the pathing handle tower blocking?+
PathfindingService recomputes the path when a new tower is placed. If no path exists (player walled off), placement is rejected. Configurable to allow 'maze' building.
How is the leaderboard wave count saved?+
EconomyManager writes 'highestWave' to DataStore on each new max. OrderedDataStore for the global leaderboard. New maxes broadcast to all players via RemoteEvent.
Related Picoo prompts
Roblox combat system
3 scripts · 1,181 lines · one recipe call. Press Play and fight with M1, E, F, Q, R and Shift.
Roblox shop system
8 files · 1,259 lines, 852 of them the shared PicooFeedback module · one recipe call. Three starter items by default; name your own items and prices in the prompt.
Roblox leaderboard
2 files · 186 lines of Luau plus a 45-instance board · one recipe call. Ranks leaderstats Coins by default; name another stat in the prompt.