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. 1

    Open a Baseplate

    Start Roblox Studio, choose the Baseplate template, then open View → Explorer, View → Properties and View → Output. Output is where errors appear — keep it open.

  2. 2

    Create the tycoon model

    In Workspace, insert a Model named Tycoon. Inside it add a Folder named Buttons and a Folder named Drops.

  3. 3

    Add the parts

    Inside Tycoon, insert four Parts and set Anchored to 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. 4

    Prepare one unlockable item

    Build a second dropper exactly where it should appear, name the part Dropper, put it in a Model named Dropper2, then drag that model into ServerStorage and inside a new Folder named TycoonItems. Items wait there until someone buys them.

  5. 5

    Add a buy button

    In Tycoon → Buttons, add a flat green Part named BuyDropper2. In Properties, scroll to Attributes and add Price (number, e.g. 50) and Unlocks (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.

PlayerData.server.lua
-- 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.

TycoonScript.server.lua
-- 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)
end

What each part does

  • Droppers are found by name, so any bought item containing a part named Dropper starts producing on its own. Give a dropper a DropValue or Interval attribute to make it better.
  • The conveyor is anchored but has a velocity — Roblox moves anything resting on it. Raise the 8 for 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. 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. 2

    Buy the upgrade

    At 50 cash, step on the button. The second dropper appears and starts producing.

  3. 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 * 8 to * -8.
  • Drops fall through the floor — the dropper is inside the conveyor; raise it.
  • Button does nothing — check the Unlocks attribute exactly matches the item name in TycoonItems.

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.

Keep reading