# TetaRdPG — Brief Sprint 4 > Statut : ⬜ À lancer > Objectif : Succès individuels + Succès communautaires + Hall of Fame + Profil joueur enrichi > Stack : NestJS · MySQL · TypeORM > Prérequis : Sprint 3 livré ✅ (items, forge, craft, economy, twitch) > Source design : `TetaRdPG/Sprint 4 _ Focus Succès & Hall of Fame.docx` + `Annexes/5. Système de succès.docx` --- ## Scope Sprint 4 ### ✅ In scope - Entité `achievements` — catalogue de succès avec critères de déblocage - Entité `player_achievements` — suivi progression par joueur - 5 catégories : Progression, Combat, Zones, Équipements, Économie - Récompenses au déblocage : Or, XP bonus, titres honorifiques - Entité `community_goals` — objectifs collectifs (monstres tués, TetardCoin cumulés) - Barre de progression communautaire - Récompenses communautaires : boosts globaux temporaires (XP/loot) - Hall of Fame mensuel — classement contributeurs + badges - Interface profil enrichi : badges, titres, % progression succès - Seeds : 15 succès individuels + 3 objectifs communautaires - API : voir section dédiée ### ❌ Out of scope - Notifications Twitch temps réel (extension Twitch) — Sprint 5 - GIGABOSS communautaire (événement 72h) — Sprint événements - Marché communautaire (échange joueurs) — Sprint économie avancée - Guildes et alliances — Sprint social - Boutique événementielle — Sprint économie avancée - Frontend React complet --- ## Décisions de design (game-designer) | Décision | Valeur | Justification | |----------|--------|---------------| | Tracking succès | Event-driven : chaque action (combat, craft, forge, level) émet un check | Pas de cron — cohérent avec le pattern lazy du projet | | Catégories succès | 5 : progression, combat, zones, equipment, economy | GDD §5.1 | | Paliers succès | 3 niveaux par succès (bronze/silver/gold) | Engagement long terme | | Récompenses déblocage | Or + titre. Pas d'item pour éviter la complexité inventaire Sprint 4 | Simplification — items récompense = Sprint 5 | | Titres joueur | 1 titre actif à la fois, affiché sur le profil | GDD §4 titres liés aux zones | | Community goals | Reset mensuel, contribution individuelle trackée | GDD §5.2 | | Hall of Fame | Classement mensuel, top 10, badges persistants | GDD §5.3 | | Boost communautaire | Stocké en DB, appliqué comme multiplicateur dans combat/craft | Ex: +20% XP pendant 3j | | Progression communautaire | Compteur global incrémenté à chaque action qualifiante | Pas de WebSocket — poll GET | --- ## Schéma DB ### `achievements` ``` id uuid PK key varchar(50) UNIQUE -- 'combat_100', 'level_50', 'zone_marais_complete' name varchar(100) description text category varchar(20) -- 'progression' | 'combat' | 'zones' | 'equipment' | 'economy' tier varchar(10) -- 'bronze' | 'silver' | 'gold' criteria_type varchar(30) -- 'combat_wins' | 'level_reached' | 'gold_accumulated' | ... criteria_value int -- seuil à atteindre reward_gold int default 0 reward_title varchar(100) NULL -- titre débloqué (nullable) ``` ### `player_achievements` ``` id uuid PK character_id uuid FK characters achievement_id uuid FK achievements progress int default 0 -- compteur courant unlocked boolean default false unlocked_at timestamp NULL ``` ### `community_goals` ``` id uuid PK name varchar(100) description text criteria_type varchar(30) -- 'total_monsters_killed' | 'total_tetardcoin' | ... target_value bigint -- objectif collectif current_value bigint default 0 reward_type varchar(30) -- 'xp_boost' | 'loot_boost' reward_multiplier decimal(3,2) -- ex: 1.20 = +20% reward_duration_hours int -- durée du boost period_start date period_end date completed boolean default false completed_at timestamp NULL ``` ### `community_contributions` ``` id uuid PK community_goal_id uuid FK community_goals character_id uuid FK characters contribution_value bigint default 0 ``` ### `hall_of_fame` ``` id uuid PK character_id uuid FK characters period varchar(7) -- '2026-04' format YYYY-MM rank int contribution_total bigint badge varchar(50) -- 'top1_april_2026' ``` ### `active_boosts` (communautaires) ``` id uuid PK boost_type varchar(30) -- 'xp_boost' | 'loot_boost' multiplier decimal(3,2) expires_at timestamp source_goal_id uuid FK community_goals ``` --- ## Seeds ### Succès individuels (15) | Key | Nom | Catégorie | Tier | Critère | Seuil | Récompense Or | Titre | |-----|-----|-----------|------|---------|-------|---------------|-------| | `combat_10` | Apprenti Guerrier | combat | bronze | combat_wins | 10 | 50 | — | | `combat_100` | Guerrier Aguerri | combat | silver | combat_wins | 100 | 200 | Guerrier Aguerri | | `combat_1000` | Légende du Combat | combat | gold | combat_wins | 1000 | 1000 | Légende | | `level_10` | Aventurier | progression | bronze | level_reached | 10 | 100 | — | | `level_50` | Héros | progression | silver | level_reached | 50 | 500 | Héros | | `level_100` | Légende Vivante | progression | gold | level_reached | 100 | 2000 | Légende Vivante | | `gold_1000` | Marchand | economy | bronze | gold_accumulated | 1000 | 100 | — | | `gold_10000` | Négociant | economy | silver | gold_accumulated | 10000 | 500 | Négociant | | `gold_100000` | Magnat | economy | gold | gold_accumulated | 100000 | 2000 | Magnat | | `forge_5` | Apprenti Forgeron | equipment | bronze | forge_upgrades | 5 | 100 | — | | `forge_25` | Maître Forgeron | equipment | silver | forge_upgrades | 25 | 500 | Maître Forgeron | | `forge_100` | Forgeron Légendaire | equipment | gold | forge_upgrades | 100 | 2000 | Forgeron Légendaire | | `craft_5` | Artisan Novice | equipment | bronze | craft_completed | 5 | 75 | — | | `craft_25` | Artisan Confirmé | equipment | silver | craft_completed | 25 | 300 | Artisan | | `craft_100` | Grand Artisan | equipment | gold | craft_completed | 100 | 1500 | Grand Artisan | ### Objectifs communautaires (3) | Nom | Critère | Cible | Boost | Durée | |-----|---------|-------|-------|-------| | Chasse aux Monstres | total_monsters_killed | 10 000 | +20% XP | 72h | | Trésor Communautaire | total_gold_earned | 1 000 000 | +15% loot | 48h | | Fièvre de la Forge | total_forge_upgrades | 500 | +10% XP | 48h | --- ## API Sprint 4 ``` # Succès individuels GET /api/achievements → catalogue complet des succès GET /api/achievements/me → progression du joueur (avec %) POST /api/achievements/claim/:id → réclamer la récompense d'un succès débloqué # Succès communautaires GET /api/community/goals → objectifs en cours + barre progression GET /api/community/goals/:id/top → top 10 contributeurs d'un objectif GET /api/community/boosts → boosts actifs (multiplicateurs en cours) # Hall of Fame GET /api/halloffame/current → classement du mois en cours GET /api/halloffame/:period → classement historique (ex: 2026-04) # Profil enrichi GET /api/profile/me → stats + titre actif + badges + succès count PUT /api/profile/title → { title: "Héros" } → changer titre actif ``` --- ## Architecture modules ``` src/ ├── achievement/ │ ├── achievement.entity.ts │ ├── player-achievement.entity.ts │ ├── achievement.module.ts │ ├── achievement.service.ts → check + unlock logic │ ├── achievement.controller.ts │ └── achievement.listener.ts → écoute events combat/craft/forge/levelup ├── community/ │ ├── community-goal.entity.ts │ ├── community-contribution.entity.ts │ ├── active-boost.entity.ts │ ├── community.module.ts │ ├── community.service.ts │ └── community.controller.ts ├── halloffame/ │ ├── hall-of-fame.entity.ts │ ├── halloffame.module.ts │ ├── halloffame.service.ts → calcul mensuel + badge attribution │ └── halloffame.controller.ts ├── profile/ │ ├── profile.module.ts │ ├── profile.service.ts │ └── profile.controller.ts └── database/ ├── achievements-seed.ts └── community-goals-seed.ts ``` --- ## Intégration modules existants ### CombatService — émission événements succès ```typescript // Après résolution combat — émettre pour achievement tracker if (result.winner === 'player') { this.eventEmitter.emit('achievement.check', { characterId: character.id, type: 'combat_wins', increment: 1, }); this.eventEmitter.emit('community.contribute', { characterId: character.id, type: 'total_monsters_killed', increment: 1, }); } ``` ### ForgeService / CraftService — même pattern ```typescript // Après forge réussie this.eventEmitter.emit('achievement.check', { characterId, type: 'forge_upgrades', increment: 1, }); this.eventEmitter.emit('community.contribute', { characterId, type: 'total_forge_upgrades', increment: 1, }); ``` ### Boosts actifs — application dans CombatEngine ```typescript // Dans CombatService — vérifier boosts communautaires actifs const xpBoost = await this.communityService.getActiveMultiplier('xp_boost'); rewards.xp = Math.floor(baseXp * xpBoost); // xpBoost = 1.0 si aucun boost ``` --- ## Migration TypeORM ``` Sprint4Achievements — 6 tables : achievements, player_achievements, community_goals, community_contributions, hall_of_fame, active_boosts + ALTER characters ADD active_title VARCHAR(100) NULL + ALTER characters ADD total_gold_earned BIGINT DEFAULT 0 -- tracking cumulé pour succès ``` --- ## Critères de validation integrator - [ ] `GET /api/achievements` → 15 succès seedés, 5 catégories - [ ] `POST /api/combat/start` → victoire → `player_achievements.progress` incrémenté pour `combat_wins` - [ ] 10 victoires → succès `combat_10` débloqué automatiquement - [ ] `GET /api/achievements/me` → progression visible avec % - [ ] `POST /api/achievements/claim/:id` → or crédité, titre disponible - [ ] Claim succès déjà réclamé → 400 - [ ] `PUT /api/profile/title` → titre actif changé - [ ] `GET /api/profile/me` → titre, badges, count succès - [ ] `GET /api/community/goals` → 3 objectifs avec barre progression - [ ] Combat victoire → `community_contributions` incrémentée - [ ] `GET /api/community/goals/:id/top` → top 10 contributeurs - [ ] Objectif communautaire atteint → boost créé dans `active_boosts` - [ ] `GET /api/community/boosts` → multiplicateur actif - [ ] Combat avec boost actif → XP = baseXp × multiplier - [ ] Boost expiré → non retourné par GET - [ ] `GET /api/halloffame/current` → classement mois en cours - [ ] Sans cookie → 401 sur toutes les routes protégées - [ ] Level up → `player_achievements.progress` incrémenté pour `level_reached` - [ ] Forge → incrémente `forge_upgrades` + `total_forge_upgrades` communautaire