Files
TetaRdPG/SPRINT3.md

7.3 KiB
Raw Blame History

TetaRdPG — Brief Sprint 3

Statut : 🔄 En cours Objectif : Items + Inventaire + Artisanat (Craft) + Forge Stack : NestJS · PostgreSQL · TypeORM (synchronize dev) Prérequis : Sprint 2 livré


Scope Sprint 3

In scope

  • Entité items (armes + armures) avec bonus stats
  • Inventaire joueur (character_items) — possession + équipement actif
  • Intégration combat : player.attack et player.defense depuis l'équipement équipé
  • Entité materials + inventaire joueur (character_materials) — loot post-combat
  • Entité recipes + ingrédients en jsonb
  • Artisanat (craft_jobs) — lazy calc timer (même pattern que endurance)
  • Forge — amélioration item niveau 15 avec risque croissant
  • Seeds : 5 items de base, 5 matériaux, 3 recettes
  • API : voir section dédiée

Out of scope

  • Boutique (achat/vente) — Sprint 4
  • Bonus de sets d'équipement — Sprint 4
  • TetardCoin (accélération craft, forge garantie) — sprint monétisation
  • Twitch, PvP, guildes
  • Frontend React

Décisions de design (game-designer)

Décision Valeur Justification
Slots équipement weapon + armor Simplifié Sprint 3 — casque/bottes Sprint 4
Player.attack en combat char.weapon?.attackBonus ?? 0 Remplace attack=0 Sprint 2
Player.defense en combat char.armor?.defenseBonus ?? 0 Remplace defense=0 Sprint 2
Loot drop 40% de chance après victoire 1 matériau aléatoire parmi ceux du monstre
Craft timer lazy calc : startedAt + durationMs Même pattern endurance — zéro job schedulé
Forge risque Niv.12 : 0% 3 : 20%
Forge succès garanti 12 TetardCoin (non implémenté Sprint 3) Placeholder, champ forcedSuccess
Forge échec item inchangé, pas de coût matériaux Sprint 3 coût matériaux forge = Sprint 4
Durée craft court: 15s (dev) / long: 60s (dev) Valeurs réelles en prod : 15min2h

Schéma DB

items

id uuid PK
name varchar(100)
description text
type varchar(20)        -- 'weapon' | 'armor'
rarity varchar(20)      -- 'common' | 'rare' | 'epic' | 'legendary'
attack_bonus int default 0
defense_bonus int default 0
force_bonus int default 0
agilite_bonus int default 0
intelligence_bonus int default 0
chance_bonus int default 0
vitalite_bonus int default 0

character_items

id uuid PK
character_id uuid FK characters
item_id uuid FK items
forge_level int default 0    -- 0 = non forgé
equipped boolean default false
acquired_at timestamp

materials

id uuid PK
name varchar(100)
description text
rarity varchar(20)

character_materials

id uuid PK
character_id uuid FK characters
material_id uuid FK materials
quantity int default 0

recipes

id uuid PK
name varchar(100)
result_item_id uuid FK items
craft_duration_seconds int
endurance_cost int
ingredients jsonb  -- [{ materialId, quantity }]

craft_jobs

id uuid PK
character_id uuid FK characters
recipe_id uuid FK recipes
started_at timestamp
completed_at timestamp   -- lazy : startedAt + duration
collected boolean default false

Seeds

Items (5)

Nom Type Rareté Attack Defense Notes
Bâton de Roseau weapon common 3 0 Arme de départ
Dague Rouillée weapon common 5 0
Épée Courte weapon rare 9 0
Gilet de Cuir armor common 0 3
Cotte de Mailles armor rare 0 7

Matériaux (5)

Nom Rareté Sources
Bave de Têtard common Têtard Vase
Écailles de Grenouille common Grenouille Boueuse
Venin de Serpent rare Serpent des Marais
Spores Vénéneuses rare Champi Vénéneux
Fragment de Boue common Golem de Boue

Recettes (3)

Nom Résultat Durée (dev) Endurance Ingrédients
Forge Bâton Renforcé Bâton de Roseau+? 15s 5 2× Bave de Têtard
Craft Dague Dague Rouillée 15s 8 3× Bave + 1× Écaille
Craft Gilet de Cuir Gilet de Cuir 30s 10 3× Écaille + 2× Fragment

API Sprint 3

# Items
GET  /api/items                     → liste tous les items (catalogue)
GET  /api/items/inventory           → inventaire du personnage connecté
POST /api/items/equip/:itemId       → équiper un item (character_items.id)
POST /api/items/unequip/:slot       → déséquiper un slot (weapon|armor)

# Materials
GET  /api/materials                 → catalogue matériaux
GET  /api/materials/inventory       → matériaux du personnage connecté

# Craft
GET  /api/craft/recipes             → liste recettes
POST /api/craft/start               → { recipeId } → lance le craft
GET  /api/craft/active              → craft en cours (lazy status)
POST /api/craft/collect/:jobId      → collecter si terminé

# Forge
POST /api/forge/upgrade             → { characterItemId } → tente amélioration

Architecture modules

src/
├── item/
│   ├── item.entity.ts
│   ├── character-item.entity.ts
│   ├── item.module.ts
│   ├── item.service.ts
│   └── item.controller.ts
├── material/
│   ├── material.entity.ts
│   ├── character-material.entity.ts
│   ├── material.module.ts
│   ├── material.service.ts
│   └── material.controller.ts
├── craft/
│   ├── recipe.entity.ts
│   ├── craft-job.entity.ts
│   ├── craft.module.ts
│   ├── craft.service.ts
│   └── craft.controller.ts
├── forge/
│   ├── forge.module.ts
│   ├── forge.service.ts
│   └── forge.controller.ts
└── database/
    └── items-seed.ts

Intégration combat (CombatEngine)

// Dans CombatService.startCombat() — charger l'équipement
const weaponBonus = char.equippedWeapon?.item.attackBonus ?? 0;
const armorBonus = char.equippedArmor?.item.defenseBonus ?? 0;

const playerStats: CombatantStats = {
  ...
  attack: weaponBonus,    // était 0 Sprint 2
  defense: armorBonus,    // était 0 Sprint 2
};

Loot post-victoire :

if (result.winner === 'player' && Math.random() < 0.4) {
  // créditer 1 matériau aléatoire dans character_materials
}

Critères de validation integrator

  • GET /api/items → 5 items seedés
  • GET /api/materials → 5 matériaux seedés
  • POST /api/items/equip/:id → item équipé, character mis à jour
  • Combat avec arme équipée → player.attack = weaponBonus
  • Victoire combat → chance de loot matériau (40%)
  • GET /api/materials/inventory → quantité augmentée après loot
  • GET /api/craft/recipes → 3 recettes disponibles
  • POST /api/craft/start → job créé, endurance déduite
  • GET /api/craft/active → status pending | ready | none
  • POST /api/craft/collect/:jobId → item ajouté à l'inventaire
  • Collect avant fin → 400 "not ready yet"
  • POST /api/forge/upgrade → niveau 1 : succès garanti
  • Forge niveau 3 → 20% chance échec (matériaux déduits, forgeLvl inchangé)
  • Sans cookie → 401 sur toutes les routes protégées
  • Endurance insuffisante pour craft → 400