FEATURE_MODULE_SPECIFICATION.md

Spécification des modules de features — Slot Factory Engine. Un bonus = un module indépendant, activé par la config du jeu, chargé dynamiquement (absent de la config ⇒ absent du bundle).


1. Interface commune (contrat)

export interface FeatureModule {
  id: string;                             // 'freeSpins', 'bonusBuy', …
  version: string;

  // Déclarations (consommées par le Factory pour la checklist & la validation)
  paramsSchema: JSONSchema;               // paramètres autorisés dans game.config.json
  requiredAssets(params): AssetKey[];     // clés de thème exigées
  requiredSounds(params): SoundKey[];
  requiredStrings(params): StringKey[];   // clés de locale exigées
  bookEvents: string[];                   // types d'events du book consommés
  mathDeps: MathDep[];                    // ex. { mode:'bonusbuy' }, { field:'freeSpinTrigger' }
  conflictsWith?: string[];               // ex. anteBet ⟂ bonusBuy actifs ensemble

  // Cycle de vie
  hooks: {
    onRegister(ctx: EngineContext): void;         // câblage bus/ui/assets
    onSpinStart?(ctx): void;
    onBookEvent?(ctx, ev: BookEvent): Promise<void>;   // cœur : PRESENTATION d'un fait du book
    onSettle?(ctx): void;
    onModeChange?(ctx, mode: string): void;
  };

  overlay?: () => Screen;                 // écran plein écran éventuel (intro FS, wheel, pick…)
  uiSlots?: UiSlotSpec[];                 // boutons/compteurs à insérer (ex. bouton BUY, meter)
  devForces?: ForceSpec[];                // entrées du panneau simulation (dev-only)
}

Règles d'or : un module présente des events du book, il ne calcule JAMAIS un résultat · toutes ses chaînes passent par i18n (couche social incluse) · tout son visuel passe par le manifest (fallback placeholder) · il déclare tout ce qu'il consomme (le Factory rend l'invisible visible).


2. Modules v1 (consommés par les templates lines-5x3 / ways-5x3 / ultra-simple)

2.1 FreeSpinsFeature

2.2 BonusBuyFeature

2.3 MultiplierFeature

2.4 AutoplayFeature (transverse, quasi-toujours actif)

2.5 TurboFeature (transverse)

2.6 CharacterActorFeature (différenciateur Cool Kids — opt-in)


3. Modules v2 (spécifiés, non construits — attendent leur 2e consommateur)

Module Cœur Assets clés BookEvents type
RespinsFeature N respins, reset sur land compteur, overlay colonne respinTrigger/Step/End
HoldAndWinFeature grille verrouillée, cash symbols, 3 respins reset symbol.cash, cellules locked/empty, bg dédié hnwStart/Land/Reset/End{total}
PickBonusFeature écran de picks, révélations items idle/revealed ×N, bg pickStart/Reveal{value}/End
WheelFeature roue segmentée, résultat du book disc/pointer/center wheelStart/Result{segment}
MysterySymbolFeature symboles voilés → reveal synchronisé symbol.mystery + reveal mysteryReveal{cells,symbol}
SymbolTransformFeature morph de symboles (ex. low→high) anims transform ou fondu moteur symbolTransform{from,to,cells}
CollectionMeterFeature jauge de collecte persistante D'UN ROUND (jamais cross-round — RGS stateless, leçon TNF) meter + icône collectStep{n}/collectComplete
AnteBetFeature +25 % coût, ×2 fréquence trigger, désactive BUY toggle UI (mode math dédié)
ExpandingWildFeature etc. présentation d'events wild du book états wild wildExpand{reel}
JackpotDisplayFeature pseudo-jackpots FIXES par palier (pas de progressif cross-joueur — impossible en pré-simulé) plaques paliers jackpotHit{tier}

4. Anti-patterns interdits (le lint les bloque)