How do I use module scripts

Hi, I have a script thats gets all the players thumbnails and stores it in a list. How would I set this up as a module script so that I can access this list from other server scripts?

-- // SERVICES
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")

local backup_thumbnail = "image_string_url"
local playerThumbnails = {}

game.Players.PlayerAdded:Connect(function(player) 
	
	-- Store thumbnail from player that joined
	local content, isReady = pcall(function()
		return Players:GetUserThumbnailAsync(player.UserId,Enum.ThumbnailType.HeadShot,Enum.ThumbnailSize.Size150x150)
	end)
	playerThumbnails[tostring(player.UserId)] = (isReady and content) or backup_thumbnail

end)

Players.PlayerRemoving:Connect(function(player)
	-- Remove stored thumbnail from player that left
	if playerThumbnails[tostring(player.UserId)] then
		playerThumbnails[tostring(player.UserId)] = nil
	end
end)
2 Likes

Create a module script somewhere

--change in current script 
local playerThumbnails = require(path.to.module)
3 Likes

When I want to mention a list inside of a module script, I usually set it as a child of the script that is mentioning the module script, then mention it directly using something like this:

local moduleScript = require(script.module) -- Rename module to the name of your module script
2 Likes

So I would just copy the code I did above and put it into a module script?

1 Like

Store the array of icons in the module. Something like:

local iconStorage = {}
iconStorage.Icons = {}

Then, under the PlayerAdded function, call a function within the module to update the icons. Your module could end up looking like:

local iconsStorage = {}
iconsStorage.Icons = {}

function iconsStorage:AddIcon(player:Player)
    local content, isReady = pcall(function()
		return Players:GetUserThumbnailAsync(player.UserId,Enum.ThumbnailType.HeadShot,Enum.ThumbnailSize.Size150x150)
	end)
    table.insert(self.Icons, isReady)
end

return iconsStorage

Bare in mind, you would need to remove the icons when a player leaves to prevent memory leaks.

2 Likes

So would I have the playerAdded function inside the module script too? Or would that be in a server script. Thanks for the help

1 Like

To access the playerThumbnails module from any other script you would simply add that same line
local playerThumbnails = require(path.to.module)
Then access the contents by:

print(playerThumbnails[toString(player.userid)])
--for example

Each reference to that same module script will look at exactly the same table which was changed by the events you already have.
You shouldn’t need to change anything else, or even add any content to the module if it is just a storage table.

1 Like

I’m pretty sure the information will get outdated if you don’t require it afterwards (at least that’s what happens for me). Might need a function to get the data from the module.

1 Like

You would need to have the PlayerAdded connection inside the server-script, the syntax I sent in the module passes the module table itself as a parameter which you can’t do inside of the module.

1 Like

Not true. Module scripts are only ever run once on the first require. Every subsequent require creates a reference/pointer to the same memory address.
So you can change the content of a table returned from a module script from any other script which has required it.
(This is a common way to reduce memory overheads by reusing functions)

1 Like

Thank you, sorry I find this really confusing. I currently have this in a module script, is this correct?

local iconStorage = {}
iconStorage.Icons = {}

local Players = game:GetService("Players")

function iconStorage:AddIcon(player:Player)
	local content, isReady = pcall(function()
		return Players:GetUserThumbnailAsync(player.UserId,Enum.ThumbnailType.HeadShot,Enum.ThumbnailSize.Size150x150)
	end)
	table.insert(self.Icons, isReady)
end

return iconStorage

Then in my server script how would I call the function inside the module script?

Thanks for your help :slight_smile:

Thank you, so what would I have inside the module script? Would I add a function into it that gets the players thumbnails?

Oh yeah, I forgot it was just a pointer to a memory location. Thanks for the correction!

Looks good, except you might want to check if there was an error getting the thumbnail to prevent future errors. You can check this by checking if the content variable is true or false depending on the function’s success.

--Script
-- // SERVICES
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")

local backup_thumbnail = "image_string_url"
local playerThumbnails = require(path.to.module) --change to wherever you place the module script 

game.Players.PlayerAdded:Connect(function(player) 
	
	-- Store thumbnail from player that joined
	local content, isReady = pcall(function()
		return Players:GetUserThumbnailAsync(player.UserId,Enum.ThumbnailType.HeadShot,Enum.ThumbnailSize.Size150x150)
	end)
	playerThumbnails[tostring(player.UserId)] = content or backup_thumbnail --edited logic (is ready and content) would evaluate to true and not assign the content!

end)

Players.PlayerRemoving:Connect(function(player)
	-- Remove stored thumbnail from player that left
	if playerThumbnails[tostring(player.UserId)] then
		playerThumbnails[tostring(player.UserId)] = nil
	end
end)
--modulescript 
local module = {}
return module

The only difference is now the table is created ‘outside’ the script, so can now be required by other scripts.
There are other ways to achieve the same effect, and lots of other things you can add, but as a basic intro, this is all you need to do.

2 Likes

This is my server script, is this correct?

-- // SERVICES
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local PlayerIcons = require(game:GetService("ReplicatedStorage"):WaitForChild("PlayerIcons"))

local playerThumbnails = {}

game.Players.PlayerAdded:Connect(function(player) 
	playerThumbnails = PlayerIcons:AddIcon(player)
end)
1 Like

Thank you very much, Ill try this out now :slight_smile:

1 Like

The function in the module is a procedure, not a function. This is because you are not returning a value, which you don’t really need to do in this case.

To get the thumbnails, you could just reference them in the module, or get them from a function.

Check for the error inside of the procedure.

if not content then table.insert(self.Icons, --[[some other image to stop errors when using the icons]])

When using the images, if there was an error, you could put a different image as I showed, or you could just double-check to make sure the player definitely has an icon.

Side note: If you are confused what self is, in this case, it refers to the module table which we return to whatever require()s it.

1 Like

Thank you very much, this is working perfectly, however when I try assign the icon to a variable, its getting the boolean assigned to it rather than the icon. Any idea why this is?

local playerThumbnails = require(game:GetService("ReplicatedStorage"):WaitForChild("PlayerIcons"))
	
	if #gamePlayers == 6 then
		for i = 3, 1, -1 do
			team1[i].RespawnLocation = workspace:FindFirstChild("Sword Fighting Arenas").Arena1.T1Spawn
			team2[i].RespawnLocation = workspace:FindFirstChild("Sword Fighting Arenas").Arena1.T2Spawn
		end
		
        -- This is getting assign the boolean
		local content1 = playerThumbnails[tostring(gamePlayers[1].UserId)]
1 Like

Module:

local module = {
  thumbnails = {}
}

module.__index = module

local function returnKey(player)
  return tostring(player.UserId)
end

function module:AddIcon(player)
self.thumbnails[returnKey(player)] = 'thumbnailID'
end

function module:GetIcon(player)
return self.thumbnails[returnKey(player)]
end

return module

Then, server script

local IconModule = require(iconmodule)

game.Players.PlayerAdded:Connect(function(player) 
	IconModule:AddIcon(player)
end)
3 Likes