
For Roblox Developers
One Lua module. One function call. Every player with Medal gets automatic clips of the best moments in your game, which are shared across Discord, TikTok, and YouTube with your gameplay.
Add NowPlayers share clips on Discord, TikTok, and YouTube. Each clip links back to your game. More clips means more players.
Kills, wins, rare drops - trigger clips at the exact moment something awesome happens. No player action needed.
20M+ gamers use Medal. Every shared clip links directly back to your game on Roblox.
Games with Medal autoclipping see more social shares, more content creators, and more new players.
Integration guide
No server setup. No in-game UI. Just Lua.
Create a new ModuleScript in ReplicatedStorage called MedalClipper and paste this code.
-- MedalClipper v1.7 (patched: nearby-player tagging removed, captureDelayMs pass-through)
-- Drop this ModuleScript into ReplicatedStorage
local HttpService = game:GetService("HttpService")
local DEFAULT_DURATION = 30
local TAG = "[_MAPIEvent][v1/event/invoke]"
local Clipper = {}
function Clipper:TriggerClip(eventId, eventName, opts)
opts = opts or {}
local gameEvent = {
eventId = eventId,
eventName = eventName,
triggerActions = { "SaveClip" },
clipOptions = {
duration = opts.duration or DEFAULT_DURATION,
captureDelayMs = opts.captureDelayMs,
},
}
-- Only include contextTags when non-empty. Roblox's JSONEncode
-- serializes an empty Lua table as "[]" (JSON array), but Medal
-- expects contextTags to be a JSON object ({"key":"value"}).
-- Omitting the field entirely is safer than sending [].
if opts.contextTags and next(opts.contextTags) then
gameEvent.contextTags = opts.contextTags
end
local payload = {
gameEvent = gameEvent,
universeId = game.GameId,
}
print(TAG, base64Encode(
HttpService:JSONEncode(payload)
))
end
function base64Encode(data)
local b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
local out, len, i = {}, #data, 1
while i <= len do
local b1 = data:byte(i) or 0
local b2 = data:byte(i + 1) or 0
local b3 = data:byte(i + 2) or 0
local n = b1 * 65536 + b2 * 256 + b3
local c1 = math.floor(n / 262144) % 64 + 1
local c2 = math.floor(n / 4096) % 64 + 1
local c3 = math.floor(n / 64) % 64 + 1
local c4 = n % 64 + 1
out[#out + 1] = b64:sub(c1, c1)
out[#out + 1] = b64:sub(c2, c2)
if i + 1 > len then
out[#out + 1] = "=="
break
elseif i + 2 > len then
out[#out + 1] = b64:sub(c3, c3) .. "="
break
else
out[#out + 1] = b64:sub(c3, c3)
.. b64:sub(c4, c4)
end
i = i + 3
end
return table.concat(out)
end
return ClipperIn any LocalScript, require the module and call TriggerClip with an event ID, a display name, and optional settings.
local Medal = require(game.ReplicatedStorage.MedalClipper)
-- Inside your kill-handling LocalScript, after the kill is confirmed:
local function onKillConfirmed(killStreak)
if killStreak < 3 then return end -- only clip 3+ streaks
Medal:TriggerClip(
"evt_kill_streak", -- eventId (you choose)
killStreak .. "-Kill Streak", -- eventName (clip title in Medal)
{
duration = 30, -- total clip length in seconds
captureDelayMs = 5000, -- 5s after the trigger; 25s before
}
)
endAPI reference
| Parameter | Type | Required | Description |
|---|---|---|---|
| eventId | string | Yes | Unique identifier for this event type. Example: "1" |
| eventName | string | Yes | Display title shown in Medal. Example: "Double Kill" |
| opts | table | No | Optional settings table (see below) |
| Field | Type | Default | Description |
|---|---|---|---|
| duration | number | 30 | Clip length in seconds |
| captureDelayMs | number | 0 | Milliseconds to keep recording after the event triggers. Use this to capture the aftermath. |
| contextTags | table | {} | Key-value pairs. Each value becomes a #hashtag in Medal. Example: { boss = "EnderDragon" } adds #EnderDragon |
Copy-paste examples
Pick your game genre, copy the snippet, and drop it in. Each example is a single function call.
Clip multi-kills and streaks
Medal:TriggerClip(
"1",
"Double Kill",
{ duration = 15 }
)Clip impossible stage completions
Medal:TriggerClip(
"2",
"Impossible Stage Cleared",
{ duration = 20 }
)Clip jumpscare reactions
Medal:TriggerClip(
"3",
"Jumpscare!",
{ duration = 15 }
)Clip rare pulls and drops
Medal:TriggerClip(
"4",
"Super Rare Drop",
{ duration = 10 }
)Clip clutch wins and aces
Medal:TriggerClip(
"5",
"Ace!",
{ duration = 20 }
)Clip records and milestones
Medal:TriggerClip(
"6",
"New World Record",
{ duration = 15 }
)How it works
The module builds a JSON payload with the event details and your game's universe ID.
The payload is base64-encoded and printed with a special tag that Medal's desktop app watches for in the Roblox log output.
Medal's replay buffer saves the last N seconds of gameplay as a clip - tagged with your event name and hashtags. Ready to share.
Every clip is a free ad. Every share brings new players. Add autoclipping today.
Add Now