# Règles spécifiques games.sasedev ## Workspace et crates - **GAME-WS-001** — Un seul workspace Cargo racine contient les crates Rust du dépôt. - **GAME-WS-002** — Toutes les crates Rust résident sous `crates/`. - **GAME-WS-003** — Les crates moteur résident sous `crates/engines/`, les crates jeu sous `crates/games/`, les bibliothèques transverses indépendantes d’une génération de moteur sous `crates/common/` et les exécutables/launchers réutilisant ces libs sous `crates/apps/`. - **GAME-WS-004** — Une crate hérite par défaut de `workspace.package.version`. - **GAME-WS-005** — Une crate arrivée à maturité peut porter sa propre version SemVer lorsqu'une décision documentée rend son cycle autonome nécessaire. - **GAME-WS-006** — Les dépendances tierces communes sont centralisées sous `[workspace.dependencies]` et consommées avec `workspace = true` lorsqu'elles sont partagées. - **GAME-WS-007** — Un jeu est prioritairement une crate `lib`; lorsqu’un lancement Desktop est nécessaire, une crate `bin` séparée sous `crates/apps/` dépend de cette lib et ne duplique pas son gameplay. - **GAME-WS-008** — Les runners Desktop sont nommés `-desktop` et restent indépendants des frontends Android. ## Générations du moteur - **GAME-ENGINE-001** — Une génération incompatible de moteur reçoit un nom explicite `engine-vN-*`. - **GAME-ENGINE-002** — `engine-v2` n'est pas créé pour une évolution mineure ; il représente une rupture d'API ou d'architecture suffisamment forte pour justifier une coexistence avec `engine-v1`. - **GAME-ENGINE-003** — Plusieurs générations de moteur peuvent coexister afin de migrer les jeux progressivement. - **GAME-ENGINE-004** — Un jeu déclare explicitement la génération de moteur qu'il consomme. - **GAME-ENGINE-005** — Une génération de moteur n'est supprimée qu'après migration, retrait ou archivage de tous ses consommateurs actifs. ## Assets - **GAME-ASSET-001** — Aucun asset de jeu n'est stocké dans une crate Rust. - **GAME-ASSET-002** — Les assets sont stockés sous `assets/`. - **GAME-ASSET-003** — `assets/common/` contient uniquement les ressources réellement mutualisées. - **GAME-ASSET-004** — Chaque jeu peut posséder `assets//` pour ses ressources spécifiques. - **GAME-ASSET-005** — Le packaging de chaque plateforme assemble les assets communs et spécifiques sans créer de copie source durable dans une crate. - **GAME-ASSET-006** — Les chemins logiques d'assets doivent éviter les collisions entre espace commun et espace jeu. ## Android - **GAME-ANDROID-001** — L'intégration Android réside sous `Android/` et reste extérieure au workspace Rust. - **GAME-ANDROID-002** — Java est la langue Android commune par défaut ; Kotlin n'est pas requis. - **GAME-ANDROID-003** — `Android/common/` contient la couche réutilisable : activité SDL dérivée, bridge natif, publicité, billing, haptique et services génériques selon les besoins. - **GAME-ANDROID-004** — `Android//` contient uniquement la configuration et les extensions spécifiques au jeu : package, manifeste, ressources Android, identifiants et Java spécifique. - **GAME-ANDROID-005** — Le code Java commun ne dépend pas d'une génération particulière du moteur Rust lorsque le contrat plateforme peut rester stable. - **GAME-ANDROID-006** — Le contrat JNI est volontairement petit, stable et orienté services plateforme. - **GAME-ANDROID-007** — SDL3 peut être consommé via son AAR officiel afin d'éviter de dupliquer ses sources Java/C dans chaque application. ## Plateformes - **GAME-PLATFORM-001** — Le gameplay ne dépend pas directement d'Android, Desktop ou Web. - **GAME-PLATFORM-002** — Les entrées physiques sont traduites en actions de jeu abstraites. - **GAME-PLATFORM-003** — Les services Ads, Billing, Share, Haptics, Leaderboard et stockage en ligne sont consommés derrière des contrats plateforme. - **GAME-PLATFORM-004** — Ads et Billing sont des capacités optionnelles ; le gameplay reste fonctionnel lorsqu'elles sont disponibles, désactivées ou non supportées. - **GAME-PLATFORM-005** — Un backend de monétisation est spécifique à sa plateforme et à sa distribution ; une intégration Android n'est pas réutilisée implicitement sur Web ou Desktop. - **GAME-PLATFORM-006** — Le runner Desktop natif SDL3 est la forme Desktop par défaut. Une variante Tauri peut coexister uniquement lorsqu'un besoin explicite le justifie et consomme la même crate lib de jeu. - **GAME-PLATFORM-007** — Une variante Tauri conserve son backend Rust sous `crates/apps/`; son frontend Vite/TypeScript réside dans la même crate sous `frontend/` et ne duplique pas le gameplay Rust. - **GAME-PLATFORM-008** — Le gameplay compilé en WebAssembly est adapté par une frontière dédiée ; le code JavaScript orchestre la WebView, les événements et le rendu Canvas mais ne réimplémente pas les règles du jeu. ## POC - **GAME-POC-001** — Les premiers POC servent à valider l'architecture et doivent rester volontairement petits. - **GAME-POC-002** — Un POC ne justifie pas l'introduction prématurée d'un ECS, moteur physique ou backend complet s'il n'en a pas besoin. ## Diagnostics structurés - **GAME-TRACE-001** — `tracing` est le mécanisme Rust canonique pour les diagnostics structurés. - **GAME-TRACE-002** — `tracing-subscriber` compose les subscribers applicatifs et de test ; une librairie métier ne configure pas silencieusement le subscriber global. - **GAME-TRACE-003** — `tracing-appender` est utilisé lorsque l’écriture non bloquante ou les fichiers de logs deviennent nécessaires ; le guard associé reste vivant pendant toute la durée utile. - **GAME-TRACE-004** — La configuration de logging commune réside dans une crate transverse et ne doit pas être dupliquée par jeu. - **GAME-PLATFORM-009** — Une adaptation WebAssembly réutilisable est une crate dédiée distincte de la crate Tauri. - **GAME-PLATFORM-010** — Dans une app Tauri, `lib.rs` reste une façade/reexport ; `tauri.rs` assemble Tauri et expose les commandes qui délèguent aux modules propriétaires. - **GAME-PLATFORM-011** — Les traces frontend Tauri passent par `@fltsci/tauri-plugin-tracing` vers `tauri-plugin-tracing`/`tracing`; les `console.*` applicatifs directs sont interdits hors fallback interne.