Files
games/docs/studies/002-LAYERING_AND_OWNERSHIP_STUDY.md
2026-09-18 14:04:12 +02:00

5.1 KiB

Étude du layering et de l'ownership

Statut

Étude non normative pour 0.2.0-0-pre.2.

Problème

Le framework doit permettre plusieurs jeux et plateformes sans transformer engine-v1 en monolithe ni multiplier prématurément les crates.

Le classement proposé repose sur la question :

qui possède la règle et qui peut légitimement la réutiliser ?

1. Engine kernel

Responsabilités candidates :

  • lifecycle ;
  • temps/scheduling minimal ;
  • orchestration générique update/render ;
  • contrats minimaux entre runtime et jeu ;
  • provenance runtime ;
  • quit/lifecycle générique.

Le kernel ne connaît pas :

  • score ;
  • vies ;
  • inventaire ;
  • ads ;
  • auth ;
  • leaderboard ;
  • maps propres au jeu ;
  • WebSocket ;
  • provider externe ;
  • règles Snake/Reflex.

2. Technical capability

Une technical capability fournit un service technique générique au jeu ou à un game-system.

Exemples :

  • input ;
  • render ;
  • audio ;
  • assets ;
  • persistence ;
  • network transport ;
  • logging ;
  • identity client ;
  • ads client.

Pattern candidat :

capability API
      ↑
game / game-system
      ↓
adapter/provider implementation

Une capability n'impose pas qu'une crate existe immédiatement.

3. Game-system

Un game-system encapsule une mécanique de gameplay réutilisable.

Exemples plausibles :

  • score ;
  • lives ;
  • energy ;
  • progression/XP ;
  • inventory ;
  • grid/tile map ;
  • collision simple ;
  • seeded challenge ;
  • puzzle primitives.

Un game-system peut dépendre de capabilities techniques mais ne doit pas dépendre d'une app plateforme.

Exemple :

energy-system
    ↓
clock capability
    ↓
reward contract

Il ne doit pas appeler directement AdMob.

4. Platform adapter

Un adapter traduit une plateforme/backend vers une technical capability.

Exemples :

input-api
  ├─ sdl-keyboard adapter
  ├─ sdl-touch adapter
  └─ web-pointer adapter

ou :

render-api
  ├─ sdl renderer
  └─ web renderer

Un adapter peut être propre à une plateforme ou partagé par plusieurs plateformes lorsque le backend le permet.

5. Provider

Un provider intègre un service externe interchangeable.

Exemples :

  • AdMob ;
  • Google OAuth ;
  • Play Games ;
  • Apple Game Center éventuel ;
  • backend leaderboards ;
  • CDN.

Différence avec platform adapter :

  • adapter = traduit un environnement technique local ;
  • provider = parle à un service ou SDK externe pouvant être substitué.

Un provider peut lui-même être platform-specific.

6. Server service

Le serveur possède les décisions qui ne peuvent pas être fiables côté client lorsqu'il existe un enjeu partagé ou compétitif.

Exemples :

  • identité canonique ;
  • leaderboard validé ;
  • matchmaking ;
  • session realtime authoritative ;
  • récompense à valeur économique ;
  • résolution de conflits cloud ;
  • anti-cheat.

Le client conserve les responsabilités locales nécessaires au fonctionnement offline lorsque le produit l'autorise.

7. Game-specific

La règle reste dans le jeu lorsque sa généralisation n'est pas démontrée.

Exemples actuels :

  • croissance et corps du Snake ;
  • génération de séquence Reflex ;
  • règle exacte d'apparition/disparition des cibles ;
  • coût précis pour creuser une case dans un jeu d'aventure ;
  • moveset d'un personnage de fighting.

Règle candidate :

un second besoin similaire peut justifier l'extraction d'un game-system ; un seul cas ne suffit pas automatiquement.

8. Tooling

Le tooling construit ou valide le produit mais n'entre pas dans le runtime du jeu.

Exemples :

  • builder Android multi-ABI ;
  • packaging ;
  • génération de config ;
  • audit manifests/capabilities ;
  • outils de contenu.

Frontières proposées

À éviter

game -> AdMob SDK
game -> Java Android
game -> Tauri command
game -> tokio-tungstenite
game -> filesystem OS direct

Préféré

game
 ↓
capability / game-system
 ↓
adapter/provider
 ↓
platform/external service

API / façade / implémentation

Lorsque la complexité le justifie, une famille peut suivre :

<domain>-api
<domain>-lib
<domain>-<provider>-lib

Mais cette structure ne doit pas être créée par réflexe.

Critères pour créer plusieurs crates :

  • plusieurs implémentations ;
  • besoin de dépendance inversée ;
  • frontière de compilation/platforme ;
  • dépendances lourdes que certains produits doivent éviter ;
  • tests/ownership clairement séparés.

Sinon une seule crate réutilisable peut suffire.

Questions à trancher plus tard

  • render doit-il rester dans engine-v1-sdl ou devenir une capability explicite ?
  • input doit-il être un domaine autonome dès 0.2.x ?
  • score/lives/energy doivent-ils être regroupés dans une crate gameplay-common ou rester séparés ?
  • grid/map/collision simple doivent-ils partager une famille de crates ?
  • networking doit-il être une technical capability ou une famille networking/ distincte au workspace ?
  • où placer la frontière entre client auth générique et provider OAuth ?