runegoblin-foundrytemplate Svelte Themes

Runegoblin Foundrytemplate

Foundry VTT Pathfinder 2e module template — TypeScript + Svelte 5 + Vite, v14 APIs only. Run 'npm run init -- <id>' to spin up a new module.

PF2e Module Template

A starting point for Pathfinder 2e Foundry VTT modules. Hybrid: compendium content (packs/) plus a scripted esmodule (src/) with a Svelte 5 UI mounted in an ApplicationV2 shell.

  • System: pf2e
  • Foundry: v13 minimum, verified on v14
  • Build: TypeScript + Svelte 5 + Vite

Use this template

This repo is a GitHub template repository. Create a new module from it, then run npm run init to rename it to your module id.

GitHub CLI (recommended) — creates the repo, clones it, and gives it its own history and remote in one step:

gh repo create rune-goblin/pf2e-my-module \
  --template rune-goblin/runegoblin-foundrytemplate \
  --private --clone
cd pf2e-my-module
npm run init -- pf2e-my-module --title "PF2e My Module"
npm install && npm run build

GitHub UI — click Use this template → Create a new repository, then:

git clone [email protected]:rune-goblin/pf2e-my-module.git
cd pf2e-my-module
npm run init -- pf2e-my-module --title "PF2e My Module"
npm install && npm run build

Plain clone — no new GitHub repo yet; start fresh history yourself:

git clone [email protected]:rune-goblin/runegoblin-foundrytemplate.git pf2e-my-module
cd pf2e-my-module
npm run init -- pf2e-my-module --title "PF2e My Module"
rm -rf .git && git init -b main
npm install && npm run build

npm run init -- <id> [--title "..."] rewrites the id/title across module.json, package.json, src/, lang/, scripts/, the release workflow, and this README, then deletes itself. It leaves .claude/ (the bundled skill) untouched, and derives --title from the id when omitted.

Layout

module.json          manifest (esmodules + styles + packs + pf2e relationship)
src/                 TypeScript + Svelte source (entry: src/index.ts)
  index.ts           registers hooks, exposes game.modules.get(id).api
  ui/ExampleApp.ts   ApplicationV2 shell that mounts a Svelte component
  ui/Example.svelte  sample Svelte 5 component (runes)
  styles.css         global styles, bundled to dist/pf2e-module-template.css
  app.d.ts           ambient *.svelte module declaration
dist/                build output (gitignored) — what module.json loads
lang/en.json         localization
packs/               LevelDB compendium packs (built)
  _source/           human-readable JSON pack sources (tracked; packed with fvtt)
scripts/link-dev.ts  sandbox symlink setup (run via node's TS type-stripping)

Develop

npm install
npm run build      # emits dist/pf2e-module-template.{js,css}
npm run dev        # vite build --watch
npm run check      # svelte-check + tsc --noEmit (foundry-pf2e types)
npm run link-dev   # symlink this repo into Foundry + pull reference sources in

npm run link-dev symlinks the repo into both Foundry instances' Data/modules/pf2e-module-template, and pulls these gitignored references into the repo for reading (not for distribution):

In-repo link Points at
_pf2e-source repos/pf2e (PF2e system source / types)
_foundry-data-v14 FoundryVTT-v14/Data
_foundry-data FoundryVTT/Data
__foundryModules-v14 FoundryVTT-v14/Data/modules
__foundryModules FoundryVTT/Data/modules

After npm run build, enable the module in a world and reload — the symlink serves dist/ live. Foundry hot-reloads .hbs/.css/.json but not esmodules, so reload the browser after a .js/.svelte rebuild.

AI tooling

This repo ships a project skill at .claude/skills/foundry-pf2e/ — the Foundry/PF2e authoring rules and reference (API, packs, Svelte-in-ApplicationV2, the Vite build, multi-client sync). Claude Code loads it automatically when you work here, and npm run init carries it into new modules.

For Svelte, the skill keeps only the Foundry integration and defers the language to Svelte's own AI tooling (@sveltejs/mcp). Two ways to use it:

  • No setup (on demand): validate a component after editing it — npx -y @sveltejs/mcp svelte-autofixer src/ui/Foo.svelte — or fetch language docs with npx -y @sveltejs/mcp get-documentation <sections>.

  • As an MCP server (optional, persistent): register it once so the tools are in every session.

    claude mcp add -s user svelte -- npx -y @sveltejs/mcp     # all your projects
    # or commit it for collaborators (writes .mcp.json to this repo):
    claude mcp add -s project svelte -- npx -y @sveltejs/mcp
    

UI: Svelte 5 in ApplicationV2

The window is a thin ApplicationV2 subclass; Svelte does the rendering. In _renderHTML you mount() the component into a detached element, _replaceHTML inserts it, and _preClose calls unmount(). See src/ui/ExampleApp.ts. Open the sample window from the console: game.modules.get('pf2e-module-template').api.open().

Compendium packs (fvtt CLI)

Foundry must be closed while packing/unpacking (LevelDB is locked when it runs).

fvtt package pack <pack-name>   --in packs/_source/<pack-name> --out packs
fvtt package unpack <pack-name> --in packs --out packs/_source/<pack-name>

Add the pack to module.json "packs"; Actor/Item packs also need "system": "pf2e".

Release

Push a tag vX.Y.Z; .github/workflows/release.yml stamps the version, type-checks, builds, and publishes a GitHub release with module.json + pf2e-module-template.zip.

Top categories

Loading Svelte Themes