- game_saves table + migration 002 (JSON state, anti-cheat metadata) - saveControllers.js : load/save avec validation delta ressources (750k/s × 1.1) - GameSaveManager : upsert MySQL ON DUPLICATE KEY UPDATE - useSaveSync hook : auto-save 30s + keepalive beforeunload + guest fallback - save-validation.test.ts : 8 tests anti-cheat - economy.ts : arbre d'évolution 5 nœuds + prestige ADN (rattrapage step 2) - economy.test.ts : +40 tests (évolution tree, multipliers, start bonus) - GDD + SPRINT1.md : docs sprint complètes - Rethème data : shop.json, Achievements.json, Cookie, Legal (rattrapage step 1)
168 lines
6.6 KiB
Markdown
168 lines
6.6 KiB
Markdown
# SPRINT1.md — Fondations Tetard Universe
|
||
|
||
> Brief technique — Sprint 1
|
||
> Date : 2026-03-20
|
||
> Réf GDD : docs/GDD.md
|
||
> Agents : game-designer (design) → build (implémentation)
|
||
|
||
---
|
||
|
||
## Objectif
|
||
|
||
Transformer le prototype Xmass Clicker en Clickerz Tetard Universe avec :
|
||
- Rethème complet (noms, visuels, textes)
|
||
- Arbre d'Évolution (permanent, jamais reset)
|
||
- Save serveur (anti-triche, fin du localStorage)
|
||
- SuperOAuth login
|
||
- Core loop jouable de bout en bout : Ponte → Générateurs → Prestige → Arbre → Nouvelle run
|
||
|
||
---
|
||
|
||
## Existant à conserver
|
||
|
||
| Composant | Fichier | État |
|
||
|-----------|---------|------|
|
||
| Core economy | `Frontend/src/core/economy.ts` | ✅ Solide — lazy calc, 5 generators, prestige |
|
||
| Tests economy | `Frontend/src/__tests__/economy.test.ts` | ✅ 13 tests |
|
||
| Backend auth | `Backend/src/controllers/authControllers.js` | ✅ JWT + SuperOAuth ID |
|
||
| DB schema | `Backend/database/schema.sql` | ✅ users + super_oauth_id |
|
||
| Prestige UI | Commit 9f0ccda | ✅ PrestigePanel + MilestoneBar |
|
||
|
||
---
|
||
|
||
## Steps
|
||
|
||
### Step 1 — Rethème Tetard Universe
|
||
|
||
**Scope :** Renommage complet, zéro changement mécanique.
|
||
|
||
- [ ] `economy.ts` : renommer generators (Manic → Nid, Tasse à café → Mare, Sucre → Marécage, Usine → Étang Ancien, Portail → Lac Mystique)
|
||
- [ ] `shop.json` : réécrire avec noms/descriptions Tetard Universe (ou supprimer si redondant avec economy.ts)
|
||
- [ ] `Achievements.json` : adapter les textes au thème marais
|
||
- [ ] UI : remplacer "cookies" / "Xmass" par "têtards" / "Clickerz" partout
|
||
- [ ] Pages : Cookie.jsx (page légale) → adapter mentions "Xmass Clicker" → "Clickerz"
|
||
- [ ] Titre / meta : "Clickerz — Tetard Universe"
|
||
|
||
**Critère done :** aucune référence à "cookie", "Xmass", "Noël" dans le code.
|
||
|
||
---
|
||
|
||
### Step 2 — Arbre d'Évolution
|
||
|
||
**Scope :** Nouveau système permanent, intégré au prestige.
|
||
|
||
- [ ] Nouveau type `EvolutionNode` dans economy.ts :
|
||
```ts
|
||
interface EvolutionNode {
|
||
id: string;
|
||
name: string;
|
||
cost: number; // en ADN Ancestral
|
||
effect: EffectType; // multiplicateur, flat bonus, unlock
|
||
value: number;
|
||
unlocked: boolean;
|
||
requires?: string; // id du nœud prérequis (linéaire Sprint 1)
|
||
}
|
||
```
|
||
- [ ] Étendre `GameState` : ajouter `ancestralDna: number`, `evolutionTree: EvolutionNode[]`
|
||
- [ ] Modifier `applyPrestige()` : calculer ADN gagné via `floor(150 × sqrt(lifetime / 1e9))`, ajouter à `ancestralDna`
|
||
- [ ] 5 nœuds linéaires (GDD : Ponte Améliorée → Instinct Grégaire → Mémoire Génétique → Mutation Alpha → Symbiose)
|
||
- [ ] `buyEvolutionNode(state, nodeId)` : acheter si ADN suffisant + prérequis débloqué
|
||
- [ ] Appliquer les effets dans `totalProductionPerSecond()` et `applyClick()`
|
||
- [ ] UI : `EvolutionTree.tsx` — panel visible après premier prestige
|
||
- [ ] Tests : couvrir achat nœud, prérequis, effets sur production
|
||
|
||
**Critère done :** un joueur peut prestige, gagner de l'ADN, acheter des nœuds, et constater l'effet sur sa prochaine run.
|
||
|
||
---
|
||
|
||
### Step 3 — Save serveur + anti-triche
|
||
|
||
**Scope :** Migrer la persistence de localStorage vers API backend.
|
||
|
||
- [ ] Backend : nouvelle table `game_saves`
|
||
```sql
|
||
CREATE TABLE game_saves (
|
||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||
user_id INT NOT NULL UNIQUE,
|
||
game_state JSON NOT NULL,
|
||
last_save TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
lifetime_tadpoles BIGINT DEFAULT 0,
|
||
prestige_count INT DEFAULT 0,
|
||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||
);
|
||
```
|
||
- [ ] Backend routes : `POST /api/save` (write), `GET /api/save` (load) — JWT required
|
||
- [ ] Validation snapshot sur `POST /api/save` :
|
||
- Vérifier `elapsed_time × max_possible_production × 1.1 >= claimed_resources`
|
||
- Si invalide → rejeter le save, logger l'anomalie
|
||
- [ ] Frontend : `useSaveSync` hook — auto-save toutes les 30s via API
|
||
- [ ] Frontend : load state depuis API au login (pas de localStorage game data)
|
||
- [ ] Supprimer la persistence localStorage pour les données de jeu
|
||
|
||
**Critère done :** fermer l'onglet, rouvrir, login → retrouver exactement son état. F12 → modifier localStorage → aucun impact sur la save serveur.
|
||
|
||
---
|
||
|
||
### Step 4 — SuperOAuth login
|
||
|
||
**Scope :** Câbler le login via SuperOAuth existant.
|
||
|
||
- [ ] Vérifier le flow SuperOAuth backend (verifyOAuth.js existe)
|
||
- [ ] Frontend : page Login avec bouton "Se connecter avec SuperOAuth"
|
||
- [ ] Redirect vers SuperOAuth → callback → JWT → session
|
||
- [ ] Protéger les routes /api/save derrière JWT
|
||
- [ ] Fallback : mode "invité" sans save serveur (localStorage temporaire) — optionnel
|
||
|
||
**Critère done :** login SuperOAuth → jeu avec save serveur. Pas de register custom (SuperOAuth gère).
|
||
|
||
---
|
||
|
||
### Step 5 — Migration SCSS → Tailwind + Zustand
|
||
|
||
**Scope :** Moderniser le frontend pour la suite.
|
||
|
||
- [ ] Installer Tailwind CSS + config Vite
|
||
- [ ] Migrer les composants clés (game view, shop, prestige panel) vers Tailwind
|
||
- [ ] Installer Zustand, créer `useGameStore` — remplacer le state lifting actuel
|
||
- [ ] Intégrer le game loop tick dans Zustand (requestAnimationFrame ou setInterval 1s)
|
||
- [ ] Supprimer les fichiers SCSS migrés
|
||
|
||
**Critère done :** game loop tourne via Zustand, UI en Tailwind, SCSS supprimé sur les composants migrés.
|
||
|
||
---
|
||
|
||
### Step 6 — Polish & deploy
|
||
|
||
**Scope :** Rendre jouable et déployer.
|
||
|
||
- [ ] UI : écran d'accueil Clickerz (logo, "Entrer dans le Marais")
|
||
- [ ] UI : feedback visuel Ponte (animation click)
|
||
- [ ] UI : affichage formaté des grands nombres (1M, 1B, 1T...)
|
||
- [ ] UI : responsive basique (jouable desktop, pas cassé mobile)
|
||
- [ ] Deploy : clickerz.tetardtek.com (Apache vhost + pm2 backend)
|
||
- [ ] Tests e2e : flow complet login → jeu → prestige → arbre → save → reload
|
||
|
||
**Critère done :** un joueur peut aller sur clickerz.tetardtek.com, login SuperOAuth, jouer, prestige, acheter dans l'arbre, fermer, revenir, retrouver sa progression.
|
||
|
||
---
|
||
|
||
## Résumé séquentiel
|
||
|
||
```
|
||
Step 1 (rethème) → Step 2 (arbre évolution) → Step 3 (save serveur)
|
||
→ Step 4 (SuperOAuth) → Step 5 (Tailwind+Zustand) → Step 6 (polish+deploy)
|
||
```
|
||
|
||
Steps 1-2 = game design. Steps 3-4 = infra/auth. Step 5 = DX. Step 6 = ship.
|
||
|
||
---
|
||
|
||
## Risques identifiés
|
||
|
||
| Risque | Mitigation |
|
||
|--------|------------|
|
||
| Équilibrage ADN trop généreux/avare | Playtest après step 2, ajuster la formule |
|
||
| SuperOAuth SDK pas à jour | verifyOAuth.js existe déjà — vérifier compat |
|
||
| Migration SCSS → Tailwind longue | Migrer uniquement les composants touchés, pas tout |
|
||
| Validation anti-triche trop stricte (faux positifs) | Marge ×1.1, logs avant rejet, soft-block d'abord |
|