In my game, I've decided to utilize the convenient uses of a module script to make some sort of universal table for all part data in-game. For some odd reason, I have not been able to access the contents of this table from the perspective of a local script within the player. I was able to access the table itself, just without the content it is supposed to have. I had also referred to Roblox's wiki page on module scripts, still however, finding no useful information on whether or not there are any special communication issues between module and local scripts. One theory I have as to why it is this way is that the table's contents are not original to the module script itself, they are instead inserted in by an alternative server script within the Workspace; I don't know why this fact would create a problem, but my various attempts at troubleshooting this issue have suggested that. As of now, I cannot think of any way around this inconvenience and any help would be greatly appreciated. If you do know know of any solution, maybe you would know of an alternative method offering a similar set of benefits to those of a module script. For those who would like to see the scripts themselves, here they are:
Module:
local module = {} module.BlockMap = {} function module.IdentifyBlock(Target) if Target and Target.Parent and Target.Parent.Name ~= "Torch" and Target.Parent ~= workspace and Target.Parent.Name ~= "Tree" and Target.Parent.Name ~= "Branch" and Target.Parent:FindFirstChild("Humanoid") == nil and Target.Parent:IsA("Tool") == false then if Target:FindFirstChild("Configuration") and Target.Configuration:FindFirstChild("BlockType") or Target.Parent:FindFirstChild("Configuration") and Target.Parent:IsA("Model") == false then local BlockConfig if Target:FindFirstChild("Configuration") then BlockConfig = Target.Configuration elseif Target.Parent:FindFirstChild("Configuration") then BlockConfig = Target.Parent.Configuration end if BlockConfig:WaitForChild("BlockType").Value == "Block" then return BlockConfig.Parent end elseif Target.Parent:IsA("Model") and Target.Parent:FindFirstChild("Configuration") and Target.Parent:FindFirstChild("Drop") == nil and Target.Parent.Configuration:FindFirstChild("BlockType") then local BlockConfig = Target.Parent.Configuration if BlockConfig:WaitForChild("BlockType").Value == "Block" then return BlockConfig.Parent end elseif Target.Parent.Parent:IsA("Model") and Target.Parent.Parent:FindFirstChild("Configuration") and Target.Parent.Parent:FindFirstChild("Drop") == nil then local BlockConfig = Target.Parent.Parent.Configuration if BlockConfig:WaitForChild("BlockType").Value == "Block" then return BlockConfig.Parent end else return nil end end end function module.GetAllNearBlocks(BaseBlock, IgnoreList) local Hitbox = BaseBlock:FindFirstChild("Hitbox") if IgnoreList == nil then IgnoreList = {} end local function IgnoreBlockRecursive(RecursiveParent) if RecursiveParent:IsA("BasePart") and RecursiveParent == BaseBlock then table.insert(IgnoreList, RecursiveParent) end for i,v in pairs(RecursiveParent:GetChildren()) do if v:IsA("BasePart") then table.insert(IgnoreList, v) end IgnoreBlockRecursive(v) end end if Hitbox then IgnoreBlockRecursive(BaseBlock) local TopRay = Ray.new(Hitbox.Position, ((Hitbox.Position + Vector3.new(0,1,0)) - Hitbox.Position).unit*2) local BottomRay = Ray.new(Hitbox.Position, ((Hitbox.Position + Vector3.new(0,-1,0)) - Hitbox.Position).unit*2) local FrontRay = Ray.new(Hitbox.Position, ((Hitbox.Position + Vector3.new(0,0,1)) - Hitbox.Position).unit*2) local BackRay = Ray.new(Hitbox.Position, ((Hitbox.Position + Vector3.new(0,0,-1)) - Hitbox.Position).unit*2) local RightRay = Ray.new(Hitbox.Position, ((Hitbox.Position + Vector3.new(1,0,0)) - Hitbox.Position).unit*2) local LeftRay = Ray.new(Hitbox.Position, ((Hitbox.Position + Vector3.new(-1,0,0)) - Hitbox.Position).unit*2) local TopHit = module.IdentifyBlock(workspace:FindPartOnRayWithIgnoreList(TopRay, IgnoreList)) local BottomHit = module.IdentifyBlock(workspace:FindPartOnRayWithIgnoreList(BottomRay, IgnoreList)) local FrontHit = module.IdentifyBlock(workspace:FindPartOnRayWithIgnoreList(FrontRay, IgnoreList)) local BackHit = module.IdentifyBlock(workspace:FindPartOnRayWithIgnoreList(BackRay, IgnoreList)) local RightHit = module.IdentifyBlock(workspace:FindPartOnRayWithIgnoreList(RightRay, IgnoreList)) local LeftHit = module.IdentifyBlock(workspace:FindPartOnRayWithIgnoreList(LeftRay, IgnoreList)) return TopHit, BottomHit, FrontHit, BackHit, RightHit, LeftHit end end return module
Server:
for i,v in pairs(MapModel:GetChildren()) do local TopHit, BottomHit, FrontHit, BackHit, RightHit, LeftHit = ServerModule.GetAllNearBlocks(v) if v:FindFirstChild("Configuration") then if TopHit ~= nil and BottomHit ~= nil and FrontHit ~= nil and BackHit ~= nil and RightHit ~= nil and LeftHit ~= nil then WaitAmount = WaitAmount + 1 if WaitAmount == 2000 then WaitAmount = 0 wait() game.ReplicatedStorage.Events.ServerToClientFunction:FireAllClients("UpdateLoadingStatus", "Reducing lag", math.floor((i/#MapModel:GetChildren())*100)) end table.insert(ServerModule.BlockMap, v) end end end
Local:
local function RenderBlock(Pos) local ClosestBlock for i,v in ipairs(ServerModule.BlockMap) do -- The table is not nil, its contents are missing. if (Pos - v.Hitbox.Position).magnitude <= .5 then ClosestBlock = v end end if ClosestBlock == nil then return end ClosestBlock.Parent = workspace.Map if ClosestBlock:IsA("BasePart") then ClosestBlock.CFrame = CFrame.new(Pos) ClosestBlock.Hitbox.CFrame = ClosestBlock.CFrame elseif ClosestBlock:IsA("Model") then ClosestBlock:SetPrimaryPartCFrame(CFrame.new(Pos)) end for i,v in ipairs(ServerModule.BlockMap) do if v == ClosestBlock then table.remove(ServerModule.BlockMap, i) break end end end