feat: Phase 3 Lore & Contenu — L'Odyssée d'un têtard

Lore Bible (canon narratif complet) + Engine Design (séparation moteur/univers).

4 nouvelles zones (Ruisseau Miroir, Marais des Murmures, Torrent Brisé, Source du Courant)
dans la chaîne d'unlock après desert (niv 16-25+).

Module NPC complet (entity, service, controller) — 8 PNJ avec dialogues évolutifs
par palier de niveau : Gorn (niv 1-15), Pierre-Mémoire (niv 16+), Mira, Vell,
La Batracienne, Le Forgeron, Le Marchand.

20 monstres lore-friendly, 12 matériaux, 15 items (dont Bâton de Gorn légendaire).

17 quêtes narratives (4 arcs ch.9-12) avec textes acceptText/completeText
qui racontent l'Odyssée. Nouveau type story_event pour les moments narratifs purs.
3 quêtes répétables optionnelles.

Seed runner : npm run seed:odyssee

Tout est additif — zéro impact sur le contenu existant niv 1-15.
This commit is contained in:
2026-03-25 00:43:26 +01:00
parent 2c94e4f3aa
commit 4beb1b2ed9
16 changed files with 1520 additions and 10 deletions

View File

@@ -3,10 +3,14 @@ import { PlayerQuestArc } from '../quest/player-quest-arc.entity';
import { QuestArc } from '../quest/quest-arc.entity';
// Zone unlock chain: each zone requires completing the previous zone's arc
// marais → always open
// egouts → requires "Les Marais du Têtard" arc completed
// desert → requires the egouts arc completed
const ZONE_ORDER = ['marais', 'egouts', 'desert'];
// marais → always open (L'Étang — niv 1-5)
// egouts → requires "Les Marais du Têtard" arc (L'Étang profond — niv 6-10)
// desert → requires egouts arc (L'Étang Brisé — niv 11-15)
// ruisseau_miroir → requires desert arc (Ruisseau Miroir — niv 16-18)
// marais_murmures → requires ruisseau_miroir arc (Marais des Murmures — niv 19-21)
// torrent_brise → requires marais_murmures arc (Torrent Brisé — niv 22-24)
// source_courant → requires torrent_brise arc (Source du Courant — niv 25+)
const ZONE_ORDER = ['marais', 'egouts', 'desert', 'ruisseau_miroir', 'marais_murmures', 'torrent_brise', 'source_courant'];
export async function getUnlockedZones(
characterId: string,