Nvidia Instant Replay Remade on Roblox

:exclamation:THIS CAN ONLY BE RUN ON THE CLIENT FOR NOW:exclamation:

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 :sweat_smile:)

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). The FrameConfig 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 the FrameConfig can be viewed in the onFrame 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 the GlobalConfig, and FrameConfig. The GlobalConfig’s location in the clip data is: Clip.customConfig. The FrameConfig can be accessed in two ways, by using the onFrame 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.

15 Likes

Cool, much like the TimeModule:

but saves data.

A few things I’ve noted:

  • the icon is crusty.
    image

  • There is no documentation whatsoever, and it is quite hard to set up. Example code?

  • Why is there a “Stop” function when we have a max duration? What should I use? Should the max duration be nil? What’s the difference between maxDuration and clipDuration?

2 Likes

maxduration is basically just the clip duration you can set on the GeForce experience panel. In other words, this is how long the clip will be capped at but the clip can still be shorter than that. Now the use of the stop function is if, for example, the developer wants to disable recording if the player is in the lobby.

oh and where ever I say maxduration in that reply I mean clipduration. don’t touch maxduration, this is a value set by the script.