-
Notifications
You must be signed in to change notification settings - Fork 6
Developer Resources
These references are for developers to maintain internal consistency.
Scripts for the mod can be found here: Khonsu, Osiris.
Skills have been converted to better match the ability they use in PF2e. This is how they're used vs their ID - significant mismatches are marked with an asterix (*).
| 2e Skill | BG3 Skill | Ability |
|---|---|---|
| Acrobatics | Acrobatics | Dex |
| Arcana | Arcana | Int |
| Athletics | Athletics | Str |
| Crafting* | Nature | Int |
| Deception | Deception | Cha |
| Diplomacy | Persuasion | Cha |
| Intimidation | Intimidation | Cha |
| Lore | History | Int |
| Medicine | Medicine | Wis |
| Nature* | AnimalHandling | Wis |
| Occultism* | Investigation | Int |
| Performance | Performance | Cha |
| Religion* | Insight | Wis |
| Society* | Religion | Int |
| Stealth | Stealth | Dex |
| Survival | Survival | Wis |
| Thievery | SleightOfHand | Dex |
A tag can apply a status, item, or circumstance bonus from a boost, so that they can stack properly. Source: PF2e_BonusStacking
Tag(OFF_GUARD) makes a creature off-guard to all attacks, which can be checked with the OffGuard() function.
If you want to add a more specific stacked bonus, you can check if you have the general tags to not apply the bonus. Here's an example from ItemBonus1ReflexSaves:
IF(not Tagged('ITEM_BON_2SAVES') and not Tagged('ITEM_BON_1SAVES') ):RollBonus(SavingThrow,1,Dexterity)
//Item bonuses
ITEM_BON_1AC
ITEM_BON_2AC
ITEM_BON_1SAVES
ITEM_BON_2SAVES
ITEM_BON_1FORT
ITEM_BON_2FORT
ITEM_BON_1REFLEX
ITEM_BON_2REFLEX
ITEM_BON_1WILL
ITEM_BON_2WILL
//Item penalties
ITEM_PEN_1SAVES
ITEM_PEN_2SAVES
ITEM_PEN_2REFLEX
ITEM_PEN_1WILL
//Status bonuses
STAT_BON_1ATTACK
STAT_BON_2ATTACK
STAT_BON_1SPELLATTACK
STAT_BON_1DAMAGE
STAT_BON_2DAMAGE
STAT_BON_3DAMAGE
STAT_BON_1AC
STAT_BON_2AC
STAT_BON_1SAVES
STAT_BON_2SAVES
STAT_BON_1WILL
STAT_BON_2WILL
STAT_BON_1REFLEX
STAT_BON_2REFLEX
STAT_BON_1FORT
STAT_BON_2FORT
STAT_BON_1[5e Skill Name]
STAT_BON_2[5e Skill Name]
STAT_BON_SPEED_05
STAT_BON_SPEED_10
STAT_BON_SPEED_15
STAT_BON_SPEED_20
//Status penalties
STAT_PEN_1ATTACK
STAT_PEN_2ATTACK
STAT_PEN_1DAMAGE
STAT_PEN_1AC
STAT_PEN_2AC
STAT_PEN_3AC
STAT_PEN_1SAVES
STAT_PEN_2SAVES
STAT_PEN_1DC
STAT_PEN_2DC
STAT_PEN_1REFLEX
STAT_PEN_2REFLEX
STAT_PEN_3REFLEX
STAT_PEN_1WILL
STAT_PEN_2WILL
STAT_PEN_3WILL
STAT_PEN_1FORT
STAT_PEN_2FORT
STAT_PEN_3FORT
STAT_PEN_1[5e Skill Name]
STAT_PEN_2[5e Skill Name]
STAT_PEN_SPEED_05
STAT_PEN_SPEED_10
//Circumstance bonuses
CIRC_BON_1ATTACK
CIRC_BON_2ATTACK
CIRC_BON_1AC
CIRC_BON_2AC
CIRC_BON_1SAVES
CIRC_BON_2SAVES
CIRC_BON_1REFLEX
CIRC_BON_2REFLEX
CIRC_BON_1WILL
CIRC_BON_2WILL
CIRC_BON_1FORT
CIRC_BON_2FORT
//Circumstance penalties
CIRC_PEN_1ATTACK
CIRC_PEN_2ATTACK
CIRC_PEN_1AC
CIRC_PEN_2AC
Dev note: Are we missing anything here?
Resistances are handled through Osiris (Story) databases. This allows them to stack appropriately, with the actual effects calculated and turned into an output status. In the main mod, they're defined in the INIT section of the PF2e_BonusStacking script.
A set of statuses (_RESIST_INPUT and _WEAK_INPUT) use their duration as the resistance values and last for one turn. An example of this is the critical effect of Frostbite, where the target has weakness equal to the spell's rank for one turn.
DB_ResistValue(damage type, status ID, value)
DB_WeakValue(damage type, status ID, value)
These databases give a fixed resistance/weakness value to a given status, such as Resist Energy.
DB_ResistStacks(damage type, status ID)
DB_VulnStacks(damage type, status ID)
These databases make a status give resistance/weakness equal to its duration, like the input statuses listed above, but the input status can have any duration. An example (though a complex one) is Elemental Betrayal, which lasts indefinitely and is removed when the timing status expires.
DB_IntrinsicResistance(damage type, passive ID, value)
DB_AncestryResistance(damage type, passive ID)
Unlike the values for statuses, these do not assign the output status. Damage reduction should be handled by the passive itself. Instead, they tell the script to take the value of the passive into account.
We use a conversion of 5 feet => 2m for all distances in the game. The most notable exception to this is that reach weapons only provide 3m of range, because animations started looking quite silly at values higher than that.
If you need to apply a status that clears on short rest, simply add it to DB_ClearStatusOnShortRest in PF2e_GLO.
Sustained spells add a status on the owner that allows the user to recast them.
Here is an example of Requirement Conditions for a spell with a "sustained" duration. These conditions allow you to sustain the spell on condition duration 1 - "once per turn on subsequent turns". The Once per Turn cooldown is not necessary, but is good practice to put.
"RequirementConditions" "HasStatus('AnimatedAssault_Owner') and OwnerCanSustain('AnimatedAssault_Owner')"
Some spells with "sustained" duration instead care about maintaining a specific status on the target, such as most witch hexes. In this case, both the owner and the target need to have a 2-duration status, but only the target's status duration matters for targeting. There shouldn't be a once-per-turn spell limit, as multiple instances of the spell can be sustained at once.
"TargetConditions" "CanSustainTarget('SHROUDOFNIGHT')"
Some spells do not have a sustained duration, and instead the Sustain action represents an action that can be taken during that spell's duration. Some spells have actions taken by sustaining them, but also have a sustained duration. In those cases, it is reasonable to not add the once per turn cooldown.
A number of Khonsu helper functions exist of the format [trait]Spell(). Whilst these provide some useful shortcuts for common target conditions, they are also intended to be detectable by passives and interrupts using HasStringInSpellConditions('[trait]Spell'). For example, if you want to give a target a bonus to saving throws from spells with the Visual trait, you can use HasStringInSpellConditions('VisualSpell') in the conditions. Note that such traits will not necessarily be passed on to the statuses that spell applies, such as in the case of an OnApplyRoll save.
Of particular note is the ConcentrateSpell() helper. This is added to both the target conditions and requirement conditions of many spells as, despite checking context.Source. Whilst its mechanical conditions would be best suited to just the RequirementConditions field, it is not possible to detect strings in that field with HasStringInSpellConditions(), so it is doubled up in TargetConditions for the sake of interrupts such as Stupefied.
Note that it is also possible to make variants of these helpers, such as RageConcentrateSpell(), that will still pass the HasStringInSpellConditions() check whilst providing different condition behaviour.
TODO: Add all scroll templates to the scroll template regeneration script by XiphiasRex
(ITEMROOT)LOOT_SCROLL_AcidArrow_0fa4bdab-9ef1-4575-b063-b3e9d359d593
(ITEMROOT)LOOT_SCROLL_Aid_3e85f140-2284-430b-b11f-2126cd85b567
(ITEMROOT)LOOT_SCROLL_AnimalFriendship_3d992632-dc98-43b1-85e5-b59ba5a6aa9a
(ITEMROOT)LOOT_SCROLL_AnimateDead_8b9b4657-93f3-4382-b6e0-a587902abcba
(ITEMROOT)LOOT_SCROLL_ArcaneEye_DONOTUSE_5314d1eb-5771-47b5-80a7-2ee093ef4618
(ITEMROOT)LOOT_SCROLL_ArcaneLock_05da1a09-2d22-4299-b4a0-c4538a91f91c
(ITEMROOT)LOOT_SCROLL_Banishment_82719943-71e0-4eb2-bc4f-c8c0dd02c47c
(ITEMROOT)LOOT_SCROLL_BestowCurse_48fbab09-ede1-4093-9223-38c9e172c061
(ITEMROOT)LOOT_SCROLL_BlackTentacles_e9fae419-8c7a-4d5d-950f-94675a2aff07
(ITEMROOT)LOOT_SCROLL_Blight_e0ee9263-3740-44fe-80da-4315cb836aef
(ITEMROOT)LOOT_SCROLL_Blindness_2c6caac0-1684-4324-abba-0b849a9add74
(ITEMROOT)LOOT_SCROLL_Blink_d3800e05-635f-47b3-80b1-1a7c4161cf89
(ITEMROOT)LOOT_SCROLL_Blur_a8b34fd5-d643-49ad-98d3-d5841492b338
(ITEMROOT)LOOT_SCROLL_BurningHands_bc00df72-3c98-4bf2-9650-28e08f79b57c
(ITEMROOT)LOOT_SCROLL_ChainLightning_13105f7d-55fa-4292-abfe-b9d80054b48e
(ITEMROOT)LOOT_SCROLL_CharmPerson_2315f935-a188-4665-9ae0-986c7a9b0021
(ITEMROOT)LOOT_SCROLL_ChillTouch_79faf049-d503-46eb-a018-69e1975777d7
(ITEMROOT)LOOT_SCROLL_ChromaticOrb_c6aef37e-bc4d-46e7-a963-15b4cd8163bd
(ITEMROOT)LOOT_SCROLL_ChromaticOrb_d338fcb9-aaf5-48b1-8333-2dd4d9f70e1b
(ITEMROOT)LOOT_SCROLL_CircleOfDeath_ad31110a-aa9a-4427-925a-9952bfbef45a
(ITEMROOT)LOOT_SCROLL_Cloudkill_0e793d2d-1cd7-4b90-a71b-821423e50969
(ITEMROOT)LOOT_SCROLL_CloudOfDaggers_33421d4f-1cac-4196-a85e-0b07bcb3ecf2
(ITEMROOT)LOOT_SCROLL_ColorSpray_c7c92bc3-e856-4403-b509-9b0491f455cd
(ITEMROOT)LOOT_SCROLL_ConeOfCold_e81e7b31-8e7a-4fc1-977d-9a9a58fdd4a0
(ITEMROOT)LOOT_SCROLL_Confusion_7634cc33-d16b-4640-ba7c-8c6a26653591
(ITEMROOT)LOOT_SCROLL_ConjureElemental_c0e92dfa-29cf-46e8-8b35-8bded679df64
(ITEMROOT)LOOT_SCROLL_ConjureMinorElemental_a30864e5-06f0-4d14-9ea4-cb6870c0ddfe
(ITEMROOT)LOOT_SCROLL_Counterspell_DONOTUSE_17f828a4-5684-42dd-9f08-ff99ba43358a
(ITEMROOT)LOOT_SCROLL_CrownOfMadness_701a7df0-728e-494a-ab2f-146aed4e8c7f
(ITEMROOT)LOOT_SCROLL_Darkness_caa812b9-9362-4c38-aef0-e3f6eb288dba
(ITEMROOT)LOOT_SCROLL_Darkvision_0d737a55-c337-4e8f-b31f-a17273099013
(ITEMROOT)LOOT_SCROLL_DetectThoughts_126cc673-1151-4113-b1bf-98457233441b
(ITEMROOT)LOOT_SCROLL_DimensionDoor_75452ba5-5758-417c-b661-8832eb64df66
(ITEMROOT)LOOT_SCROLL_DisguiseSelf_b3376ca4-393c-4191-aa67-a02c94d6a236
(ITEMROOT)LOOT_SCROLL_Disintegrate_3f737706-57ca-45e6-b0d1-45238da76329
(ITEMROOT)LOOT_SCROLL_DispelMagic_DONOTUSE_bc5c0bcf-144f-46ed-bcde-e6bd1225efb9
(ITEMROOT)LOOT_SCROLL_DominatePerson_3b447e07-3e73-4906-9f7e-63a87e2da909
(ITEMROOT)LOOT_SCROLL_Enlarge_7c4c3ae1-26ac-4765-a5d5-586976e0e458
(ITEMROOT)LOOT_SCROLL_ExpeditiousRetreat_eedf0539-6a47-480e-8b23-a133b222241f
(ITEMROOT)LOOT_SCROLL_Eyebite_cecb1802-b2c0-4d65-aa08-aa15ca3619eb
(ITEMROOT)LOOT_SCROLL_FalseLife_7d76665a-3b9e-4495-a3c6-a05340704194
(ITEMROOT)LOOT_SCROLL_Fear_4cdb2434-0ffa-4fb1-9c42-d6451978f35b
(ITEMROOT)LOOT_SCROLL_FeatherFall_82cbfcd2-cf80-4acd-9f1f-51835693b0e6
(ITEMROOT)LOOT_SCROLL_FeignDeath_6e13fbf8-3db5-4420-8691-653d5ecb753e
(ITEMROOT)LOOT_SCROLL_FindFamiliar_fb975b01-40d5-49a3-b60a-d2f13a1f8009
(ITEMROOT)LOOT_SCROLL_Fireball_79d2bb95-53fc-4e41-a004-5e1b83db8de7
(ITEMROOT)LOOT_SCROLL_FireBolt_fdfe5d75-0e8b-47f8-b128-d57081cb8981
(ITEMROOT)LOOT_SCROLL_FireShield_Chill_DONOTUSE_5d2e1c40-e85e-4027-aefe-b9731a2de2c9
(ITEMROOT)LOOT_SCROLL_FireShield_Warm_6b87f7b4-441c-41cf-92c3-29e258747454
(ITEMROOT)LOOT_SCROLL_FlameBlade_a6d216e9-c9e9-4310-b155-0e4f50682377
(ITEMROOT)LOOT_SCROLL_FlamingSphere_0922de82-149f-4cac-aa98-e26222fd7714
(ITEMROOT)LOOT_SCROLL_FleshToStone_a9135751-3a8a-4070-9f3a-11d24d123a3f
(ITEMROOT)LOOT_SCROLL_Fly_1df15994-c860-4930-beed-3135b74025fa
(ITEMROOT)LOOT_SCROLL_FogCloud_dcb51bec-90bd-4d0a-942d-72034782bdf5
(ITEMROOT)LOOT_SCROLL_FreezingSphere_74d0e4f0-de97-4097-a7e7-f5759a375c81
(ITEMROOT)LOOT_SCROLL_GaseousForm_4c026e53-4000-4818-913c-a5662ee7c061
(ITEMROOT)LOOT_SCROLL_GlobeOfInvulnerability_8d4c06d1-e504-49b0-a4fa-5179ab717f1e
(ITEMROOT)LOOT_SCROLL_GlyphOfWarding_056f10e1-01e7-4622-907f-faad8d48bbe6
(ITEMROOT)LOOT_SCROLL_Goodberry_dff353d0-c1d4-43af-8664-bf08a9ffae07
(ITEMROOT)LOOT_SCROLL_Grease_094c9b7f-0b7d-4813-92ea-7267afb62b07
(ITEMROOT)LOOT_SCROLL_GustOfWind_6bedf433-994f-4624-bb2a-cdf6f46d539a
(ITEMROOT)LOOT_SCROLL_Haste_96d4aba5-bd76-4bae-a726-37a6c96776ab
(ITEMROOT)LOOT_SCROLL_HideousLaughter_8bc1a0d8-af28-45b2-b1ca-1f15e3c47b1b
(ITEMROOT)LOOT_SCROLL_HoldMonster_d621c19f-d5c8-433c-bc75-7f2eb87d2f0a
(ITEMROOT)LOOT_SCROLL_HoldPerson_5e077657-8b5e-4e69-ae2e-95eab691fa41
(ITEMROOT)LOOT_SCROLL_HypnoticPattern_bdf15fb0-d9df-4509-ad70-42b5fad11971
(ITEMROOT)LOOT_SCROLL_IceKnife_f26320fa-9a25-4f79-80fc-e356268cf474
(ITEMROOT)LOOT_SCROLL_IceStorm_e8c3ad4e-37f0-46c8-bf25-0ddc2dcb0139
(ITEMROOT)LOOT_SCROLL_Invisibility_6ed22182-90a6-418a-8aa7-909b9e77aa47
(ITEMROOT)LOOT_SCROLL_Invisibility_Greater_795e4282-27c3-4177-b532-9e6559a26531
(ITEMROOT)LOOT_SCROLL_IrresistibleDance_3c8db4fb-c10b-415d-b9cd-c3254265b778
(ITEMROOT)LOOT_SCROLL_Jump_e1f15103-bb95-476f-8b09-091f51b2f645
(ITEMROOT)LOOT_SCROLL_Knock_4c1a886a-7db5-4e00-bbc6-d4243534f057
(ITEMROOT)LOOT_SCROLL_LightningBolt_83600284-8f78-409f-a0e0-d262b2bdea64
(ITEMROOT)LOOT_SCROLL_Longstrider_82370a33-5243-4fad-9880-b0a8c2b5a225
(ITEMROOT)LOOT_SCROLL_MageArmor_2ccab07d-0ccb-45e6-8f43-8ffb6a62da11
(ITEMROOT)LOOT_SCROLL_MagicMissile_945cd4f0-991b-4663-b72e-790d49fee27e
(ITEMROOT)LOOT_SCROLL_MagicWeapon_ccf1bd99-e807-44e6-9a0a-7645ad533a8f
(ITEMROOT)LOOT_SCROLL_MirrorImage_019d8804-56ee-44eb-959a-db5377cda8ae
(ITEMROOT)LOOT_SCROLL_MistyStep_9a2a3fcc-d948-4463-b88b-a9d61b77b015
(ITEMROOT)LOOT_SCROLL_PhantasmalForce_2eb2147d-5bcb-4b0e-ac73-b2a4d1deeb77
(ITEMROOT)LOOT_SCROLL_PhantasmalKiller_3b802734-ad6e-45a4-988b-f7241636e5e9
(ITEMROOT)LOOT_SCROLL_PlanarBinding_6ac3b9ab-fdb4-47e8-8a35-91747de2afc8
(ITEMROOT)LOOT_SCROLL_Polymorph_389da9ab-bee7-447c-9bed-f1021ddc94d4
(ITEMROOT)LOOT_SCROLL_ProtectionFromEnergy_9f8502bf-727f-40c7-93a3-5fab6ba2e2f5
(ITEMROOT)LOOT_SCROLL_ProtectionFromEvilAndGood_03771ebc-83ca-45d2-8bd5-d382b6d6d824
(ITEMROOT)LOOT_SCROLL_RayOfEnfeeblement_cd1da9c5-c9ea-4d2a-93ce-e201c97eded9
(ITEMROOT)LOOT_SCROLL_RayOfFrost_f6cbfbb3-7eab-4f78-afde-073756c4e26d
(ITEMROOT)LOOT_SCROLL_RayOfSickness_22ef638a-206f-4874-8f68-e2a378df1158
(ITEMROOT)LOOT_SCROLL_RemoveCurse_dea31400-25e5-4e69-bb76-14430fe46673
(ITEMROOT)LOOT_SCROLL_ResilientSphere_f5bf39c0-2df3-4cd4-842c-c1862e6f80aa
(ITEMROOT)LOOT_SCROLL_Revivify_c1c3e4fb-d68c-4e10-afdc-d4550238d50e
(ITEMROOT)LOOT_SCROLL_ScorchingRay_577a83c9-0bb7-4670-b0e9-d9a4738f6a0a
(ITEMROOT)LOOT_SCROLL_SeeInvisibility_2e7fc397-cb84-4573-b6c7-1c7a8f2742d6
(ITEMROOT)LOOT_SCROLL_Seeming_d2573c9b-6de2-45bd-8032-b8a59432f4b5
(ITEMROOT)LOOT_SCROLL_Shatter_2ad118cb-b11f-45ca-a206-7575bbbaccc6
(ITEMROOT)LOOT_SCROLL_ShockingGrasp_a9ced623-a25d-4d2b-bca5-644b7230c869
(ITEMROOT)LOOT_SCROLL_Sleep_2ce88bf0-fe06-46bd-b71e-18bc6dc8eb9d
(ITEMROOT)LOOT_SCROLL_SleetStorm_be05f7d0-ffa0-46e3-a0d6-66e3333159f1
(ITEMROOT)LOOT_SCROLL_Slow_4c990ca3-01f6-4536-b8f3-c26cd9a0ca8b
(ITEMROOT)LOOT_SCROLL_SpeakWithDead_36d01b98-1702-4d00-81a9-1b8469dd67a5
(ITEMROOT)LOOT_SCROLL_StinkingCloud_0f0a7a12-1c77-423a-b16e-4a9a5480c05e
(ITEMROOT)LOOT_SCROLL_Stoneskin_7f39977f-bcab-4dda-933f-bd70cb333ecc
(ITEMROOT)LOOT_SCROLL_SummonQuasit_f912ea9b-0e2f-45b4-b12d-fa6ec89dc758
(ITEMROOT)LOOT_SCROLL_Sunbeam_049d70c4-7ea3-4b6c-af6f-44dab7813a89
(ITEMROOT)LOOT_SCROLL_Telekinesis_1d5ecaca-310b-4622-b302-81331c0a8e9e
(ITEMROOT)LOOT_SCROLL_Thunderwave_94caa680-50b8-46b1-b775-19150d783b2f
(ITEMROOT)LOOT_SCROLL_TrueResurrection_01d1b2b2-9e6b-4ad2-8d63-59f9caf1d389
(ITEMROOT)LOOT_SCROLL_VampiricTouch_6fd2d3d4-801c-4591-9c05-db8a68e51808
(ITEMROOT)LOOT_SCROLL_WallOfFire_0f3c7369-d0bd-4b97-960d-1407f4c8eebf
(ITEMROOT)LOOT_SCROLL_WallOfIce_e7dc56bc-b169-4a46-b8ee-cc6474dd7b15
(ITEMROOT)LOOT_SCROLL_WallOfStone_d13587f4-a1f4-4833-bd1e-da1c7951d680
(ITEMROOT)LOOT_SCROLL_Web_2eedb4ac-47fa-4039-9684-8b4bb0923a26
(ITEMROOT)LOOT_SCROLL_WitchBolt_e69f52a4-3d86-4f08-a9b4-c70ba4cc3070
These are principles that we follow when making content in order to keep the presentation of information consistent.
BG3's interface can be oppressive when displaying large amounts of spell information, and PF2e has some very long descriptions. Thankfully, some of the nuances that PF2e's descriptions cover can be ignored in the context of a video game.
When implementing an action, spell, or feature, start with the original rules text from Nethys, and then make modifications from there to account for changes made. Distances and Damage values should be implemented as description parameters, and this might require some rewording of rules text (such as 'a persistent [1d4 slashing damage]' instead of '1d4 persistent slashing damage'.
Degrees of success can sometimes result in significant description bloat. For simple effects, it can be helpful to reduce the degrees of success information to prose, utilising brackets for critical effects e.g. "The target becomes frightened 1 on a success (frightened 2 on a critical success)."
When writing descriptions for status effects that implement an action or spell's effect, remove the flavour text from the original ability.
Make use of LSTags wherever possible, and especially for passives that grant abilities and abilities that apply statuses.
In order for spells to be cast using slots at higher ranks, they require an explicit version of that spell defined for each spell slot rank, even when they don't have any effect when upcast.
Spells should have their level set to their lowest available rank, even on their upcast variants.
Focus spells (not cantrips) should have their level be their lowest rank. This is documented on the spell's Nethys entry.
If possible, use "action" style icons for focus spells rather than "spell" styled icons, so that they can stand out in contrast to the many slotted spells a caster has prepared. Spell icons have a brush strokes effect and they have a constant gray/brown background rather than matching the spell's color. As art assets are limited, this is more a suggestion, but it helps to keep it in mind.