# 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 |