Script Library

Scripts & Modules

Original Luau modules written and maintained by Spider Games. Copy-paste ready, MIT-licensed, no obfuscation. Click any entry to expand the code.

6 modules

DataStore Wrapper

dataserverretry-safe

Thin wrapper around DataStoreService with automatic retries, exponential backoff, and session locking to avoid duped saves.

local DataStoreService = game:GetService("DataStoreService")

local Wrapper = {}
Wrapper.__index = Wrapper

function Wrapper.new(storeName: string)
    local self = setmetatable({}, Wrapper)
    self.Store = DataStoreService:GetDataStore(storeName)
    return self
end

function Wrapper:SafeGet(key: string, retries: number?)
    retries = retries or 3
    for attempt = 1, retries do
        local ok, result = pcall(function()
            return self.Store:GetAsync(key)
        end)
        if ok then
            return result
        end
        task.wait(attempt * 0.5)
    end
    warn("[DataStore] Failed to fetch key:", key)
    return nil
end

function Wrapper:SafeSet(key: string, value: any, retries: number?)
    retries = retries or 3
    for attempt = 1, retries do
        local ok = pcall(function()
            self.Store:SetAsync(key, value)
        end)
        if ok then return true end
        task.wait(attempt * 0.5)
    end
    warn("[DataStore] Failed to save key:", key)
    return false
end

return Wrapper

Notification Toast System

uiclientqueue

Queued toast notifications with tween-in/out, auto-dismiss, and a max-visible cap so spam messages don't stack forever.

local TweenService = game:GetService("TweenService")

local Toast = {}
local queue = {}
local activeCount = 0
local MAX_VISIBLE = 3

local function playToast(gui, message)
    gui.TextLabel.Text = message
    gui.Position = UDim2.new(1, 20, 0, gui.LayoutOrder * 60)
    gui.Visible = true

    local tweenIn = TweenService:Create(gui, TweenInfo.new(0.3), {Position = UDim2.new(1, -260, 0, gui.LayoutOrder * 60)})
    tweenIn:Play()

    task.delay(3, function()
        local tweenOut = TweenService:Create(gui, TweenInfo.new(0.3), {Position = UDim2.new(1, 20, 0, gui.LayoutOrder * 60)})
        tweenOut:Play()
        tweenOut.Completed:Wait()
        gui.Visible = false
        activeCount -= 1
    end)
end

function Toast.Show(gui, message)
    if activeCount >= MAX_VISIBLE then
        table.insert(queue, {gui, message})
        return
    end
    activeCount += 1
    playToast(gui, message)
end

return Toast

Camera Shake Module

fxclientcamera

Perlin-noise based camera shake with adjustable magnitude, roughness, and fade-out — good for explosions or impact feedback.

local RunService = game:GetService("RunService")
local camera = workspace.CurrentCamera

local ShakeModule = {}
local activeShakes = {}

function ShakeModule.Shake(magnitude: number, duration: number)
    table.insert(activeShakes, {magnitude = magnitude, timeLeft = duration, seed = math.random(0, 1000)})
end

RunService.RenderStepped:Connect(function(dt)
    local offset = Vector3.zero
    for i = #activeShakes, 1, -1 do
        local shake = activeShakes[i]
        shake.timeLeft -= dt
        if shake.timeLeft <= 0 then
            table.remove(activeShakes, i)
        else
            local t = os.clock() * 20 + shake.seed
            local falloff = shake.timeLeft
            offset += Vector3.new(
                math.noise(t, 0) * shake.magnitude * falloff,
                math.noise(0, t) * shake.magnitude * falloff,
                0
            )
        end
    end
    camera.CFrame = camera.CFrame * CFrame.new(offset)
end)

return ShakeModule

Inventory System (Grid)

gameplayserverstackable

Grid-based inventory with stack limits, item swapping, and server-authoritative validation to prevent client-side item duping.

local Inventory = {}
Inventory.__index = Inventory

function Inventory.new(slotCount: number)
    local self = setmetatable({}, Inventory)
    self.Slots = table.create(slotCount, false)
    return self
end

function Inventory:AddItem(itemId: string, quantity: number, stackLimit: number)
    for i, slot in ipairs(self.Slots) do
        if slot and slot.Id == itemId and slot.Quantity < stackLimit then
            local space = stackLimit - slot.Quantity
            local toAdd = math.min(space, quantity)
            slot.Quantity += toAdd
            quantity -= toAdd
            if quantity <= 0 then return true end
        end
    end
    for i, slot in ipairs(self.Slots) do
        if not slot then
            self.Slots[i] = {Id = itemId, Quantity = math.min(quantity, stackLimit)}
            quantity -= self.Slots[i].Quantity
            if quantity <= 0 then return true end
        end
    end
    return false -- inventory full
end

return Inventory

Loading Screen Controller

uiclientprogress

Tracks ContentProvider preload progress and drives a progress bar so players don't see pop-in on join.

local ContentProvider = game:GetService("ContentProvider")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local LoadingController = {}

function LoadingController.Run(progressBar: Frame)
    local assets = ReplicatedStorage:GetDescendants()
    local total = #assets
    local loaded = 0

    for _, asset in ipairs(assets) do
        task.spawn(function()
            pcall(function()
                ContentProvider:PreloadAsync({asset})
            end)
            loaded += 1
            local pct = loaded / total
            progressBar.Size = UDim2.new(pct, 0, 1, 0)
        end)
    end

    while loaded < total do
        task.wait(0.1)
    end
end

return LoadingController

Remote Event Throttler

gameplaysecuritynetworking

Rate-limits incoming RemoteEvent calls per-player to protect the server from spam or malformed request floods.

local Players = game:GetService("Players")

local Throttler = {}
local callLog = {}

function Throttler.Wrap(remoteEvent: RemoteEvent, maxCallsPerSecond: number, callback)
    remoteEvent.OnServerEvent:Connect(function(player, ...)
        local now = os.clock()
        callLog[player] = callLog[player] or {}
        local log = callLog[player]

        while #log > 0 and now - log[1] > 1 do
            table.remove(log, 1)
        end

        if #log >= maxCallsPerSecond then
            return -- drop the call, player is over the limit
        end

        table.insert(log, now)
        callback(player, ...)
    end)

    Players.PlayerRemoving:Connect(function(player)
        callLog[player] = nil
    end)
end

return Throttler

Have a script worth sharing?

Submit your own module in Discord and the team will review it for the library.

Submit on Discord