Howdy! I’m currently developing a custom loading screen for a game. I have the GUI created and all that good stuff, but I’m currently having trouble figuring out how I should properly utilize RequestQueueSize using the ContentProvider service. With that being said, I have a few questions in mind.
Here’s what I want to know
How long should I wait for RequestQueueSize while using a custom loading screen?
What are some proper usage cases for RequestQueueSize?
Is an example like the Developer Hub’s example on RequestQueueSize reliable?
I wouldn’t use RequestQueueSize for a custom loading screen if I were preloading assets. I would load assets and once an asset is loaded, set the size of the loading bar. An example of this is:
local contentProvider = game:GetService('ContentProvider')
local assetsToLoad
for i = 1,#assetsToLoad do
local asset = assetsToLoad[i]
contentProvider:PreloadAsync{asset}
bar.Size = UDim2.new(i/#assetsToLoad,0,1,0)
end
You can create something similar with RequestQueueSize, by requesting the queue size every so often. It can be written like so:
local contentProvider = game:GetService('ContentProvider')
local assetsToLoad
contentProvider:PreloadAsync(assetsToLoad)
local originalSize = contentProvider.RequestQueueSize
local function update()
local n = contentProvider.RequestQueueSize
if n > 1 then
return true
else
bar.Size = UDim2.new(n/originalSize,0,1,0)
end
end
--Connect it up to a loop
I’m not entirely sure of a use-case for it, besides a loading screen. Also, do you mean how long you should wait until RequestQueueSize is 0?
Honestly, you shouldn’t be using RequestQueueSize, period. Your first solution works fine enough. Not only is RequestQueueSize an arbitrary value (thus your second solution produces inaccurate results regardless), but there are countless issues from technical to UX and beyond that are involved in its use.
PreloadAsync is the way to go, as is only running it on the assets that should be visible immediately. The client can stream the rest of asset downloading in the background while the game runs.
There’s frankly no use case for reading from RQS or using it as a value for your loading screens. It should just stay as a property that you can access to see how many assets are preparing to download but that’s about it. The Shift + F3 menu also shows RQS for debugging purposes (?).
Worth noting as well: please don’t use PreloadAsync of 1 asset in a loop.
The correct way to do this is:
Create a table with all assets/instances you need to preload (note that PreloadAsync assumes that the content id arguments are images; if you need to preload sounds/meshes/etc. you need to specify instances that carry the required data
Call PreloadAsync once with the table
Use the recently added callbackFunction argument of PreloadAsync to monitor progress and update progress bars.
Calling PreloadAsync one asset at a time serializes the loading of assets, whereas PreloadAsync of the entire table will do asset load in parallel which can be much faster especially if assets aren’t in the on-disk cache.
For specifying instances such as sounds, meshes, etc. could GetDescendants() be used on already existing instances, or would it be better to preload assets and parent them to existing instances?
PreloadAsync will do descendant traversal for you actually, so if you have a UI that you want to preload you can do PreloadAsync on the ScreenGui or something like that.
I recall that there was a callbackFunction added to PreloadAsync some time ago but there was never any announcement about it nor documentation posted about it (about to go file a documentation request).
With that being said though, how are you able to track progress? As far as I’m aware, the function fires for each item in the list but there’s no way to get a guaranteed size. When PreloadAsync traverses descendants, the array expands.
There was an important reason for this, which has to do with fixing moderation exploits. And the idea is that you don’t need to create new instances - you can often use instances that you already have.
You could use an infinite-scrolling progress bar (and if you need a counter, just count upwards) But yeah the total count isn’t known unless you want to count the number of descendants and deduplicate the ids in the result…
That’s a bit of a yikes from me. I was hoping that we’d be able to get the known number of assets to make an accurate progress bar and I don’t know how I feel about traversing more than once or using upwards arbitrary progress trackers like that…
I generally create the instance once the asset has finished loading, so my game ends up creating dozens of temporary instances in some cases. Is it possible to reuse these temporary instances and their tables for separate Preload calls that may be running at the same time? or is the instance and table referenced internally until the request completes/fails?
(sorry this isn’t quite on-topic)
I’ve had cases where I preloaded rbxassetid://12345678, but it came back as https://assetdelivery.roblox.com/v1/asset/?id=12345678, so comparing the ID with anything isn’t necessarily reliable.
Yeah, the only way to get this data reliably would be to have the callback return some sort of progress indicator in addition to the status of the asset.