fvtt-svelte Svelte Themes

Fvtt Svelte

The FoundryVTT example game system using Svelte components

fvtt-svelte

A minimal Foundry VTT v14 game system written in TypeScript with Svelte 5 sheets and vanilla CSS. The mechanics mirror the canonical asacolips boilerplate: two actor types (character, npc), three item types (item, feature, spell), six d20-style abilities, HP/power resources, and a d20 + @abil.mod + ceil(@lvl/2) roll formula on owned items.

Stack

  • TypeScript — strict mode, ESM, bundled with Vite.
  • Svelte 5 — runes mode ($state, $derived, $props). Components are mounted into ApplicationV2 content via mount() / unmount().
  • Vanilla CSS — single stylesheet at css/system.css, no preprocessor.
  • Foundry V2 APIsDataModel for schemas, DocumentSheetV2 for sheets, no Handlebars templates.

Layout

src/
  system.ts                # main entry — Hooks.once("init"), registers everything
  config.ts                # BOILERPLATE config object (ability labels, etc.)
  helpers.ts               # roll-data shaping
  data/                    # DataModel schemas
    character.ts npc.ts item.ts feature.ts spell.ts
  documents/               # Document subclasses (rolls, derived data)
    actor.ts item.ts
  sheets/                  # ApplicationV2 + Svelte mount glue
    actor-sheet.ts item-sheet.ts
    components/            # Svelte 5 sheet UIs
      ActorApp.svelte ItemApp.svelte
      CharacterSheet.svelte NpcSheet.svelte
      ItemSheet.svelte FeatureSheet.svelte SpellSheet.svelte
css/system.css             # vanilla, scoped via .fvtt-svelte
lang/en.json
system.json template.json

Develop

npm install
npm run build    # one-time: produce dist/ so Foundry can register the system
npm run dev      # start Vite dev server with HMR (run Foundry on :30000)

Symlink dist/ into your Foundry user data so Foundry can read system.json from disk:

ln -s "$(pwd)/dist" "$FOUNDRY_DATA/Data/systems/fvtt-svelte"

Production build

vite build emits a self-contained Foundry system folder at dist/system.json, template.json, the bundled system.js, css/, lang/, and license/readme. Foundry serves it directly; nothing else needed.

Dev workflow with HMR

npm run dev starts a Vite dev server on port 30001 that proxies to Foundry on port 30000. Open Foundry at http://localhost:30001/ instead of the usual port — Vite intercepts every request under /systems/fvtt-svelte/ and serves source files directly with HMR.

What you get:

  • .svelte edits hot-swap the component without a page reload (state preserved where possible) — that's vite-plugin-svelte doing its thing.
  • .ts edits trigger a fast module reload or page reload as Vite sees fit.
  • css/system.css edits require a manual page reload — Foundry loads CSS via <link>, which is incompatible with Vite's JS-wrapped CSS HMR, so the dev server serves CSS raw instead.
  • Everything else (Foundry's UI, websocket, assets) proxies straight through.

This pattern is adapted from the Lancer system's Vite setup. If your Foundry runs on a different port, edit FOUNDRY_PORT / VITE_PORT in vite.config.ts.

Mechanics summary

  • Character actor: level, six abilities (str/agi/vig/int/tec/luc), HP, power, biography. mod = floor((value - 10) / 2) is derived per-ability.
  • NPC actor: cr, HP, power, biography.
  • Item: quantity, weight, formula (default d20 + @str.mod + ceil(@lvl/2)); rolls via the chat card "Roll" button.
  • Feature / Spell: descriptive items; spells additionally carry spellLevel.

Top categories

Loading Svelte Themes