Asset loading techniques?

Hi there:
Since the removal of the :Preload() function from ContentProvider I have been struggling to efficiently load the assets into the game. This is, the game takes long (to the point the client disconnects from the server due to timeout) to load for it’s development stage!

How do I load the assets:

  1. I request the list from a module serverside:
-- the actual module has way more entries than this.
local images = {
	{"icons/arrow_button_left", 1243045644},
	{"icons/arrow_button_right", 1243045650},
	{"icons/logo_a", 1254423406},
	{"icons/logo_a_stroked", 1254423411},
	{"icons/logo_d", 1254423354},
	{"icons/logo_d_stroked", 1254423402},
local meshes = {
    {"meshes/environment/lobbyGarage/door_extruded", 1145143218},
	{"meshes/environment/lobbyGarage/door_lock", 1145143732},
	{"meshes/environment/lobbyGarage/lights_main", 1145144022},
	{"meshes/environment/lobbyGarage/lights_main_frame", 1145144300},
	{"meshes/environment/lobbyGarage/lights_side", 1145165736},
	{"meshes/environment/lobbyGarage/main", 1145166425},

return {images, meshes}

The first value of each table is just a “want” and not necessarily a “need”. Said value is displayed in the Loading Gui. Second value is the rbxassetid.

  1. When the list arrives at the script:
-- assetLibrary is the module above
for _,v in pairs(assetLibrary[1]) do
	ImageLabel.Image = "rbxassetid://"..tostring(v[2])
	asset.Text = "Loading File "..tostring(loadedAssets + 1).." of "..tostring(assetNum)..":"
	assetName.Text = v[1]
	progress.Text = tostring(math.floor((loadedAssets/assetNum) * 100)).."%"
	loadedAssets = loadedAssets + 1

plr:GetMouse().Icon = "rbxgameasset://Images/cursor"

for _,a in pairs(assetLibrary[2]) do
	MeshPart.MeshId = "rbxassetid://"..tostring(a[2]) -- i'm using a SpecialMesh since it's MeshId property can be written.
	asset.Text = "Loading File "..tostring(loadedAssets + 1).." of "..tostring(assetNum)..":"
	assetName.Text = a[1]
	progress.Text = tostring(math.floor((loadedAssets/assetNum) * 100)).."%"
	loadedAssets = loadedAssets + 1

I load each asset individually because I want to keep track of how many assets are already loaded. If I call the :Preload() function with all the assets, it would yield the script until loading was done.

What is happening:

All images are “failing” to load:

--23:26:53.027 - ContentProvider:PreloadAsync() failed for rbxassetid://1243044904
--23:26:53.458 - Image "" failed to load in "TextureManager::PreloadTexture": Request failed

I am not sure if this is a failure/ineficiency on Roblox’s end to send the data or an issue with the loading script.


If you verify both the erroring IDs by going to their respective Library-pages, you’ll notice that the first ID in your error actually is a SolidModel, not an image. (
The second one is a place, not an image. (

I don’t entirely understand where those two IDs come from, though. They’re not in your list of IDs.
Is there reason for why you decide to do ContentProvider:PreloadAsync() with a single instance in a loop? I assume it’s because you want the progress-text, but for that you can use

You can fix the incorrect IDs very easily by putting all the images/meshes from the table into to a group or folder, and simply do ContentProvider:PreloadAsync(folder:GetChildren()).

So it turns out that I placed the “subtract 1” technique just to see, didn’t work, and forgot to remove it.

But the error still persists after the correction:

Not to mention that in-game it still takes too long to load. I am investigating whether this only happens with me or with everyone else (with a 5Mbps connection like me)

Roblox deals with the correct assetId if you input the Decal into a .Image, .Texture, etc. property. That means if you input the Decal ID (from the website) into a Decal/Texture/ImageLabel, Roblox will automatically fetch the right corresponding ID for you. However, I don’t think this is the case when doing it through scripts. That’s why I suggested adding them all to a folder.


The type of asset 1243045644 is Decal instead of Image. This is a common mistake. Decal is actually an xml file which contains an Image assetid.

One easy way to convert Decal id to Image id is:
1.Create an Decal in Studio.
2.Copy url “” into Texture property field.
3.Studio will download that xml file and get internal Image id for you. It will be “rbxassetid://1243045641” in this case.
This can only be done in studio interface. “” can’t be used in script.


There is a fun sort of ‘hack’ that means you can load unions / meshes far faster:

  • Place them infront of the camera with a GUI on top to hide (loading bar)
  • Keep counting poly counts until they aren’t nil / 0
  • All unions loaded