PDA

View Full Version : Rolling 3d6 instead of 1d20 in the Pathfinder 2 ruleset



EmptyOwl
June 24th, 2020, 13:55
Hiyas,

I am seeing some weird behavior if I try to replace d20 with 3d6 in the Pathfinder 2 die rolling functions. In the following function fragment what is nDiceRoll? I thought it was the result of the dice rolled (i.e., the result of the 3d6) vs nTotal which would be the total of the roll + mods. This seems to be true except that nDiceRoll only stores the result of the first d6 rolled. I find this confusing and how would I store the total of the 3d6 to compare the dice roll result and total result to determine critical fails, fails, success, and crit success?

Fragment of the base getd20CheckResult:

function getd20CheckResult(nDiceRoll, nTotal, nTargetDC)
Line 476: if (nTotal >= (nTargetDC + 10) or nDiceRoll == 20) and nDiceRoll ~= 1 then
Line 476: if (nTotal >= (nTargetDC + 10) or nDiceRoll == 20) and nDiceRoll ~= 1 then
Line 478: elseif nDiceRoll == 1 and nTotal < (nTargetDC + 10) then
Line 484: if (nTotal <= (nTargetDC - 10) or nDiceRoll == 1) and nDiceRoll ~= 20 then
Line 484: if (nTotal <= (nTargetDC - 10) or nDiceRoll == 1) and nDiceRoll ~= 20 then
Line 486: elseif nDiceRoll == 20 and nTotal > (nTargetDC - 10) then
Line 491: GlobalDebug.consoleObjects("GameSystem.getd20CheckResult - sResult, nDiceRoll, nTotal, nTargetDC = ", sResult, nDiceRoll, nTotal, nTargetDC);
Line 491: GlobalDebug.consoleObjects("GameSystem.getd20CheckResult - sResult, nDiceRoll, nTotal, nTargetDC = ", sResult, nDiceRoll, nTotal, nTargetDC);

My experimental 3d6 tester function:

function getd20CheckResult(nDiceRoll, nTotal, nTargetDC)
-- Return the level of success/failure based off the target DC
-- This function should only be called if there is a target DC - success/failure cannot be determined without.
if nTargetDC == nil then
return "";
end

local sResult = "";

-- Roll meets or exceeds target DC - success unless there is a critical success/failure.
if nTotal >= nTargetDC then
sResult = "SUCCESS";
if (nTotal >= (nTargetDC + 6) or nDiceRoll == 18 or nDiceRoll == 17 or nDiceRoll == 16) and (nDiceRoll ~= 3 and nDiceRoll ~= 4 and nDiceRoll ~= 5) then
sResult = "CRITICAL SUCCESS";
elseif (nDiceRoll == 3 or nDiceRoll == 4 or nDiceRoll == 5) and nTotal < (nTargetDC + 6) then
sResult = "FAILURE";
end
-- Roll doesn't meet target DC - failure unless there is a critical success/failure.
elseif nTotal < nTargetDC then
sResult = "FAILURE";
if (nTotal <= (nTargetDC - 6) or (nDiceRoll == 3 or nDiceRoll == 4 or nDiceRoll == 5)) and (nDiceRoll ~= 18 and nDiceRoll ~= 17 and nDiceRoll ~= 16) then
sResult = "CRITICAL FAILURE";
elseif (nDiceRoll == 18 or nDiceRoll == 17 or nDiceRoll == 16) and nTotal > (nTargetDC - 6) then
sResult = "SUCCESS";
end
end

Mine seems to work except it seems to only base comparisons of the dice roll based on the first d6 in the roll. If my logic is off, it may be becasue I fiddled with the function before I realized the strange 1 die result behavior. Any help on this would be appreciated!

Thanks!

damned
June 24th, 2020, 13:59
use Debug.chat() or Debug.console() liberally to find out what is actually happening.
As the system was using a single dice earlier its possible that you need to add some function or process to sum the results of all the dice before this function.

Trenloe
June 24th, 2020, 14:36
Moved to a new thread to specifically discuss this issue.

As damned suggests, use debug to see what values are being passed.

Also extract the ruleset to a location outside of the FG rulesets folder and use an editor that has "find in files" functionality - look for where getd20CheckResult is called, which should give you a better context for the parameters being passed and returned.

superteddy57
June 25th, 2020, 10:50
Also understand that some code will look for rRoll.aDice[1] for results and crit information in a few rulesets. When you use 3d6 to replace the d20, it then adds two more dice to the aDice table. That could cause problems for you as well.

EmptyOwl
June 25th, 2020, 17:22
Also understand that some code will look for rRoll.aDice[1] for results and crit information in a few rulesets. When you use 3d6 to replace the d20, it then adds two more dice to the aDice table. That could cause problems for you as well.

Thanks for the move and responses!

I haven't done much programming since some C++ (and not much object oriented stuff even then) in college in the '90's so I am WAY behind on these new-fanggled scripting languages. May I ask is rRoll.aDice[1] a reference to a 1x1 table or to a memory reference for the rRoll of the array of dice? I see the brackets scattered in the scripts but don't really grasp what the number inside means. I thought it was just a reference to a specific instance of the function that could be recalled and accessed. Appreciate the help!

Thanks!

Trenloe
June 25th, 2020, 17:25
Info on LUA tables here: https://www.lua.org/pil/2.5.html

The [1] means it's the first "thing" in the LUA table - that could be a variable (string, boolean, number, etc.) or it could be another LUA table.

superteddy57
June 25th, 2020, 17:35
Trenloe linked an excellent resource. What helped me understand LUA in a nutshell is its all about the table. You can place anything in a table with LUA and also nest tables within tables.

Example Time
rRoll.aDice[#]
rRoll <-- Table
aDice <-- Nested Table
{"d6", "d6", "d6"} <-- Another Nested Table that you can access using 1, 2, or 3 to get that particular entry.

There are more under aDice, but say I wanted the result for the second d6 roll. I can call it by using 'rRoll.aDice[2].result' and do what I need to do with it. Just some snippets of information regarding LUA in your particular case. Try using Debug.chat("rRoll", rRoll) in your code and should output the contents of the rRoll at that point in the code. Which you will see is basically a table with varying data types. If you ever get lost, Debug.chat or Debug.console is great to verify things are being passed and collected.

EmptyOwl
June 27th, 2020, 00:47
Hey all, still trying to hammer this out :-)

Using Debug.chat("rDice", rDice) not debug.chat() (<-as this really seemed to piss FGU off) inside the getd20CheckResult function in the manager_gamesystem.lua, I got the following info (the actual roll was 5+2+3=10 +3 STR mod=13 total result):

s'rRoll' | { s'aDice' = { #1 = { s'value' = #5, s'type' = s'd6', s'result' = #5 }, #2 = { s'value' = #2, s'type' = s'd6', s'result' = #2 }, #3 = { s'value' = #3, s'type' = s'd6', s'result' = #3 }, s'expr' = s'3d6' }, s'nMod' = #3, s'sType' = s'ability', s'bSecret' = bFALSE, s'sDesc' = s'[ABILITY] Strength check' }

I grok much of it, but isn't # the length function in Lua? Or does # mean it is a number value, while s means a string value? Is this only used in Debug, as I cant find any info on that function....

Thanks for the tips and patience!

damned
June 27th, 2020, 00:59
debug.chat() firstly doesnt work because its case is incorrect
secondly you need to tell teh system what to output with your debug

remember about adice being an array?
well the results are also an array

#1 is the results of the first dice, #2 the second etc.

rRoll.aDice[1] is going to be { s'value' = #5, s'type' = s'd6', s'result' = #5 }

EmptyOwl
June 27th, 2020, 01:30
Sweet, got FGU to recognize 3d6 and base stuff off the roll total. I am sure there are a lot of little things I am missing but got attacks and abilities done so far. Thanks so much for taking the time to help! Probably break with the next update, lol! Next: learning how to make it an extension.

damned
June 27th, 2020, 02:41
They are numbers and strings.
Sometimes you still need to convert a number to a number with tonumber()