feat: systeme tiers PNJ 0-3 + equipment by role + archetype factory

migration_003: tier/archetype_key, boss exclus sim, equipement distinctif
equipment_by_role.json: loadouts par role (armes/armure/consommables)
archetypes.json: 11 archetypes tier3 + lieutenant tier2
pnj_factory.py: spawn_from_archetype, equip_character, spawn_batch
character_creator.py: nouveaux roles + tier + archetype_key dans INSERT
init_pnj.py: 10 PNJ tier1 + 8 lieutenants tier2 par faction
db.py: get_characters(min_tier=1) exclut boss, get_all_characters pour seeds
tick.py: seeds tous tiers, survival/actions tier>=1 seulement

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Corback
2026-06-16 01:04:01 +02:00
parent c422d62f10
commit 873106d5cb
8 changed files with 895 additions and 44 deletions
+159
View File
@@ -0,0 +1,159 @@
{
"_comment": "Bibliothèque d'archétypes PNJ. Le LLM pioche ici pour instancier un PNJ de passage (tier 3) ou nommé (tier 2). Chaque archétype définit le template — le LLM choisit le nom, la faction et la localisation.",
"garde_faction": {
"role": "garde",
"origin": "survivant",
"tier": 3,
"description": "Garde d'une faction, posté à un point stratégique",
"faction_pool": ["union", "cda", "syndicat_capitole", "regie", "dynaste_oak"],
"location_hints": ["zone contrôlée par la faction d'appartenance"],
"caps_range": [50, 250],
"personality_traits": ["loyal", "méfiant envers étrangers", "obéit aux ordres"],
"motivations": ["protéger son territoire", "nourrir sa famille", "progresser dans la hiérarchie"],
"equipment_role": "garde"
},
"vendeur_ambulant": {
"role": "marchand",
"origin": "survivant",
"tier": 3,
"description": "Marchand itinérant qui circule entre les zones sûres",
"faction_pool": [null, "consortium", "regie"],
"location_hints": ["laplace", "nola_vieux_carre", "independance", "baton_rouge"],
"caps_range": [300, 1500],
"personality_traits": ["opportuniste", "bavard", "prudent", "connait les routes"],
"motivations": ["faire du profit", "survivre", "collecter des informations"],
"equipment_role": "marchand"
},
"habitant_nola": {
"role": "survivant_generique",
"origin": "survivant",
"tier": 3,
"description": "Habitant ordinaire du Vieux Carré ou d'Indépendance",
"faction_pool": [null, "union", "regie"],
"location_hints": ["nola_vieux_carre", "independance"],
"caps_range": [10, 100],
"personality_traits": ["peureux", "curieux", "communautaire", "se méfie des armés"],
"motivations": ["rester en vie", "protéger sa famille", "trouver de l'eau propre"],
"equipment_role": "survivant_generique"
},
"pillard_errant": {
"role": "pillard",
"origin": "survivant",
"tier": 3,
"description": "Pillard solitaire ou en petite bande, sans base fixe",
"faction_pool": ["ecumeurs", null],
"location_hints": ["nola_cbd", "pearl_river", "donaldsonville"],
"caps_range": [0, 150],
"personality_traits": ["impulsif", "violent", "opportuniste", "craintif devant la force"],
"motivations": ["piller", "manger", "dominer les faibles"],
"equipment_role": "pillard"
},
"passeur_bayou": {
"role": "passeur",
"origin": "survivant",
"tier": 3,
"description": "Guide qui connaît les routes secrètes à travers les bayous",
"faction_pool": [null, "ecumeurs"],
"location_hints": ["pearl_river", "donaldsonville", "oak_plantation"],
"caps_range": [100, 600],
"personality_traits": ["taciturne", "fiable si payé", "indépendant", "survivaliste"],
"motivations": ["caps", "indépendance totale", "connaître les secrets des factions"],
"equipment_role": "passeur"
},
"chasseur_primes": {
"role": "chasseur_primes",
"origin": "survivant",
"tier": 3,
"description": "Mercenaire qui traite les contrats d'élimination ou de capture",
"faction_pool": [null, "syndicat_capitole"],
"location_hints": ["baton_rouge", "laplace", "nola_fleuve"],
"caps_range": [200, 800],
"personality_traits": ["professionnel", "froid", "pragmatique", "loyauté achetable"],
"motivations": ["les caps", "la réputation", "accomplir le contrat"],
"equipment_role": "chasseur_primes"
},
"scavenger_freelance": {
"role": "scavenger",
"origin": "survivant",
"tier": 3,
"description": "Récupérateur de ferraille et de technologie pré-guerre",
"faction_pool": [null],
"location_hints": ["nola_cbd", "donaldsonville", "pearl_river"],
"caps_range": [20, 200],
"personality_traits": ["curieux", "bricoleur", "avare", "évite les conflits"],
"motivations": ["trouver des pièces rares", "vendre au Consortium", "survivre"],
"equipment_role": "scavenger"
},
"medecin_freelance": {
"role": "docteur",
"origin": "habitant_abri",
"tier": 3,
"description": "Médecin indépendant qui soigne sans question contre paiement",
"faction_pool": [null, "union", "consortium"],
"location_hints": ["laplace", "independance", "nola_vieux_carre"],
"caps_range": [200, 1000],
"personality_traits": ["neutre politiquement", "humaniste", "épuisé", "précieux"],
"motivations": ["soigner", "survivre", "garder la neutralité"],
"equipment_role": "docteur"
},
"messager_faction": {
"role": "passeur",
"origin": "survivant",
"tier": 3,
"description": "Courrier entre factions, transporte messages et petits colis",
"faction_pool": ["union", "consortium", "regie", "syndicat_capitole"],
"location_hints": ["toutes zones sûres"],
"caps_range": [50, 300],
"personality_traits": ["discret", "rapide", "mémorise sans noter", "refuse de lire les messages"],
"motivations": ["caps par livraison", "rester neutre", "éviter d'être intercepté"],
"equipment_role": "passeur"
},
"fugitif": {
"role": "survivant_generique",
"origin": "survivant",
"tier": 3,
"description": "Quelqu'un qui fuit une faction — esclave évadé, déserteur, criminel",
"faction_pool": [null],
"location_hints": ["pearl_river", "nola_cbd", "donaldsonville"],
"caps_range": [0, 50],
"personality_traits": ["terrorisé", "méfiant extrême", "désespéré", "potentiellement dangereux"],
"motivations": ["ne pas être retrouvé", "atteindre une zone sûre", "survivre une journée de plus"],
"equipment_role": "survivant_generique"
},
"technicien_freelance": {
"role": "technicien",
"origin": "initie_confrerie",
"tier": 3,
"description": "Ingénieur indépendant qui répare armes, générateurs et pip-boys",
"faction_pool": [null, "consortium"],
"location_hints": ["laplace", "independance", "baton_rouge"],
"caps_range": [100, 500],
"personality_traits": ["concentré", "peu bavard", "obsédé par les machines", "honnête sur les prix"],
"motivations": ["réparer des choses", "collecter des composants rares", "fuir le conflit"],
"equipment_role": "technicien"
},
"lieutenant_faction": {
"role": "lieutenant",
"origin": "survivant",
"tier": 2,
"description": "Officier de rang intermédiaire, bras droit opérationnel d'un chef",
"faction_pool": ["union", "cda", "syndicat_capitole", "regie", "dynaste_oak", "ecumeurs", "consortium", "grand_krewe"],
"location_hints": ["QG ou zone clé de la faction"],
"caps_range": [200, 800],
"personality_traits": ["ambitieux", "dévoué à la faction", "respecté des gardes", "jaloux du boss"],
"motivations": ["monter en grade", "protéger la faction", "accumuler des ressources personnelles"],
"equipment_role": "lieutenant"
}
}
+248
View File
@@ -0,0 +1,248 @@
{
"_comment": "Loadouts d'équipement par rôle. Chaque entrée = un item inventory complet.",
"garde": {
"_desc": "Milicien faction — armé, léger blindage",
"weapons": [
{"item_slug": "pistolet_10mm", "item_name": "Pistolet 10mm", "item_type": "weapon_ranged",
"quantity": 1, "weight": 1.5, "damage_dice": 2, "damage_type": "physical",
"damage_range": "medium", "is_equipped": true}
],
"armor": [
{"item_slug": "veste_blindee", "item_name": "Veste blindée", "item_type": "armor",
"quantity": 1, "weight": 3.0, "armor_rating": 1, "is_equipped": true}
],
"consumables": [
{"item_slug": "stimpak", "item_name": "Stimpak", "item_type": "drug", "quantity": 1, "hp_heal": 4},
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 3, "hp_heal": 2},
{"item_slug": "eau_purifiee", "item_name": "Eau purifiée", "item_type": "drink", "quantity": 2}
]
},
"marchand": {
"_desc": "Commerçant — défense minimale, stock commercial",
"weapons": [
{"item_slug": "pistolet_10mm", "item_name": "Pistolet 10mm", "item_type": "weapon_ranged",
"quantity": 1, "weight": 1.5, "damage_dice": 2, "damage_type": "physical",
"damage_range": "medium", "is_equipped": false}
],
"armor": [],
"consumables": [
{"item_slug": "stimpak", "item_name": "Stimpak", "item_type": "drug", "quantity": 2, "hp_heal": 4},
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 5, "hp_heal": 2},
{"item_slug": "eau_purifiee", "item_name": "Eau purifiée", "item_type": "drink", "quantity": 3}
],
"stock": [
{"item_slug": "igname_cuite", "item_name": "Igname cuite", "item_type": "food", "quantity": 6, "hp_heal": 3},
{"item_slug": "outils_reparation","item_name": "Outils de répar.", "item_type": "misc", "quantity": 2},
{"item_slug": "eau_purifiee_vrac","item_name": "Eau purifiée (lot)","item_type": "drink","quantity": 5}
]
},
"eclaireur": {
"_desc": "Rôdeur marais — longue portée, discret, autonome",
"weapons": [
{"item_slug": "fusil_chasse", "item_name": "Fusil de chasse", "item_type": "weapon_ranged",
"quantity": 1, "weight": 3.0, "damage_dice": 3, "damage_type": "physical",
"damage_range": "medium", "is_equipped": true},
{"item_slug": "couteau_survie", "item_name": "Couteau de survie", "item_type": "weapon_melee",
"quantity": 1, "weight": 0.3, "damage_dice": 1, "damage_type": "physical",
"damage_range": "short", "is_equipped": false}
],
"armor": [
{"item_slug": "combinaison_renforcee", "item_name": "Combinaison renforcée", "item_type": "armor",
"quantity": 1, "weight": 2.0, "armor_rating": 1,
"properties": {"stealth_bonus": 1}, "is_equipped": true}
],
"consumables": [
{"item_slug": "stimpak", "item_name": "Stimpak", "item_type": "drug", "quantity": 2, "hp_heal": 4},
{"item_slug": "antidote", "item_name": "Antidote", "item_type": "drug", "quantity": 1},
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 4, "hp_heal": 2},
{"item_slug": "eau_sale", "item_name": "Eau sale", "item_type": "drink", "quantity": 2,
"properties": {"irradiated": true, "rad_on_drink": 1}}
]
},
"docteur": {
"_desc": "Médecin terrain — trousse complète, défense minimale",
"weapons": [
{"item_slug": "pistolet_10mm", "item_name": "Pistolet 10mm", "item_type": "weapon_ranged",
"quantity": 1, "weight": 1.5, "damage_dice": 2, "damage_type": "physical",
"damage_range": "medium", "is_equipped": false}
],
"armor": [],
"consumables": [
{"item_slug": "stimpak", "item_name": "Stimpak", "item_type": "drug", "quantity": 5, "hp_heal": 4},
{"item_slug": "radaway", "item_name": "RadAway", "item_type": "drug", "quantity": 2, "rad_heal": 3},
{"item_slug": "trousse_soin", "item_name": "Trousse de soin","item_type":"misc", "quantity": 2},
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 3, "hp_heal": 2},
{"item_slug": "eau_purifiee", "item_name": "Eau purifiée", "item_type": "drink", "quantity": 3}
]
},
"technicien": {
"_desc": "Ingénieur — arme énergie, outils de réparation",
"weapons": [
{"item_slug": "pistolet_laser", "item_name": "Pistolet laser", "item_type": "weapon_energy",
"quantity": 1, "weight": 1.0, "damage_dice": 2, "damage_type": "energy",
"damage_range": "medium", "is_equipped": true}
],
"armor": [],
"consumables": [
{"item_slug": "stimpak", "item_name": "Stimpak", "item_type": "drug", "quantity": 2, "hp_heal": 4},
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 3, "hp_heal": 2},
{"item_slug": "eau_sale", "item_name": "Eau sale", "item_type": "drink", "quantity": 2,
"properties": {"irradiated": true, "rad_on_drink": 1}},
{"item_slug": "outils_reparation","item_name": "Outils de répar.","item_type": "misc", "quantity": 1},
{"item_slug": "composants_elec", "item_name": "Composants élec.", "item_type": "misc", "quantity": 5}
]
},
"pillard": {
"_desc": "Pillard — violence rapide, armure bricole",
"weapons": [
{"item_slug": "batte_cloutee", "item_name": "Batte cloutée", "item_type": "weapon_melee",
"quantity": 1, "weight": 1.5, "damage_dice": 2, "damage_bonus": 1, "damage_type": "physical",
"damage_range": "short", "properties": {"brutal": true}, "is_equipped": true},
{"item_slug": "couteau_combat", "item_name": "Couteau de combat", "item_type": "weapon_melee",
"quantity": 1, "weight": 0.5, "damage_dice": 1, "damage_type": "physical",
"damage_range": "short", "is_equipped": false}
],
"armor": [
{"item_slug": "armure_planches", "item_name": "Armure de planches", "item_type": "armor",
"quantity": 1, "weight": 4.0, "armor_rating": 1,
"properties": {"homemade": true}, "is_equipped": true}
],
"consumables": [
{"item_slug": "jet", "item_name": "Jet", "item_type": "drug", "quantity": 1,
"properties": {"speed_bonus": 1, "addictive": true}},
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 2, "hp_heal": 2},
{"item_slug": "eau_sale", "item_name": "Eau sale", "item_type": "drink", "quantity": 1,
"properties": {"irradiated": true, "rad_on_drink": 1}}
]
},
"survivant_generique": {
"_desc": "Habitant lambda — outil basique, survie quotidienne",
"weapons": [
{"item_slug": "baton", "item_name": "Bâton", "item_type": "weapon_melee",
"quantity": 1, "weight": 1.0, "damage_dice": 1, "damage_type": "physical",
"damage_range": "short", "is_equipped": true}
],
"armor": [],
"consumables": [
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 2, "hp_heal": 2},
{"item_slug": "eau_sale", "item_name": "Eau sale", "item_type": "drink", "quantity": 2,
"properties": {"irradiated": true, "rad_on_drink": 1}}
]
},
"raider_boss": {
"_desc": "Chef de bande — armé lourd, butin accumulé",
"weapons": [
{"item_slug": "fusil_chasse", "item_name": "Fusil de chasse", "item_type": "weapon_ranged",
"quantity": 1, "weight": 3.0, "damage_dice": 3, "damage_type": "physical",
"damage_range": "medium", "is_equipped": true},
{"item_slug": "batte_cloutee", "item_name": "Batte cloutée", "item_type": "weapon_melee",
"quantity": 1, "weight": 1.5, "damage_dice": 2, "damage_bonus": 1, "damage_type": "physical",
"damage_range": "short", "properties": {"brutal": true}, "is_equipped": false}
],
"armor": [
{"item_slug": "cuir_renforce", "item_name": "Cuir renforcé", "item_type": "armor",
"quantity": 1, "weight": 4.5, "armor_rating": 2, "is_equipped": true}
],
"consumables": [
{"item_slug": "stimpak", "item_name": "Stimpak", "item_type": "drug", "quantity": 2, "hp_heal": 4},
{"item_slug": "jet", "item_name": "Jet", "item_type": "drug", "quantity": 2,
"properties": {"speed_bonus": 1, "addictive": true}},
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 3, "hp_heal": 2},
{"item_slug": "eau_sale", "item_name": "Eau sale", "item_type": "drink", "quantity": 2,
"properties": {"irradiated": true, "rad_on_drink": 1}}
]
},
"lieutenant": {
"_desc": "Bras droit de faction — mieux équipé qu'un garde",
"weapons": [
{"item_slug": "fusil_chasse", "item_name": "Fusil de chasse", "item_type": "weapon_ranged",
"quantity": 1, "weight": 3.0, "damage_dice": 3, "damage_type": "physical",
"damage_range": "medium", "is_equipped": true},
{"item_slug": "pistolet_10mm", "item_name": "Pistolet 10mm", "item_type": "weapon_ranged",
"quantity": 1, "weight": 1.5, "damage_dice": 2, "damage_type": "physical",
"damage_range": "medium", "is_equipped": false}
],
"armor": [
{"item_slug": "cuir_renforce", "item_name": "Cuir renforcé", "item_type": "armor",
"quantity": 1, "weight": 4.5, "armor_rating": 2, "is_equipped": true}
],
"consumables": [
{"item_slug": "stimpak", "item_name": "Stimpak", "item_type": "drug", "quantity": 2, "hp_heal": 4},
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 3, "hp_heal": 2},
{"item_slug": "eau_purifiee", "item_name": "Eau purifiée", "item_type": "drink", "quantity": 2}
]
},
"chasseur_primes": {
"_desc": "Mercenaire — équipé pour capturer ou tuer",
"weapons": [
{"item_slug": "carabine_308", "item_name": "Carabine .308", "item_type": "weapon_ranged",
"quantity": 1, "weight": 3.5, "damage_dice": 3, "damage_bonus": 1, "damage_type": "physical",
"damage_range": "long", "properties": {"piercing": 1}, "is_equipped": true},
{"item_slug": "couteau_combat", "item_name": "Couteau de combat", "item_type": "weapon_melee",
"quantity": 1, "weight": 0.5, "damage_dice": 2, "damage_type": "physical",
"damage_range": "short", "is_equipped": false}
],
"armor": [
{"item_slug": "cuir_renforce", "item_name": "Cuir renforcé", "item_type": "armor",
"quantity": 1, "weight": 4.5, "armor_rating": 2, "is_equipped": true}
],
"consumables": [
{"item_slug": "stimpak", "item_name": "Stimpak", "item_type": "drug", "quantity": 3, "hp_heal": 4},
{"item_slug": "mentats", "item_name": "Mentats", "item_type": "drug", "quantity": 1,
"properties": {"int_bonus": 2, "per_bonus": 1}},
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 3, "hp_heal": 2},
{"item_slug": "eau_purifiee", "item_name": "Eau purifiée", "item_type": "drink", "quantity": 2}
]
},
"passeur": {
"_desc": "Guide / passeur entre zones — mobile, discret",
"weapons": [
{"item_slug": "couteau_combat", "item_name": "Couteau de combat", "item_type": "weapon_melee",
"quantity": 1, "weight": 0.5, "damage_dice": 2, "damage_type": "physical",
"damage_range": "short", "is_equipped": true}
],
"armor": [],
"consumables": [
{"item_slug": "stimpak", "item_name": "Stimpak", "item_type": "drug", "quantity": 1, "hp_heal": 4},
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 3, "hp_heal": 2},
{"item_slug": "eau_sale", "item_name": "Eau sale", "item_type": "drink", "quantity": 3,
"properties": {"irradiated": true, "rad_on_drink": 1}}
]
},
"scavenger": {
"_desc": "Récupérateur de ferraille — outils, peu d'armes",
"weapons": [
{"item_slug": "baton", "item_name": "Bâton", "item_type": "weapon_melee",
"quantity": 1, "weight": 1.0, "damage_dice": 1, "damage_type": "physical",
"damage_range": "short", "is_equipped": true}
],
"armor": [],
"consumables": [
{"item_slug": "cram", "item_name": "Cram", "item_type": "food", "quantity": 2, "hp_heal": 2},
{"item_slug": "eau_sale", "item_name": "Eau sale", "item_type": "drink","quantity": 2,
"properties": {"irradiated": true, "rad_on_drink": 1}},
{"item_slug": "outils_reparation", "item_name": "Outils de répar.", "item_type": "misc", "quantity": 1},
{"item_slug": "ferraille", "item_name": "Ferraille", "item_type": "misc", "quantity": 5,
"weight": 2.0}
]
},
"chef_faction": {
"_desc": "Chef de faction — équipement narratif unique, hors sim",
"weapons": [],
"armor": [],
"consumables": []
}
}