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

241 lines
5.1 KiB
Markdown

<!-- file: docs/studies/002-LAYERING_AND_OWNERSHIP_STUDY.md -->
<!-- version: 1 -->
# É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 :
```text
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 :
```text
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 :
```text
input-api
├─ sdl-keyboard adapter
├─ sdl-touch adapter
└─ web-pointer adapter
```
ou :
```text
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
```text
game -> AdMob SDK
game -> Java Android
game -> Tauri command
game -> tokio-tungstenite
game -> filesystem OS direct
```
### Préféré
```text
game
capability / game-system
adapter/provider
platform/external service
```
## API / façade / implémentation
Lorsque la complexité le justifie, une famille peut suivre :
```text
<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 ?