# SPRINT3.md — Prestige Loop > Brief technique — Sprint 3 > Date : 2026-03-28 > Réf GDD : docs/GDD.md > Dépend : Sprint 2 livré (3/3) > Agents : game-designer (design) → build (implémentation) --- ## Objectif Transformer le prestige d'une mécanique de reset en une **boucle de progression motivante et endless**. Le joueur doit sentir l'accélération à chaque génération, faire des choix de build durables, et viser des paliers qui récompensent la spécialisation. --- ## Pré-requis technique — Migration saves > À traiter en amont de Step 1 — pas un step visible, mais bloquant. ### Pattern `saveVersion` + `migrateSave()` (décision session 2026-03-28) Le GameState est stocké en JSON unique dans MySQL. Ajouter/modifier des champs sans migration = `undefined` silencieux → NaN → bugs fantômes. **Mécanisme :** - Ajouter `saveVersion: number` au `GameState` - Saves Sprint 2 existantes = version absente → traitées comme `v1` - Sprint 3 = `v2` - Fonction `migrateSave(state: unknown): GameState` appliquée au chargement (frontend `useSaveSync` + backend `saveControllers`) - `v1 → v2` : injecter defaults (`runStats` vide, `treeResetCount: 0`, `freeResetAvailable: true`, `repeatableNodes: {}`, nouveaux nœuds arbre) - Les 18 nœuds Sprint 2 conservent leur `id` — les nouveaux s'ajoutent - Champ critique manquant → log warning + default safe (jamais de crash) - Chaque sprint futur ajoute un step de migration (`v2 → v3`, etc.) ### Schéma DB - `ALTER TABLE game_saves ADD COLUMN save_version INT DEFAULT 1` - Pas de migration du JSON existant en DB — la migration est lazy (au chargement) ### Validation - Charger une save Sprint 2 brute sur le nouveau code → `migrateSave` injecte v2 - Pas de perte de données, pas de reset forcé - Les nœuds arbre existants (18) gardent leur position et état unlocked --- ## Steps ### Step 1 — Prestige Experience **Scope :** Rendre le moment du prestige satisfaisant et informatif. **Design :** - Écran de prestige redesigné : - Preview ADN gagné (avant de confirmer) - Comparaison : "Run actuelle vs meilleure run" (durée, têtards, ADN) - Compteur de générations (nombre total de prestiges) - Statistiques de run persistées : - Durée de la run - Têtards produits (lifetime cette run) - Vitesse de progression vs run précédente (% plus rapide / plus lent) - Branche d'arbre principale utilisée - Animation de reset : transition visuelle (le marais "renaît") - Hooks audio-ready : prévoir les points d'ancrage pour le son (Sprint futur) **Technique :** - `PrestigeScreen.tsx` : composant modal fullscreen (pas un simple bouton) - `RunStats` dans le GameState : ```ts interface RunStats { startedAt: number; tadpolesProduced: number; prestigeCount: number; bestRun: { duration: number; tadpoles: number; adn: number; }; } ``` - Backend : persister `runStats` dans la save (même pattern save serveur) - Rebalancer la formule prestige pour l'endless (voir section Formules) **Critère done :** le joueur clique Prestige → voit un écran avec preview ADN + stats comparées → confirme → animation → nouvelle run. Les stats de la meilleure run sont persistées. --- ### Step 2 — Arbre d'Évolution V2 — Profondeur endless **Scope :** Étendre l'arbre à ~30 nœuds avec capstones game-changers et scaling post-capstone infini. **Design — Structure par branche :** **Branche Ponte (click) — 8-10 nœuds :** - Tier 1 : Ponte Améliorée (+100% click) — 1 ADN - Tier 2 : Click Critique (5% chance ×10) — 5 ADN - Tier 3 : Frénésie (click power +1% par click dans les 10 dernières sec, cap +50%) — 15 ADN - Tier 3 alt (exclusif) : Concentration (+200% click, -25% idle) — 15 ADN - Capstone : **Ponte Automatique** — auto-click 1/sec, scale avec upgrades ponte — 200 ADN - Post-capstone (repeatable) : +5% auto-click speed, coût ×2 — départ 500 ADN **Branche Marais (production) — 8-10 nœuds :** - Tier 1 : Instinct Grégaire (+50% production tous générateurs) — 3 ADN - Tier 2 : Spécialisation (un générateur au choix ×3) — 8 ADN - Tier 3 : Écosystème (+10% prod par type de générateur possédé) — 25 ADN - Tier 3 alt (exclusif) : Monoculture (un seul type ×5, les autres ×0.5) — 25 ADN - Capstone : **Symbiose Totale** — chaque générateur booste les autres (+2% par type possédé) — 300 ADN - Post-capstone (repeatable) : +1% symbiose, coût ×2 — départ 600 ADN **Branche Adaptation (utility) — 8-10 nœuds :** - Tier 1 : Mémoire Génétique (commence chaque run avec 100 têtards) — 2 ADN - Tier 2 : Métabolisme Rapide (+25% offline cap) — 10 ADN - Tier 3 : Héritage (conserve 5% des générateurs tier 1 entre prestiges) — 30 ADN - Tier 3 alt (exclusif) : Mutation ADN (+25% ADN gagné au prestige) — 30 ADN - Capstone : **Mémoire du Marais** — offline cap 25% → 75%, durée 2h → 8h — 250 ADN - Post-capstone (repeatable) : +2% offline cap (au-delà de 75%), coût ×2 — départ 500 ADN **Nœud cross-branche — Convergence (évolutif, décision session 2026-03-28) :** Un seul nœud qui évolue quand le joueur atteint de nouveaux paliers de diversification. Pattern `tier` sur le nœud — fondation pour d'autres nœuds évolutifs futurs. ``` Convergence Alpha (tier 1) Condition : 1 capstone + tier 3 d'une 2e branche (~prestige 12-15) Coût : 500 ADN Effet : +10% à tous les effets de l'arbre Convergence Omega (tier 2 — même nœud, upgrade auto) Condition : 2 capstones atteintes Coût : 500 ADN supplémentaires (total investi : 1000) Effet : +10% tous effets + -20% coût post-capstones ``` Technique — champ `tier` sur `EvolutionNode` : ```ts tier?: number; // 1 = Alpha, 2 = Omega (current level) maxTier?: number; // 2 tierUpgradeCost?: number; // 500 tierUpgradeCondition?: string; // "2_capstones" ``` UX : notification "Convergence a évolué !" quand la condition tier 2 est remplie. Le joueur voit sa récompense grandir — pas un 2e nœud à acheter séparément. **Technique :** - `DEFAULT_EVOLUTION_TREE` : ~30 nœuds (tree data structure, pas array) - Ajouter `tier: number` et `repeatable: boolean` aux `EvolutionNode` - `repeatableCount: number` dans le state pour les nœuds post-capstone - UI : garder le layout 3 colonnes, ajouter scroll vertical par branche - Capstones visuellement distincts (bordure dorée, icône spéciale) - Cross-branche : section basse, verrouillée visuellement jusqu'aux conditions - Convergence : badge évolutif (Alpha → Omega), indicateur de progression vers le prochain tier **Reset arbre — 1 gratuit par prestige (décision session 2026-03-28) :** Chaque prestige offre 1 reset gratuit (nouvelle génération = nouvelle chance de build). Resets supplémentaires dans la même génération = payants. ``` freeResetAvailable: boolean // true après chaque prestige, false après usage resetCostInGeneration: number = 5 × extraResetsUsed // linéaire, pas exponentiel ``` | Reset# (dans la même génération) | Coût ADN | |----------------------------------|----------| | 1er | Gratuit (offert par prestige) | | 2e | 5 | | 3e | 10 | | 4e | 15 | Pas punitif, encourage l'expérimentation, mais décourage le spam. **Fondation build-sharing (Sprint 4+ vision) :** Le build de l'arbre est exportable en string compacte (nœuds unlocked encodés). Permet le partage de builds entre joueurs et les "runs prestige" communautaires. → Structurer l'arbre state pour faciliter l'export dès Sprint 3 : `buildCode: string` = nœuds unlocked encodés base36 ou similaire. **Critère done :** l'arbre affiche ~30 nœuds sur 3 branches + cross-branche, les capstones changent le gameplay de manière perceptible, les post-capstones sont achetables en boucle. --- ### Step 3 — Milestones de Prestige **Scope :** Récompenser la persévérance avec des paliers de prestige qui débloquent cosmétiques exclusifs et bonus légers. **Design :** | Palier | Récompense | Type | |--------|------------|------| | 1 prestige | Badge "Première Génération" + ruban queue | cosmétique | | 3 prestiges | Titre "Gardien Récurrent" | cosmétique | | 5 prestiges | Start avec 1 Nid gratuit | gameplay léger | | 10 prestiges | Skin "Têtard Ancestral" (body prestige) + couronne dorée | cosmétique | | 15 prestiges | +5% offline cap permanent | gameplay léger | | 25 prestiges | Cape d'algues ancestrales + aura prestige | cosmétique | | 50 prestiges | Titre "Légende du Marais" + particules dorées permanentes | cosmétique | | 100 prestiges | Skin "Têtard Primordial" (full set) | cosmétique | - Les bonus gameplay sont **légers** — jamais assez pour casser l'économie - Les cosmétiques prestige-only ne sont pas obtenables autrement (exclusivité = motivation) - Écran milestones accessible depuis le menu prestige (progress bar vers le prochain palier) **Technique :** - `PrestigeMilestone` type : ```ts interface PrestigeMilestone { id: string; threshold: number; // nombre de prestiges requis reward: MilestoneReward; claimed: boolean; } type MilestoneReward = | { type: "cosmetic"; cosmeticId: string } | { type: "bonus"; effect: EffectType; value: number } | { type: "title"; title: string }; ``` - Intégrer avec le système cosmétiques V1 existant — ajouter `source: "prestige_milestone"` aux cosmétiques - UI : `MilestonesPanel.tsx` — liste verticale avec progress bar, claim button, preview reward - Backend : valider les claims (le joueur ne peut pas claim un milestone sans le nombre de prestiges) **Critère done :** atteindre 5 prestiges → notification milestone → claim → Nid gratuit actif + cosmétique dans l'inventaire. --- ## Formules — Rebalancing endless (décisions session 2026-03-28) ### Formule ADN (remplace l'actuelle) Actuelle : `adn = floor(150 × sqrt(lifetime_tadpoles / 1e9))` — s'aplatit trop vite. Nouvelle : ``` adn = max(1, floor(base × log10(tadpoles / threshold) × (1 + bonus))) base = 50 threshold = 1e6 (1M têtards — seuil minimum pour prestige) bonus = min(0.05 × prestigeCount, 3.0) // cap ×4 max à 80 prestiges clamp = minimum 1 ADN si tadpoles >= threshold ``` | Run | Tadpoles | Prestige# | Bonus | ADN gagné | |-----|----------|-----------|-------|-----------| | 1 | 1M (seuil) | 0 | ×1.0 | **1** (clamp) | | 1 | 10M | 0 | ×1.0 | **50** | | 5 | 100M | 4 | ×1.20 | **120** | | 15 | 1B | 14 | ×1.70 | **255** | | 30 | 10B | 29 | ×2.45 | **430** | | 80+ | 100B | 80 | ×4.00 | **800** (cap bonus atteint) | La courbe log scale bien : récompense toujours plus, oblige à aller exponentiellement plus loin. Le cap du bonus évite que l'endgame trivialise l'arbre. ### Courbe coût post-capstones — paliers par tranche Le ×2 brut crée un mur après ~8 achats. Scaling par tranche : ``` Achats 1-5 : cost = base × 1.5^n Achats 6-10 : cost = base × 1.5^5 × 1.8^(n-5) Achats 11+ : cost = base × 1.5^5 × 1.8^5 × 2.0^(n-10) ``` | Achat# | Coût (base 500) | ~Runs nécessaires (400 ADN/run) | |--------|-----------------|--------------------------------| | 1 | 750 | ~2 | | 5 | 3 797 | ~10 | | 10 | 68 890 | ~172 | | 15 | 2.2M | endgame long | Chaque achat reste "quelques sessions" en mid-game, puis ralentit en endgame sans frapper un mur infranchissable. ### Courbe coût nœuds standards Définis manuellement par nœud (1, 3, 5, 8, 10, 15, 25, 30, 200, 250, 300, 500, 1000 ADN). ### Vérification d'équilibre - Premier capstone : entre le 8e et 12e prestige (spécialisation une branche) - Arbre "complet" (hors post-capstone) : ~15-20 prestiges - Post-capstones : progression infinie, chaque achat = investissement plus lourd mais gain marginal - Cross-branche : joueur dédié à 25+ prestiges **Niveau de confiance : moyen** — les chiffres sont calibrés sur les formules mais devront être playtestés. Toutes les constantes centralisées dans `balance.ts` pour ajustement rapide. --- ## Résumé séquentiel ``` Migration saves → Step 1 (prestige experience) → Step 2 (arbre V2 endless) → Step 3 (milestones) ``` Step 1 = le moment. Step 2 = la profondeur. Step 3 = la motivation long terme. --- ## Risques identifiés | Risque | Mitigation | Statut | |--------|------------|--------| | Formule ADN mal calibrée | Constantes dans `balance.ts`. Clamp min 1 + cap bonus ×4. Playtest après Step 1 | ✅ adressé | | Capstones trop puissants (Ponte Auto trivialise) | Tester chaque capstone isolément. Auto-click = 1/sec de base | à tester | | Post-capstone wall en late-game | Scaling par tranche (×1.5/×1.8/×2.0) au lieu de ×2 brut | ✅ adressé | | Migration saves casse les joueurs existants | Pattern `saveVersion` + `migrateSave()` lazy. Saves Sprint 2 = v1, migrées automatiquement | ✅ adressé | | Reset arbre frustrant | 1 gratuit par prestige + linéaire au-delà. Pas d'exponentiel | ✅ adressé | | Arbre V2 complexe visuellement | Progressive disclosure : griser les nœuds non débloquables, tooltip clair | à tester | | Build-sharing string : encodage fragile | Valider le décodage côté client. Nœud inconnu dans le code = ignoré (forward compat) | Sprint 4 |