Pass Loop In Module Script To Script?

  1. What do you want to achieve? Keep it simple and clear!
    I want to transfer what i get from a code in a module script to a script.

  2. What is the issue? Include screenshots / videos if possible!
    The issue is I don’t know how module scripts work, and I am using it for the first time because I think it will help me in the long run with resusing certain things like colors.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried looking at videos and also seeing what other people have said about how to use module scripts but I don’t know how to apply it to my specific situation.

I know I have to use “Module = require…” and “Module.firstModuleData” in my main script and define my code in the module script with “Module.firstModuleData”

Here is the code I want to use in the module script. I am using a loop with GetTagged to get a list of parts with the same tag. I want to transfer this list to the main script so I can change it’s material property!

for i, Lightbulbs1 in ipairs(CollectionService:GetTagged("Mainstage Backdrop Lightbulb Lights Alternating Pattern Group 1")) do

If i need to provide any extra info please ask, any help is appreciated!

1 Like

A ModuleScript just stores code that your Scripts or LocalScripts can utilize. In order to send data back to the Script calling the ModuleScript, the script would need to call a function or method that returns the data.

local module = {}
local CollectionService = game:GetService("CollectionService")

function module:DoAction()
   local newT = {}
   for i, Lightbulbs1 in ipairs(CollectionService:GetTagged("Tag")) do
      if Lightbulbs1.Name ~= "Bulb2" then
         table.insert(newT, Lightbulbs1)
      end
   end
   return newT
end

return module
local m = require(script.ModuleScript)

print(m:DoAction()) --> {Bulb1, Bulb3, Bulb4}

3 spaces are used for tabs in this example. You may need to replace them with tabs in your editor.

: and . both will work for the function call. Generally : is used when the method needs access to itself through self.
Any time you want something out of a ModuleScript, it needs to be done through a function call with a return statement.

1 Like

If you are only trying to get all the parts that are tagged and not doing any other code to filter out the instances, please do not use a loop. A loop is not necessary if all you’re doing is getting the tagged instances.

Instead, just use :GetTagged like you are doing in your loop. This method just returns a table of all the tagged instances.

CollectionService:GetTagged("TagName") --> {Part1, Part2, Part3, ...}
1 Like

Thank you so much for the help! So what you wrote did end up printing out all the tagged parts through the main script. What I want to do though is take this collection of parts and change their material now. Would that look something like this?

module:DoAction().Material = Enum.Material.Neon -- i want the parts to be neon

As for the loop, I just realized you’re right. I don’t think I need it? I only used it because I thought I needed it to get a list of all the parts with the same tag.

If the goal of your ModuleScript was just to send back a list of the parts, you can cut that function call out entirely and just directly iterate through the tagged parts from :GetTagged.

for i, bulb in ipairs(CollectionService:GetTagged("Tag")) do
   bulb.Material = Enum.Material.Neon
end

This cuts your function call out entirely and just directly updates the material from the tagged items.
In the event you tag non-parts, you may want to implement a check for the type of instance you are dealing with. You can either use Part (for only parts, not spheres, cylinders, or wedges), or you can use BasePart which includes every physical object that you can change the Material, Size, Position, etc. of.

Your code would then look something like this:

for _, bulb in pairs(CollectionService:GetTagged("Tag")) do
   if bulb:IsA("BasePart") then
      bulb.Material = Enum.Material.Neon
   end
end

Notice that I did not use ipairs and turned i into _. Using ipairs makes no difference when iterating a table that has no keys. Using an underscore is standard when you aren’t using a variable.

1 Like

What if I want to do the GetTagged part of the code in the ModuleScript and change the Material property in the main Script? I only want to do this so I dont have to type out the sam,e code in multiple scripts and just have it stored in the module script so I can refference it when needed!

You would be doing this anyways. If your ModuleScript is just getting you a table of the parts, you still have to iterate that table again in your main script. You might as well just iterate it in your main script to begin with.

module:DoAction().Material = Enum.Material.Neon --> {Material = Enum.Material.Neon} (not what you want)

You would have to do this anyways:

for _, bulb in pairs(module:DoAction()) do
   bulb.Material = Enum.Material.Neon
end

There is no reason to do two loops when :DoAction() just gives you a table.

1 Like

Okay thank you soooo much. I was starting to think this wasn’t worth it lol, so I’m glad someone with more understanding of this could let me know why! Thank you for the help, I will do it the way you said instead! Again, thank you and I will mark this as the solution. :grin:

Sorry, I was just thinking about this and hopefully you might know if this would work or not. But if I use the ModuleScript to get a table of the parts, cant I insert that table into another table and then call on it from the main Script to avoid havign to iterate through it? Like something like this:

Module.firstModuleData = {}

for i, bulb in ipairs(CollectionService:GetTagged("Tag")) do
   table.insert(Module.firstModuleData, bulb)
end

Not sure if this works but something along these lines?
Then in the main script i would just do something like this

local a = Module.firstModuleData

a.Material = Enum.Material.Neon 

return sends a table. You cannot set the material of a table. You need to iterate the table and set the material on everything inside the table.

CollectionService:GetTagged is an iterable. All your function call does is return another iterable, identical to :GetTagged. It’s redundant to have a loop to then use another loop. Just use :GetTagged in your main script.

If you have arguments to pass and manipulate the data, that’s a different story.

Ahhh ok then. Thank you so much again! You were really helpful.