Concepts fondamentaux
La feuille est la source unique de vérité
Il existe exactement une forme canonique de vos données : la feuille. Tout le reste en est dérivé :
- L'IR (Définitions immuables) est la forme validée et assemblée de la feuille.
- Les classes C# générées sont le schéma de l'IR, rendu fortement typé.
- Les ScriptableObjects issus du bake sont les valeurs de l'IR, rendues chargeables — un cache de consultation, jamais une vérité indépendante.
Toute modification passe par la feuille et doit réussir la validation de réimport pour devenir réelle. Modifier directement une SO bake créerait une seconde vérité et contournerait la validation, si bien que le produit refuse volontairement de le prendre en charge comme flux de travail.
(L'interrupteur « Modification test » de l'inspecteur existe pour des expérimentations temporaires à l'exécution. Il n'est jamais réécrit dans la feuille, et le réimport l'efface.)
Pourquoi c'est important : les projets qui traitent la SO comme la source de vérité finissent avec des données non validées qui dérivent de la feuille, sans aucun moyen de les réconcilier. Ici, la réconciliation est structurelle — régénérez toujours à partir de la feuille.
L'IR — un assemblage immuable et validé
L'IR est ce que produit la validation. Pour chaque onglet, elle détient une SheetTable (schéma + enregistrements) dont les cellules sont déjà des valeurs typées : int, float, valeurs d'enum, références d'enregistrement, références d'asset, listes, types de plugin personnalisés.
Propriétés clés :
- Aucun assemblage partiel. Si une seule erreur existe, où que ce soit, l'IR n'est pas construit (
ImportResult.Success == false ⇔ Registry == null— un invariant strict). - Aucun null. Une cellule optionnelle vide matérialise immédiatement la valeur par défaut de son type, marquée
IsDefaulted— les consommateurs n'ont jamais à vérifier de null. - Immuable. L'IR est en lecture seule après l'assemblage ; les sorties (codegen, bake, export) le lisent, et ne le modifient jamais.
Le pipeline
fetch → parse markers/schema → parse cells → validate (keys, references,
@overlap, asset keys, domain rules) → assemble IR → codegen (.cs) → bake (SO)
└──────────────── collect ALL diagnostics ────────────────┘- La validation collecte tout. Vous obtenez la liste complète des problèmes en une seule exécution — où / quoi / pourquoi / comment, pour chaque erreur — au lieu de corriger une erreur par réimport.
- Le codegen est la dernière étape, après la validation et l'assemblage des valeurs, car l'écriture des fichiers
.csdéclenche un rechargement de domaine. Le pipeline est structuré pour que ce rechargement soit sûr et que la chaîne reprenne automatiquement après celui-ci. - Les erreurs sont des objets structurés, restitués sous forme de phrases. Chaque erreur porte l'onglet, la ligne (indexée à partir de 1), et la lettre de colonne et le nom de champ. Elle porte aussi la valeur fautive, la règle enfreinte, et une suggestion exploitable (avec des propositions de correspondance la plus proche pour les fautes de frappe). Les mêmes objets se restituent aussi sous forme de coordonnées machine pour les logs/la CI.
La chaîne d'import automatique
Lorsqu'un schéma est nouveau ou modifié, une exécution d'import effectue en interne :
- Écriture du code généré → compilation par Unity → rechargement de domaine.
- Après le rechargement, la chaîne reprend d'elle-même et termine le bake.
Vous n'avez jamais besoin de redéclencher quoi que ce soit manuellement. Si la compilation échoue (par ex. votre code de jeu référence un champ qu'un renommage vient de modifier), la chaîne s'interrompt de façon sûre avec une phrase exploitable dans la console au lieu de boucler (plafond de 3 tentatives, journal de reprise).
Typage fort, aucun parsing à l'exécution
Le codegen lit @name / @type / @desc et émet, pour chaque onglet Foo :
FooDefinition— une classe d'enregistrement fortement typée, un champ par colonne ;@descdevient le commentaire de documentation XML et l'infobulle de l'inspecteur.FooDatabase : DefinitionDatabase— la SO conteneur par onglet, avecRecords, des recherches d'id paresseuses (lazy), et uneSchemaFingerprint.
Le bake écrit de vrais champs typés — aucun parsing de texte à l'exécution, aucune réflexion à l'exécution — ce qui le rend sans danger pour IL2CPP (aucun risque lié au stripping).
Le chargement par adresse — comment le cache reste partageable
Les SO bake sont des caches propres à chaque machine, avec des GUID propres à chaque machine. Des références de scène directes vers elles casseraient d'une machine à l'autre. À la place :
- L'import enregistre automatiquement chaque SO Database dans le groupe Addressables
SheetForge, à l'adresse stable"SheetForge/{tab}"(les re-bakes relient le nouveau GUID à la même adresse ; les onglets supprimés sont nettoyés). - Le code de jeu charge par adresse :
SheetForgeDatabases.LoadAsync<FooDatabase>("Foo"). - L'asset de groupe Addressables est gitignoré et autoréparateur (recréé par l'import lorsqu'il est absent).
Les baselines — comment l'aller-retour préserve votre feuille
À l'import, un instantané normalisé de la structure de chaque onglet (lignes de marqueur, ordre des colonnes, commentaires, texte écrit à la main) est stocké comme baseline. L'export échange ensuite les valeurs actuelles des SO dans la structure de la baseline.
Un aller-retour feuille → import → export → feuille préserve donc votre feuille à 100 % sur le plan structurel, et préserve les valeurs sur le plan sémantique :
1.0↔1est autorisé car la valeur est identique.- Les flottants utilisent le format d'aller-retour le plus court.
- Le séparateur décimal est toujours
., indépendant de la locale.
Ce qui est commité et ce qui est régénéré
| Artefact | Politique |
|---|---|
| Feuilles (fichiers locaux) / Feuille Google | La vérité. Commité(e) / partagé(e). |
SO Database issues du bake (Assets/SheetForgeBaked) | Cache gitignoré propre à chaque machine — régénérer en exécutant un import. |
Code généré (Assets/SheetForgeGenerated) | La recommandation est de le committer. C'est le code source propre de votre projet, il vit en dehors de Assets/SheetForge, si bien que réinstaller le produit ne peut pas le supprimer, et le committer signifie qu'un clone tout neuf compile avant que quiconque ait lancé un import. La sortie est déterministe, si bien que les imports des coéquipiers produisent des octets identiques. Le mettre au gitignore est une alternative valable ; le prochain import le régénère. Un projet antérieur à cette valeur par défaut continue de générer dans Assets/SheetForge/Runtime/Generated jusqu'à ce que ce dossier soit vide ; voir Prise en main. |
Asset de groupe Addressables SheetForge | Gitignoré, autoréparateur. Ne commitez pas le diff de paramètres d'une ligne que sa première création produit. |
Le propre dossier Generated d'un package de domaine | Le choix du package lui-même. L'exemple SheetForge.PluginDemo fourni commite son code généré afin que la démo compile immédiatement après l'import. |
| Asset de paramètres d'import | À gérer par vous ; gardez les chemins de clé de compte de service hors du dépôt (utilisez la variable d'environnement SHEETFORGE_SHEETS_KEY). |
Extension sans modification
Des contrats d'enregistrement permettent aux plugins de rejoindre le pipeline sans aucune modification du Core :
- parseurs de type de cellule (y compris les types wrapper), validateurs de domaine, contributeurs d'arêtes ;
- marqueurs structurels personnalisés, modèles « Créer une feuille », fournisseurs de source d'import ;
- les surcharges de canevas, les registres de code, les widgets, les actions, les widgets de cellule, les préréglages de couleur et les chaînes d'UI du Data Studio.
Le Core ne référence jamais un package de domaine ; cette dépendance à sens unique est imposée par le compilateur. La liste faisant autorité — et son décompte — se trouve dans Création de plugins.
Pages associées
- Syntaxe des feuilles — la grammaire des marqueurs et des types que lit le parseur
- Data Studio — la création par-dessus ce modèle
- Sources, export et push — la mécanique de l'aller-retour
- Noyau de création — le moteur sous-jacent à la fenêtre de création