Original Luau modules written and maintained by Spider Games. Copy-paste ready, MIT-licensed, no obfuscation. Click any entry to expand the code.
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
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
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
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
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
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
Submit your own module in Discord and the team will review it for the library.
Submit on Discord