### Install JavaScript Dependencies Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Install all necessary JavaScript dependencies for the project using npm ci. This command ensures a clean installation based on the package-lock.json. ```bash npm ci ``` -------------------------------- ### Start Development Server Without Building Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Start the development server directly without triggering a build. This is useful for rapidly testing JavaScript changes after an initial build. ```bash npm run serve ``` -------------------------------- ### Full Commit Message Example Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/MERGE_REQUESTS.md A comprehensive example of a commit message that includes a conventional commit prefix, a detailed message, an issue reference, and a past reference. ```git fix(pack): formula in ninja werewolf's bite max charges Fixes #1234 Refs: c74aee4d ``` -------------------------------- ### Build and Serve System with Vite Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Build the system and start a Vite development server. This server proxies Foundry VTT on port 30000 and enables hot reloading for CSS and HBS files. ```bash npm run build:serve ``` -------------------------------- ### Example of @Ability Enricher Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/help/en/Enrichers.md Use this enricher to roll an ability check. It takes the ability key as an argument. ```text @Ability[str] ``` -------------------------------- ### Conventional Commit Message Examples Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/MERGE_REQUESTS.md Examples of commit messages following the conventional commits format, including prefixes, optional details, and breaking change indicators. ```git feat: add more ice cream ``` ```git fix: cmb was doubled ``` ```git style(css): change header text color to green ``` ```git feat(pack): simplify class feature formulas ``` ```git build: extract packs faster ``` ```git test: actor poisoning ``` -------------------------------- ### Example of @Action Enricher Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/help/en/Enrichers.md Use this enricher as a shorthand for @Use when the action is on the same item as the chat card. It takes the action name as an argument and an optional label. ```text @Action[Grab]{Followup} ``` -------------------------------- ### Examples of @Toggle Enricher Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/help/en/Enrichers.md Use this enricher to toggle an existing buff or item by name. It supports options for level, type, and enabling/disabling. ```text @Toggle[Mage Armor;level=@cl;type=buff] ``` ```text @Toggle[Rage;type=buff;disable] ``` ```text @Toggle[Bless;enable;level=5;type=buff] ``` -------------------------------- ### JSDoc Function Documentation Format Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/CODE.md Prefer this JSDoc format for function documentation. It includes a title, description, usage examples, remarks, and detailed parameter/return/throws information. ```javascript /** * Clear Title for Functionality * * Description * * @example * ```js * how to use it * ``` * * @remarks * - Something weird * * @hidden * @protected * @this {InCaseNotObvious} * @param {Type} name - Description * @param {OtherType} [name2] - Description for optional param * @returns {Type} - Description * @throws {ErrorType} - Explanation */ ``` -------------------------------- ### Damage Roll Example with Size Modifier Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/help/en/Formulas.md Demonstrates a damage roll calculation that includes a size modifier. This example shows how to apply dice rolls and size adjustments. ```FoundryVTT Formula sizeRoll(2, 6, @size) ``` -------------------------------- ### Global Namespace Access Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Access to the `pf1` system's API is available globally after initialization. All sub-namespaces are frozen read-only objects. This example shows how to access various namespaces like `config`, `documents`, `dice`, and `utils` once the system is ready. ```APIDOC ## Global Namespace Access ### Description Access to the `pf1` system's API is available globally after initialization. All sub-namespaces are frozen read-only objects. This example shows how to access various namespaces like `config`, `documents`, `dice`, and `utils` once the system is ready. ### Usage ```js // Access via global after system is ready (Hooks.once("ready", ...)) Hooks.once("pf1PostReady", () => { // Top-level namespaces console.log(pf1.config); console.log(pf1.const); console.log(pf1.documents); console.log(pf1.models); console.log(pf1.dice); console.log(pf1.registry); console.log(pf1.components); console.log(pf1.utils); console.log(pf1.applications); console.log(pf1.migrations); }); ``` ``` -------------------------------- ### Examples of @Apply Enricher Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/help/en/Enrichers.md Use this enricher to apply a defined buff to actors. It can take a buff name or UUID and optional level. If a name is provided, it searches directories and compendiums. ```text @Apply[Special Mood] ``` ```text @Apply[Compendium.pf1.commonbuffs.Item.IlO0CNpAIKZtNYu8;level=5] ``` ```text @Apply[Rage;level=3] ``` ```text @Apply[Shield;level=@cl] ``` -------------------------------- ### Access and Unregister Registry Entries Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Access registered entries using the registry's get() method and retrieve all labels with getLabels(). Unregister entries by namespace using unregister(). ```javascript // Access registered entries at runtime const sonic = pf1.registry.damageTypes.get("sonic"); console.log("Sonic damage:", sonic?.name, sonic?.category); const allTypes = pf1.registry.damageTypes.getLabels({ sort: true }); // => { slashing: "Slashing", piercing: "Piercing", sonic: "Sonic", ... } // Unregister all entries from a namespace pf1.registry.damageTypes.unregister("my-module"); ``` -------------------------------- ### Conditional Damage on Specific Attacks Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/help/en/Items/Actions.md Example of a formula that applies damage only to a specific attack in a sequence. It uses the @attackCount variable to check if it's the second attack (index 1). ```text if(eq(@attackCount, 1), 2d8) ``` -------------------------------- ### Build Production-Ready System Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Build the complete system for production into the 'dist' directory. This output can then be copied or symlinked into Foundry VTT's data directory. ```bash npm run build ``` -------------------------------- ### Build System with Watch Mode Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Build the system and continuously watch for file changes, automatically rebuilding when modifications are detected. ```bash npm run build:watch ``` -------------------------------- ### Configure Foundry VTT Data Path Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Create a foundryconfig.json file to specify paths for Foundry VTT data and application, and to control browser opening behavior during builds. ```json { "dataPath": "/.local/share/FoundryVTT>", "appPath": "", "routePrefix": "", "openBrowser": true // Open a web browser when running `npm run build:serve`; defaults to false } ``` -------------------------------- ### Link Built System to Foundry Data Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Create a symbolic link from Foundry VTT's system data directory to the built 'dist' directory. This is useful when using the 'serve' command. ```bash npm run link dist ``` -------------------------------- ### Commit Message with Past Reference Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/MERGE_REQUESTS.md Example of a commit message that includes a reference to a previous commit or merge request using the 'Refs' keyword. ```git Refs: c74aee4d, !4300 ``` -------------------------------- ### Critical-Only Bonus Damage Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/help/en/Items/Actions.md Example of a formula that applies bonus damage only on critical hits. It checks the critical multiplier pass using the @critCount variable. ```text if(eq(@critCount, 1), 1d6) ``` -------------------------------- ### pf1.migrations.migrateWorld() Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Migrates all world data (actors, items, compendium packs, chat messages) to the current system version. Automatically invoked by the system on `ready`; can also be triggered manually by a GM. ```APIDOC ## `pf1.migrations.migrateWorld(options?)` — World Data Migration Migrates all world data (actors, items, compendium packs, chat messages) to the current system version. Automatically invoked by the system on `ready`; can also be triggered manually by a GM. ### Parameters - **options** (object, optional) - Configuration options for the migration. - **unlock** (boolean, optional) - If true, includes locked compendiums in the migration. Defaults to false. - **fast** (boolean, optional) - If true, skips documents that have already been migrated. Defaults to false. - **systemPacks** (boolean, optional) - If true, includes system pack migration. Defaults to true. - **dialog** (object | null, optional) - Configuration for the progress dialog. - **top** (number) - The top position of the dialog. - **left** (number) - The left position of the dialog. If set to null or falsy, the dialog is disabled. ### Related Functions - **`pf1.migrations.check(): { need: boolean, from: string | null }`**: Checks if migration is needed and from which version. - **`pf1.migrations.autoMigrate(): Promise`**: Runs the automatic migration process. - **`pf1.migrations.migrateActors(options?): Promise`**: Migrates only actor data. - **`pf1.migrations.migrateCompendiums(packs: CompendiumCollection[], options?): Promise`**: Migrates specific compendium packs. - **`pf1.migrations.isMigrated(doc: Document): boolean`**: Checks if a specific document has been migrated. ### Example Usage ```js // Check if migration is needed const { need, from } = pf1.migrations.check(); console.log("Needs migration:", need); console.log("Migrating from:", from); // e.g. "11.9" // Run automatic migration (used by system on startup) if (need) { await pf1.migrations.autoMigrate(); } // Manual full world migration with all options await pf1.migrations.migrateWorld({ unlock: true, // include locked compendiums fast: true, // skip already-migrated docs systemPacks: false, // skip system pack migration dialog: { // show progress dialog (set falsy to disable) top: 100, left: 200, }, }); // Migrate only actors await pf1.migrations.migrateActors({ fast: true }); // Migrate only specific compendiums const packs = [game.packs.get("world.my-pack")]; await pf1.migrations.migrateCompendiums(packs, { unlock: true, fast: false }); // Check if a specific document has been migrated const actor = game.actors.getName("Valeros"); const isMigrated = pf1.migrations.isMigrated(actor); console.log("Actor migrated:", isMigrated); ``` ``` -------------------------------- ### Use Bun Instead of Node.js Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Replace 'npm' commands with 'bun' for project management when using Bun as an alternative to Node.js. Note that 'npm ci' does not have a direct equivalent in Bun. ```bash bun serve ``` -------------------------------- ### Define and Use Item Actions with Action Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Explore how to identify and utilize actions defined within an item, including checking for damage, range, and applying enhancements. This is useful for programmatic interaction with item abilities. ```javascript const fireball = actor.items.find(i => i.name === "Fireball"); const action = fireball.system.actions.contents[0]; // Action identification console.log("Action name:", action.name); // e.g. "Fireball" console.log("Action img:", action.img); console.log("Has damage:", action.hasDamage); // true console.log("Is ranged:", action.isRanged); // true console.log("Enhancement bonus:", action.enhancementBonus); // Range console.log("Range value:", action.range?.value); // e.g. "long" console.log("Range units:", action.range?.units); // "ft", "m", "close", etc. // Damage parts for (const dmgPart of action.damage?.parts ?? []) { console.log("Damage formula:", dmgPart.formula); console.log("Damage types:", [...dmgPart.types]); // e.g. ["fire"] } // Use the action directly await action.use({ rollMode: "roll", measureTemplate: true, // auto-place measured template clCheck: false, }); ``` -------------------------------- ### Commit Message with Issue References Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/MERGE_REQUESTS.md Example of a commit message that includes references to issues or merge requests using keywords like 'Fixes', 'Implements', 'Closes', or 'Related to'. ```git Fixes #1234 ``` ```git Implements #321 ``` ```git Closes #231 ``` ```git Related to #213 ``` -------------------------------- ### Build System Without Packs Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Build the system, skipping the building of packs. This command uses Vite directly to bypass pack generation. ```bash npx vite build ``` -------------------------------- ### Registry.register() Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt The `Registry` base class provides a system for registering extensible game content such as damage types, conditions, and materials. Modules can call `register()` during specific Foundry hooks to add custom content. ```APIDOC ## `Registry.register()` — Extensible Game Content Registries The `Registry` base class implements a `Collection`-backed system for registering extensible game content (damage types, conditions, materials, script call categories, sources). Modules call `register()` during the appropriate Foundry hook. ```js // Register a custom damage type during pf1RegisterDamageTypes hook Hooks.on("pf1RegisterDamageTypes", (registry) => { registry.register("my-module", "sonic", { name: "Sonic", img: "icons/svg/sound.svg", category: "energy", // "physical" | "energy" | "misc" color: "#aaccff", resist: true, isModifier: false, }); }); // Register a custom condition during pf1RegisterConditions hook Hooks.on("pf1RegisterConditions", (registry) => { registry.register("my-module", "overcharged", { name: "Overcharged", texture: "icons/svg/lightning.svg", mechanics: { changes: [{ formula: "-2", target: "ac.normal", type: "untyped" }], flags: [], contexts: [], }, hud: { show: true, include: [], exclude: [] }, }); }); // Access registered entries at runtime const sonic = pf1.registry.damageTypes.get("sonic"); console.log("Sonic damage:", sonic?.name, sonic?.category); const allTypes = pf1.registry.damageTypes.getLabels({ sort: true }); // => { slashing: "Slashing", piercing: "Piercing", sonic: "Sonic", ... } // Unregister all entries from a namespace pf1.registry.damageTypes.unregister("my-module"); ``` ``` -------------------------------- ### pf1.utils.Alignment Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt The `Alignment` class wraps two-character alignment codes and provides methods for checking alignment properties, getting localized labels, calculating step distances, and modifying alignments. ```APIDOC ## `pf1.utils.Alignment` — Alignment Parsing and Manipulation The `Alignment` class wraps the two-character alignment code (e.g. `"lg"`, `"cn"`, `"tn"`) and provides boolean accessors, localized labels, step distance calculation, and relative/absolute alignment changes. ```js const align = new pf1.utils.Alignment("lg"); // Lawful Good console.log(align.lawful); // true console.log(align.good); // true console.log(align.evil); // false console.log(align.chaotic); // false console.log(align.trueNeutral); // false console.log(align.label); // "Lawful Good" (localized) console.log(align.toString()); // "lg" // Count alignment steps between two alignments const ce = new pf1.utils.Alignment("ce"); console.log(align.stepsTo(ce)); // 2 (lawful→chaotic = 1, good→evil = 1) // Shift alignment relatively align.change({ type: "relative", value: "e", step: 1 }); // shift toward evil console.log(align.toString()); // "ln" // Set alignment absolutely align.change({ type: "absolute", value: "tn" }); console.log(align.toString()); // "tn" // Static parse helper const parsed = pf1.utils.Alignment.parse("ng"); console.log(parsed.good); // true console.log(parsed.neutral); // true ``` ``` -------------------------------- ### Foundry Hooks — System Extension Points Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt The pf1 system broadcasts custom hooks that modules can use to register content, react to system events, and modify behavior at key lifecycle points. ```APIDOC ## Foundry Hooks — System Extension Points The pf1 system broadcasts custom hooks that modules can use to register content, react to system events, and modify behavior at key lifecycle points. ### Available Hooks - **`pf1PostInit`**: Called after system initialization. Safe to access `pf1.config`, `pf1.registry`, etc. - **`pf1PostReady`**: Called after world data is ready. Actors and items are accessible. - **`pf1RegisterDamageTypes`**: Called during registry initialization. Use to register custom damage types. - Receives a `registry` object as an argument. - **`pf1PreActionUse`**: Called before an action is used. Allows interception or augmentation. - Receives a `shared` object containing `item`, `action`, `actor`, `token`, `formData`, `config`, `useOptions`. - Returning `false` prevents the action use. - **`pf1MigrationStarted`**: Called when a migration process begins. - Receives an object with a `scope` property. - **`pf1MigrationCompleted`**: Called when a migration process completes. - Receives an object with `scope` and `count` properties. ### Example Usage ```js // Called after system init — safe to access pf1.config, pf1.registry, etc. Hooks.on("pf1PostInit", () => { console.log("PF1 system initialized"); // Register custom config entries or registry items here }); // Called after world data is ready — actors/items are accessible Hooks.on("pf1PostReady", () => { console.log("PF1 world is ready"); }); // Hook called during registry initialization — register custom damage types Hooks.on("pf1RegisterDamageTypes", (registry) => { registry.register("my-module", "force", { name: "Force", category: "energy", color: "#9966ff", img: "icons/svg/force.svg", resist: false, }); }); // Hook called when an action is used — intercept or augment usage Hooks.on("pf1PreActionUse", (shared) => { // shared contains: item, action, actor, token, formData, config, useOptions if (shared.action.name === "Power Attack") { console.log("Power Attack detected!"); // Return false to prevent the action use } }); // Hook for migration start/end Hooks.on("pf1MigrationStarted", ({ scope }) => { console.log("Migration started for:", scope); }); Hooks.on("pf1MigrationCompleted", ({ scope, count }) => { console.log(`Migration done: ${count} docs in scope ${scope}`); }); ``` ``` -------------------------------- ### Access and Use Item Data with ItemPF Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Learn how to access item properties, check their status, and programmatically use actions or modify charges. Requires an actor and an item document. ```javascript const sword = actor.items.find(i => i.name === "Longsword"); // Item subtype and type inspection console.log("Item type:", sword.type); // "weapon" console.log("Item subType:", sword.subType); // e.g. "1h-melee" // Check physical item properties console.log("Is physical:", sword.isPhysical); // true console.log("Is charged:", sword.isCharged); // depends on uses config console.log("Current charges:", sword.charges); // number or null console.log("Max charges:", sword.maxCharges); // Use an action from this item programmatically const action = sword.system.actions.contents[0]; await action.use({ primaryAttack: true, powerAttack: false, skipAttacks: 0, rollMode: "roll", // "publicroll" | "gmroll" | "blindroll" | "selfroll" }); // Add charges to an item await sword.addCharges(3); // adds 3 charges // Create item via dialog const newItem = await pf1.documents.ItemPF.createDialog( { type: "feat" }, { parent: actor } ); ``` -------------------------------- ### Extend Foundry Hooks for System Events Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt The Pathfinder 1e system provides custom hooks for module integration. Use `Hooks.on` to subscribe to events like initialization, world readiness, migration status, and action usage. ```javascript Hooks.on("pf1PostInit", () => { console.log("PF1 system initialized"); // Register custom config entries or registry items here }); ``` ```javascript Hooks.on("pf1PostReady", () => { console.log("PF1 world is ready"); }); ``` ```javascript Hooks.on("pf1PreActionUse", (shared) => { // shared contains: item, action, actor, token, formData, config, useOptions if (shared.action.name === "Power Attack") { console.log("Power Attack detected!"); // Return false to prevent the action use } }); ``` ```javascript Hooks.on("pf1MigrationStarted", ({ scope }) => { console.log("Migration started for:", scope); }); Hooks.on("pf1MigrationCompleted", ({ scope, count }) => { console.log(`Migration done: ${count} docs in scope ${scope}`); }); ``` -------------------------------- ### Format Formulas for Readability Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/COMPENDIUMS.md Demonstrates proper spacing for formulas to ensure correct parsing by Foundry and improve readability. Avoid concatenating operators with variables or numbers. ```plaintext 10 + floor((@item.level - 1) / 7) * 10 ``` -------------------------------- ### Configure Git for Development Workflow Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Set Git configuration options to ensure a smooth development workflow, including enabling pull rebasing and configuring line endings and case sensitivity. ```bash git config pull.rebase true ``` ```bash git config core.autocrlf false ``` ```bash git config core.ignorecase false ``` ```bash git config core.eol lf ``` -------------------------------- ### ItemPF Methods Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Interact with ItemPF documents, including accessing system data, checking properties, using actions, and adding charges. ```APIDOC ## ItemPF `ItemPF` extends Foundry's `Item` document. All item system logic resides in its `TypeDataModel` (`system` property). `ItemPF` handles creation side-effects (spellbook creation on class add, racial speed on race add), supplemental item grants, and action use dispatching. ### Accessing Item Data ```js // Access item system data const sword = actor.items.find(i => i.name === "Longsword"); // Item subtype and type inspection console.log("Item type:", sword.type); // "weapon" console.log("Item subType:", sword.subType); // e.g. "1h-melee" // Check physical item properties console.log("Is physical:", sword.isPhysical); // true console.log("Is charged:", sword.isCharged); // depends on uses config console.log("Current charges:", sword.charges); // number or null console.log("Max charges:", sword.maxCharges); ``` ### Using Item Actions ```js // Use an action from this item programmatically const action = sword.system.actions.contents[0]; await action.use({ primaryAttack: true, powerAttack: false, skipAttacks: 0, rollMode: "roll", // "publicroll" | "gmroll" | "blindroll" | "selfroll" }); ``` ### Managing Charges ```js // Add charges to an item await sword.addCharges(3); // adds 3 charges ``` ### Creating Items via Dialog ```js // Create item via dialog const newItem = await pf1.documents.ItemPF.createDialog( { type: "feat" }, { parent: actor } ); ``` ``` -------------------------------- ### Run Changelog Script Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/MERGE_REQUESTS.md Execute the changelog script to add entries to the CHANGELOG.md file. This script will prompt for a message, change type, and an optional issue number. ```bash npm run addlog ``` -------------------------------- ### Configure jsconfig.json or tsconfig.json for System Typings Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/other/MODULE_DEV.md Include this configuration in your project's jsconfig.json or tsconfig.json to enable type checking and autocompletion for the Pathfinder 1e system typings. ```json { "references": [{ "path": "./pf1/" }], "include": ["pf1/**/*.mjs", "pf1/**/*.d.ts"], "exclude": ["pf1/dist/", "pf1/foundry/", "pf1/node_modules/"] } ``` -------------------------------- ### Challenge Rating (CR) Conversion Utilities Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Utilize the CR class for converting challenge rating strings to numbers, numbers to strings, and retrieving XP values. Supports fractional CRs and provides step index conversion. ```javascript // Parse CR strings to numbers console.log(pf1.utils.CR.fromString("1/2")); // 0.5 console.log(pf1.utils.CR.fromString("1/4")); // 0.25 console.log(pf1.utils.CR.fromString("1/3")); // 0.3375 console.log(pf1.utils.CR.fromString("12")); // 12 // Convert numbers back to display strings console.log(pf1.utils.CR.fromNumber(0.5)); // "1/2" console.log(pf1.utils.CR.fromNumber(0.25)); // "1/4" console.log(pf1.utils.CR.fromNumber(7)); // "7" // Get XP for a given CR console.log(pf1.utils.CR.getXP(5)); // 1600 console.log(pf1.utils.CR.getXP(0.5)); // 200 console.log(pf1.utils.CR.getXP(0.25)); // 100 // CR step index conversion (for advancement tables) console.log(pf1.utils.CR.fromStep(0)); // 0.125 (1/8) console.log(pf1.utils.CR.getStep(1)); // 6 (index in crSteps) ``` -------------------------------- ### Action Model Methods Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Details on the Action component model, including identification, range, damage, and programmatic use. ```APIDOC ## Action (component model) `Action` is a pseudo-document embedded inside `ActionItemModel`-based items. It defines attack, damage, activation, target, range, and other parameters for how an item is used. Each item can have multiple actions stored in `item.system.actions`. ### Action Identification and Properties ```js const fireball = actor.items.find(i => i.name === "Fireball"); const action = fireball.system.actions.contents[0]; // Action identification console.log("Action name:", action.name); // e.g. "Fireball" console.log("Action img:", action.img); console.log("Has damage:", action.hasDamage); // true console.log("Is ranged:", action.isRanged); // true console.log("Enhancement bonus:", action.enhancementBonus); ``` ### Range Information ```js // Range console.log("Range value:", action.range?.value); // e.g. "long" console.log("Range units:", action.range?.units); // "ft", "m", "close", etc. ``` ### Damage Parts ```js // Damage parts for (const dmgPart of action.damage?.parts ?? []) { console.log("Damage formula:", dmgPart.formula); console.log("Damage types:", [...dmgPart.types]); // e.g. ["fire"] } ``` ### Using an Action Programmatically ```js // Use the action directly await action.use({ rollMode: "roll", measureTemplate: true, // auto-place measured template clCheck: false, }); ``` ``` -------------------------------- ### Configure i18n Ally for Localization Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Configure the i18n Ally extension to recognize localization keys in various template languages and specify the locale path. This helps in managing translations effectively. ```yaml languageIds: - javascript - typescript - handlebars - html usageMatchRegex: - "game.i18n.localize(['"]({key})['"])" - "game.i18n.format(['"]({key})['"])" - "{{{~?\s*localize\s+['"]({key})['"]" - "(localize\s+['"]({key})['"])" - "\.dataset\.tooltip\s+=\s+['"]({key})['"]" - "\s+data-tooltip=['"]({key})['"]" - ' blank=[''"']({key})[''"']' - ' label=[''"']({key})[''"']' - "ui.notifications.\w+(['"]({key})['"])" localePaths: - 'lang' monopoly: true ``` -------------------------------- ### Migrate World Data Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Use `pf1.migrations` to update world data to the latest system version. This can be triggered automatically on `ready` or manually by a GM with various options for control. ```javascript const { need, from } = pf1.migrations.check(); console.log("Needs migration:", need); console.log("Migrating from:", from); // e.g. "11.9" ``` ```javascript if (need) { await pf1.migrations.autoMigrate(); } ``` ```javascript await pf1.migrations.migrateWorld({ unlock: true, // include locked compendiums fast: true, // skip already-migrated docs systemPacks: false, // skip system pack migration dialog: { // show progress dialog (set falsy to disable) top: 100, left: 200, }, }); ``` ```javascript await pf1.migrations.migrateActors({ fast: true }); ``` ```javascript const packs = [game.packs.get("world.my-pack")]; await pf1.migrations.migrateCompendiums(packs, { unlock: true, fast: false }); ``` ```javascript const actor = game.actors.getName("Valeros"); const isMigrated = pf1.migrations.isMigrated(actor); console.log("Actor migrated:", isMigrated); ``` -------------------------------- ### Define System Relationships in module.json Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/other/MODULE_DEV.md Add this 'relationships' object to your module.json to specify compatibility with the Pathfinder 1e system, ensuring it only enables for supported versions. ```json "relationships": { "systems": [ { "id": "pf1", "compatibility": { "minimum": "11.8","verified": "11.9" } } ], } ``` -------------------------------- ### AND Logic Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/help/en/Formulas.md Evaluates to 1 if all conditions are true, 0 otherwise. Accepts any number of parameters. ```formula and(lt(@attributes.encumbrance.level, 2), lt(@armor.type, 3)) ``` -------------------------------- ### Register Custom Damage Types and Conditions Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Register custom damage types or conditions by hooking into the appropriate 'pf1Register' events. Ensure your module name is unique. ```javascript Hooks.on("pf1RegisterDamageTypes", (registry) => { registry.register("my-module", "sonic", { name: "Sonic", img: "icons/svg/sound.svg", category: "energy", // "physical" | "energy" | "misc" color: "#aaccff", resist: true, isModifier: false, }); }); // Register a custom condition during pf1RegisterConditions hook Hooks.on("pf1RegisterConditions", (registry) => { registry.register("my-module", "overcharged", { name: "Overcharged", texture: "icons/svg/lightning.svg", mechanics: { changes: [{ formula: "-2", target: "ac.normal", type: "untyped" }], flags: [], contexts: [], }, hud: { show: true, include: [], exclude: [] }, }); }); ``` -------------------------------- ### pf1.utils.CR Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt The `CR` class provides static methods for converting challenge rating strings to and from numeric representations, and for looking up XP values associated with a CR. ```APIDOC ## `pf1.utils.CR` — Challenge Rating Utilities The `CR` class provides static methods to convert challenge rating strings (including fractional CRs) to and from numeric representations and to look up XP values. ```js // Parse CR strings to numbers console.log(pf1.utils.CR.fromString("1/2")); // 0.5 console.log(pf1.utils.CR.fromString("1/4")); // 0.25 console.log(pf1.utils.CR.fromString("1/3")); // 0.3375 console.log(pf1.utils.CR.fromString("12")); // 12 // Convert numbers back to display strings console.log(pf1.utils.CR.fromNumber(0.5)); // "1/2" console.log(pf1.utils.CR.fromNumber(0.25)); // "1/4" console.log(pf1.utils.CR.fromNumber(7)); // "7" // Get XP for a given CR console.log(pf1.utils.CR.getXP(5)); // 1600 console.log(pf1.utils.CR.getXP(0.5)); // 200 console.log(pf1.utils.CR.getXP(0.25)); // 100 // CR step index conversion (for advancement tables) console.log(pf1.utils.CR.fromStep(0)); // 0.125 (1/8) console.log(pf1.utils.CR.getStep(1)); // 6 (index in crSteps) ``` ``` -------------------------------- ### Compile Compendiums Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/COMPENDIUMS.md Compiles compendium data into Foundry-appropriate database format. This command is automatically invoked by `npm run build`. ```bash npm run packs:compile ``` -------------------------------- ### Accessing pf1 Global Namespace Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Access the `pf1` global namespace and its sub-namespaces after the system is ready. This provides access to configuration, documents, dice utilities, and more. ```javascript Hooks.once("pf1PostReady", () => { // Top-level namespaces console.log(pf1.config); // Localized game config constants console.log(pf1.const); // Non-localized constants and regexes console.log(pf1.documents); // ActorPF, ItemPF, etc. console.log(pf1.models); // actor.* console.log(pf1.dice); // RollPF, D20RollPF, DamageRoll console.log(pf1.registry); // damageTypes, conditions, materials, ... console.log(pf1.components); // ActionUse, ChatAttack, Resource console.log(pf1.utils); // createTag, CR, Alignment, formula, ... console.log(pf1.applications); // All UI application classes console.log(pf1.migrations); // migrateWorld, check, autoMigrate }); ``` -------------------------------- ### Register Custom Damage Types Source: https://context7.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/llms.txt Use the `pf1RegisterDamageTypes` hook during system initialization to register new damage types with custom properties like name, category, color, and image. ```javascript Hooks.on("pf1RegisterDamageTypes", (registry) => { registry.register("my-module", "force", { name: "Force", category: "energy", color: "#9966ff", img: "icons/svg/force.svg", resist: false, }); }); ``` -------------------------------- ### Configure VS Code Windows Terminal Environment Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/docs/contributing/DEV_ENV.md Set the NODE_ENV to development for the integrated terminal on Windows. This ensures development-specific configurations are active. ```json { "terminal.integrated.env.windows": { "NODE_ENV": "development" } } ``` -------------------------------- ### Calculate Alignment Steps - alignmentSteps Source: https://gitlab.com/foundryvtt_pathfinder1e/foundryvtt-pathfinder1/-/blob/master/help/en/Formulas.md Returns the number of steps between two alignments. Use to quantify the difference between character alignments. Allowed values are lg, ln, le, ng, tn, ne, cg, cn, ce. ```javascript alignmentSteps(lg, ce) ``` ```javascript alignmentSteps(ln, tn) ``` ```javascript alignmentSteps(lg, lg) ``` ```javascript alignmentSteps(@alignment, lg) ```