Module script help

I need help with module script combining table values together.


As you can see it doesn’t combine the values together rather just retypes the output the same over and over.

Here’s both scripts and their locations.

-- Autonomous mining script for all assets, Workspace --

local miningModule = require(game.ServerScriptService.FunctionsModuleScript)
local runService = game:GetService("RunService")
local Players = game:GetService("Players")
local MiningRadius = script.Parent
local elementName = script.Parent:FindFirstAncestorWhichIsA("Model").Name -- find the model to which the element name will be decided
local elementValue = script.Parent:FindFirstAncestorWhichIsA("Model").Part.ElementValue.Value -- added in an intValue constraint
local connection = nil
local finishTime = 1
local startTime = 0

--TouchPart.Transparency = 1 -- note: remember to initialize before duplication

-- When player touches the mining radius --
MiningRadius.Touched:Connect(function(otherPart)
	if otherPart.Parent:IsA("Model") and otherPart.Parent:FindFirstChild("Humanoid") then
		local player = Players:GetPlayerFromCharacter(otherPart.Parent)
		if player then
			
-- checks if connection and runs service --
			if (connection) then return end
			connection = runService.Heartbeat:Connect(function()
				if os.clock() - startTime < finishTime then
					return
				end

			startTime = tonumber(os.clock()) -- changes time value to number value
			miningModule.touchFunction(MiningPart) -- calls module script
				
			end)
		end
	end
end)

-- When player leaves the mining radius --
MiningRadius.TouchEnded:Connect(function(otherPart)
	if otherPart.Parent:IsA("Model") and otherPart.Parent:FindFirstChild("Humanoid") then
		local Player = Players:GetPlayerFromCharacter(otherPart.Parent)
		if Player then
			
-- checks for connection and disconnects --			
			if (connection) then
				connection:Disconnect()
				connection = nil
			end
		end
	end
end)
-- This module calculates mining values adding to inventory --

local miningModule = {} 

function miningModule.getmats(MiningPart)

	local elementName = game.Workspace.Collectables:FindFirstChild("Apple").Name
	local elementValue = game.Workspace.Collectables:FindFirstChild("Apple").Part.ElementValue.Value

	local inventory = {elementName, elementValue} -- saving data to table
	inventory[2] = inventory[2] + 1 -- Value to be increased by Game Passes, buffs and events
	print(inventory[1], inventory[2])
	wait(1)

end

function miningModule.touchFunction(MiningPart)
	miningModule.getmats(MiningPart)
end

return miningModule

This is my first time using Module and I’ve had to change the code around but it’s not working properly.
It used to be the script in the workspace looked for the model closest to it “The element” and the model was thusly named working up from the script. Now with the Module I have to work downwards from workspace and this is creating the issue. I am trying to create the script to find the “model”.Name within the mining radius “Part”, create the name of the element and add to the inventory. While I had it working in the original location with,

local elementName = script.Parent:FindFirstAncestorWhichIsA("Model").Name -- find the model to which the element name will be decided
local elementValue = script.Parent:FindFirstAncestorWhichIsA("Model").ElementValue.Value -- added in an intValue constraint

it wasn’t safe enough from exploiters so I changed it to ServerScriptService (ModuleScript) but now I can no longer tell the script to look for a model.Name or even a part.Name (since there will be many parts/models) in the Inventory.

Basically I just want the module script to add to the value of Inventory[2] and to find the name of the model for Inventory[1].

I don’t understand what you’re trying to do, but it’s printing apple every single time because you set it up that way (Both elementName and elementValue is “Apple”). You could try using the MiningPart instead…

local miningModule = {} 

function miningModule.getmats(MiningPart)
	local elementObject = workspace.Collectables:FindFirstChild(MiningPart.Name)
	if not elementObject then
		for _, object in pairs(workspace.Collectables:GetChildren()) do
			local newElementObject = MiningPart:FindFirstAncestor(object.Name)
			if not newElementObject then
				repeat task.wait()
					newElementObject = newElementObject:FindFirstAncestor(object.Name) or nil
				until newElementObject or newElementObject == nil
			end
			if newElementObject then 
				if not newElementObject:IsA("Model") then
					newElementObject = nil
				end
				elementObject = newElementObject
				break
			end
		end
	end
	
	local elementName = elementObject and elementObject.Name
	local elementValue = elementObject and elementObject.Part.ElementValue.Value

	local inventory = {elementName, elementValue} -- saving data to table
	inventory[2] = inventory[2] + 1 -- Value to be increased by Game Passes, buffs and events
	print(inventory[1], inventory[2])
	task.wait(1)

end

function miningModule.touchFunction(MiningPart)
	miningModule.getmats(MiningPart)
end

return miningModule

Yes I know, I added Apple since “Model” seemed to create error and I wanted it to just work for Apple to start with and then work out how to make Banana and Blueberry. Apple 1,2,3 etc instead i got Apple 1 (1,2,3) etc.

I will try your code when I get home.

I apologize for my lateness of reply. I tried your script and had various problems with FindFirstAncestor() and nil. I played around with it a bit to no avail. You mentioned I was less than specific with my question so I thought I would add this.

local miningModule = {} 

function miningModule.getmats(MiningPart)
	
	local TouchedPart = -- the part the player is currently touching
		-- get ancestor of TouchedPart which is a model
		-- get name of the model and make that the elementName
		-- make Model.intValue.Value for the elementValue
		
	
	local inventory = {elementName, elementValue} -- saving data to table
	inventory[2] = inventory[2] + 1 -- Value to be increased by Game Passes, buffs and events
	print(inventory[1], inventory[2])
	task.wait(1)

end

function miningModule.touchFunction(MiningPart)
	miningModule.getmats(MiningPart)
end

return miningModule

I apologize for any and all confusion.

It’s printing that you only have 1 apple each time because you define inventory inside the scope every time you run the function. Anything you changed in the inventory table isn’t going to exist once the function ends.

You can move the variable outside the scope like this

local miningModule = {} 


local inventory = {}

function miningModule.getmats(MiningPart)
	
	local elementName = "Apple"
	local elementValue = 5
	
	local Found = false
	for i, v in pairs(inventory) do
		if v.Name == "Apple" then
			Found = true
			v.Amount += elementValue
			break
		end
	end
	
	if not Found then
		table.insert(inventory, {Name = elementName, Amount = elementValue})
	end
	
end

return miningModule

But now we have another problem. There isn’t a separate table for each players inventory. If you are going to save this to a datastore, I’d suggest setting up DataStore2 which you can read about here:

After you have it set up, this is how simple it will be to save everything:

local DataStore2 = require(game.ServerScriptService.DataStore2) -- Require the DataStore2 ModuleScript depending on where it's located

DataStore2("Inventory", player):Update(function(InventoryTable) -- Gets the existing InventoryTable from DataStore2 so we can change it
	local Found = false
	for i, v in pairs(InventoryTable) do -- Iterate through the Table to check if we already have a table for the specific elementName
		if v.Name == elementName then
			Found = true -- If found, change Found to true so we don't create another one later in the script
			v.Amount += elementValue -- Increment the value by the elementValue. Using += increments the value. This is the equivalent of typing out "v.Amount = v.Amount + elementValue"
			break -- Break the loop so that we don't waste any resources since we already have what we were looking for
		end
	end

	if not Found then -- If we didn't find the table in the previous loop, create a new table inside of InventoryTable for that specific elementName
		table.insert(InventoryTable, {Name = elementName, Amount = elementValue}) -- Set Amount to elementValue
	end
return InventoryTable -- Return the InventoryTable in it's updated form back to the DataStore2 module which will be automatically saved when the player leaves

Yeah I’ve been reading up on DataStore2 and I’m still trying to work out the difference between the DataStores. In the module script function you defined the elementName as Apple. I really don’t know how to explain my dilemma properly. This code might work perfectly for apple but my game will probably have about 40-50 different elements to craft with.

I’m thinking about how to add different elements to a players inventory as they find them and then saving them into datastore when they leave. If I need to make 40-50 scripts; one for each element I guess I don’t need a module. I am grateful for all the assistance thus far and I’ll need to look more into DataStore2 when I get to that point.

For now I just want to collect apple and have apple in inventory along with how many apples I collected, collect banana and have banana in inventory and the value, blueberry, pear, pineapple etc.