Why is my __nodes table nil in a certain function


#1

I am working on a CameraAPI. I am stumped on one thing, though. This used to work before (with the same code), but now it doesn’t

I have a CameraApi table. It uses a constructor:

CameraApi:Instantiate()

The module itself calls this constructor on its last line of code

return CameraApi:Instantiate

The constructor returns the following metatable:

return setmetatable(Info, self)

Here’s where I go deeper into the problem. In Info, there is a class called Cutscene with the constructor :CreateCutscene with the argument CutsceneName (which is stored in its own Info table(no variable assigned))

Now, I need to explain the functions. It has a __nodes table.

I use getters(accessors) and setters(mutators) for my Cutscene class

function Info.Cutscene:GetCameraNodes()
       return self.__nodes
end

I have a handy function which changes where the Camera Node faces.

function Info.Cutscene:SetNodeDirection()
      local Nodes = self:GetCameraNodes
       -- ...
end

Whenever I call :GetCameraNodes or print it, it returns nil in this function.
There is nothing that sets __nodes to nil, and this module worked before with the same exact code

Is this a bug from Roblox?


#2

local Nodes = self:GetCameraNodes()

Do you need parens at the end? Can maybe try using self.__nodes directly from the SetNodeDirection fn and see it the problem is with the getter or with calling the getter. I don’t know. Not really enough shown for me to help. If you are retrieving the nodes indirectly, there can be reasons for getting nil that have nothing to do with the nodes table. Weird that it worked before and then just stopped.


#3

Ah, the problem is obviously that OOP is secretly the bane of every developer’s existence (I have strong feelings for OOP…).

But on a more serious note, __ prepending properties are generally for internal Lua methods only. When you read __ you should think ‘black magic voodoo ahead: enter and manipulate at your own peril’. It is common to use a single _ though to denote private properties / internal use only.

Is __nodes set directly in Cutscene, or is it access through a __index metamethod? How do you know that it is not being changed? It may be worth logging all setting and getting traffic affecting __nodes by using an __index and __newindex method and moving __nodes to an upvalue only accessed via those metamethods. Finally, is the function calling Info.Cutscene using the : operator and is the proper self being set?


#4

Okay, I see many people are asking questions about how the Module is set up, so I decided to open the Module model.

Here’s the link:


#5

hmm… seems to be working for me as best I can tell.

-- some test code in a localscript

local camapi = require(workspace.CameraApi)

local myscene = camapi.Cutscene:CreateCutscene("testscn")
local mynodes = myscene:GetCameraNodes()

for _,i in pairs(myscene._nodes) do
	print(i)
end

for _,i in pairs(myscene:GetCameraNodes()) do
	print(i)
end

myscene:SetNodeDirection(2) -- added a print inside this fn to see if Node(x) was working

in the module I changed _nodes = {} in the local Meta table to

_nodes = {["CameraNode1"]=1,["CameraNode2"]=2,["CameraNode3"]=3}

and I get values when using the SetNodeDirection.

Will see if I can figure out how to set up the nodes the correct way and see if that makes a difference XD


#6

I think it’s a big from roblox themselves. Hopefully this will be patched


#7

Maybe so. I changed everything back and used your CreateCameraNode() method to set things up and I’m not seeing nil values for the node table. The only other thing I can think of is to check your calling script. Maybe the problem is there somehow rather than with the module (though prob not unless you hack together tests like I did). Sorry I’m not able to reproduce it. Best of luck on finding the issue or having Roblox fix what broke. Peace.


#8

Interesting. Thank you for trying, though.


#9

Oh, I see it. Seems like something the editor should have flagged (in a perfect world).

-- error
--[[
19:27:20.728 - Workspace.CameraApi:136: attempt to call method 
'SetNodeDireciton' (a nil value)
]]--

-- offending code
	function Info.Cutscene:FaceNodeLeft(Num)
		self:SetNodeDireciton(Num, Vector3.new(0,-90,0)) <-- Direction is mispelled
	end

#10

I haven’t used :FaceNodeLeft for testing, so I didn’t really proofread. It doesn’t really effect if self._nodes is nil


#11

Well shoot. heh.

Here’s my test script. Only other thing I could find was with :IsNodeInCutscene. If you are using that in your tests you can get back nil for every number.
Otherwise, it all works well for me. Out of ideas for real now. Definite head scratcher.

local camApi = require(workspace.CameraApi)

-- create a new scene
local newScene = camApi.Cutscene:CreateCutscene("testscene")

-- add some nodes
newScene:CreateCameraNode(Vector3.new(0,10,0), Vector3.new(), 1)
newScene:CreateCameraNode(Vector3.new(10,10,0), Vector3.new(), 2)
newScene:CreateCameraNode(Vector3.new(20,10,0), Vector3.new(), 3)
newScene:CreateCameraNode(Vector3.new(30,10,0), Vector3.new(), 4)
newScene:CreateCameraNode(Vector3.new(40,10,0), Vector3.new(), 5)
newScene:CreateCameraNode(Vector3.new(50,10,0), Vector3.new(), 6)
newScene:CreateCameraNode(Vector3.new(50,10,10), Vector3.new(), 7)
newScene:CreateCameraNode(Vector3.new(50,10,20), Vector3.new(), 10)

-- change some node directions
newScene:SetNodeDirection(2, Vector3.new(45,45,0))
newScene:SetNodeDirection(3, Vector3.new(0,90,-10))

newScene:FaceNodeLeft(1)		-- spelling fixed
newScene:FaceNodeRight(10)
newScene:FaceNodeFront(4)
newScene:FaceNodeBack(5)
newScene:FaceNodeUp(6)
newScene:FaceNodeDown(7)

-- make the nodes visible
for n=1, 10 do
	--print(newScene:IsNodeInCutscene(n)) -- changed IsNodeInCutscene to work with int arg
	if newScene:IsNodeInCutscene(n) then
		newScene:ShowNodeDirection(n)
	end
end

#12

I am going to rewrite the whole code. The CameraApi looks too complicated. I’ll fix a lot of problems with this API anyway.