How do I make a module return a new table everytime, so scripts get their own table instead of sharing the table of that module?

Does anyone have some good tutorials for this? Basically I have a module that returns some functions relating to weapons, tagging hits, and setting the player. Only problem is that everytime a new player loads this module, every other player gets their weapons set to be “owned” by the new player (causing the old players to be able to shoot themselves, not hit the new player, etc).

How do I make it so the module gives new players a new table with the functions and values, instead of a reference to the table?

2 Likes

There’s probably a better way of doing this, but maybe use nested tables? Within the standard table in the module, have a table for each player so it gets their specific owned items.

That would ruin modules. What you can do is give each player their own copy, or when you require, have a function that recursively copies tables.

2 Likes

Have you looked into OOP?
This might help: Programming in Lua : 16

There’s two ways you could do this. You can make it return a function that returns a table when called. Quick mockup of what this could look like:

local t = {}

return function()
	return t
end

Alternatively, you can make it return a table like normal but :Clone() the module when required so it doesn’t cache. Quick example:

require(module:Clone())

However, like incapaz said, this kind of ruins the point of using a module. Can you explain your use case? There’s probably a better solution. You should be able to use a class-like setup and just have a function within the module that creates a new table for each player. As much as it pains me to suggest OOP, here.

2 Likes

My use case is having a lot of functions that I use between all my weapons in a game I’m working on. Functions such as playing sounds, creating beams, creating explosions, tagging humanoids for registering kills, and setting touch damage. I’m doing this in attempts to save me copy pasting a bunch of stuff from weapon to weapon.

1 Like

Can’t you just pass the player as an argument to these functions?

2 Likes

I could do this, but I’m trying to make it so I can just do Module:SetUser() per script and save having to pass the player through the arguments. I’m experimenting with different stuff (I’m still a bit of a beginner at scripting), and this is my attempt at what people have been saying about creating a new table.

function Weapon.new()
	local NewWeapon = {}
	NewWeapon.User = nil
	
	function NewWeapon:SetUser(player)
		self.User = player
	end
	
	function NewWeapon:SetUserFromCharacter(character)
		self:SetUser(game:GetService("Players"):GetPlayerFromCharacter(character))
	end 
	
	function NewWeapon:TagHumanoid(targetHumanoid)
		if not NewWeapon.User then
			warn("Weapon has no user, cannot tag humanoid.")
			return
		end
		local tag = targetHumanoid:FindFirstChild("LastHit")
		if tag then
			tag.Value = NewWeapon.User.Name
		else
			local newtag = Instance.new("StringValue")
			newtag.Name = "LastHit"
			newtag.Parent = targetHumanoid
			newtag.Value = NewWeapon.User.Name
		end
	end
	
	for k,v in pairs(Weapon) do
		NewWeapon[k] = v
	end
	
	return NewWeapon
end

1 Like

That looks fine, as long as you’re calling .new() for each player and calling the functions on what it returns rather than the module itself. Does that not work for some reason?

5 Likes

Calling some players to test it out right now, I’ll let you know in a couple minutes if this works :wink:

Edit : It works, thanks everyone! :smiley:

2 Likes