PDA

View Full Version : Error only on creation of a new Character



bloodylemming
January 2nd, 2022, 20:03
I'm getting an error, but only when I create a new character.
[ERROR] Script execution error: [string "numLevel"]:9: attempt to index a nil value

Here's the code on line 9.

nodeChar.getChild("numProficiencyBonus").setValue(nLevel);


I set some debug code to see if there was a value present, and there is. It's a number value, as expected...

Zacchaeus
January 2nd, 2022, 20:23
What ruleset? How are you creating the character? We need a bit more info I think.

bloodylemming
January 2nd, 2022, 20:57
What ruleset? How are you creating the character? We need a bit more info I think.

Custom ruleset built off CoreRPG. So far, all I've really done is create the character...

Moon Wizard
January 2nd, 2022, 21:49
I don't see "numLevel" on that line. Are you sure that's the right script?

JPG

bloodylemming
January 2nd, 2022, 21:56
I don't see "numLevel" on that line. Are you sure that's the right script?

JPG

That's the code within numLevel.

Here's the complete code within the item numLevel.


function onFirstLayout()
onValueChanged();
end
function onValueChanged()
local nodeChar = window.getDatabaseNode();
local nLevel = nodeChar.getChild("numLevel").getValue();
--set Bonuses
nodeChar.getChild("numProficiencyBonus").setValue(nLevel);
nodeChar.getChild("numNonProficiencyBonus").setValue(math.floor(nLevel / 4));
nodeChar.getChild("numFamiliarBonus").setValue(math.floor(nLevel / 2));
nodeChar.getChild("numSpellcastingBonus").setValue(nLevel);

charManager.setSpells(nodeChar, nLevel); --sets number of spell slots
end


The first line with .setValue(nLevel) is line 9...

damned
January 3rd, 2022, 03:16
Set a Default value of 0 in the field?

bloodylemming
January 3rd, 2022, 03:23
Set a Default value of 0 in the field?

I have, and added debug code which shows that default value.

damned
January 3rd, 2022, 03:28
Try get rid of


function onFirstLayout()
onValueChanged();
end

bloodylemming
January 3rd, 2022, 03:42
Try get rid of


function onFirstLayout()
onValueChanged();
end

I tried that and got other errors, dealing with setting the number of spells of each level the character could cast, but I figured out a way around those, so I guess it's good now. Thank you.
No clue why there was both a value and not...

Moon Wizard
January 3rd, 2022, 07:44
You can't assume that getChild("<name>") will always return a node; which is where I'm guessing that the nil error is coming from. If that database node does not exist, then the getChild function will return nil; which will throw an error since you are then trying to call setValue on a nil value.

Instead of this:
local nLevel = nodeChar.getChild("numLevel").getValue();
nodeChar.getChild("numProficiencyBonus").setValue(nLevel);
nodeChar.getChild("numNonProficiencyBonus").setValue(math.floor(nLevel / 4));
nodeChar.getChild("numFamiliarBonus").setValue(math.floor(nLevel / 2));
nodeChar.getChild("numSpellcastingBonus").setValue(nLevel);

Try this:
local nLevel = DB.getValue(nodeChar, "numLevel", 0);
DB.setValue(nodeChar, "numProficiencyBonus", "number", nLevel);
DB.setValue(nodeChar, "numNonProficiencyBonus", "number", math.floor(nLevel / 4));
DB.setValue(nodeChar, "numFamiliarBonus", "number", math.floor(nLevel / 2));
DB.setValue(nodeChar, "numSpellcastingBonus", "number", nLevel);

Also, if the prof/nonprof/familiar/spellcasting bonuses are always based on level, I would recommend not even storing in the database at all. Just pull the level information when you need it, and apply the calculation then. Possibly even adding a global script like CharManager, with functions like getLevel(nodeChar), getProfBonus(nodeChar), ...

Regards,
JPG

bloodylemming
January 3rd, 2022, 18:20
You can't assume that getChild("<name>") will always return a node; which is where I'm guessing that the nil error is coming from. If that database node does not exist, then the getChild function will return nil; which will throw an error since you are then trying to call setValue on a nil value.

Instead of this:
local nLevel = nodeChar.getChild("numLevel").getValue();
nodeChar.getChild("numProficiencyBonus").setValue(nLevel);
nodeChar.getChild("numNonProficiencyBonus").setValue(math.floor(nLevel / 4));
nodeChar.getChild("numFamiliarBonus").setValue(math.floor(nLevel / 2));
nodeChar.getChild("numSpellcastingBonus").setValue(nLevel);

Try this:
local nLevel = DB.getValue(nodeChar, "numLevel", 0);
DB.setValue(nodeChar, "numProficiencyBonus", "number", nLevel);
DB.setValue(nodeChar, "numNonProficiencyBonus", "number", math.floor(nLevel / 4));
DB.setValue(nodeChar, "numFamiliarBonus", "number", math.floor(nLevel / 2));
DB.setValue(nodeChar, "numSpellcastingBonus", "number", nLevel);

Also, if the prof/nonprof/familiar/spellcasting bonuses are always based on level, I would recommend not even storing in the database at all. Just pull the level information when you need it, and apply the calculation then. Possibly even adding a global script like CharManager, with functions like getLevel(nodeChar), getProfBonus(nodeChar), ...

Regards,
JPG
I added the debug to put the value of numLevel in chat before the set value is called, and it displayed properly, but still threw the error at the first .setValue. numLevel existed as did it's default value, so I don't know why the error is thrown, unless they're being calculated on dfferent threads and there's no reconciliation? I know, I'm reaching.... I'll try DB. Is this a lua thing, or is it in the Developers Guide. A cursory search didn't turn up anything related...

Not familiar with DB (database?)

The way this game works, those values are always needed, and aren't automatically added to anything because circumstance determines when your character gets it and when they don't. I just produce the values and allow it to be added to the modifier stack.

Trenloe
January 3rd, 2022, 18:52
I added the debug to put the value of numLevel in chat before the set value is called, and it displayed properly, but still threw the error at the first .setValue. numLevel existed as did it's default value, so I don't know why the error is thrown, unless they're being calculated on dfferent threads and there's no reconciliation?
As Moon Wizard mentioned - "You can't assume that getChild("<name>") will always return a node" - if you did some debug along the lines of Debug.console("Child numProficiencyBonus = ", nodeChar.getChild("numProficiencyBonus")); you'll probably see this being reported in the console as Child numProficiencyBonus = nil

Like I've mentioned before - when you get nil errors you need to work out what is actually nil - and to do that you have to deconstruct the statement if you have multiple objects/functions in the statement. For example, one of your lines of code is: nodeChar.getChild("numProficiencyBonus").setValue( nLevel); - this is carrying out API calls on the nodeChar database node object, and on the database node object returned from nodeChar.getChild("numProficiencyBonus") - if either of these are nil you'll get the error you're seeing. So, deconstruct the line where the error is being reported to see what is actually nil - which is more than likely the getChild("<name>") API function mention by Moon Wizard - because the database node you're trying to access hasn't been created yet. Moon Wizard mentions using DB.setValue because it creates the child node if it doesn't exist - this API function is from the DB package (detailed in the Wiki development guide): https://fantasygroundsunity.atlassian.net/wiki/spaces/FGCP/pages/996644582/DB#setValue

bloodylemming
January 3rd, 2022, 19:09
As Moon Wizard mentioned - "You can't assume that getChild("<name>") will always return a node" - if you did some debug along the lines of Debug.console("Child numProficiencyBonus = ", nodeChar.getChild("numProficiencyBonus")); you'll probably see this being reported in the console as Child numProficiencyBonus = nil

Like I've mentioned before - when you get nil errors you need to work out what is actually nil - and to do that you have to deconstruct the statement if you have multiple objects/functions in the statement. For example, one of your lines of code is: nodeChar.getChild("numProficiencyBonus").setValue( nLevel); - this is carrying out API calls on the nodeChar database node object, and on the database node object returned from nodeChar.getChild("numProficiencyBonus") - if either of these are nil you'll get the error you're seeing. So, deconstruct the line where the error is being reported to see what is actually nil - which is more than likely the getChild("<name>") API function mention by Moon Wizard - because the database node you're trying to access hasn't been created yet. Moon Wizard mentions using DB.setValue because it creates the child node if it doesn't exist - this API function is from the DB package (detailed in the Wiki development guide): https://fantasygroundsunity.atlassian.net/wiki/spaces/FGCP/pages/996644582/DB#setValue

Okay, so it's likely that numProficiencyBonus didn't exist, and since I was only testing the the end part, I wasn't finding the problem? That makes sense. Thank you both.