THIS CAN ONLY BE RUN ON THE CLIENT FOR NOW
For the past week or so, I’ve been working on a remake of Nvidia’s Instant Replay on Roblox. I’ve had this idea for a long time now, and now was a great time to make it. I hope for this to give accessibility to players who don’t have a computer, or a good one. This is also great for ease of reporting.
For how you may save clips, that’s all on your own.
What I did for my game was to create a datastore for each player, and every time they clip something, it creates a new key (the key name is the date the clip was created.) in that datastore which holds the clip data. You may be wondering how i fetch multiple keys and get all the datastores. I use an external webserver and connect to Roblox’s Datastore Open Cloud API which has specific functions the regular Datastore Service doesn’t have.
Resources and Documentation
(Before beginning, I expect you to have knowledge on Lua to use this.)
This is what the instant replay looks like:
https://streamable.com/s1pknu
(most of the video is me looking for the actual clip saved )
Now here’s the model:
https://www.roblox.com/library/14557523374/Roblox-Instant-Replay
Let’s talk about how to use this script. First off, this script is Object Oriented.
-
This first function is:
RobloxReplay.Replay(clipdata: {})
. This returns a remote which you can connect to with:RobloxReplay.Replay(clipdata):Connect(function(GlobalConfig, FrameConfig) end)
. TheFrameConfig
will return nil if the frame didn’t have anything set to it with:setFrameConfig(config)
. -
The main function is:
RobloxReplay.startPlayerClipper(player: Player, clipDuration: number, config: table)
(The config argument is saved in the clip data. So when replaying the clip, you’ll have the choice to add a connection and get the config and frame config as it updates each frame. An example use of this is to set the current map.)
You’ll need to define this as a variable to use any function other than the replay function. -
Now that you’ve defined it, use the
ReplayInstance:setGlobalConfig(config: {})
to set the config variable talked about right above. -
You can also use the
ReplayInstance:setFrameConfig(config: {})
to set the FRAME config. This will only appear on one frame of the clip. The theFrameConfig
can be viewed in theonFrame
connection. -
To stop recording, use:
ReplayInstance:Stop()
. This returns nil. -
And, finally, to clip the last
clipDuration
seconds use:ReplayInstance:Clip()
. This returns a table of all the data saved in that clip, including theGlobalConfig
, andFrameConfig
. TheGlobalConfig
’s location in the clip data is:Clip.customConfig
. The FrameConfig can be accessed in two ways, by using theonFrame
connection’s 2nd argument, or by going to it’s specific location:Clip[frameNumber].frameConfig
.
Example Code
With this, you can clip something off a keybind. It also keeps the clip data for later use. (LOCALSCRIPT)
repeat wait() until game:IsLoaded()
local RobloxReplay = require(game.ReplicatedStorage.RobloxClipping)
local plr = game.Players.LocalPlayer
local uis = game:GetService("UserInputService")
local ReplayInstance = RobloxReplay.startPlayerClipper(plr, 30) -- config argument isn't required
local clipData
uis.InputBegan:Connect(function(input,gpe)
if gpe then return end
if input.KeyCode == Enum.KeyCode.Delete then
clipData = ReplayInstance:Clip()
end
end)
This replays whatever clip you put into it. (LOCALSCRIPT)
uis.InputBegan:Connect(function(input,gpe)
if gpe then return end
if input.KeyCode == Enum.KeyCode.Home then
if clipdata then
RobloxReplay.Replay(clipdata)
end
end
end)
This changes the global and frame config whenever the map changes.
-- SERVER
-- vvv game loop vvv
while wait(5) do
-- map stuff
game.ReplicatedStorage.mapchanged:FireAllClients(map.Name)
end
-- CLIENT
game.ReplicatedStorage.mapchanged:Connect(function(map)
ReplayInstance:setGlobalConfig({map})
ReplayInstance:setFrameConfig({map})
end)
Conclusion
If you have any questions, feel free to reply them. If not, please send feedback about the project, and the post as this is my first one.