Coding dice rolls (actions) in CoreRPG
I seem to keep discussing how to roll dice as part of the CoreRPG action manager flow, so it's high time I actually spent the time and put a thread together regarding the subject.
This thread aims to provide details of the CoreRPG actions manager package which is used as the basis for the majority of dice rolling (actions) in CoreRPG and ruleset layered on top of CoreRPG (5E, Pathfinder, 3.5E, 4E, Call of Cthulhu, Castles & Crusades, etc., etc.).
Before you start! Actions can get pretty complex fast. They can use a lot of advanced techniques/procedures (targeting, effects, etc.) and you can soon lose yourself in the complex nested code and give up. Your first custom action doesn't have to be complex (see the basic example in post #4). Start off without targeting, without effects, without success/failure reporting. Then, once you have the base action sorted out, you can slowly add these in. Even if you're an experienced programmer, you can soon get lost in the specifics of FG and it's layered code. Take it in small steps...
Action - this is a term FG uses to describe a specific piece of the RPG system's mechanics that usually requires a dice roll. Common actions are: dice, attack, damage, save, init, skill, etc. and depend on the RPG system in question.
As Fantasy Grounds dice rolling is asynchronous - i.e. FG code doesn't sit waiting for the dice to land before continuing (this would be disastrous to performance), there has to be a number of steps to putting the action together and then processing the result of the action once the dice roll land. These are accomplished in the specific ruleset through an Action Manager.
In it's simplest form, an action could just be a simple dice roll - no recipient (target) of the dice roll, no intended success/fail threshold, etc.. Just roll the dice, add modifiers if necessary, and then display the result. Such an action would have the action type set to "dice".
In a more complex form, say a d20 based attack, there would be one or more targets of the attack, there could be many modifiers (including effects both on the source of the action and the target/s), there would be a threshold the roll needs to meet to succeed (the AC of the target/s), and there could be additional processing needed for certain rolls (critical or fumble). All of this is handled by the ActionAttack package (and the relevant built-in helper functions).
The following posts won't go into the full detail of such a complex action as a d20 RPG attack, but will break down a slightly simpler action to illustrate how the process works. Examples of how to create your own actions will follow.
Note: When you create a new action type, you must let FG know that a new action is present. FG will not process actions with a type it is not aware of. CoreRPG comes with three default action types: dice, table and effect which are stored in the actions table in the GameSystem package (scripts\manager_gamesystem.lua):
Code:
-- Ruleset action types
actions = {
["dice"] = { bUseModStack = "true" },
["table"] = { },
["effect"] = { sIcon = "action_effect", sTargeting = "all" },
};
Most rulesets will override this with their own scripts\manager_gamesystem.lua file.
Actions can also be added (handy for extensions) using the GameSystem.actions["XXX_actionname_XXX"] = { XXX_parameters_XXX }; command in the action manager onInit function. See post #4 for an example.
Targetable actions (drag/drop to Combat Tracker entry) In order to make an action drag/droppable it needs to be added to the GameSystem.targetactions LUA table.