Chapitre 0

Architecture d'un Système FoundryVTT

Découvrez la structure fondamentale d'un système FoundryVTT v13 : arborescence des fichiers, cycle de vie et flux de données.

Qu'est-ce qu'un système FoundryVTT ?

Un système FoundryVTT est un module spécialisé qui définit les règles de jeu, les structures de données des personnages et objets, ainsi que les interfaces utilisateur associées.

💡 Système vs Module

Contrairement aux modules qui étendent les fonctionnalités existantes, un système constitue le socle fondamental d'un monde de jeu. Chaque monde FoundryVTT est associé à un unique système (D&D 5e, Pathfinder, etc.).

Ce que définit un système

  • Structure des données : Quelles informations stocke un personnage ? Quels champs pour une arme ?
  • Règles de calcul : Comment calculer la CA, les modificateurs, les dégâts ?
  • Interface utilisateur : À quoi ressemblent les feuilles de personnage ?
  • Jets de dés : Comment effectuer un jet d'attaque, de sauvegarde ?
  • Données de référence : Monstres, sorts, équipements préchargés (compendiums)

Arborescence type d'un projet

Voici la structure de fichiers recommandée pour un système FoundryVTT moderne :

mon-systeme/
├── system.json              # Manifeste du système (obligatoire)
├── mon-systeme.mjs          # Point d'entrée JavaScript principal
├── mon-systeme.css          # Feuilles de style compilées
├── module/                  # Code source JavaScript/TypeScript
│   ├── _module.mjs          # Export centralisé des sous-modules
│   ├── config.mjs           # Configuration globale du système
│   ├── settings.mjs         # Paramètres système
│   ├── utils.mjs            # Fonctions utilitaires
│   ├── data/                # DataModels (schémas de données)
│   │   ├── _module.mjs
│   │   ├── actor/           # Modèles pour les Actors
│   │   │   ├── character.mjs
│   │   │   ├── npc.mjs
│   │   │   └── templates/   # Templates réutilisables
│   │   ├── item/            # Modèles pour les Items
│   │   │   ├── weapon.mjs
│   │   │   ├── spell.mjs
│   │   │   └── templates/
│   │   └── shared/          # Champs partagés
│   ├── documents/           # Extensions de Documents
│   │   ├── actor.mjs
│   │   ├── item.mjs
│   │   ├── active-effect.mjs
│   │   └── chat-message.mjs
│   ├── applications/        # Feuilles et interfaces (AppV2)
│   │   ├── actor/
│   │   ├── item/
│   │   └── sheets/
│   ├── dice/                # Logique de jets de dés personnalisés
│   └── canvas/              # Extensions du canvas
├── templates/               # Templates Handlebars (.hbs)
│   ├── actors/
│   ├── items/
│   └── chat/
├── packs/                   # Compendiums (données précompilées)
│   ├── monsters/
│   └── spells/
├── lang/                    # Fichiers de traduction
│   └── en.json
├── icons/                   # Icônes du système
├── fonts/                   # Polices personnalisées
└── less/ ou scss/           # Sources des styles

Rôle des dossiers principaux

Dossier Rôle
module/data/ DataModels - Schémas de validation et structure des données
module/documents/ Extensions des classes Document (Actor, Item, ActiveEffect...)
module/applications/ Interfaces utilisateur - feuilles de personnage, fiches d'objets
module/dice/ Classes de jets de dés personnalisés
templates/ Templates Handlebars (.hbs) pour le rendu HTML
packs/ Compendiums de données de référence

Cycle de vie : init → setup → ready

FoundryVTT exécute les systèmes selon un cycle de vie précis, orchestré par des Hooks. Comprendre ce cycle est essentiel pour savoir où placer votre code.

1. Chargement

Le navigateur charge le manifeste system.json, puis les fichiers esmodules et styles.

2. Hook "init"

  • Enregistrer les classes de documents dans CONFIG
  • Enregistrer les DataModels
  • Configurer les classes de rolls
  • Enregistrer les paramètres système
  • Précharger les templates Handlebars
⚠️ Attention : Les données du monde ne sont PAS encore disponibles !

3. Hook "i18nInit"

Le système d'internationalisation est prêt. C'est le moment de pré-localiser vos configurations.

4. Hook "setup"

  • Les packs de compendiums sont indexés
  • Finaliser la configuration
⚠️ Attention : Les données du monde ne sont TOUJOURS PAS disponibles !

5. Hook "ready"

  • Le monde est entièrement chargé
  • game.actors, game.items, game.scenes sont disponibles
  • Effectuer les migrations de données
  • Initialiser les interfaces persistantes

Exemple de code d'initialisation

// main.mjs - Point d'entrée du système

// Hook "init" - Configuration initiale
Hooks.once("init", function() {
  // Exposer le système globalement
  globalThis.monsysteme = game.monsysteme = Object.assign(
    game.system, 
    globalThis.monsysteme
  );
  
  // Enregistrer la configuration
  CONFIG.MONSYSTEME = MONSYSTEME;
  
  // Enregistrer les classes de documents
  CONFIG.Actor.documentClass = documents.MonActor;
  CONFIG.Item.documentClass = documents.MonItem;
  
  // Enregistrer les DataModels
  CONFIG.Actor.dataModels = dataModels.actor.config;
  CONFIG.Item.dataModels = dataModels.item.config;
  
  // Enregistrer les feuilles
  DocumentSheetConfig.registerSheet(Actor, "monsysteme", CharacterSheet, {
    types: ["character"],
    makeDefault: true,
    label: "Feuille de Personnage"
  });
  
  // Précharger les templates
  loadTemplates([
    "systems/monsysteme/templates/actors/character-sheet.hbs",
    "systems/monsysteme/templates/items/item-sheet.hbs"
  ]);
});

// Hook "setup" - Configuration avancée
Hooks.once("setup", function() {
  // Les compendiums sont indexés
  console.log("Setup terminé");
});

// Hook "ready" - Le monde est chargé
Hooks.once("ready", function() {
  // Vérifier et effectuer les migrations
  if ( game.user.isGM ) {
    performMigrations();
  }
  
  // Le jeu est prêt !
  console.log("Système prêt !");
});

Flux de données

Comprendre comment les données circulent dans FoundryVTT est crucial pour développer efficacement.

┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│   system    │────▶│  DataModel   │────▶│  Document   │
│    .json    │     │ (TypeData)   │     │  (Actor,    │
│             │     │              │     │   Item...)  │
└─────────────┘     └──────────────┘     └─────────────┘
       │                   │                    │
       │                   │                    │
       ▼                   ▼                    ▼
┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│documentTypes│     │ defineSchema │     │ prepareData │
│ packs       │     │ validation   │     │ _preCreate  │
│compatibility│     │ migration    │     │ _onCreate   │
└─────────────┘     └──────────────┘     └─────────────┘
                                               │
                                               ▼
                                        ┌─────────────┐
                                        │ Application │
                                        │  (Sheet)    │
                                        │             │
                                        └─────────────┘

Les 4 couches principales

  1. system.json (Manifeste)

    Déclare les types de documents supportés (documentTypes), les compendiums, et les métadonnées.

  2. DataModel (Schéma de données)

    Définit la structure des données via defineSchema(), valide les entrées, et gère les migrations.

  3. Document (Logique métier)

    Étend Actor, Item, etc. Contient prepareData() et les méthodes de jeu.

  4. Application (Interface)

    Les feuilles de personnage et fiches d'objets qui affichent et éditent les données.

💡 Principe de responsabilité
  • DataModel : Quelles données existent et comment les valider
  • Document : Comment utiliser ces données (calculs, actions)
  • Application : Comment afficher et modifier ces données

Points clés pour démarrer

  1. Commencez par system.json

    Définissez vos types de documents (Actor, Item) et les métadonnées du système.

  2. Créez les DataModels

    Définissez les schémas de validation avec defineSchema().

  3. Étendez les Documents

    Ajoutez la logique métier dans prepareData().

  4. Créez les feuilles

    Interfaces utilisateur avec Application V2.

  5. Prévoyez les migrations

    Votre schéma de données évoluera. Anticipez !

Ressources et documentation

🎯 Exercice : Explorez un système existant

La meilleure façon d'apprendre est d'explorer. Téléchargez un système open-source et analysez sa structure.

  1. Installez le système Simple Worldbuilding dans FoundryVTT
  2. Naviguez dans le dossier Data/systems/worldbuilding/
  3. Ouvrez system.json et identifiez :
    • Les types d'Actor définis
    • Les types d'Item définis
    • Le fichier d'entrée (esmodules)
  4. Trouvez le hook init dans le code JavaScript
💡 Astuce

Vous pouvez aussi explorer le code source de dnd5e sur GitHub pour voir un système complet et professionnel.