Some checks failed
CI/CD — Build & Deploy / Build & Deploy (push) Failing after 35s
- 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
316 lines
13 KiB
Markdown
316 lines
13 KiB
Markdown
# 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 |
|