### Install Dependencies Source: https://foundryvtt.wiki/en/development/guides/gitlab-pipeline Prepares the environment by installing zip and git utilities. ```yaml before_script: | apk add --no-cache zip git ``` -------------------------------- ### Initialize World Settings and Setup Hook Source: https://foundryvtt.wiki/en/development/api/hooks Registers a world setting and uses the ready hook to trigger a one-time setup function for the game world. ```javascript Hooks.once("init", () => { game.settings.register('mySystem', 'setupWorld', { name: 'Setup World', scope: 'world', config: false, type: Boolean, default: false }) }); Hooks.once("ready", () => { const isWorldSetup = game.settings.get("mySystem", "setupWorld"); if (!isWorldSetup && game.users.activeGM?.isSelf) setupWorld() }) async setupWorld() { const warning = ui.notifications.warn("Setting up world, please do not exit the program") // do stuff await game.settings.set("mySystem", "setupWorld", true) ui.notifications.remove(warning) } ``` -------------------------------- ### Start Tour on First Login Source: https://foundryvtt.wiki/en/development/guides/tours Uses the 'ready' hook to check if a tour has been started. If the tour status is 'unstarted', it initiates the tour. This is useful for onboarding new users. Consider checking if the user is the GM for specific tours. ```javascript Hooks.once("ready", async function () { if(game.tours.get("myModuleName.tourName").status == "unstarted") { game.tours.get("myModuleName.tourName").start(); } }); ``` -------------------------------- ### Install Boilerplate Dependencies Source: https://foundryvtt.wiki/en/development/guides/SD-tutorial/SD01-Getting-started After cloning the Boilerplate repository, navigate into the directory and run this command to install the necessary Node.js dependencies for the generator. Ensure Node.js version 20 or higher is installed. ```bash npm install ``` -------------------------------- ### Start Vite Development Server Source: https://foundryvtt.wiki/en/development/guides/vite Command to initiate the Vite development server. ```bash $ npx vite serve vite v2.5.0 dev server running at: > Local: http://localhost:30001/systems/lancer/ > Network: use `--host` to expose ready in 205ms. ``` -------------------------------- ### Example Asset Placement Source: https://foundryvtt.wiki/en/development/api Illustrates the recommended directory structure for placing page assets, such as images, relative to the documentation page. ```bash /development/api └── document └── document-console.png ``` -------------------------------- ### ApplicationV2 Manual Drag/Drop Setup Source: https://foundryvtt.wiki/en/development/guides/applicationV2-conversion-guide Manual implementation of drag and drop handlers for base ApplicationV2 classes. ```javascript const { DragDrop } = foundry.applications.ux class MyAppV2 extends HandlebarsApplicationMixin(ApplicationV2) { #dragDrop static DEFAULT_OPTIONS = { dragDrop: [{ dragSelector: '[data-drag="true"]', dropSelector: '.drop-zone' }] } constructor(options = {}) { super(options) this.#dragDrop = this.#createDragDropHandlers() } #createDragDropHandlers() { return this.options.dragDrop.map((d) => { d.permissions = { dragstart: this._canDragStart.bind(this), drop: this._canDragDrop.bind(this) } d.callbacks = { dragstart: this._onDragStart.bind(this), dragover: this._onDragOver.bind(this), drop: this._onDrop.bind(this) } return new DragDrop(d) }) } _onRender(context, options) { this.#dragDrop.forEach((d) => d.bind(this.element)) } _canDragStart(selector) { return this.document.isOwner && this.isEditable } _canDragDrop(selector) { return this.document.isOwner && this.isEditable } _onDragOver(event) { // Optional: handle dragover events if needed } } ``` -------------------------------- ### Configure Foundry Install Path Source: https://foundryvtt.wiki/en/development/guides/improving-intellisense Specify the installation directory of Foundry VTT in a configuration file. This path is device-specific and should not be committed. ```yaml installPath: "C:\\Program Files\\Foundry Virtual Tabletop\\Version 13" ``` -------------------------------- ### Full template.json Boilerplate Example Source: https://foundryvtt.wiki/en/development/guides/SD-tutorial/SD04-templatejson A comprehensive example of a template.json file defining actor and item types, shared base templates, and specific attributes. ```json { "Actor": { "types": ["character", "npc"], "templates": { "base": { "health": { "value": 10, "min": 0, "max": 10 }, "power": { "value": 5, "min": 0, "max": 5 }, "biography": "" } }, "character": { "templates": ["base"], "attributes": { "level": { "value": 1 } }, "abilities": { "str": { "value": 10 }, "dex": { "value": 10 }, "con": { "value": 10 }, "int": { "value": 10 }, "wis": { "value": 10 }, "cha": { "value": 10 } } }, "npc": { "templates": ["base"], "cr": 0 } }, "Item": { "types": ["item", "feature", "spell"], "templates": { "base": { "description": "" } }, "item": { "templates": ["base"], "quantity": 1, "weight": 0, "formula": "d20 + @str.mod + ceil(@lvl / 2)" }, "feature": { "templates": ["base"] }, "spell": { "templates": ["base"], "spellLevel": 1 } } } ``` -------------------------------- ### Legacy FormApplication Example Source: https://foundryvtt.wiki/en/development/guides/converting-to-appv2 A standard implementation of a FormApplication before migration to ApplicationV2. ```javascript class TemplateApplication extends FormApplication { static get defaultOptions() { return foundry.utils.mergeObject(super.defaultOptions, { id: "foo-form", title: `My Module: ${game.i18n.localize("FOO.form.title")}`, template: "./modules/foo/templates/form.hbs", classes: ["form"], width: 640, height: "auto", closeOnSubmit: true, }); } getData() { const setting = game.settings.get("foo", "config"); return { setting } } async activateListeners(html) { super.activateListeners(html); html.find("input[name=something]").on("click", /* ... */); html.find("button[name=reset]").on("click", async (event) => { await game.settings.set("foo", "config", {}); }); } async _updateObject(event, formData) { await Promise.all( Object.entries(formData) .map(([key, value]) => game.settings.set("foo", key, value)); ); } } ``` -------------------------------- ### Configure system.json manifest and download URLs Source: https://foundryvtt.wiki/en/development/guides/SD-tutorial/SD03-systemjson Example configuration for manifest and download properties using Gitlab URLs for a specific release version. ```json "manifest": "https://gitlab.com/asacolips-projects/foundry-mods/boilerplate/-/raw/main/system.json", "download": "https://gitlab.com/asacolips-projects/foundry-mods/boilerplate/-/archive/1.0.0/boilerplate-1.0.0.zip", ``` -------------------------------- ### Register and Configure Custom Tours Source: https://foundryvtt.wiki/en/development/guides/tours Hooks into the setup process to register tours from JSON files and defines a custom Tour class for pre-step logic. ```javascript Hooks.once("setup", async function () { registerMyTours(); } // necessary to toggle tab from settings to chat before you are able to target #chat Hooks.on("closeToursManagement", function (event) { ui.sidebar.activateTab("chat"); }); class MyTour extends Tour { async _preStep() { await super._preStep(); const currentStep = this.currentStep; if(currentStep.id == "chat") { ChatMessage.create({ content: "

Demo MyTour

", speaker: ChatMessage.getSpeaker({alias: "MyTour", color: "#ff0000"}) }); } else { console.log("MyTours | Tours _preStep: ",currentStep.id); } } } async function registerMyTours() { try { game.tours.register(moduleName, 'format', await MyTour.fromJSON('/modules/'+moduleName+'/tours/chat.json')); if(game.user.isGM) { game.tours.register(moduleName, 'settings', await MyTour.fromJSON('/modules/'+moduleName+'/tours/settings.json')); } } catch (error) { console.error("MyTour | Error registering tours: ",error); } } ``` -------------------------------- ### Hooks.callAll() Examples Source: https://foundryvtt.wiki/en/development/guides/Hooks_Listening_Calling Examples of using Hooks.callAll() to trigger various events within the Foundry VTT system. These hooks are used to notify different parts of the system about changes or events. ```APIDOC ## Hooks.callAll() ### Description Triggers all registered callbacks for a given hook event. ### Method `Hooks.callAll(hookName, ...args)` ### Endpoint N/A (Client-side JavaScript API) ### Parameters - **hookName** (string) - The name of the hook event to call. - **...args** (any) - Arguments passed to the registered callbacks. ### Request Example ```javascript Hooks.callAll("updateWorldTime", worldTime, dt) Hooks.callAll("init") Hooks.callAll('setup') Hooks.callAll("ready") Hooks.callAll("pauseGame", this.data.paused) Hooks.callAll(`create${type}`, doc, options, userId) Hooks.callAll(`update${doc.documentName}`, doc, change, options, userId) Hooks.callAll(`delete${doc.documentName}`, doc, options, userId) Hooks.callAll("updateCompendium", this, documents, options, userId) Hooks.callAll(`preCreate${embeddedName}`, doc, d, options, user.id) Hooks.callAll(`preUpdate${embeddedName}`, doc, d, options, user.id) Hooks.callAll(`preDelete${embeddedName}`, doc, options, user.id) Hooks.callAll("preUpdateActor", this.actor, data, options, user.id) Hooks.callAll(`create${embeddedName}`, doc, options, userId) Hooks.callAll(`update${embeddedName}`, doc, d, options, userId) Hooks.callAll(`delete${embeddedName}`, doc, options, userId) Hooks.callAll("updateActor", this.actor, data, options, userId) Hooks.callAll('canvasInit', this) Hooks.callAll("canvasPan", this, constrained) Hooks.callAll("canvasPan", this, {x: stage.pivot.x, y: stage.pivot.y, scale: stage.scale.x}) Hooks.callAll("control"+this.constructor.embeddedName, this, this._controlled) Hooks.callAll("hover"+this.constructor.embeddedName, this, this._hover) Hooks.callAll("collapseSidebar", this, this._collapsed) Hooks.callAll("changeSidebarTab", app) Hooks.callAll(`getSceneControlButtons`, controls) Hooks.callAll("collapseSceneNavigation", this, this._collapsed) Hooks.callAll("initializePointSourceShaders", this, this.animation.type) Hooks.callAll("targetToken", this.user, token, targeted) Hooks.callAll("lightingRefresh", this) Hooks.callAll("sightRefresh", this) Hooks.callAll("rtcSettingsChanged", this, changed) Hooks.callAll(`${key}Changed`, volume) ``` ### Response N/A (This is an API call, not an endpoint response) ### Response Example N/A ``` -------------------------------- ### GitHub Actions Build Step Source: https://foundryvtt.wiki/en/development/api/CompendiumCollection Example workflow step to ensure compendiums are built during CI/CD processes. ```yaml - name: Install Dependencies run: npm ci - name: Build Packs run: | npm run pullYMLtoLDB --if-present ``` -------------------------------- ### Override prepareBaseData() Source: https://foundryvtt.wiki/en/development/guides/SD-tutorial/SD06-Extending-the-Actor-class Example of an empty override for the base data preparation step. ```javascript /** @override */ prepareBaseData() { // Data modifications in this step occur before processing embedded // documents or derived data. } ``` -------------------------------- ### Start Tour with Timeout Source: https://foundryvtt.wiki/en/development/guides/tours When opening a window like client-settings, it is recommended to call tour.start() within a timeout function to ensure proper rendering and execution. ```javascript setTimeout(function(){ game.tours.get("myModuleName.tourName").start(); }, 1000); ``` -------------------------------- ### Legend for Foundry VTT Settings Source: https://foundryvtt.wiki/en/development/api/settings Notation guide for understanding static methods, instance methods, and the game object structure. ```text Setting.defineSchema // `.` indicates static method or property ClientSettings#register // `#` indicates instance method or property game.settings.register // The ClientSettings class is instantiated as part of the `game` object ``` -------------------------------- ### Example Module File Structure Source: https://foundryvtt.wiki/en/development/guides/gitlab-pipeline This is a recommended file structure for your Foundry VTT module repository to facilitate pipeline packaging. Ensure module.json and .gitlab-ci.yml are in the root directory. ```text my-module --| module.json | /.git | /src---| | /packs | /scripts | /styles | /templates ``` -------------------------------- ### Handle i18n Initialization Hook Source: https://foundryvtt.wiki/en/development/api/localization Example of using the `i18nInit` hook to localize configuration data after settings are loaded and localizations are available. ```javascript Hooks.once("i18nInit", () => { // Localize CONFIG additions here }); ``` -------------------------------- ### Basic _prepareContext Implementation Source: https://foundryvtt.wiki/en/development/guides/from-load-to-render A minimal example of overriding `_prepareContext` to include system data and schema fields in the rendering context. Ensure `super` is called to preserve default behavior. ```javascript async _prepareContext(options) { const context = await super._prepareContext(options) return Object.assign(context, { system: this.document.system, systemFields: this.document.system.schema.fields, }) } ``` -------------------------------- ### Registering Hook Callbacks Source: https://foundryvtt.wiki/en/development/guides/Hooks_Listening_Calling Examples of using Hooks.on to register callbacks for specific events. ```javascript Hooks.on("init", async function () { //obviously triggered by a Hooks.callAll() that's gonna call every module/system that registered 'init', no matter what }); ``` ```javascript Hooks.on("renderCompendium", (compendiumApp, html, appData) => { //TODO: add real world, working example }); ``` -------------------------------- ### Register a Custom Client Setting Source: https://foundryvtt.wiki/en/development/guides/handling-data Shows how to register a new setting for a module using `game.settings.register`. This example registers a number setting with a range, configuration option, and an onChange callback. ```javascript /* * Create a custom config setting */ await game.settings.register('myModuleId', 'mySettingName', { name: 'My Setting', // can also be an i18n key hint: 'A description of the registered setting and its behavior.', // can also be an i18n key scope: 'world', // "world" = sync to db, "client" = local storage config: true, // false if you dont want it to show in module config type: Number, // Number, Boolean, String, or even a custom class or DataModel default: 0, range: {. // range turns the UI input into a slider input min: 0, max: 100, step: 10 }, onChange: value => { // value is the new value of the setting console.log(value) }, filePicker: false, // set true with a String `type` to use a file picker input, requiresReload: false, // when changing the setting, prompt the user to reload }); ``` -------------------------------- ### Define Package-Specific Translations Source: https://foundryvtt.wiki/en/development/api/localization Example of a language.json file structure for a package, demonstrating nested namespaces and overriding system translations. ```json { "MYMODULE": { "Foo": "Bar" }, "DND5E.Item.Property.Magical": "Supernatural" } ``` -------------------------------- ### Example module.json Manifest URL Source: https://foundryvtt.wiki/en/development/guides/releases-and-history This field in module.json should point to the latest release's manifest JSON, ensuring Foundry clients always fetch the most recent manifest. ```json "manifest": "https://github.com/ElfFriend-DnD/AmazingModule/releases/latest/download/module.json" ``` -------------------------------- ### Legend for API Documentation Source: https://foundryvtt.wiki/en/development/api/time Notation guide for distinguishing between static and instance members in the API documentation. ```text CalendarData.formatTimestamp // `.` indicates static method or property CalendarData#timeToComponents // `#` indicates instance method or property ``` -------------------------------- ### Triggering Hooks Source: https://foundryvtt.wiki/en/development/guides/Hooks_Listening_Calling Examples of using Hooks.call and Hooks.callAll to trigger events within the Foundry VTT system. ```javascript Hooks.callAll("ready"); // called when the game is done initializing its data structure and is 'ready' ``` ```javascript Hooks.call("dropCanvasData", this, data); // when anything is dragDropped onto the canvas // ('this' being the canvas instance) ``` ```javascript Hooks.callAll(`update${doc.documentName}`, doc, change, options, userId); // that will trigger for any document type, // giving us a wide range of hookNames to deal with like // 'updateActor', 'updateMacro', 'updateChatMessage'... ``` -------------------------------- ### Localization JSON for Data Model Fields Source: https://foundryvtt.wiki/en/development/api/localization Provides an example of a JSON localization file that pairs with a DataModel using LOCALIZATION_PREFIXES. It shows how to define 'hint' and 'label' for fields like 'someMessage'. ```json { "NESTED": { "Path": { "FIELDS": { "someMessage": { "hint": "Behavior hint", "label": "Behavior label" } } } } } ``` -------------------------------- ### Basic String Translation Example Source: https://foundryvtt.wiki/en/development/guides/localization/localization-best-practices Demonstrates a simple string translation where a phrase is split into multiple keys. This approach can cause issues in languages with different grammatical structures. ```json "modulename.phrase": "This is an", "modulename.noun": "apple" ``` -------------------------------- ### Example 'includes' field in Manifest+ Source: https://foundryvtt.wiki/en/development/manifest-plus The 'includes' field is an array of strings specifying relative file paths to be included in the package zip archive. This is useful for deployment tools. ```json "includes": [ "relative/path/to/files/script.js", "relative/to/templates/template.html", "path/to/image/assets/folder" ] ``` -------------------------------- ### Parameterized String Translation Example Source: https://foundryvtt.wiki/en/development/guides/localization/localization-best-practices Shows how to use placeholders for dynamic content in translations. This method allows translators to reorder words and adapt to different grammatical structures. ```json "modulename.phrase": "This is an {noun}", "modulename.noun": "apple" ``` -------------------------------- ### Initialize System with 'init' Hook Source: https://foundryvtt.wiki/en/development/guides/SD-tutorial/SD05-Creating-your-main-JS-file Use the 'init' hook to perform essential system setup, including adding utility classes to the global game object, defining custom configuration constants, setting initiative formulas, defining custom document classes, and registering custom sheet applications. ```javascript /* -------------------------------------------- */ /* Init Hook */ /* -------------------------------------------- */ Hooks.once('init', function () { // Add utility classes to the global game object so that they're more easily // accessible in global contexts. game.boilerplate = { BoilerplateActor, BoilerplateItem, rollItemMacro, }; // Add custom constants for configuration. CONFIG.BOILERPLATE = BOILERPLATE; /** * Set an initiative formula for the system * @type {String} */ CONFIG.Combat.initiative = { formula: '1d20 + @abilities.dex.mod', decimals: 2, }; // Define custom Document classes CONFIG.Actor.documentClass = BoilerplateActor; CONFIG.Item.documentClass = BoilerplateItem; // Active Effects are never copied to the Actor, // but will still apply to the Actor from within the Item // if the transfer property on the Active Effect is true. CONFIG.ActiveEffect.legacyTransferral = false; // Register sheet application classes Actors.unregisterSheet('core', ActorSheet); Actors.registerSheet('boilerplate', BoilerplateItemSheet, { makeDefault: true, label: 'BOILERPLATE.SheetLabels.Actor', }); Items.unregisterSheet('core', ItemSheet); Items.registerSheet('boilerplate', BoilerplateItemSheet, { makeDefault: true, label: 'BOILERPLATE.SheetLabels.Item', }); // Preload Handlebars templates. return preloadHandlebarsTemplates(); }); ``` -------------------------------- ### Example TinyMCE translation file content Source: https://foundryvtt.wiki/en/development/guides/localization/localizing-tinymce An example of how to append custom keys to the TinyMCE translation object. ```javascript tinymce.addI18n('fi',{ ...omitted data... "Caption": "Seloste", "Insert template": "Lis\u00e4\u00e4 pohja", "Custom": "Mukautettu", "Secret": "Salainen" }); ``` -------------------------------- ### Display Forge Installs Badge Source: https://foundryvtt.wiki/en/development/guides/repository-bling Shows the percentage of users who have installed a module via The Forge. Replace [YOUR_PACKAGE_NAME] with the name field from your manifest. ```markdown [![Forge Installs](https://img.shields.io/badge/dynamic/json?label=Forge%20Installs&query=package.installs&suffix=%25&url=https%3A%2F%2Fforge-vtt.com%2Fapi%2Fbazaar%2Fpackage%2F[YOUR_PACKAGE_NAME]&colorB=4aa94a)](https://forge-vtt.com/bazaar#package=[YOUR_PACKAGE_NAME]) ``` -------------------------------- ### Bundle and Package Module Source: https://foundryvtt.wiki/en/development/guides/gitlab-pipeline Copies the configuration file to the source directory and creates a zip archive for the release. ```bash # copy module.json to src echo "[Info] Bundling module... this may take some time" cp -v "${CI_PROJECT_DIR}/module.json" "${MODULE_DIRECTORY}/module.json" # Package module cd "${MODULE_DIRECTORY}" zip -qr "${RELEASE_FILE}" . cd ${CI_PROJECT_DIR} ``` -------------------------------- ### Handlebars Helper Example Source: https://foundryvtt.wiki/en/development/guides/SD-tutorial/SD02-Stuff-to-be-aware-of An example of a Handlebars helper function in Javascript that concatenates strings. This can be used within your Handlebars templates to combine text dynamically. ```javascript Handlebars.registerHelper('concat', function() { return Array.prototype.slice.call(arguments, 0, -1).join(' '); }); ``` -------------------------------- ### Hooks.call() with Interruption Examples Source: https://foundryvtt.wiki/en/development/guides/Hooks_Listening_Calling Specific examples demonstrating Hooks.call() usage where callbacks might interrupt the flow or modify data before it's passed further. This is common for pre-event hooks. ```APIDOC ## Hooks.call() with Interruption ### Description Examples of using `Hooks.call()` for pre-event hooks that can modify data or interrupt the default behavior. ### Method `Hooks.call(hookName, ...args)` ### Endpoint N/A (Client-side JavaScript API) ### Parameters - **hookName** (string) - The name of the hook event to call. - **...args** (any) - Arguments passed to the registered callbacks. ### Request Example ```javascript Hooks.call(`preCreate${type}`, doc, createData, options, user.id) Hooks.call(`preUpdate${doc.documentName}`, doc, update, options, user.id) Hooks.call(`preDelete${doc.documentName}`, doc, options, user.id) Hooks.call("modifyTokenAttribute", {attribute, value, isDelta, isBar}, updates) Hooks.call("dropCanvasData", this, data) Hooks.call("dropActorSheetData", actor, this, data) Hooks.call("dropRollTableSheetData", this.document, this, data) Hooks.call("chatBubble", token, html, message, {emote}) Hooks.call("hotbarDrop", this, data, slot) Hooks.call("chatMessage", this, message, chatData) Hooks.call(`get${cls.name}EntryContext`, html, entryOptions) Hooks.call(`get${cls.name}EntryContext`, html, entryOptions) Hooks.call(`get${cls.name}SoundContext`, html, entryOptions) ``` ### Response - **result** (any) - The return value of the last executed callback, or `false` if the hook was interrupted. ### Response Example N/A ``` -------------------------------- ### Hooks.call() Examples Source: https://foundryvtt.wiki/en/development/guides/Hooks_Listening_Calling Examples of using Hooks.call() to trigger events that may be interrupted or have specific return values. This is often used for actions that can be modified or cancelled by registered callbacks. ```APIDOC ## Hooks.call() ### Description Calls a hook event and returns the result of the last callback. If any callback returns `false`, the hook call is interrupted. ### Method `Hooks.call(hookName, ...args)` ### Endpoint N/A (Client-side JavaScript API) ### Parameters - **hookName** (string) - The name of the hook event to call. - **...args** (any) - Arguments passed to the registered callbacks. ### Request Example ```javascript Hooks.call(`render${cls.name}`, this, html, data) Hooks.call(`get${cls.name}HeaderButtons`, this, buttons) Hooks.call(`close${cls.name}`, this, el) Hooks.call("applyActiveEffect", actor, change) Hooks.call("renderChatMessage", this, html, messageData) Hooks.call("canvasReady", this) Hooks.call(`paste${cls.name}`, this._copy, toCreate) Hooks.call(`get${cls.name}FolderContext`, html, folderOptions) Hooks.call(`get${cls.name}EntryContext`, html, entryOptions) Hooks.call("getSceneNavigationContext", html, contextOptions) Hooks.call(`getUserContextOptions`, html, contextOptions) Hooks.call(`get${cls.name}EntryContext`, html, entryOptions) Hooks.call(`paste${cls.name}`, this._copy, toCreate) ``` ### Response - **result** (any) - The return value of the last executed callback, or `false` if the hook was interrupted. ### Response Example N/A ``` -------------------------------- ### Custom Enrichment Function Example Source: https://foundryvtt.wiki/en/development/guides/enrichers This example demonstrates how to create a temporary custom enrichment function. It adds a custom enricher, calls TextEditor.enrichHTML, and then removes the custom enricher to avoid global side effects. ```typescript export const myEnrichHTML = async(text: string): Promise => { const enricherConfig = { pattern: myRegex, enricher: myEnricherFn, replaceParent: false, // or true, as you need }; // add your enricher CONFIG.TextEditor.enrichers.push(enricherConfig); // call enrichHTML const enrichedText = await TextEditor.enrichHTML(text || '', { // any options you want to pass in for your enricher or to disable defaults }); // remove your enricher CONFIG.TextEditor.enrichers = CONFIG.TextEditor.enrichers .filter((f): boolean => (f!=enricherConfig)); return enrichedText; } ``` -------------------------------- ### ApplicationV2 Lifecycle and Rendering Source: https://foundryvtt.wiki/en/development/api/applicationv2 Demonstrates how to instantiate, render, and close an ApplicationV2 instance. It also shows how to refresh an existing application. ```APIDOC ## ApplicationV2 Lifecycle ### Description This section covers the basic lifecycle of an ApplicationV2 instance, including instantiation, rendering, and closing. ### Methods - **new MyApp().render(true)**: Instantiates a new application and renders it to the screen. - **myApp.render()** or **this.render()**: Refreshes an already rendered application. - **myApp.close()**: Removes the application from the UI. The instance persists until garbage collected. ### Example ```javascript // Instantiate and render a new application const myApp = new MyApp(); myApp.render(true); // Refresh the application myApp.render(); // Close the application myApp.close(); ``` ``` -------------------------------- ### Complex Localization Example for Legendary Actions Source: https://foundryvtt.wiki/en/development/api/localization An example of a complex localization string for 'legendary actions' that uses placeholders for dynamic content like '{name}'. This demonstrates the importance of nested localization keys for clarity and reusability. ```json { "MOBLOKS5E.LegendaryText": "The {name} can take 3 legendary actions, choosing from the options below. Only one legendary action option can be used at a time and only at the end of another creature's turn. The {name} regains spent legendary actions at the start of its turn." } ``` -------------------------------- ### Open a FormApplication instance Source: https://foundryvtt.wiki/en/development/guides/understanding-form-applications Instantiate and render the custom application to the screen. ```javascript /** * To open your application */ new MyFormApplication('example').render(true); ``` -------------------------------- ### Example Map Note Icon Translation JSON Source: https://foundryvtt.wiki/en/development/guides/localization/localizing-map-note-icons This is an example of the translated JSON file for map note icons. Replace the English keys with your localized strings. Ensure the file is named according to your language tag (e.g., fi-FI_icons.json). ```json { "Anchor": "Ankkuri", "Barrel": "Tynnyri", } ``` -------------------------------- ### Get a Setting Value Source: https://foundryvtt.wiki/en/development/guides/handling-data Retrieves the current value of a registered setting. ```javascript const someVariable = game.settings.get('myModuleId','myModuleSetting'); console.log(someVariable); // expected to be 'foo' ``` -------------------------------- ### Initialize FormApplication with Partials Source: https://foundryvtt.wiki/en/development/guides/Tabs-and-Templates/Tabs-FormApplication Extended initialization logic that includes loading required Handlebars partials. ```javascript class myFormApplication extends FormApplication { constructor(object, options) { super(object, options); } static get defaultOptions() { return super.defaultOptions; } getData(options = {}) { return super.getData().object; // the object from the constructor is where we are storing the data } activateListeners(html) { super.activateListeners(html); } async _updateObject(event, formData) { return; } } const template_file = "macro_data/TEMPLATE_FILE"; loadTemplates(["macro_data/tab_partial.html"]); const template_data = { header: "Handlebars header text.", tabs: [{ label: "tab1", title: "My First Tab", content: "Fancy tab1 content."}, { label: "tab2", title: "My Second Tab", content: "Fancy tab2 content."}], footer: "Handlebars footer text."}; const my_form = new myFormApplication(template_data, { template: template_file, tabs: [{navSelector: ".tabs", contentSelector: ".content", initial: "tab1"}] }); // data, options const res = await my_form.render(true); ``` -------------------------------- ### Complete module.json with Manifest and Download URLs Source: https://foundryvtt.wiki/en/development/guides/local-to-repo This shows the module.json file after adding the manifest and download URLs. Remember to include commas at the end of each added line. ```json { "id": "my-module", "title": "My Module", "version": "1.0.0", "manifest": "https://github.com/my-user/my-module/releases/latest/download/module.json", "download": "https://github.com/my-user/my-module/releases/download/1.0.0/module.zip", "compatibility": { "minimum": "12", "verified": "12" } } ``` -------------------------------- ### DialogV2 Static Methods (prompt) Source: https://foundryvtt.wiki/en/development/api/dialogv2 Demonstrates the usage of the `DialogV2.prompt` static method for displaying a dialog with custom content and options. ```APIDOC ## DialogV2.prompt() This static method displays a prompt dialog. It is asynchronous and returns a Promise. ### Parameters: - `options` (object): Configuration options for the dialog. - `window` (object): Window title. - `title` (string): The title to display in the dialog's window. - `content` (string): The HTML content to display within the dialog. - `modal` (boolean): Whether the dialog should be modal. - `actions` (object, optional): Callbacks for actions defined in the content. - `render` (function, optional): Callback function triggered when the dialog finishes rendering. ### Request Example: ```javascript const response = await foundry.applications.api.DialogV2.prompt({ window: { title: "User Input" }, content: "

Please enter your name:

", modal: true, actions: { submit: (event, target) => { // Handle submission } }, render: (app) => { console.log("Dialog rendered:", app); } }); ``` ### Response: Returns a Promise that resolves with the dialog's response. The structure of the response depends on the dialog's implementation and user interaction. ``` -------------------------------- ### Socket Interface Legend Source: https://foundryvtt.wiki/en/development/api/sockets Notation guide for interpreting Foundry VTT API documentation. ```text SocketInterface.dispatch // `.` indicates static method or property Socket#on // `#` indicates instance method or property ``` -------------------------------- ### Game Class Initialization Flow Source: https://foundryvtt.wiki/en/development/api/game Illustrates the sequence of calls for creating and initializing the Game instance. This process includes establishing server connections, fetching data, and constructing the singleton `game` object. ```javascript 1. `Game.create` is called after all code is imported a. `Game.connect` establishes the underlying socket connection with the server b. `Game.getData` fetches the live data from the database. c. `new Game` constructs the singleton instance which is publicly stashed as `game` 2. `Game.initialize` is called, which progressively builds out the `game` instance and calls a series of hooks. ``` -------------------------------- ### Override prepareData() Source: https://foundryvtt.wiki/en/development/guides/SD-tutorial/SD06-Extending-the-Actor-class Example of calling the super method to maintain the default data preparation lifecycle. ```javascript /** @override */ prepareData() { // Prepare data for the actor. Calling the super version of this executes // the following, in order: data reset (to clear active effects), // prepareBaseData(), prepareEmbeddedDocuments() (including active effects), // prepareDerivedData(). super.prepareData(); } ``` -------------------------------- ### Define System Configuration Constants Source: https://foundryvtt.wiki/en/development/guides/SD-tutorial/SD13-Localization Create a configuration file to map ability keys to their corresponding localization string identifiers. ```javascript export const MYSYSTEM = {} MYSYSTEM.abilities = { "str": "MYSYSTEM.AbilityStr", "dex": "MYSYSTEM.AbilityDex", "con": "MYSYSTEM.AbilityCon", "int": "MYSYSTEM.AbilityInt", "wis": "MYSYSTEM.AbilityWis", "cha": "MYSYSTEM.AbilityCha" } ``` -------------------------------- ### GET CompendiumCollection#getDocuments Source: https://foundryvtt.wiki/en/development/api/CompendiumCollection Retrieves an array of documents from a compendium, optionally filtered by query parameters. ```APIDOC ## GET CompendiumCollection#getDocuments ### Description Retrieves documents from the compendium. If no query is provided, returns all documents. ### Parameters #### Query Parameters - **query** (object) - Optional - Filter criteria. Examples include { type: "weapon" }, { _id__in: arrayOfIds }, or { type__in: ["weapon", "armor"] }. ### Response #### Success Response (200) - **documents** (Array) - An array of documents matching the query. ``` -------------------------------- ### Define Compendium Legend Source: https://foundryvtt.wiki/en/development/api/CompendiumCollection Notation guide for static and instance methods within the CompendiumCollection class. ```javascript CompendiumCollection.createCompendium // `.` indicates static method or property CompendiumCollection#getDocument // `#` indicates instance method or property ``` -------------------------------- ### Development Entrypoint Files Source: https://foundryvtt.wiki/en/development/guides/vite Placeholder files required for FoundryVTT to load the development environment. ```javascript // only required for dev // in prod, foundry loads lancer.mjs, which is compiled by vite/rollup // in dev, foundry loads lancer.mjs, this file, which loads lancer.ts import './src/lancer.ts'; ``` ```css /** * only required in dev * in prod, foundry loads style.css, as compiled by vite/rollup, * mostly from the `import lancer.scss` line at the top of lancer.ts * * in dev, foundry loads style.css, this file, which is a no-op * in dev, lancer.ts imports lancer.scss directly */ ``` -------------------------------- ### Interrupting Hook Events Source: https://foundryvtt.wiki/en/development/guides/Hooks_Listening_Calling Example of returning false in a hook callback to prevent the default behavior of an event. ```javascript //if there's a canvas init, register a permanent protection against some 'types' Hooks.once('canvasInit', (canvas) => { Hooks.on("dropCanvasData", (canvas, dropData) => { if ( dropData.type === 'Actor') { const actor = game.actors.get(dropData.id); if ( actor.name === 'Xx_DarkSasuke69420_xX' ) { return false; } } }); }); ``` -------------------------------- ### Importing ApplicationV2 and HandlebarsApplicationMixin Source: https://foundryvtt.wiki/en/development/api/applicationv2 Demonstrates how to import ApplicationV2 and HandlebarsApplicationMixin using object destructuring for cleaner syntax. This is a common pattern when working with ESModules in Foundry VTT. ```javascript const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api class MyHandlebarsApp extends HandlebarsApplicationMixin(ApplicationV2) {} ``` -------------------------------- ### Add Foundry Paths to .gitignore Source: https://foundryvtt.wiki/en/development/guides/improving-intellisense Prevent Foundry VTT installation paths from being committed to your version control system. ```gitignore foundry-config.yaml foundry ``` -------------------------------- ### Getting a Flag's Value Source: https://foundryvtt.wiki/en/development/api/flags Demonstrates how to retrieve a flag's value from a document using the `getFlag` method. ```APIDOC ## GET /documents/{documentId}/flags/{scope}/{flagName} ### Description Retrieves the value of a specific flag from a document. ### Method `GET` ### Endpoint `/documents/{documentId}/flags/{scope}/{flagName}` ### Parameters #### Path Parameters - **documentId** (string) - Required - The ID of the document to retrieve the flag from. - **scope** (string) - Required - The namespace of the flag. - **flagName** (string) - Required - The name of the flag. #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **value** (any) - The value of the requested flag. #### Response Example ```json "foo" ``` ``` -------------------------------- ### Configure FormApplication dialog dimensions Source: https://foundryvtt.wiki/en/development/guides/Tabs-and-Templates/Template-Basics Demonstrates how to pass dynamic options during instantiation to control dialog size and resizability. ```javascript const my_form = new myFormApplication(template_data, { template: template_file, width: "400", height: "auto", resizable: true }); ``` -------------------------------- ### Define DataModel Schema Legend Source: https://foundryvtt.wiki/en/development/api/DataModel Notation guide for identifying static versus instance members in DataModel documentation. ```text DataModel.defineSchema // `.` indicates static method or property DataModel#invalid // `#` indicates instance method or property ``` -------------------------------- ### Execute Production Build Source: https://foundryvtt.wiki/en/development/guides/vite Runs the Vite build process to generate production-ready files in the dist directory. ```bash $ npx vite build vite v2.5.0 building for production... ✓ 963 modules transformed. rendering chunks (9)... dist/lancer.es.js 0.04 KiB / brotli: 0.05 KiB dist/lancer.es.js.map 0.09 KiB dist/aws-exports.js 0.92 KiB / brotli: 0.42 KiB dist/aws-exports.js.map 2.32 KiB dist/index.js 1.69 KiB / brotli: 0.70 KiB dist/index.js.map 5.04 KiB dist/marked.js 46.42 KiB / brotli: 12.97 KiB dist/marked.js.map 137.94 KiB dist/index4.js 52.08 KiB / brotli: 14.08 KiB dist/index4.js.map 238.45 KiB dist/Credentials.js 138.40 KiB / brotli: 29.90 KiB dist/Credentials.js.map 968.75 KiB dist/style.css 36.59 KiB / brotli: 7.38 KiB dist/index2.js 144.89 KiB / brotli: 34.89 KiB dist/index2.js.map 602.29 KiB dist/index3.js 179.36 KiB / brotli: 33.85 KiB dist/index3.js.map 1536.81 KiB dist/lancer.js 1030.44 KiB / brotli: skipped (large chunk) dist/lancer.js.map 1777.34 KiB ``` -------------------------------- ### Initialize TabbedDialog with default settings Source: https://foundryvtt.wiki/en/development/guides/Tabs-and-Templates/Extending-Dialog-with-Tabs Demonstrates creating a dialog with three tabs using default configuration values. ```javascript let d = new TabbedDialog( { title: "Test Tabbed Dialog", header: "Test header", footer: "Test footer", tabs: [ { }, { }, { } ], buttons: { one: { icon: '', label: "Option One", callback: () => console.log("Chose One") }, two: { icon: '', label: "Option Two", callback: () => console.log("Chose Two") } }, default: "two", render: html => console.log("Register interactivity in the rendered dialog"), close: html => console.log("This always is logged no matter which option is chosen") }, { resizable: true } ); d.render(true); ``` -------------------------------- ### Example Handlebars tab part Source: https://foundryvtt.wiki/en/development/guides/Tabs-and-Templates/Tabs-in-AppV2 A sample template for a tabbed section, requiring data-group and data-tab attributes and the tab.cssClass class. ```handlebars

Aptitudes

{{#each this.aptitudes}} {{#if this.show}}
{{this.label}}
{{this.trait}}
{{this.totalRanks}}d{{this.die}}
{{/if}} {{/each}}
``` -------------------------------- ### Choosing the Right Base Class for V13 Applications Source: https://foundryvtt.wiki/en/development/guides/applicationV2-conversion-guide Illustrates how to extend different v2 application classes based on the intended use case: ActorSheetV2 for actor sheets, DocumentSheetV2 for other document types, ApplicationV2 for custom applications, and DialogV2 for prompts. ```javascript class MyActorSheet extends HandlebarsApplicationMixin(ActorSheetV2) { // Gets automatic drag/drop, actor-specific features } // For item sheets - use DocumentSheetV2 class MyItemSheet extends HandlebarsApplicationMixin(DocumentSheetV2) { // Gets document handling, no automatic drag/drop } // For configuration dialogs - use ApplicationV2 class MyConfigDialog extends HandlebarsApplicationMixin(ApplicationV2) { // Gets basic application features only } // For user prompts - use DialogV2 class MyPrompt extends DialogV2 { // Gets modal behavior, button handling } ``` -------------------------------- ### Configure jsconfig.json for IntelliSense Source: https://foundryvtt.wiki/en/development/guides/improving-intellisense Set up your `jsconfig.json` file in the project root to include your ESM files. This enables IntelliSense for Foundry VTT modules and client/common paths. ```json { "compilerOptions": { "module": "ES2022", "target": "ES2022", "paths": { "@client/*": ["./foundry/client/*"], "@common/*": ["./foundry/common/*"] }, }, "exclude": ["node_modules", "**/node_modules/*"], "include": ["your-package-root.mjs", "foundry/client/client.mjs", "foundry/client/global.d.mts", "foundry/common/global.d.mts"], "typeAcquisition": { "include": ["jquery"] } } ``` -------------------------------- ### Get Module Setting Value Source: https://foundryvtt.wiki/en/development/api/settings Retrieve the value of a module setting. The returned value is constructed using the `type` specified during registration. ```javascript const someVariable = game.settings.get('myModuleName','myModuleSetting'); console.log(someVariable); // expected to be 'foo' ``` -------------------------------- ### Configuration Settings for Tours Source: https://foundryvtt.wiki/en/development/guides/tours Defines configuration settings for tours, including selectors for specific UI elements. Use this to mark elements for tour steps. ```json { "title": "Configuration Settings", "description": "Howto mark the Button Configuration Settings for Tours", "canBeResumed": false, "display": true, "steps": [ { "id": "configSettings", "selector": "button[data-action=\"configure\"]", "title": "Config Tour", "content": "MYTRANSLATION.tours.configSettings", "sidebarTab" "settings" }, { "id": "stepTwo", // ... } ] } ``` ```json { "title": "..", "description": "...", "display": true, "steps": [ { "id": "configSettings", "selector": ".tabs>a[data-tab='actors']", //... } ] } ``` -------------------------------- ### Get Square Grid Space Coordinates Source: https://foundryvtt.wiki/en/development/api/canvas Retrieves the grid space coordinates for the currently hovered square grid. Requires the mouse position. ```javascript const p = canvas.mousePosition; // { x, y } const { x, y } = canvas.grid.getTopLeftPoint({x: p.x, y: p.y }); ``` -------------------------------- ### Using LOCALIZATION_PREFIXES for Data Models Source: https://foundryvtt.wiki/en/development/api/localization Demonstrates how to use the static LOCALIZATION_PREFIXES property in a custom DataModel to automatically generate localization keys for 'hint' and 'label' fields. This simplifies configuration form generation. ```javascript export default class MyModel extends foundry.abstract.DataModel { static LOCALIZATION_PREFIXES = ["NESTED.Path"]; static defineSchema() { return { someMessage: new fields.StringField() }; } } ```