Trouble switching from Instances to Module Scripts!

I want to be able to switch from utilizes Instances to Module Scripts because I’ve heard that it’s better overall, however, the process is currently very confusing to me. I’ve tried looking at a few sources but I just can’t put my finger on how it works. Pretty much, I want to learn how to store data in modules as opposed to instances, I’ve tried to follow the Roblox Wiki, but the only resource I found focused more on datastores.

If someone could explain it to me in any way possible, or show me the way that you would go about doing it, I would really appreciate it. Any information at all would be a life-saver as I try to learn how to change my scripting habits.

This is what I got from following one of the forums, but I just can’t understand it. Within the script I wrote comments to try and decipher what everything meant and what I don’t understand.

--[[ Main Table being defined, I think I understand this part. It's just mainly used as a way to require the script from my understanding.]]--
local Stats = {}

--[[I understand that this is where the Player's Data will be stored, but don't know quite how it works. If I wanted to reference this data inside of a normal script, would I do Stats.PlayerData.???]]--
local PlayerData = {}


--[[This is a function to change the Player's stats but I don't fully understand it. If someone could explain this in a detailed manner or show me your own way of how you would do this. I would really appreciate it!]]--

function Stats:ChangeStat(Player, Stat, Value)
	local PlayerUserID = "Player_"..Player.UserId
	assert (typeof(PlayerData[PlayerUserID][Strength]) == typeof(Value), "The Stat trying to be changed is not a value.")
	if typeof(PlayerData[PlayerUserID][Stat]) == "number" then
		PlayerData[PlayerUserID][Stat] = PlayerData[PlayerUserID][Stat] + Value
	else
		PlayerData[PlayerUserID][Stat] = Value
	end
end

--[[This is supposed to create the Player Data, but how exactly does it work? I know that it requires the player's name as a Parameter, and then uses it to find their ID. The ID then has a table of its own with other values that are considered the 'Stats', right?]]--
local function SetupPlayerData(Player)
	local PlayerUserID = "Player_"..Player.UserId
	PlayerData[PlayerUserID] = {Strength=0, Agility=0, Endurance=0, Stamina=0}
end

--[[This doesn't look like it belongs here. Wouldn't this belong on a server script? I'm not entirely sure how I would ago about setting up their individual data. When I've tried it doesn't let me access the SetupPlayerData variable, and when i made it global, it started giving me a bunch of errors.]]--

game.Players.PlayerAdded:Connect(SetupPlayerData)

return Stats

I’m also trying to practice with Printing to understand the basic gist of things. How would I reference a player’s specific stat through this? If I wanted to figure out what the value is? Would I use either of these?

local Stats = require(game.ServerStorage.ModulePractice)

print (Stats.PlayerData.PlayerUserID.Strength)
local Stats = require(game.ServerStorage.ModulePractice)

print (Stats[PlayerData][PlayerUserID][Agility])

Sorry for all of these questions, I would appreciate it if anyone could answer ANY of these questions. I’m just trying my best to learn. If you can direct me to some resources I’d also appreciate that, the only roblox wiki I found on it just wasn’t really specific

Greetings, so first of all the example you sent seems a bit confusing for beginners, I made this up which I hope can help better to understand modules.

In a normal server script you put this:

ModuleScript = require(script.ModuleScript)

baseValue = 5 --Value to give when a player joins

game.Players.PlayerAdded:Connect(function(Player) --Whenever a player joins
   ModuleScript.saveValue(Player, baseValue) --Triggers the module function which saves the value
   print(ModuleScript.getValue(Player)) --Retreives and print the value
end)

While in the module you write this:

local module = {}

function module.saveValue(Player, Value)
    module[Player.Name] = Value --Sets the value you want to store under the player name in the table
end

function module.getValue(Player)
    return module[Player.Name] or 0 --Returns to the script the value which was stored, if it can't find it then it returns 0
end

return module

Hope this helped out!

1 Like

Hey before you actually switch, tell me are you looking for fast replication if that’s the case just stick with value objects.

1 Like

@Ponzimus
Thank you for this simplified version, the Roblox Wiki had me so confused man. I’ll break this apart and try to learn how to create my own modules.

@0Shank
Value objects replicate quicker? Could you explain more about the differences between the two, there’s a lot of mixed information. Some people say there’s a negligible difference and others say that module scripts are far better.

Hey sorry, by fast replication I meant easier to setup not necessarily faster for replication BUT there is one reason why it’s faster an inbuilt queuing system. Value objects they que their changes. What’s the good thing about this?

This que is qued for 20hz and sent to the client (that’s how fast the network replicator sends data). If the value object is changed during that time then the que will just use the new .Changed event, it won’t keep the exisiting one in the que.

For example:

Int value changes now it gets qued for about 20hz
Int value is changed again before the que is sent to the client

Now the old int value .Changed event is removed from the que and the new update is used. Good since we only get one .Changed event instead of two. For the same int value.

Source:

The network replicator only sends data at about roughly ~20 Hz. For properties we queue sending a changed event when the value changes only if there’s not already a changed event in the queue. If the property changes again while that’s still in the replication queue we update the existing changed event in the queue and do not queue any new events. Values replicated as properties will skip sending intermediate values between replication steps.

If you want to go the remote route you can. It allows more complex data such as tables. (I mean you could do that with value objects to using a folder with value objects but uh that sucks)

If your looking to send simple data which is replicated, value objects might be more performant sometimes because of the queing system. Value objects don’t necessarily have cons if your using them this way.

If your sending more complex data that’s when you should try converting your data into module scripts.

Basically value objects are faster when you have data which is very dynamic.

1 Like

I might utilize a mixture of both then, I personally find Instances easier, I just didn’t want to get into the habit of doing something what might be ‘wrong’. I’ll use Instances for more basic things and shift into module scripts when storing complex information. I appreciate the help!

You aren’t really doing anything wrong. Use the tool which fits your job. If someone says x is better for every case then they’re probably wrong. So yah utilizing both is an good idea.

Value objects - Simple Dyanmic data

Module scripts - Complex less dynamic data

Complex dynamic data - Interesting one (not sure which one would be good)

1 Like