§ How to · with Picoo

How to make a Roblox simulator (with AI)

By Sametcan Tasgiran, Founder & Developer·Published ·Updated

A Roblox simulator runs on one loop: collect, earn, upgrade, rebirth, repeat. Ask Picoo to make a simulator game, or a collecting simulator with upgrades and rebirth, and it applies its simulator_loop recipe, which builds the whole loop with one server script and the orbs and pads it runs on.

5 files · 1,158 lines · one recipe call. Collect orbs, buy upgrades, rebirth for a bigger multiplier.

Collectible orbs

40 Neon orbs scattered over a 120-stud zone. Walk through one to collect it; it pays once, disappears, and respawns 4 seconds later at a new random spot. Collection happens on the server.

Upgrade pad

Step on UPGRADE to buy a level for 25 × 1.15^level coins. Each level multiplies orb value by 1.08, so cost grows faster than power and each upgrade takes a little longer than the last.

Rebirth pad

Step on REBIRTH with 1000 × (rebirths + 1)^1.5 coins to reset coins and level for one more rebirth. Each rebirth adds 50% to your power: 1 + 0.5 × rebirths.

Saved before rebirth

The rebirth writes the new state to the DataStore first and applies it only after the save succeeds, so a failed save changes nothing.

Leaderstats + saves

Coins and Rebirths show in the player list. Coins, level and rebirths save to the Simulator_v1 DataStore when a player leaves and when the server shuts down, and load on join. A failed load is never saved over: that session does not save, and on a live server the rebirth pad does nothing for that player; in a Studio play test it works but is not saved.

Pickup and rebirth effects

Pickups show a floating score, upgrades pulse the pad and pop a LEVEL label over the player, and a rebirth gets a full reveal.

Files Picoo ships for this prompt

5 files · 1158 lines · one recipe call

ServerScriptService/SimulatorServer.lua

Orb pickups, upgrade and rebirth pads, cost curves, leaderstats and DataStore saves

295 lines

Workspace/Orbs

Folder of 40 Neon orbs the server scatters over a 120-stud zone

instance

Workspace/SimPads

UPGRADE and REBIRTH pads with floating labels

instance

ReplicatedStorage/PicooFeedback

Shared game-feel module for the pickup, score, level-up and rebirth effects

851 lines

StarterPlayer/StarterPlayerScripts/PicooFeedbackClient

Loads the client half of PicooFeedback for every player

12 lines

Sample output: ServerScriptService/SimulatorServer.lua

--!strict
-- Generated by Picoo recipe: simulator_loop
-- collect -> currency -> multiplier -> rebirth

-- (excerpt)

--------------------------------------------------------------------
-- CURVES — the whole game is these three functions.
--------------------------------------------------------------------

-- Cost grows geometrically, power grows more slowly. Each upgrade then takes a
-- little longer to earn than the last, so upgrades never turn trivial while the
-- numbers grow, which is the rhythm players actually stay for.
local function upgradeCost(level: number): number
	return math.floor(BASE_COST * COST_GROWTH ^ level)
end

local function powerOf(d: Data): number
	-- Rebirths are a separate, linear multiplier on top. Folding them into the
	-- same exponential is what makes late numbers unreadable.
	return POWER_GROWTH ^ d.level * (1 + 0.5 * d.rebirths)
end

local function rebirthRequirement(rebirths: number): number
	return math.floor(REBIRTH_REQ * (rebirths + 1) ^ 1.5)
end

-- (excerpt)

--------------------------------------------------------------------
-- REBIRTH PAD
--------------------------------------------------------------------

rebirthPad.Touched:Connect(function(hit)
	local character = hit:FindFirstAncestorOfClass("Model")
	local player = character and Players:GetPlayerFromCharacter(character)
	local d = player and data[player.UserId]
	if not player or not d or not padReady(player) then return end
	-- Rebirth saves too: never over a failed load. A live server does nothing for
	-- that player; a Studio play test rebirths in memory only (below).
	if not loaded[player.UserId] and not playTest[player.UserId] then return end

	local need = rebirthRequirement(d.rebirths)
	if d.coins < need then return end

	-- ORDER MATTERS. Compute the next state, PERSIST it, and only then apply it.
	-- Clearing progress before the save means a failure in between leaves the
	-- player wiped with nothing gained, and that is unrecoverable.
	local nextState: Data = { coins = 0, level = 0, rebirths = d.rebirths + 1 }
	if loaded[player.UserId] then
		local _, err = safe(function() return (STORE :: DataStore):SetAsync("u_" .. player.UserId, nextState) end)
		if err then
			warn("[Simulator] rebirth save failed, nothing changed: " .. err)
			return
		end
	end

	data[player.UserId] = nextState
	stats(player)
	-- The one moment in a simulator worth a full reveal: the player just traded
	-- everything they had for it.
	Feedback.reveal(rebirthPad, { name = "REBIRTH " .. nextState.rebirths, weight = 1, color = Color3.fromRGB(255, 190, 90) }, { player = player })
end)

Building a Roblox simulator

Simulator is the easiest genre to start and the easiest to unbalance. The loop is collect, earn, upgrade, rebirth, and it usually breaks economically rather than technically: upgrades that are trivial by level ten, a power curve that stalls, or a rebirth that wipes a player when a save fails. simulator_loop is built around those three.

The curves are three functions near the top of SimulatorServer. An upgrade costs 25 × 1.15^level coins and each level multiplies orb value by 1.08, so cost outgrows power and each upgrade takes a little longer than the last as the numbers climb. Rebirth is a separate, linear multiplier on top, 1 + 0.5 × rebirths, and its requirement grows as 1000 × (rebirths + 1)^1.5. The base cost, both growth rates and the rebirth requirement are recipe settings you can set in the prompt.

Rebirth is where simulators lose players' progress. The rebirth pad computes the next state (0 coins, level 0, one more rebirth), writes it to the DataStore first, and applies it only after the write succeeds; if the save fails, nothing changes. Regular saves happen when a player leaves and when the server shuts down (BindToClose), and coins, level and rebirths load back on join. If that load fails, the session is never saved and, on a live server, the rebirth pad, which also writes to the DataStore, does nothing for that player, so the progress already stored is never overwritten. In a Studio play test of an unpublished place (or with Studio API access off), where every load fails, the rebirth works in memory and nothing is saved.

Orbs are collected by the server. Each of the 40 Neon orbs pays out once per pickup, turns invisible and untouchable, and respawns 4 seconds later at a random spot in the 120-stud zone. Pickups, level-ups and rebirths get PicooFeedback effects: a floating score, a pad pulse with a LEVEL label over the player on upgrade, and a full reveal on rebirth. Shops, pets, gamepasses and a global leaderboard are follow-up prompts on top.

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 is collecting protected from exploits?+

There is no collect remote to fire: orbs are collected by the server's own Touched handler. Each orb pays once, then goes invisible and untouchable until it respawns 4 seconds later, so walking through it with several body parts, or touching it again, does not pay twice.

Can I change the economy?+

Yes. Describe it and Picoo passes the values to the recipe: currency name, orb count (5 to 120), orb value, upgrade base cost, cost growth (1.02 to 2), power growth (1.01 to 1.5), rebirth requirement and zone size (40 to 400 studs). All but the orb count also sit as constants near the top of SimulatorServer; the orb count is the number of orbs in Workspace/Orbs.

How does rebirth interact with upgrades?+

Rebirth resets coins and upgrade level to 0 and adds one rebirth. Your power is the upgrade multiplier (1.08^level) times 1 + 0.5 × rebirths, and the next rebirth costs more: 1000 × (rebirths + 1)^1.5.

Can I add a cross-server leaderboard?+

Yes. Ask for a global leaderboard of the top players. Picoo's global_leaderboard recipe reads the Coins leaderstat by default, the one this simulator creates, and shows the top 10 across all servers on a board, from an OrderedDataStore it updates when players leave and every 60 seconds.

What about gamepass perks?+

Ask for them in a follow-up prompt, for example a 2x coins gamepass. Orb payouts are computed in one place, the orb Touched handler that multiplies by powerOf, which is where a gamepass multiplier goes.

Related Picoo prompts