Really good preloading system for free (Ensures 100% of assets are loaded) (Read fully)

(For anyone who doesn’t script or doesn’t know how to use this script, just use the plus icon on the replicatedfirst service and insert a local script. Then paste this code.)

Let me first explain the benefits of using this preloading system compared to regular ones.

  1. It’s in replicatedfirst (although many preloading systems do this I’ll still explain the benefit). This means that the preloading system will run before any other scripts as it’s replicated to the client immediately.

  2. I am preloading every type of asset in this script, so this is convertible for any game. And very useful for big ones.

  3. Let’s say you are hiring scripters, let’s say they made very bad unoptimized code and they never preloaded the assets they used (e.g. sounds, animations, etc). It would be very ineffective to go into each script and just do “preloadasync or waitforchild” especially if your game has many scripts you would need to identify which one is using assets.

  4. Question: Why not just do preloadasync? Why are you disabling and enabling scripts? And why preloading so many times? Answer: Let me explain, firstly when the player joins I ensure all local side scripts that start as soon as the player joins are disabled. Why do I do this? Well the whole point of preloadasync is to yield the script UNTIL the assets are loaded in. If I just did preloadasync then what would this mean? The scripts would run and not be yielded and therefore are still capable of receiving errors. However, by disabling these scripts it ensures no code is ran UNTIL the assets are loaded. As you can see the scripts are enabled after preloading is done. And I also preload again after the character is added because there could be some assets that weren’t found when the player joined (e.g. assets which load after the character has added). Now I know that I shouldn’t be putting the characteradded wait event in replicatedfirst as that’s not how to use it properly however this would make thigns more complicated as I’d have to split the system into two scripts.

  5. Why do you have so many pcalls? (Protected calls) This is because since we are messing around with enabling and disabling scripts, we would never want anything to go wrong with that. Especially sicne this is happening as soon as the player joins so there could be problems plus we’re handling hundreds of scripts possibly.

  6. Why do you have two tables for playerscripts and startercharacterscripts? So some games have scripts which they don’t awnt to enabled, if I didn’t use these tables I’d be enabling every single script which is very bad because some code may be designed not to run in some games. So you can filter out which scripts you want to enable or not. If you want to keep a specific script disabled, you can just edit my script and put it in the if statement that checks if the scripts are already disabled.

  7. Are you sure this works and doesn’t cause any problems? Yes, to my own research I have tried this script in two big games and I was able to preload around 300-400 assets with no issues whatsoever. With extra safety (e.g. pcalls and disabling/enabling scripts).

  8. “I use waitforchilds in alot of my scripts I don’t need this” I agree to an extent as using waitforchilds means you kind of don’t need this script (it’s mostly for creators who forgot to preload their assets in their scripts or had bad scripters that didn’t do this and are unable to go through each script and find which asset to preload). However, the script gives you extra security knowing that all assets are preloaded + with your waitforchilds.

local player = game.Players.LocalPlayer

local StarterCharacterScripts = {}

local PlayerScriptsTable = {}

local ContentProvider = game:GetService("ContentProvider")

local ConversionTable = {
	[1] = "Image",
	[2] = "T-Shirt",
	[3] = "Sound",
	[4] = "Mesh",
	[5] = "Script",
	[8] = "Hat",
	[9] = "Place",
	[10] = "Model",
	[11] = "Shirt",
	[12] = "Pants",
	[13] = "Decal",
	[17] = "Head",
	[18] = "Face",
	[19] = "Gear",
	[21] = "Badge",
	[24] = "Animation",
	[27] = "Torso",
	[28] = "Right Arm",
	[29] = "Left Arm",
	[30] = "Left Leg",
	[31] = "Right Leg",
	[32] = "Package",
	[34] = "Gamepass",
	[38] = "Plugin",
	[40] = "Meshpart",
	[41] = "Hair Accessory",
	[42] = "Face Accessory",
	[43] = "Neck Accessory",
	[44] = "Shoulder Accessory",
	[45] = "Front Accessory",
	[46] = "Back Accessory",
	[47] = "Waist Accessory",
	[61] = "Emote Animation",
	[62] = "Video",
}

local ConfirmedAssets = {}

local function DisablePlayerScript()
	for Every, PlayerScript in player:GetDescendants() do
		if PlayerScript:IsA("LocalScript") or PlayerScript:IsA("Script") and PlayerScript ~= script then
			if PlayerScript.Enabled == false then
				return
			else
				PlayerScript.Enabled = false
				table.insert(PlayerScriptsTable, PlayerScript)
			end
		end
	end
end

local function EnablePlayerScripts()
	for Every, PlayerScript in PlayerScriptsTable do
		if PlayerScript:IsA("LocalScript") or PlayerScript:IsA("Script") and PlayerScript ~= script then
			PlayerScript.Enabled = true
		end
	end
end

local function InsertPlayerAssets()
	for Every, Asset in game:GetDescendants() do
		if table.find(ConversionTable, Asset.ClassName) then
			table.insert(ConfirmedAssets, Asset)
		end
	end
	
	for Every, Asset in player:GetDescendants() do
		if table.find(ConversionTable, Asset.ClassName) then
			table.insert(ConfirmedAssets, Asset)
		end
	end
end


local success, errormessage = pcall(function()
	DisablePlayerScript()
end)

while not success do
	DisablePlayerScript()
	task.wait()
end

local succeed, failure = pcall(function()
	InsertPlayerAssets()
end)

while not succeed do
	InsertPlayerAssets()
	task.wait()
end


local fix, didntwork = pcall(function()
	ContentProvider:PreloadAsync(ConfirmedAssets)
end)

while not fix do
	ContentProvider:PreloadAsync(ConfirmedAssets)
	task.wait()
end

local notangry, angry = pcall(function()
	EnablePlayerScripts()
end)

while not notangry do
	EnablePlayerScripts()
	task.wait()
end

local character = player.Character or player.CharacterAdded:Wait()

local function DisableStarterCharacterScripts()
	for Every, CharacterScript in character:GetDescendants() do
		if CharacterScript:IsA("LocalScript") or CharacterScript:IsA("Script") and CharacterScript ~= script then
			if CharacterScript.Enabled == false then
				return
			else
				CharacterScript.Enabled = false
				table.insert(StarterCharacterScripts, CharacterScript)
			end
		end
	end
end

local function EnableCharacterScripts()
	for Every, CharacterScript in StarterCharacterScripts do
		if CharacterScript:IsA("LocalScript") or CharacterScript:IsA("Script") and CharacterScript ~= script then
			CharacterScript.Enabled = true
		end
	end
end

local function InsertCharacterAssets()
	for Every, Asset in game:GetDescendants() do
		if table.find(ConversionTable, Asset.ClassName) then
			table.insert(ConfirmedAssets, Asset)
		end
	end
end


local happy, nothappy = pcall(function()
	DisableStarterCharacterScripts()
end)

while not happy do
	DisableStarterCharacterScripts()
	task.wait()
end

local win, lost = pcall(function()
	InsertCharacterAssets()
end)

while not win do
	InsertCharacterAssets()
	task.wait()
end

local done, stilldoing = pcall(function()
	ContentProvider:PreloadAsync(ConfirmedAssets)
end)

while not done do
	ContentProvider:PreloadAsync(ConfirmedAssets)
	task.wait()
end

local worked, didntwork = pcall(function()
	EnableCharacterScripts()
end)

while not worked do
	EnableCharacterScripts()
	task.wait()
end

print(ConfirmedAssets)

This script will optimize your client alot more, and is very helpful for big games with tons of models and what not.

9 Likes

Let me know your thoughts on this guys by the way. Just make a post! Also funny pcall names by the way “happy” “not happy” haha.

sounds cool, however i always use :waitforchild so I wont be using it.

try uploading this to the marketplace instead of just having to copy and paste it?

1 Like

This is very nice! As a beginner solo developer this is going to be helpful. I do have one piece of advice. For the devforum post I suggest creating a website for all the information or api and such! Thank you again.

2 Likes

Oh I can’t make websites lol, I’m just a luau programmer. Glad I could help though!

Yes this is mostly for game creators who have buggy code or what not, but actually I still recommend using this script because this ensures all assets are preloaded as soon as the game starts which optimizes your client alot. Plus with the extra waitforchilds you have your basically secure!

Yes good idea. I’ve never really made free models before so yeah.

I hope this script helps guys.