How to make a tycoon in Roblox Studio
A working tycoon from an empty Baseplate — claim pad, droppers, conveyor, collector, buy buttons and saved cash — with complete Luau scripts.
Updated October 23, 202612 min read
A tycoon is the classic first Roblox game: you claim a plot, machines make money, and you spend that money on buttons that unlock more machines. It looks simple, but it touches most of what a real game needs — server scripts, a leaderboard, physics, purchases and saving. This guide builds a working one-plot tycoon from an empty Baseplate. Every script below is complete; paste it as-is and it runs.
How a tycoon works
Every tycoon, from a lemonade stand to a giant factory, is the same loop:
- Claim pad — the first player to touch it owns the plot.
- Dropper — spawns a small part every few seconds. Each part carries a cash value.
- Conveyor — moves the parts along.
- Collector — destroys parts and adds their value to the owner's cash.
- Buy buttons — cost cash and unlock the next dropper, a wall, an upgrade.
- Leaderstats and saving — shows cash on the player list and keeps it between visits.
All of this runs in server Scripts. Money must never be decided on the player's device, or exploiters can give themselves anything.
Step 1: Set up the place
- 1
Open a Baseplate
Start Roblox Studio, choose the Baseplate template, then open
View → Explorer,View → PropertiesandView → Output. Output is where errors appear — keep it open. - 2
Create the tycoon model
In Workspace, insert a
ModelnamedTycoon. Inside it add aFoldernamedButtonsand aFoldernamedDrops. - 3
Add the parts
Inside
Tycoon, insert four Parts and setAnchoredto true on each:ClaimPad— a flat 6×1×6 part at the plot entrance.Dropper— a block raised a few studs above the conveyor's start.Conveyor— a long 4×1×20 strip. Turn it so its front face (the Move tool's blue arrow side) points toward the collector.Collector— a part at the conveyor's end, a little higher than the belt so drops bump into it.
- 4
Prepare one unlockable item
Build a second dropper exactly where it should appear, name the part
Dropper, put it in a Model namedDropper2, then drag that model intoServerStorageand inside a new Folder namedTycoonItems. Items wait there until someone buys them. - 5
Add a buy button
In
Tycoon → Buttons, add a flat green Part namedBuyDropper2. In Properties, scroll to Attributes and addPrice(number, e.g. 50) andUnlocks(string,Dropper2).
Step 2: Cash on the leaderboard, saved between visits
Insert a Script into ServerScriptService, name it PlayerData and paste this. A folder named exactly leaderstats under the player is what makes Roblox show the value on the player list.
-- ServerScriptService > PlayerData (Script)
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local store = DataStoreService:GetDataStore("TycoonCash_v1")
local function save(player)
-- Never save over real progress if loading failed.
if not player:GetAttribute("DataLoaded") then return end
local cash = player.leaderstats.Cash
local ok, err = pcall(function()
store:SetAsync("player_" .. player.UserId, cash.Value)
end)
if not ok then
warn("Could not save", player.Name, err)
end
end
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats" -- this exact name shows the board
leaderstats.Parent = player
local cash = Instance.new("IntValue")
cash.Name = "Cash"
cash.Parent = leaderstats
local ok, saved = pcall(function()
return store:GetAsync("player_" .. player.UserId)
end)
if ok then
cash.Value = saved or 0
player:SetAttribute("DataLoaded", true)
else
warn("Could not load", player.Name, saved)
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
for _, player in Players:GetPlayers() do
task.spawn(onPlayerAdded, player) -- anyone who joined before this ran
end
Players.PlayerRemoving:Connect(save)
game:BindToClose(function()
for _, player in Players:GetPlayers() do
save(player)
end
end)Step 3: The tycoon script
Insert a Script directly inside the Tycoon model, name it TycoonScript and paste this. It handles the claim pad, droppers, conveyor, collector and buttons.
-- Workspace > Tycoon > TycoonScript (Script)
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
local ServerStorage = game:GetService("ServerStorage")
local tycoon = script.Parent
local items = ServerStorage:WaitForChild("TycoonItems")
local owner = nil -- the Player who claimed this plot
local function cashOf(player)
local stats = player:FindFirstChild("leaderstats")
return stats and stats:FindFirstChild("Cash")
end
-- 1. Claim: the first player to step on the pad owns the plot.
tycoon.ClaimPad.Touched:Connect(function(hit)
if owner then return end
local player = Players:GetPlayerFromCharacter(hit.Parent)
if not player or player:GetAttribute("OwnsTycoon") then return end
owner = player
player:SetAttribute("OwnsTycoon", true)
tycoon.ClaimPad.BrickColor = BrickColor.new("Lime green")
end)
Players.PlayerRemoving:Connect(function(player)
if player == owner then
owner = nil
tycoon.ClaimPad.BrickColor = BrickColor.new("Medium stone grey")
end
end)
-- 2. Droppers: every part named "Dropper" spawns a block worth cash.
local function runDropper(dropper)
task.spawn(function()
while dropper.Parent do
if owner then
local drop = Instance.new("Part")
drop.Size = Vector3.new(1, 1, 1)
drop.BrickColor = BrickColor.new("Bright yellow")
drop.CFrame = dropper.CFrame * CFrame.new(0, -dropper.Size.Y / 2 - 1, 0)
drop:SetAttribute("Value", dropper:GetAttribute("DropValue") or 1)
drop.Parent = tycoon.Drops
drop:SetNetworkOwner(nil) -- the server moves drops, not a client
Debris:AddItem(drop, 20) -- clean up anything that falls off
end
task.wait(dropper:GetAttribute("Interval") or 2)
end
end)
end
for _, part in tycoon:GetDescendants() do
if part.Name == "Dropper" and part:IsA("BasePart") then
runDropper(part)
end
end
tycoon.DescendantAdded:Connect(function(part)
if part.Name == "Dropper" and part:IsA("BasePart") then
runDropper(part)
end
end)
-- 3. Conveyor: an anchored part with a velocity pushes whatever sits on it.
tycoon.Conveyor.AssemblyLinearVelocity = tycoon.Conveyor.CFrame.LookVector * 8
-- 4. Collector: turns drops into the owner's cash.
tycoon.Collector.Touched:Connect(function(hit)
local value = hit:GetAttribute("Value")
if not value or hit.Parent ~= tycoon.Drops then return end
hit:Destroy()
local cash = owner and cashOf(owner)
if cash then
cash.Value += value
end
end)
-- 5. Buy buttons: each has Price (number) and Unlocks (item name) attributes.
for _, button in tycoon.Buttons:GetChildren() do
local price = button:GetAttribute("Price") or 0
local item = items:FindFirstChild(button:GetAttribute("Unlocks") or "")
button.Touched:Connect(function(hit)
if not owner or not item or not button.Parent then return end
if Players:GetPlayerFromCharacter(hit.Parent) ~= owner then return end
local cash = cashOf(owner)
if not cash or cash.Value < price then return end
cash.Value -= price
item.Parent = tycoon -- it appears exactly where you built it
button:Destroy()
end)
endWhat each part does
- Droppers are found by name, so any bought item containing a part named
Dropperstarts producing on its own. Give a dropper aDropValueorIntervalattribute to make it better. - The conveyor is anchored but has a velocity — Roblox moves anything resting on it. Raise the
8for a faster belt. Moving or resizing the part resets its velocity, which is why the script sets it on start. SetNetworkOwner(nil)keeps drop physics on the server, so a player's device can't teleport drops into the collector.- Buttons check that the person touching them is the owner and has enough cash, then move the item from ServerStorage into the plot.
Step 4: Test it
- 1
Press Play
Walk onto the claim pad — it turns green and the dropper starts. Watch cash rise in the top-right player list.
- 2
Buy the upgrade
At 50 cash, step on the button. The second dropper appears and starts producing.
- 3
Test with two players
In the testing controls on the left of Studio's top bar, pick Server & Clients, choose 2 clients and press Play. Make sure the second player cannot claim the plot or press its buttons. Close the test with End Session.
If something does not work
- Nothing happens and Output says “X is not a valid member of Model” — a part name doesn't match the script. Names are case-sensitive.
- Drops slide the wrong way — rotate the conveyor 180° or change
* 8to* -8. - Drops fall through the floor — the dropper is inside the conveyor; raise it.
- Button does nothing — check the
Unlocksattribute exactly matches the item name inTycoonItems.
Step 5: Make it a real game
The loop works. What separates a test place from a tycoon people play for an hour:
- A progression curve. Each upgrade should cost roughly 1.5–2.5× the last and pay back in a minute or two. Plan 15–30 buttons before you build them.
- Multiple plots. Duplicate the Tycoon model for each player slot. Items in ServerStorage then need to be positioned relative to each plot, e.g. with
PivotTo. - Saving purchases, not just cash: store a list of bought item names and rebuild the plot on join.
- Rebirths — reset the plot for a permanent multiplier. This is what keeps players coming back.
- Monetization — a 2× cash game pass is the classic one. See how to make a game pass.
- Looks. Replace grey blocks with a themed build, add a UI for cash and a sound when money comes in.
FAQ
How long does it take to make a tycoon in Roblox Studio?
The basic loop in this guide takes about an hour. A tycoon people actually play, with 20 or more upgrades, rebirths, saving and a themed build, usually takes days to weeks.
Why does my tycoon cash not save in Studio?
Data stores only work in a published place, and Studio needs 'Enable Studio Access to API Services' turned on in the game's Security settings. In a live server they work without that toggle.
Should tycoon scripts be Scripts or LocalScripts?
Server Scripts. Cash, purchases and drops must be handled on the server, otherwise exploiters can change them. LocalScripts are only for UI and input.