Skip to content

A deep dive on how the Roblox bootstrapper works

pizzaboxer edited this page Sep 5, 2024 · 40 revisions

Bloxstrap essentially works by mimicking the behaviour of the official Roblox bootstrapper, and then expanding on it to provide additional useful functionality, much of which would not be possible otherwise. Other people would probably benefit from understanding how that works, so here it is.

This will also only concern Windows, as I actually have no idea how it works on Mac. I don't own a Mac.

Bootstrapper installation

Roblox installs to %LOCALAPPDATA%\Roblox, under a single user account only. It used to support being installed system-wide as Administrator, but not anymore, as it results in a lot of mess relating to permissions and stuff. So, this page will only be relevant to functionality in the context of it being installed and ran in single-user mode only.

Installing/Updating Roblox

Identifying game client versions

Each version of the Roblox game client has several identifiers. However, the only one that you need to worry about is the version GUID, which is what is used to identify versions on Roblox's deployment system. An example of one is version-824aa25849794d67.

The latest version GUID can be fetched from https://clientsettingscdn.roblox.com/v2/client-version/WindowsPlayer, which delivers a JSON response, where the version GUID is attributed under clientVersionUpload.

The bootstrapper keeps track of the version GUID for the version of Roblox it currently has installed. It will check that API whenever it's launched, and carry out a Roblox update if the latest version GUID has changed.

The deployment system

Roblox distributes the game client across several categorized .zip files called packages, and uploads them to Amazon S3. Roblox then mirrors their S3 storage across several different CDNs. Here's all of the domains of which you can download Roblox from.

Type Base URL Notes
Amazon S3 https://s3.amazonaws.com/setup.roblox.com/ Where everything is sourced from. Also the slowest, that's why the CDNs exist.
Amazon S3 http://setup.roblox.com/ A direct alias for S3 above. Avoid using this, HTTPS doesn't work properly on it.
Akamai https://setup-ak.rbxcdn.com/ CDN mirror for S3
Cachefly https://roblox-setup.cachefly.net/ CDN mirror for S3
Cachefly https://setup-cfly.rbxcdn.com/ A direct alias for the domain above on rbxcdn.com.
Balanced https://setup.rbxcdn.com/ Preferred, CDN balancer that automatically chooses between Akamai and Cachefly.

The bootstrapper uses the balanced one whenever it can. However, it will also used the other ones mentioned for redundancy in case setup.rbxcdn.com is inaccessible, if it's ever down or happens to be blocked or something.

The self-updating mechanism

You may have noticed that the latest version API supplies a version number for the bootstrapper.

Aside from updating Roblox, the bootstrapper can also update itself. The bootstrapper is always built and deployed alongside a Roblox version. When the bootstrapper is about to install a new version of Roblox, it checks that latest bootstrapper version number against its own, and updates itself if it needs to, before updating Roblox.

You'll see this happening if you see a briefly-flashing "Please wait..." or "Getting the latest Roblox..." message when the bootstrapper is started.

Downloading and assembling an installation

Now, we'll get to actually downloading files. Alongside the packages, there are also files that contain manifest data, named rbxManifest.txt, rbxPkgManifest.txt.

The files for every version are stored at the root of the base URL, with their file names being prefixed with the version GUID. For example, rbxPkgManifest.txt for version-824aa25849794d67 on the CDN balancer will be located at https://setup.rbxcdn.com/version-824aa25849794d67-rbxPkgManifest.txt.

rbxManifest.txt records information of every single game client file, with data being grouped two lines at a time. It really just records the MD5 hash. As far as I'm aware, this is no longer used. At one point, it was used for checking the integrity of a Roblox installation, but the bootstrapper hasn't appeared to do that for years. Regardless, the file is still generated for new version deployments.

rbxPkgManifest.txt records information of every single downloadable package, with data being grouped four lines at a time. It records compressed size, uncompressed size, and MD5 hash. File sizes are recorded as number of bytes. You can use this manifest for identifying what packages you need to download, or for determining how much disk space is needed to install/update Roblox.

The bootstrapper has a hardcoded table that records the associated extraction directory for each package. You can easily find these yourself using a hex editor or something. You can check them all out here.

Roblox installations are stored in %LOCALAPPDATA%\Roblox\Versions\<version GUID>\. Downloaded packages are cached in %LOCALAPPDATA%\Roblox\Downloads. These are (or should be) regularly cleaned out after a period of time or whenever it's suitable to do so, such as after an update.

In short, the bootstrapper will gather the list of packages to download from the package manifest, download them, and extract them accordingly. It's pretty simple.

Installing WebView2

Unlike every other package, WebView2RuntimeInstaller.zip is only extracted on the condition that the WebView2 runtime is not installed. It checks for that according to these registry keys.

The package contains an online runtime installer. If the bootstrapper finds it's not installed, it extracts the package, and then runs the installer with the provided args of /silent /install. It automatically installs quietly in the background, while the bootstrapper shows its own indefinite progress state waiting for it to finish.

Starting Roblox

Protocol/URI handling

Roblox registers two protocols: roblox and roblox-player. The former is relatively new and used only for universal deeplinking, whereas the latter is more traditional and is used for everything else. Here's some examples of launch URIs which use these protocols that you can try out by pasting them into your browser's URL bar:

roblox-player:1+launchmode:app
roblox://experiences/start?placeId=1818

The first one will simply launch the desktop app, the second one will launch and join Crossroads. This is how Roblox launches itself from your web browser.

The roblox://experiences/start deeplink supports the following parameters:

- placeId
- gameInstanceId
- accessCode
- linkCode
- launchData
- joinAttemptId
- joinAttemptOrigin
- reservedServerAccessCode
- callId
- browserTrackerId

Brief disambiguation:

  • The term "protocol" refers to protocol identifiers such as roblox and roblox-player
  • The term "launch URI" refers to the full string used for launching the application such as roblox-player:1+blahblahblah
  • The term "protocol handler" refers to the application that's launched to handle the protocol

Registering protocols is pretty simple. If you don't understand how they work, just open the Registry editor, go to HKEY_CURRENT_USER\SOFTWARE\Classes\roblox-player, and examine how it's structured. The protocol handler is registered under shell\open\command, where the '%1' token gets substituted with the launch URI.

When the bootstrapper starts Roblox, it passes the protocol string directly into RobloxPlayerBeta.exe as the first launch argument. You don't really need to do anything, unless you want to manipulate the data given so you can control Roblox to behave in a certain way.

Parsing roblox-player protocol URIs

Here's a quick tip to parsing roblox-player URIs. Take a longer one for example:

roblox-player:1+launchmode:play+robloxLocale:en_us+gameLocale:en_us+LaunchExp:InApp

If you look closely at this, you may notice that this is designed to cleverly form a stream of key-value pairs, all delimited by '+' symbols. Even the protocol identifier itself is part of it. For the sake of clarity, it would look something like this if you serialized it to JSON form:

{"roblox-player": 1, "launchmode": "play", "robloxLocale": "en_us", "gameLocale": "en_us", "LaunchExp": "InApp"}

If you ever need to parse/modify the string, you don't need to do anything special or complicated, it's really simple.

How this all fits together

As of March 2024, Roblox has made drastic changes to how the launch process works. The old model used to work like this:

  • RobloxPlayerLauncher.exe gets registered as the handler for the protocols and 'Roblox Player' shortcut
  • When launched, it checks for client updates, and carries out an upgrade if needed
  • After that, it then parses the launch URI string into launch flags for RobloxPlayerBeta.exe and starts it
  • It waits for it to signal a start event, then closes.

In practice:

  • Web browser navigates to roblox-player:1+launchmode:play+robloxLocale:en_us+gameLocale:en_us+LaunchExp:InApp
  • That then launches RobloxPlayerLauncher.exe roblox-player:1+launchmode:play+robloxLocale:en_us+gameLocale:en_us+LaunchExp:InApp
  • That then launches RobloxPlayerBeta.exe -app --rloc=en_us --gloc=en_us

Since then, the new model works like this:

  • RobloxPlayerLauncher.exe itself gets registered as the handler for the protocols and 'Roblox Player' shortcut
  • When launched, it checks for client updates.
  • If an upgrade is needed, it launches RobloxPlayerInstaller.exe with the same launch URI
    • which will then afterwards launch the new RobloxPlayerBeta.exe with the same launch URI.

In practice:

  • Web browser navigates to roblox-player:1+launchmode:app
  • That then launches RobloxPlayerBeta.exe roblox-player:1+launchmode:App
  • If an upgrade is needed, it launches RobloxPlayerInstaller.exe roblox-player:1+launchmode:App and exits
    • which then launches RobloxPlayerBeta.exe roblox-player:1+launchmode:App

In other words, there's no bootstrapper anymore. RobloxPlayerLauncher.exe is no longer used, with the player taking over launch handling itself. RobloxPlayerInstaller.exe is a slightly stripped down version of the launcher which is only supposed to be used for upgrades. This was done to cut down launch times.

Bloxstrap sticks mostly to the old model, because it needs to carry out stuff before Roblox launches. However, as of v2.6.0, it does directly pass launch URI to RobloxPlayerBeta instead of parsing it into launch flags.


That's about all you need to know for how the Roblox bootstrapper works. Fairly straightforward.

If you ever need to quickly download a Roblox version, see rdd.latte.to. It's essentially just a web implementation of the bootstrapper's client download system.

Clone this wiki locally