Files
games/docs/studies/005-DEPENDENCY_AND_COMPOSITION_STUDY.md
2026-09-18 14:46:05 +02:00

5.8 KiB

Étude des dépendances et de la composition

Statut

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

Objectif

Permettre qu'un produit choisisse uniquement ce dont il a besoin, sans duplication des jeux et sans couplage aux providers/platformes.

Dépendances proposées

Direction générale :

game-specific
    ↓
game-systems
    ↓
technical capability APIs
    ↓
engine kernel contracts

Les implémentations sont injectées/composées par le produit :

app/product
 ├─ game
 ├─ adapters
 ├─ providers
 └─ runtime/backend

Le jeu ne choisit pas lui-même son provider AdMob, son adapter Android ou son transport concret.

Dépendances interdites candidates

  • kernel → game ;
  • kernel → provider ;
  • game-system → application plateforme ;
  • game → SDK publicitaire ;
  • game → Java Android ;
  • game → Tauri ;
  • provider → game-specific ;
  • serveur générique → crate d'application client.

Des exceptions ne doivent être introduites qu'après justification explicite.

Composition statique

La direction proposée reste la composition Rust statique.

Exemple conceptuel :

game-snake-android
  ├─ game-snake
  ├─ engine-v1-...
  ├─ input-touch adapter
  ├─ render-sdl adapter
  ├─ logging-android
  └─ ads-admob provider [si activé]

Un autre produit :

game-snake-desktop
  ├─ game-snake
  ├─ engine-v1-...
  ├─ input-keyboard adapter
  ├─ render-sdl adapter
  └─ no ads provider

Le gameplay reste le même.

Cargo features

Les features Cargo restent utiles pour :

  • capacités locales d'une crate ;
  • optional dependencies ;
  • sélection technique bornée.

Elles ne doivent pas devenir le langage global de composition du produit, car leur unification à travers le graphe peut rendre les variantes difficiles à raisonner.

Manifest produit/jeu

Un manifest dédié pourra décrire plus tard :

  • engine generation ;
  • plateformes ;
  • capabilities requises ;
  • capabilities optionnelles ;
  • providers ;
  • online policy ;
  • input profiles ;
  • asset packs ;
  • logging profile.

Exemple purement illustratif :

[product]
game = "snake"
engine = "v1"

[capabilities]
score = "required"
auth = "optional"
ads = "disabled"
online = "optional"

[platforms]
desktop = true
android = true
web = true

Ce format n'est pas encore retenu.

Crates : création à la demande

Un concept réservé n'entraîne pas automatiquement une crate.

Créer une crate devient justifié notamment si :

  • plusieurs consommateurs réels existent ;
  • une dépendance lourde doit être isolée ;
  • plusieurs providers/adapters sont nécessaires ;
  • une frontière platform-specific est requise ;
  • un contrat stable mérite une API séparée.

Structure workspace candidate

La structure pourrait évoluer vers des familles comme :

crates/
  engines/
  capabilities/
  game-systems/
  providers/
  networking/
  games/
  apps/
  servers/
  common/
  tools/

Cette arborescence est une hypothèse d'étude. Elle n'est pas encore un contrat de fichiers.

Realtime : séparation des responsabilités

Le temps réel ne doit pas être représenté par une seule capability websocket.

Découpage candidat :

transport
    ↓
wire protocol / message codec
    ↓
session protocol
    ↓
synchronization strategy
    ↓
game-specific authoritative simulation

Responsabilités :

  • transport — connexion, frames, timeout, reconnexion bas niveau ;
  • wire protocol — envelope, version, message ids, serialization ;
  • session protocol — join/leave/start/end, identity/session ids, heartbeat ;
  • synchronization strategy — tick, input stream, snapshots, deltas, acknowledgement, resync ;
  • game-specific simulation — validation des inputs et évolution authoritative du monde selon les règles du jeu.

Le framework peut fournir les couches techniques réutilisables sans imposer une simulation générique identique à Snake, Racing ou Fighting.

Le serveur Web/API classique peut partager des types/protocoles avec le service realtime, mais il ne doit pas obligatoirement partager le même process ni la même cadence d'exécution.

Bot / AI execution

Le pilotage artificiel doit emprunter autant que possible les mêmes semantic actions qu'un joueur humain :

observation
    ↓
bot strategy
    ↓
semantic action
    ↓
game simulation

La stratégie peut être composée :

  • dans le client pour un mode offline ;
  • dans le serveur authoritative pour une partie online ;
  • dans un outil de test pour simulation/charge.

Le kernel n'a pas à connaître l'algorithme utilisé.

Web et services par jeu

La composition backend doit permettre un démarrage partagé puis une séparation progressive :

games.sasedev.com
    ├─ auth
    ├─ common API
    ├─ leaderboard
    ├─ realtime
    └─ game modules

puis, si nécessaire :

game-domain
    ├─ www
    ├─ api
    ├─ realtime
    └─ cdn

L'identité canonique et les contrats communs doivent survivre à ce changement de déploiement.

Online/offline

La composition doit pouvoir exprimer :

  • offline-only ;
  • online-optional ;
  • online-required ;
  • online-required pour une capability particulière.

Un jeu online-optional ne doit pas avoir à compiler tout un stack realtime s'il n'en a pas besoin.

Étape suivante après validation de l'étude

Après revue de 0-pre.2, les décisions retenues pourront être promues progressivement vers docs/architecture/.

Ce n'est qu'après cette promotion qu'il sera pertinent de planifier les POC techniques, notamment Tauri Android, Web/WASM et les variantes natives, pour tester les hypothèses de plateforme.