A little perplexed about why I cant :FindFirstChild that exists

Hello, I am a little perplexed again and trying to understand something and grow my knowledge.

I have a module script located in Replicated Storage and under the module script, I create Value Objects to store data I need during the game session that does not get saved to a datastore. It looks like this:

When the player joins, I create a Folder for that player underneath the module with this function:

function sessionData.playerSetup(player)
    local newFolder = Instance.new("Folder")
    newFolder.Name = tostring(player)
    newFolder.Parent = script
    sessionData.addPotionTimer(player)
end

After that I add the Value Object like so:

function sessionData.playerRemove(player)
    local storageName = tostring(player)
    local thisStorage = script:FindFirstChild(storageName)
    thisStorage:Destory()
end

And it looks like this:

OK, now the setup is done, lets move to the problem. In another script I am trying to reference that folder and value object and set its value. I am doing it like this:

local replicatedStorage = game:GetService("ReplicatedStorage")
local sessionData = require(replicatedStorage:WaitForChild("SessionData"))

function potionTimer.setTimer(player,potion)
    local thisPlayer = tostring(player)
    local playerFolder = replicatedStorage.sessionData:FindFirstChild(thisPlayer)
    local thisTimer = playerFolder:FindFirstChild("PotionTimer")	
    thisTimer.Value = potion.duration
end

When i run this, i get an error that says:
[ReplicatedStorage.SessionData:11: attempt to call field ‘addPotionTimer’ (a nil value)]

If I simply change the line that reads:

local playerFolder = replicatedStorage.sessionData:FindFirstChild(thisPlayer)

TO

local playerFolder = replicatedStorage.SessionData:FindFirstChild(thisPlayer)

then it will work. All I did is capitalize the first S of SessionData which is the module scripts actual name inside ReplicatedStorage. The lowercase “s” of sessionData is the variable I set at the top of the script using require().

The perplexing part is, I have done this same sort of thing in other script in this game and it is able to use the variable. I prefer to use the variable defined because if i move the script, it is of course much easier to simply change the defined variable instead of combing through script changing every reference.

Thanks for taking the time to read thorough all of this, as I said I am trying to understand this inconsistency behavior. I have something very similar to this working in another script and don’t understand why its not working here.

It’s because of require()

you aren’t getting the reference to the script like FindFirstChild does.
So you can not use it as a path, but instead as an extension to more functions.

Also “sessionData” is not a child object of ReplicatedStorage. but “SessionData” is. that’s why the capital S works and the other does not.

3 Likes

Yes is know the capital S is the actual object, but I did not realize I could not use the require()'ed object as part of a path. I can swear I accomplished this in another script and that’s why I was perplexed. I am going to go and double-check that is the case.

Thanks!

What you could do is include a custom function in your module, that way it does exist! >:D

-- mobile 4 space indent thanks

local module = {
    stuff = {"lol"}
}

function module:FindFirstChild(query)
    local do a thing to sift through stuff? or module
    return result or nil
end

return module

EDIT: Meant to add a regular reply, not a reply to the above comment. I dislike mobile.

1 Like

Yes this does lead me to wonder how to deal with variable names when I need to require() for the module contents as well as use find it through its path.

I guess I would need to create 2 variables then?

local sessionData_MODULE = require(replicatedStorage:WaitForChild(SessionData)local
sessionData_PATH = replicatedStorage:FindFirstChild("SessionData")

this is super ugly and unwieldy (is that a word?). Looking for advice here. What do you all do when you need to require a module for its contents as well as point to its location inside one script, let alone being consistent with variable names across the entire project.

If you want to do something like that, you have it backwards. Index the path first, require it second.

local sD_Path = place
local sD_Module = require(sD_Path)
1 Like

I still think this entire method of having to add PATH and MODULE to the variables ls ugly and awkward. I am curious how other people organize the code and variables to make this look and feel cleaner and consistent across scripts

Most people don’t index a module. They have a function in the module to return ModuleScript children or only have the children accessible to the module.

2 Likes

This makes sense to me. I think as a general rule I will avoid modules having children that need to be indexed inside scripts. I will just use a different way of organizing I think.

You can always store your assets in folders under a StorageService, which is a pretty popular alternative to storing children directly inside a script. Just don’t let it get too messy - even folders are capable of becoming nightmares.