Requiring module from other script to another one

I am making a game and I’ve already implemented my data system using ProfileStore. I am often requiring my setup script (my script to make ProfileStore load and get data), and I’m getting tired of requiring each single time the setup script to obtain my data. I remembered that I recently saw a technique that allows a script to make another script script or multiple require a module of your own choice. That is perfect for my issue! Does anyone have any idea on how to achieve this goal?

To make a module globally accessible across scripts without needing to require it repeatedly, you can leverage the shared table in Roblox. The shared table is a global table available across all server-side scripts (or all client-side scripts), which allows you to store and access data or modules globally. Here’s how you can implement it:


Solution

  1. Store the Module in shared:

    • In your setup script, store your module in the shared table. This makes it globally accessible to all other scripts.
    -- SetupScript
    local ProfileStore = require(game.ServerScriptService:WaitForChild("ProfileStoreModule"))
    
    -- Store in shared for global access
    shared.ProfileStore = ProfileStore
    
  2. Access the Module from Other Scripts:

    • Instead of using require in every script, you can simply reference shared.ProfileStore.
    -- AnotherScript
    local ProfileStore = shared.ProfileStore
    
    -- Use ProfileStore as needed
    local playerData = ProfileStore:GetData("Player123")
    print(playerData)
    

Benefits:

  • Convenience: You only need to require the module once, in the setup script, and then it becomes accessible globally.
  • Consistency: Any changes to the ProfileStore logic or data are reflected globally, as all scripts access the same instance.

Alternative (Custom Global Table):

If you want more control or avoid potential conflicts with the shared table, you can create your own global table:

  1. Create a Global Table Script:

    • Create a ModuleScript named Globals in a shared location (e.g., ReplicatedStorage or ServerScriptService).
    -- Globals (ModuleScript)
    local Globals = {}
    return Globals
    
  2. Store Your Module in the Global Table:

    • In your setup script, populate the global table with your module.
    -- SetupScript
    local Globals = require(game.ServerScriptService:WaitForChild("Globals"))
    local ProfileStore = require(game.ServerScriptService:WaitForChild("ProfileStoreModule"))
    
    Globals.ProfileStore = ProfileStore
    
  3. Access the Global Table from Other Scripts:

    • Reference the global table to access your module.
    -- AnotherScript
    local Globals = require(game.ServerScriptService:WaitForChild("Globals"))
    local ProfileStore = Globals.ProfileStore
    
    -- Use ProfileStore as needed
    local playerData = ProfileStore:GetData("Player123")
    print(playerData)
    

Key Notes:

  • shared is convenient but has potential downsides, like accidental overwrites if multiple scripts use the same key.
  • Using a custom global table (like the Globals example) provides more control and avoids shared table conflicts.

What in the world? Shared table? Is that what ChatGPT came up with? You can’t just throw ChatGPT responses into someones topic. It is just incorrect.

Yes, they are using chatgpt. I can’t blame them since there is no rule regarding AI for responses but this does block legitimate programmers responses.

2 Likes

Your response does not make any sence! You just provided variables which don’t require the other script, and instead itself only!

My bad! I didn’t see “ProfileStore”, the script I provided is for profileservice so I suggest you watch a tutorial like this one:

Profileservice module

What do you mean by constantly “requiring” your module? You can setup a manager module and require it only once but you would still have to use module.LoadProfile(userId) (example), an alternative you can use is directly managing and loading data inside the main script but I dont recommend this. If you want to setup a manager script you can do something like this:

local ProfileService = require(script.Parent.ProfileService)
local ProfileTemplate = require(script.Parent.Template) -- your template script, you can just set this to a template table

local ProfileStore = ProfileService.GetProfileStore("Name", ProfileTemplate.DataTemplate)
local playerProfiles = {}

local PlayerData = {}

function PlayerData.GetProfile(player)
	if playerProfiles[player.UserId] then
		return playerProfiles[player.UserId]
	end

	local profile = ProfileStore:LoadProfileAsync("Player_" .. player.UserId)
	if profile then
		profile:Reconcile()
		profile:ListenToRelease(function()
			playerProfiles[player.UserId] = nil
			player:Kick("Data released.")
		end)
		if player:IsDescendantOf(game.Players) == true then
			playerProfiles[player.UserId] = profile
		else
			profile:Release()
		end
		return profile
	else
		player:Kick("Data failed to load.")
		return nil
	end
end

return PlayerData
3 Likes

This is the exact video I watched to make the ProfileStore Script!

I want a script that loops every decendant of the game, and if it is a ServerScript, a ClientScript or a ModuleScript, then the script would automaticaly recognise and require() the ProfileStore script and essentialy “autocomplete” it and not give out an error what does the ProfileStore mean. This will give the option to write

ProfileStore:GetData(Player)

and give me the PlayerData handed to the script without ever writing

local ProfileStore = require(game.ServerScriptService.Folder.Folder.Folder.Folder.ProfileStore)
1 Like

This is not a practical approach but if you insist on it you can use something like:

local function requireFunction()
	for _, obj in pairs(game.ServerScriptService:GetDescendants()) do
		if (obj:IsA("ModuleScript") or obj:IsA("Script")) and obj.Name == "ProfileStore" then
			return require(obj)
		end
	end
end
1 Like