Roblox devving, made simple

A collection of clean, ready-to-use Lua scripts for your Roblox games. From crypto simulators to obby checkpoints โ€” just copy, paste, and build.

What is this?

Claudeblox Engineering is a curated library of Roblox Lua scripts organized by game type and feature. Whether you're building a tycoon, simulator, obby, or RPG โ€” we've got the foundational code you need. All scripts follow best practices and are designed to be readable, modifiable, and game-ready.

๐Ÿ’ฐ Crypto & Economy Systems

Crypto Mining System Intermediate
local MiningSystem = {}

local CRYPTO_TYPES = {
    Bitcoin = {rate = 0.00001, difficulty = 1.0},
    Ethereum = {rate = 0.0003, difficulty = 0.8},
    Dogecoin = {rate = 1.5, difficulty = 0.3},
}

function MiningSystem:mine(player, cryptoType)
    local crypto = CRYPTO_TYPES[cryptoType]
    if not crypto then return end
    
    local miner = player:GetAttribute("MinerLevel") or 1
    local earned = crypto.rate * miner / crypto.difficulty
    
    local wallet = player.leaderstats[cryptoType]
    wallet.Value = wallet.Value + earned
end

return MiningSystem
Crypto Wallet UI Handler Beginner
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local wallet = script.Parent

local function formatCrypto(value)
    if value >= 1000000 then
        return string.format("%.2fM", value / 1000000)
    elseif value >= 1000 then
        return string.format("%.2fK", value / 1000)
    end
    return string.format("%.4f", value)
end

player.leaderstats.Bitcoin.Changed:Connect(function(val)
    wallet.BitcoinLabel.Text = formatCrypto(val)
end)
Trading System Advanced
local TradeService = {}
local activeTrades = {}

function TradeService:createOffer(seller, crypto, amount, price)
    local offer = {
        id = HttpService:GenerateGUID(),
        seller = seller.UserId,
        crypto = crypto,
        amount = amount,
        pricePerUnit = price,
        timestamp = os.time()
    }
    table.insert(activeTrades, offer)
    return offer.id
end

function TradeService:acceptOffer(buyer, offerId)
    for i, offer in ipairs(activeTrades) do
        if offer.id == offerId then
            local totalCost = offer.amount * offer.pricePerUnit
            -- Transfer crypto and cash
            table.remove(activeTrades, i)
            return true
        end
    end
    return false
end

๐Ÿƒ Obby & Platformer Systems

Checkpoint System Beginner
local checkpoint = script.Parent
local stageNumber = checkpoint:GetAttribute("Stage")

checkpoint.Touched:Connect(function(hit)
    local player = Players:GetPlayerFromCharacter(hit.Parent)
    if not player then return end
    
    local currentStage = player.leaderstats.Stage.Value
    
    if stageNumber > currentStage then
        player.leaderstats.Stage.Value = stageNumber
        player.RespawnLocation = checkpoint
        
        -- Play checkpoint sound
        checkpoint.Sound:Play()
    end
end)
Kill Brick Beginner
local killPart = script.Parent
local debounce = {}

killPart.Touched:Connect(function(hit)
    local humanoid = hit.Parent:FindFirstChild("Humanoid")
    if not humanoid then return end
    
    local player = Players:GetPlayerFromCharacter(hit.Parent)
    if debounce[player] then return end
    
    debounce[player] = true
    humanoid.Health = 0
    
    task.delay(1, function()
        debounce[player] = nil
    end)
end)
Moving Platform Intermediate
local TweenService = game:GetService("TweenService")
local platform = script.Parent

local startPos = platform.Position
local endPos = startPos + Vector3.new(20, 0, 0)
local moveTime = 3

local tweenInfo = TweenInfo.new(
    moveTime,
    Enum.EasingStyle.Sine,
    Enum.EasingDirection.InOut,
    -1, -- infinite repeat
    true -- reverse
)

local tween = TweenService:Create(
    platform,
    tweenInfo,
    {Position = endPos}
)

tween:Play()

๐Ÿพ Pet & Collection Systems

Pet Follow System Intermediate
local PetModule = {}

function PetModule:spawnPet(player, petId)
    local petModel = ReplicatedStorage.Pets[petId]:Clone()
    local character = player.Character
    
    petModel.Parent = workspace.ActivePets
    
    -- Follow behavior
    RunService.Heartbeat:Connect(function()
        if not character then return end
        
        local targetPos = character.HumanoidRootPart.Position
            + Vector3.new(3, 2, 0)
        
        local newCF = CFrame.new(
            petModel.PrimaryPart.Position:Lerp(targetPos, 0.1)
        )
        petModel:SetPrimaryPartCFrame(newCF)
    end)
end
Egg Hatching Intermediate
local EggService = {}

local EGGS = {
    Common = {
        cost = 100,
        pets = {
            {name = "Dog", chance = 40},
            {name = "Cat", chance = 40},
            {name = "Bunny", chance = 20},
        }
    },
    Rare = {
        cost = 500,
        pets = {
            {name = "Dragon", chance = 10},
            {name = "Phoenix", chance = 5},
            {name = "Unicorn", chance = 85},
        }
    }
}

function EggService:hatch(player, eggType)
    local egg = EGGS[eggType]
    local roll = math.random(1, 100)
    local cumulative = 0
    
    for _, pet in ipairs(egg.pets) do
        cumulative = cumulative + pet.chance
        if roll <= cumulative then
            return pet.name
        end
    end
end
Pet Inventory Beginner
local MAX_PETS = 50

function addPet(player, petName)
    local inventory = playerData[player.UserId].pets
    
    if #inventory >= MAX_PETS then
        return false, "Inventory full!"
    end
    
    local pet = {
        id = HttpService:GenerateGUID(),
        name = petName,
        level = 1,
        equipped = false
    }
    
    table.insert(inventory, pet)
    return true, pet
end

๐Ÿญ Tycoon & Building Systems

Dropper System Beginner
local dropper = script.Parent
local dropPart = ReplicatedStorage.DropPart

local DROP_RATE = 1 -- seconds
local DROP_VALUE = 5

while true do
    task.wait(DROP_RATE)
    
    local newDrop = dropPart:Clone()
    newDrop.Position = dropper.Position - Vector3.new(0, 2, 0)
    newDrop:SetAttribute("Value", DROP_VALUE)
    newDrop.Parent = workspace.Drops
    
    Debris:AddItem(newDrop, 30)
end
Collector/Conveyor Beginner
local collector = script.Parent
local owner = collector:GetAttribute("Owner")

collector.Touched:Connect(function(hit)
    local value = hit:GetAttribute("Value")
    if not value then return end
    
    local player = Players:GetPlayerByUserId(owner)
    if player then
        player.leaderstats.Cash.Value += value
    end
    
    hit:Destroy()
end)
Button Purchase Intermediate
local button = script.Parent
local price = button:GetAttribute("Price")
local unlockItem = button:GetAttribute("Unlocks")

local debounce = false

button.Touched:Connect(function(hit)
    if debounce then return end
    
    local player = Players:GetPlayerFromCharacter(hit.Parent)
    if not player then return end
    
    local cash = player.leaderstats.Cash
    
    if cash.Value >= price then
        debounce = true
        cash.Value -= price
        
        -- Unlock the item
        local item = button.Parent[unlockItem]
        item.Transparency = 0
        item.CanCollide = true
        
        button:Destroy()
    end
end)

๐Ÿ’พ Data & Saving Systems

DataStore Save/Load Advanced
local DataStoreService = game:GetService("DataStoreService")
local playerStore = DataStoreService:GetDataStore("PlayerData_v1")

local DEFAULT_DATA = {
    cash = 0,
    level = 1,
    inventory = {},
    settings = {music = true, sfx = true}
}

function loadData(player)
    local key = "Player_" .. player.UserId
    
    local success, data = pcall(function()
        return playerStore:GetAsync(key)
    end)
    
    if success and data then
        return data
    end
    return DEFAULT_DATA
end

function saveData(player, data)
    local key = "Player_" .. player.UserId
    
    pcall(function()
        playerStore:SetAsync(key, data)
    end)
end
Leaderstats Setup Beginner
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player
    
    local cash = Instance.new("IntValue")
    cash.Name = "Cash"
    cash.Value = 0
    cash.Parent = leaderstats
    
    local level = Instance.new("IntValue")
    level.Name = "Level"
    level.Value = 1
    level.Parent = leaderstats
end)
Auto-Save System Intermediate
local SAVE_INTERVAL = 60 -- seconds

-- Auto-save loop
while true do
    task.wait(SAVE_INTERVAL)
    
    for _, player in ipairs(Players:GetPlayers()) do
        local data = collectPlayerData(player)
        saveData(player, data)
    end
end

-- Save on leave
Players.PlayerRemoving:Connect(function(player)
    local data = collectPlayerData(player)
    saveData(player, data)
end)

-- Save on shutdown
game:BindToClose(function()
    for _, player in ipairs(Players:GetPlayers()) do
        local data = collectPlayerData(player)
        saveData(player, data)
    end
end)

โš”๏ธ Combat & Abilities Systems

Basic Sword Beginner
local tool = script.Parent
local damage = 25
local debounce = false

tool.Handle.Touched:Connect(function(hit)
    if debounce then return end
    
    local humanoid = hit.Parent:FindFirstChild("Humanoid")
    if not humanoid then return end
    if humanoid == tool.Parent.Humanoid then return end
    
    debounce = true
    humanoid:TakeDamage(damage)
    
    task.delay(0.5, function()
        debounce = false
    end)
end)
Cooldown Manager Intermediate
local CooldownManager = {}
local cooldowns = {}

function CooldownManager:start(player, ability, duration)
    local key = player.UserId .. "_" .. ability
    cooldowns[key] = tick() + duration
end

function CooldownManager:isReady(player, ability)
    local key = player.UserId .. "_" .. ability
    local endTime = cooldowns[key]
    
    if not endTime then return true end
    return tick() >= endTime
end

function CooldownManager:remaining(player, ability)
    local key = player.UserId .. "_" .. ability
    local endTime = cooldowns[key]
    
    if not endTime then return 0 end
    return math.max(0, endTime - tick())
end
Projectile System Advanced
local Projectile = {}

function Projectile:fire(origin, direction, speed, damage)
    local bullet = Instance.new("Part")
    bullet.Size = Vector3.new(0.5, 0.5, 2)
    bullet.CFrame = CFrame.new(origin, origin + direction)
    bullet.Anchored = false
    bullet.CanCollide = false
    bullet.Parent = workspace
    
    local velocity = Instance.new("BodyVelocity")
    velocity.Velocity = direction.Unit * speed
    velocity.MaxForce = Vector3.new(1e9, 1e9, 1e9)
    velocity.Parent = bullet
    
    bullet.Touched:Connect(function(hit)
        local humanoid = hit.Parent:FindFirstChild("Humanoid")
        if humanoid then
            humanoid:TakeDamage(damage)
        end
        bullet:Destroy()
    end)
    
    Debris:AddItem(bullet, 5)
end

๐ŸŽฎ UI & Effects Systems

Notification System Beginner
local TweenService = game:GetService("TweenService")
local notifFrame = script.Parent

function showNotification(message, duration)
    duration = duration or 3
    
    notifFrame.TextLabel.Text = message
    notifFrame.Position = UDim2.new(0.5, 0, -0.1, 0)
    notifFrame.Visible = true
    
    local slideIn = TweenService:Create(
        notifFrame,
        TweenInfo.new(0.3),
        {Position = UDim2.new(0.5, 0, 0.1, 0)}
    )
    slideIn:Play()
    
    task.delay(duration, function()
        local slideOut = TweenService:Create(
            notifFrame,
            TweenInfo.new(0.3),
            {Position = UDim2.new(0.5, 0, -0.1, 0)}
        )
        slideOut:Play()
    end)
end
Button Hover Effects Beginner
local TweenService = game:GetService("TweenService")
local button = script.Parent

local originalSize = button.Size

button.MouseEnter:Connect(function()
    TweenService:Create(
        button,
        TweenInfo.new(0.15),
        {Size = originalSize + UDim2.new(0.02, 0, 0.02, 0)}
    ):Play()
end)

button.MouseLeave:Connect(function()
    TweenService:Create(
        button,
        TweenInfo.new(0.15),
        {Size = originalSize}
    ):Play()
end)
Daily Reward Timer Intermediate
local REWARD_COOLDOWN = 86400 -- 24 hours

function canClaimReward(player)
    local lastClaim = playerData[player.UserId].lastReward
    if not lastClaim then return true end
    
    return os.time() - lastClaim >= REWARD_COOLDOWN
end

function claimReward(player)
    if not canClaimReward(player) then
        return false
    end
    
    local streak = playerData[player.UserId].streak or 0
    streak = streak + 1
    
    local reward = 100 * streak
    player.leaderstats.Cash.Value += reward
    
    playerData[player.UserId].lastReward = os.time()
    playerData[player.UserId].streak = streak
    
    return true, reward
end