Files
ki-fwi/docs/adr/0002-phaser-hors-budget-initial.md
OKIandClaude Opus 5 3c660c776b feat(session-4): module Pa touché et scène arcade Ranmasé en Phaser 4
Pa touché est une consultation, pas un mode de jeu : cinq plantes triées
par gravité, dépliables, sans chrono, sans score, sans épreuve. Le module
affiche lui-même qu'il n'a pas encore été relu par une personne compétente
et dit que cette relecture est la contribution la plus utile au projet.

Ranmasé : import dynamique, game.destroy(true) au démontage, communication
par événements — la scène ne touche aucun état Svelte et n'émet que sur
changement, jamais par frame. Miroir DOM sémantique, canvas aria-hidden,
jouable au clavier. Écran de chargement designé.

Game design guidé par la pédagogie : laisser passer une plante dangereuse
ne coûte rien (c'est le bon geste), ramasser le mauvais fruit coûte 2
points et pas une vie (il n'y a pas d'erreur à cueillir), une plante
dangereuse sur cinq.

Budgets mesurés et consignés dans l'ADR 0002
- shell hors Phaser : 78 Ko gzip (budget 170)
- Phaser seul : 348 Ko gzip, sous le seuil de réexamen de 450
- absent du chemin critique de l'accueil, vérifié sur le HTML prérendu
- build total 1,4 Mo

Une prescription de l'ADR 0002 était fausse : l'option `resolution`
n'existe pas dans Phaser 4 (pixelRatio y est en lecture seule). Le
plafonnement passe par un tampon de rendu fixe 480×640 étiré en CSS —
plafond dur plutôt que relatif. L'ADR est corrigé, pas contourné.

Reste non mesuré : les 30 fps sur Mali-G52, qui demandent un appareil réel.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 12:07:48 -04:00

81 lines
3.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR 0002 — Phaser 4 et l'écart au budget JS
- **Statut :** accepté, avec mesure à compléter en session 4
- **Date :** 2026-07-27
- **Session :** 0 — cadre et données
## Contexte
Le playbook OKI §2.7 fixe un budget non négociable de **170 Ko de JS initial compressé**.
Le mode arcade « Ranmasé » demande de la physique, des particules et du *game feel* : le
faire en DOM coûterait plus cher en travail et en performance qu'un moteur éprouvé.
Le pack d'origine prescrivait « Phaser 5 ». **Phaser 5 n'existe pas.** Vérification faite
au démarrage de la session :
```
$ npm view phaser version
4.2.1
```
La branche courante est Phaser 4 — 4.0 « Caladan » (avril 2026), 4.1 « Salusa »,
4.2 « Giedi » — avec un moteur WebGL réécrit en *render nodes*. Partir de Phaser 3 aurait
été partir d'une branche en fin de vie.
## Décision
Utiliser **`phaser@^4`** (4.2.1 au moment de la décision), et assumer un **écart documenté**
au budget JS, borné par quatre conditions :
1. Phaser n'est **jamais** dans le chemin critique. Import dynamique dans la route
`(jeu)/ranmase` uniquement, jamais au layout racine.
2. Le shell reste **≤ 170 Ko gzip**, Phaser exclu. Le budget n'est pas relâché : il est
mesuré à part.
3. L'entrée dans la scène passe derrière un **écran de chargement designé** (playbook P5,
en KA avec le tambour `ka`), pas derrière une page blanche.
4. Rendu `AUTO` (WebGL avec repli canvas), DPR plafonné à **1,5**,
`powerPreference: 'low-power'`, cible **30 fps stables sur Mali-G52**.
## Conséquences
- Le budget d'entrée du site (≤ 2 Mo) et les Core Web Vitals (LCP < 2,5 s, INP < 200 ms,
CLS < 0,05) restent mesurés **sur l'accueil et sur une fiche**, pages qui ne chargent
jamais Phaser.
- Un utilisateur qui ne joue jamais au mode arcade ne télécharge jamais Phaser. Les quatre
autres modes sont en Svelte pur (ADR 0003).
- La session 4 doit renseigner ici la **mesure réelle** du bundle Phaser en gzip et le
relevé de fps sur mobile d'entrée de gamme.
### Mesures — à compléter en session 4
| Mesure | Cible | Relevé (2026-07-27) |
|---|---|---|
| Shell JS initial, Phaser exclu (gzip) | ≤ 170 Ko | **78 Ko** ✅ |
| Bundle Phaser seul (gzip) | information | **348 Ko** — sous le seuil de réexamen de 450 Ko |
| Phaser dans le chemin critique de l'accueil | absent | **absent**, vérifié sur le HTML prérendu ✅ |
| Poids total du build | ≤ 2 Mo | **1,4 Mo** ✅ |
| fps scène Ranmasé sur Mali-G52 | ≥ 30 stables | **non mesuré** — demande un appareil réel |
Le total JS du site atteint 426 Ko gzip, mais 348 Ko ne sont téléchargés qu'à l'entrée dans
`/je/ranmase/`. Un visiteur de l'encyclopédie ne les voit jamais.
### Correction apportée à cet ADR par la mise en œuvre
Cet ADR prescrivait un « DPR plafonné à 1,5 » via l'option `resolution`. **Cette option
n'existe pas dans Phaser 4** : `pixelRatio` y est une information matérielle en lecture
seule, et `resolution` avait déjà été neutralisée en Phaser 3.
L'objectif est atteint autrement, et mieux : le tampon de rendu est fixé à **480 × 640**,
étiré en CSS par le mode `FIT`. Le GPU dessine donc toujours 480 × 640 pixels, quel que
soit le DPR de l'appareil — c'est-à-dire un plafond dur, là où `resolution` n'aurait donné
qu'un plafond relatif.
`powerPreference: 'low-power'` existe bien, sous la clé `render`.
## Condition de réexamen
Si la mesure de session 4 montre que Phaser dépasse ~450 Ko gzip, ou que les 30 fps ne
sont pas tenus sur mobile d'entrée de gamme, la scène « Ranmasé » est réécrite en DOM/CSS
avec une boucle rAF maison — le playbook P3 (« DOM d'abord, WebGL seulement où ça paie »)
reprend alors la main. Les quatre autres modes n'en dépendent pas : le jeu reste entier.