diff --git a/docs/GDD.md b/docs/GDD.md index e274c2a..c757538 100644 --- a/docs/GDD.md +++ b/docs/GDD.md @@ -165,18 +165,26 @@ Sprint 1 — linéaire (5 nœuds). Sprint 2+ → branches. --- -## Hors scope Sprint 1 +## Sprint 2 — Offline, Branches & Cosmétiques + +Brief technique : `docs/SPRINT2.md` + +| Feature | Design | +|---------|--------| +| Offline gains | Courbe inversée 100%→0% sur 2h, cap 25% prod idle, écran résumé au retour | +| Arbre 3 voies | Ponte (click) / Marais (production) / Adaptation (utility), ~15 nœuds, reset gratuit | +| Cosmétiques V1 | 5 slots SVG overlay, récompenses achievements + prestige tiers, inventaire | + +## Hors scope Sprint 2 - Boucle 3 (méta, events, leaderboard) -- Branches arbre d'évolution (linéaire suffit) -- Cosmétiques / skins -- Monétisation effective +- Monétisation effective (boutique cosmétique payante) - Sound / musique -- Mobile responsive (desktop first) -- Offline gains calculés côté serveur (Sprint 2) -- Migration Express → Fastify (si besoin Sprint 3+) +- Mobile responsive (session dédiée) +- Migration Express → Fastify - Intégration Twitch - Multijoueur +- Coût reset arbre (gratuit Sprint 2, payant plus tard) --- @@ -186,3 +194,4 @@ Sprint 1 — linéaire (5 nœuds). Sprint 2+ → branches. |------|------------| | 2026-03-17 | GDD initial — sprint1-step1, stack React+TS+Vite, mécaniques core | | 2026-03-20 | Refonte game-designer — Tetard Universe, Arbre d'Évolution, anti-triche backend, SuperOAuth, stack confirmée Express | +| 2026-03-28 | Sprint 1 livré (6/6). Sprint 2 briefé — offline gains courbe inversée, arbre 3 voies, cosmétiques récompenses | diff --git a/docs/SPRINT2.md b/docs/SPRINT2.md new file mode 100644 index 0000000..b384c36 --- /dev/null +++ b/docs/SPRINT2.md @@ -0,0 +1,143 @@ +# SPRINT2.md — Offline, Branches & Cosmétiques + +> Brief technique — Sprint 2 +> Date : 2026-03-28 +> Réf GDD : docs/GDD.md +> Dépend : Sprint 1 livré (6/6) +> Agents : game-designer (design) → build (implémentation) + +--- + +## Objectif + +Trois features qui transforment Clickerz d'un prototype jouable en un jeu avec rétention : +- Offline gains avec courbe inversée (incite à jouer actif) +- Arbre d'Évolution 3 voies (builds, choix, rejouabilité) +- Cosmétiques par récompense (feedback visuel, motivation prestige) + +--- + +## Steps + +### Step 1 — Offline gains (courbe inversée) + +**Scope :** Calculer les gains hors-ligne avec une courbe dégressive pour inciter le jeu actif. + +**Design :** +- Courbe inversée : efficacité 100% → 0% sur 2h d'absence + - 0-15min : 100% de la prod idle + - 15min-1h : dégression linéaire 100% → 25% + - 1h-2h : dégression 25% → 0% + - >2h : cap — plus rien (le marais dort) +- Prod offline plafonnée à 25% de la prod idle moyenne +- Au retour du joueur : écran "Pendant ton absence..." avec résumé des gains + +**Technique :** +- `applyIdleGains()` existe déjà — ajouter un facteur `offlineEfficiency(elapsedMs)` +- `offlineEfficiency(ms)` : retourne le multiplicateur (1.0 → 0.0) basé sur la courbe +- Backend : valider le gain offline au `GET /api/save` (même pattern anti-triche) +- Frontend : composant `OfflineReport` affiché si `elapsed > 60s` au chargement +- GameState : ajouter `lastOnline: number` (timestamp dernière activité réelle) + +**Critère done :** fermer le jeu, revenir 30min après → écran résumé + gains corrects. Revenir 3h après → même résultat qu'après 2h (cap). + +--- + +### Step 2 — Arbre d'Évolution 3 voies + +**Scope :** Transformer l'arbre linéaire en arbre à 3 branches avec choix de build. + +**Design :** +- 3 voies depuis la racine : + - **Ponte** (click) — multiplicateurs click, click critique, auto-click + - **Marais** (production) — multiplicateurs idle, générateurs bonus, production globale + - **Adaptation** (utility) — start bonus, offline boost, prestige ADN bonus, cost reduction +- Chaque voie : 4-5 nœuds progressifs (coût ADN croissant) +- Le joueur peut investir dans plusieurs voies — pas de lock exclusif +- Choix intra-nœud : certains nœuds proposent 2 options mutuellement exclusives (pick one) +- Reset : gratuit pour l'instant (bouton "Réinitialiser l'Arbre" — rembourse tout l'ADN dépensé) + - Futur : coût ADN croissant par reset (1er gratuit, 2e = 10 ADN, etc.) + +**Technique :** +- Refactorer `EvolutionNode` : + ```ts + interface EvolutionNode { + id: string; + name: string; + cost: number; + effect: EffectType; + value: number; + unlocked: boolean; + requires: string | null; // nœud parent + branch: "ponte" | "marais" | "adaptation"; + exclusive_with?: string; // id du nœud alternatif (pick one) + } + ``` +- `DEFAULT_EVOLUTION_TREE` : ~15 nœuds (5 par voie) +- `resetEvolutionTree(state)` : rembourse tout l'ADN, relock tous les nœuds +- UI : `EvolutionTree.tsx` → layout 3 colonnes (une par voie), header avec couleur + - Ponte = vert, Marais = bleu, Adaptation = ambre +- Animer les connexions entre nœuds (lignes SVG ou borders) + +**Critère done :** le joueur voit 3 voies distinctes, peut investir ADN dans chaque, constater les effets, et reset gratuitement. + +--- + +### Step 3 — Cosmétiques V1 (récompenses) + +**Scope :** Système d'équipement cosmétique sur le sprite têtard, gagné par achievements et prestige. + +**Design :** +- 5 slots : hat, eyes, body, tail, accessory (déjà dans tadpole.svg V5) +- Sources de cosmétiques : + - **Achievements** : débloquer un cosmétique quand un achievement est complété + - **Prestige tiers** : skin spécial à 5, 10, 25, 50 prestiges +- Inventaire : liste des cosmétiques possédés, équipés (1 par slot max) +- Rendu : stack SVG — base (tadpole.svg) + overlays par slot équipé +- Pas de boutique / pas de currency cosmétique — uniquement des récompenses + +**Technique :** +- GameState : ajouter `cosmetics: { inventory: string[], equipped: Record }` +- Définir les cosmétiques : + ```ts + interface Cosmetic { + id: string; + name: string; + slot: "hat" | "eyes" | "body" | "tail" | "accessory"; + svg: string; // chemin vers le SVG overlay + source: "achievement" | "prestige"; + sourceId: string; // achievement id ou "prestige_10" + } + ``` +- 8-10 cosmétiques initiaux (2 par slot) : + - hat : couronne (prestige 10), casquette marais (achievement 10 succès) + - eyes : lunettes savant (prestige 5), masque grenouille (achievement 1M têtards) + - body : cape algues (prestige 25), armure écailles (achievement tous générateurs) + - tail : flamme (prestige 50), ruban (achievement premier prestige) + - accessory : aura-swamp (existe déjà), particules dorées (achievement 5 prestiges) +- UI : page `/cosmetics` ou section dans Settings — grille inventaire + preview sprite +- `TadpoleSprite.tsx` : composant qui empile base SVG + overlays équipés + +**Critère done :** débloquer un achievement → cosmétique dans l'inventaire → équiper → voir le changement sur le sprite en jeu. + +--- + +## Résumé séquentiel + +``` +Step 1 (offline gains) → Step 2 (arbre 3 voies) → Step 3 (cosmétiques) +``` + +Step 1 = rétention. Step 2 = profondeur. Step 3 = récompense visuelle. + +--- + +## Risques identifiés + +| Risque | Mitigation | +|--------|------------| +| Courbe offline trop punitive | Playtester, ajuster les paliers. Logs pour traquer le % de gains offline | +| Arbre déséquilibré (une voie OP) | 3 voies testables indépendamment. Reset gratuit = le joueur corrige | +| Nœuds exclusifs confus UX | Tooltip clair "Choisis l'un des deux", preview de l'effet avant achat | +| SVG overlay perf (mobile) | Lazy load des SVG, max 5 overlays simultanés (1 par slot) | +| Reset arbre exploitable | Gratuit = pas de cheese possible. Le coût viendra plus tard |