Files
ClickerZ/docs/SPRINT3.md
Tetardtek ed8cf87d4e
Some checks failed
CI/CD — Build & Deploy / Build & Deploy (push) Failing after 35s
feat: Sprint 3 — Prestige Loop endless
- Migration saves: saveVersion pattern + migrateSave lazy (v1→v2)
- Formule ADN rebalancée: log10 + clamp min 1 + cap bonus ×4
- Prestige Experience: modal fullscreen, preview ADN, stats run, best run
- Arbre V2: 25 nœuds, 3 capstones, post-capstones repeatables (scaling par tranche)
- Convergence évolutif Alpha→Omega (tier system)
- Reset arbre: 1 gratuit/prestige, payant linéaire au-delà
- Milestones prestige: 8 paliers (1→100), cosmétiques exclusifs, bonus gameplay
- balance.ts: constantes centralisées pour playtest
- 136 tests green, 0 regression
2026-03-28 18:24:24 +01:00

316 lines
13 KiB
Markdown
Raw 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.
# 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 |