Require does not return the same value

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    for every call of require(game.ServerStorage.craftingRecipes) it returns the same value

  2. What is the issue? Include screenshots / videos if possible!
    it returns {} instead

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

A ModuleScript is a type of Lua source container that runs once and must return exactly one value. This value is then returned by a call to require given the ModuleScript as the only argument. ModuleScripts run once and only once per Lua environment and return the exact same value for subsequent calls to require .

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

--script
function ReplicatedStorage.WhatCanLocalPlayerCraft.OnServerInvoke (player)
	local wood = player:WaitForChild'leaderstats':WaitForChild('Wood').Value
	local stones = player:WaitForChild'leaderstats':WaitForChild('Stones').Value
	local notUnLocked = require(game.ServerStorage.craftingRecipes)--this require
	local UnLocked = {}
	print(notUnLocked,UnLocked,'server')-- prints
	for k,v in pairs(notUnLocked) do
		if v.requiredStones >= stones and v.requiredWood >= wood then
			notUnLocked[k] = nil
			UnLocked[k] = {k,v}
		end
	end
	return UnLocked,notUnLocked
end
--module script
local requirements = {
	['boat']={requiredStones = 10,requiredWood=300},
	['stone'] = {requiredStones=20,requiredWood=1}
}

return requirements

Have you tried print(#requirements) on both sides?

which

if you mean module and script it prints 0

I just realised this is a dictionary and not an array, I apologise, have you tried traversing over the elements of the dictionary with pairs()?

Modules are not really intended to be used in this way. Think of require more as an import of the code so it can be called not as a function. Typically a module returns a table with properties and methods (functions) that can be called with arguments to work on. They can return a function but that function should be called separately in your code.

The first time a module is required the code inside is executed and the result is cached. If you call require on the same module again you are going to get the cached instance from the first time. Typically you would require the module close to the top of the script then reference the result later.

--script

local craftingRecipes = require(game.ServerStorage.craftingRecipes)

function ReplicatedStorage.WhatCanLocalPlayerCraft.OnServerInvoke (player)
	local wood = player:WaitForChild'leaderstats':WaitForChild('Wood').Value
	local stones = player:WaitForChild'leaderstats':WaitForChild('Stones').Value
	local notUnLocked = craftingRecipes
	local UnLocked = {}
	print(notUnLocked,UnLocked,'server')-- prints
	for k,v in pairs(notUnLocked) do
		if v.requiredStones >= stones and v.requiredWood >= wood then
			notUnLocked[k] = nil
			UnLocked[k] = {k,v}
		end
	end
	return UnLocked,notUnLocked
end

It looks like your code is expecting the require to return a new instance of the state each time it is called, that won’t happen the changes you make will be there the next time you call require. You probably need your module to maintain the state internally keyed by player and provide methods to get and set it.

1 Like

As you saved the requirements as

local requirements = {
	['boat']={requiredStones = 10,requiredWood=300},
	['stone'] = {requiredStones=20,requiredWood=1}
}

By saving it inside a variable, instead directly return it:

return {
	['boat']={requiredStones = 10,requiredWood=300},
	['stone'] = {requiredStones=20,requiredWood=1}
}

But this has to do with you not setting the path up correctly. As currently they are stuck to these values, instead connect them to a path of where the required values are at.

As you are running the table on the server. instead you should do this on the module script.
Note that a module script run client-sided can not read anything from the ServerStorage.

i know this

can you explain this more

i am not expecting an instance i am expecting that require returns the same value each time it is called

how?


client code

toClone = game:GetService("ReplicatedStorage").ExampleCraft
function call (functiontocall,...)
	functiontocall(...)
end
script.Parent.Craft.Event:Connect(function(thing)
	game.ReplicatedStorage.Craft:FireServer(thing)
end)
unexample = game.ReplicatedStorage.UnExampleCraft
function reload()
	for i,v in ipairs(script.Parent.ScrollingFrame:GetChildren()) do
		if v:IsA("GuiObject") then
			v:Destroy()
		end
	end
	local invokeResult,nInvokeResult = game.ReplicatedStorage.WhatCanLocalPlayerCraft:InvokeServer()
	print(invokeResult,nInvokeResult)
	for k,v in pairs(invokeResult) do
		local clone = toClone:Clone()
		clone.Parent = script.Parent.ScrollingFrame
		call(function(CLone,text)
			wait(1)
			CLone.Event:Fire(
				text[1],'\nwood required '..text[2]['requiredWood']..'\nstones required '..text[2]['requiredStones'])----
		end,clone,v)
	end
	for k,v in pairs(nInvokeResult) do
		local clone = unexample:Clone()
		call(function(CLone,text)
			wait(1)
			CLone.Event:Fire(
				text[1],'\nwood required '..text[2]['requiredWood']..'\nstones required '..text[2]['requiredStones'])----
		end,clone,v)
		clone.BackgroundColor3 = Color3.fromRGB(127, 0, 0)
		clone.Parent = script.Parent.ScrollingFrame
	end
end
reload()
game:GetService("ContextActionService"):BindAction('open or  close',function(str,input,input2)
	if input == Enum.UserInputState.Begin then
		script.Parent.Visible = not script.Parent.Visible
		wait()
		reload()
	end
end,true,Enum.KeyCode.C)
while wait(5) do
	reload()
end
for i, v in pairs(requirements) do
	print(i, v)
end

Like this.

An example of what I meant was, have.

  1. Attributes
  2. ValueObjects

Then set up a path for the Attributes/ValueObjects like so:

return {
	['boat'] = {requiredStones = script:GetAttribute("boat" .. "Stones"), requiredWood = script:GetAttribute("boat" .. "Wood")},
	['stone'] = {requiredStones = script:GetAttribute("stone" .. "Stones"),requiredWood = script:GetAttribute("stone" .. "Wood")}
}

You could run through all the attributes as well or run through all the children, this would be a far more reliable method.

i did this

script:SetAttribute("boat" .. "requiredStones",10)

script:SetAttribute("boat" .. "requiredWood",300)

script:SetAttribute("stone" .. "requiredStones",20)

script:SetAttribute("stone" .. "requiredWood",1)

return {

['boat'] = {

requiredStones = script:GetAttribute("boat" .. "requiredStones"),

requiredWood = script:GetAttribute("boat" .. "requiredWood")

},

['stone'] = {

requiredStones = script:GetAttribute("stone" .. "requiredStones"),

requiredWood = script:GetAttribute("stone" .. "requiredWood")

}

}

and even seting the parent to ReplicatedStorage wont solve it