Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
sentinelcore avatar

Roblox Remote Events

  • 350 installs
  • 11 repo stars
  • Updated February 23, 2026
  • sentinelcore/roblox-skills

Use roblox-remote-events for development tasks

About

roblox-remote-events: A skill for development. This provides functionality for development workflows.

  • roblox-remote-events

Roblox Remote Events by the numbers

  • 350 all-time installs (skills.sh)
  • +28 installs in the week ending Aug 5, 2026 (Skillselion tracking)
  • Ranked #1,197 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/sentinelcore/roblox-skills --skill roblox-remote-events

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs350
repo stars11
Last updatedFebruary 23, 2026
Repositorysentinelcore/roblox-skills

What it does

Use roblox-remote-events for development tasks

Files

SKILL.mdMarkdownGitHub ↗

Roblox Remote Events & Functions

RemoteEvent vs RemoteFunction

TypeDirectionReturns value?Use when
RemoteEventAny directionNo (fire-and-forget)Notifying server of player action, broadcasting state
RemoteFunctionClient→ServerYes (yields caller)Client needs a result back (e.g. fetch inventory)
UnreliableRemoteEventAny directionNoHigh-frequency updates where dropped packets are fine

Default to RemoteEvent. Avoid server→client RemoteFunction — an exploiter's frozen callback stalls your server thread indefinitely.

---

Where to Put Remotes

Always store Remotes in ReplicatedStorage. Create them from a server Script that runs before any LocalScript.

ReplicatedStorage/
  Remotes/
    DealDamage        (RemoteEvent)
    GetInventory      (RemoteFunction)
    SyncPosition      (UnreliableRemoteEvent)
-- Script in ServerScriptService
local folder = Instance.new("Folder")
folder.Name = "Remotes"
folder.Parent = game:GetService("ReplicatedStorage")

local function make(class, name)
    local r = Instance.new(class)
    r.Name = name
    r.Parent = folder
    return r
end

make("RemoteEvent",           "DealDamage")
make("RemoteFunction",        "GetInventory")
make("UnreliableRemoteEvent", "SyncPosition")

---

Firing Patterns

Client → Server (FireServer)

-- LocalScript
local DealDamage = game:GetService("ReplicatedStorage").Remotes:WaitForChild("DealDamage")
DealDamage:FireServer({ targetId = 12345, amount = 50 })
-- First arg on server is always the firing Player (injected automatically, cannot be spoofed)
-- Script (server) — VALIDATE everything in the payload
DealDamage.OnServerEvent:Connect(function(player, data)
    -- player identity is trustworthy; data contents are not
end)

Server → One Client

local Notify = game:GetService("ReplicatedStorage").Remotes:WaitForChild("Notify")
Notify:FireClient(player, { message = "Welcome!" })
-- LocalScript
Notify.OnClientEvent:Connect(function(data)
    print(data.message)
end)

Server → All Clients

AnnounceEvent:FireAllClients({ text = "Game starting in 10 seconds!" })

RemoteFunction (Client Calls, Server Returns)

-- Script (server)
GetInventory.OnServerInvoke = function(player)
    return getPlayerInventory(player.UserId)
end
-- LocalScript
local inventory = GetInventory:InvokeServer()  -- yields until server returns

UnreliableRemoteEvent (High-Frequency Sync)

-- LocalScript
RunService.Heartbeat:Connect(function()
    SyncPosition:FireServer(character.HumanoidRootPart.CFrame)
end)
-- Script (server) — still validate
SyncPosition.OnServerEvent:Connect(function(player, cframe)
    if typeof(cframe) ~= "CFrame" then return end
    -- apply with sanity bounds check
end)

---

CRITICAL: Server-Side Security

The client is hostile. Treat every argument as untrusted input.

local MAX_DAMAGE = 100
local COOLDOWNS = {}
local COOLDOWN_SECONDS = 0.5

DealDamage.OnServerEvent:Connect(function(player, data)
    -- 1. Rate limit
    local now = tick()
    if COOLDOWNS[player.UserId] and now - COOLDOWNS[player.UserId] < COOLDOWN_SECONDS then
        return
    end
    COOLDOWNS[player.UserId] = now

    -- 2. Type checks
    if type(data) ~= "table" then return end
    if type(data.targetId) ~= "number" then return end
    if type(data.amount) ~= "number" then return end

    -- 3. Range clamp
    local amount = math.clamp(data.amount, 0, MAX_DAMAGE)

    -- 4. Server-side weapon lookup — never trust client-provided Instance
    local weapon = getEquippedWeapon(player)
    if not weapon then return end

    -- 5. Server-side target lookup
    local target = getPlayerByUserId(data.targetId)
    if not target then return end

    applyDamage(target, amount, player)
end)

---

Exploit Patterns & Defenses

ExploitWhat the attacker doesDefense
Argument injectionSends unexpected types to crash handlerType-check all arguments
Damage amplificationSends amount = math.hugeClamp to sane maximum
Remote spamFires thousands of times per secondPer-player cooldown
Spoofed targetSends another player's UserIdServer resolves from its own state
Infinite yieldNever returns from OnClientEvent callbackAvoid server→client RemoteFunction
Duplicate actionReplays a valid fire to buy twiceCheck state / consume token before acting

---

Quick Reference

FireServer(args)            LocalScript → server
FireClient(player, args)    server → one client
FireAllClients(args)        server → every client
InvokeServer(args)          LocalScript → server, waits for return
OnServerEvent               server-side listener for FireServer
OnClientEvent               client-side listener for FireClient/FireAllClients
OnServerInvoke              server-side function assigned for InvokeServer

---

Common Mistakes

MistakeFix
OnServerEvent in a LocalScriptUse OnClientEvent on client; OnServerEvent is server-only
Remotes in ServerStorageMove to ReplicatedStorage
Trusting payload beyond player identityValidate every field in the payload
Server→client RemoteFunctionUse RemoteEvent; frozen client stalls server thread
No WaitForChild in LocalScriptRemotes may not exist yet; always use WaitForChild
Multiple OnServerInvoke assignmentsOnly the last assignment wins; keep it in one place
Firing inside tight loop without throttleUse UnreliableRemoteEvent or accumulate delta time

Related skills

Backend & APIsbackendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.