Aller au contenu principal

People — comédien·ne·s, équipe technique, intermédiaires

Fiche d'entité. Respecte README.md : DefState, stats 0–100, euros entiers suffixés _eur, Tick = demi-journée, Rated pour tout ce qui peut mentir, aucun champ muté hors événement.

1. Rôle dans le jeu

Les gens sont l'entité la plus riche du modèle, délibérément.

C'est là que vit le mensonge. Une Alexa 35 est une Alexa 35 ; un chef opérateur arrive avec un CV, une démo montée par quelqu'un d'autre et un agent payé pour embellir. La règle perçu vs réel n'a d'intérêt que sur les personnes — donc les personnes portent la quasi-totalité des Rated du jeu, le matériel presque aucun.

C'est là que vit le mécanisme central, « engager pas cher, payer plus tard ». Chaque économie faite au recrutement se rembourse au tournage sous forme de temps : le chef machino à 280 €/j au lieu de 420 €/j monte le travelling en 3 h au lieu de 1 h 30, et 1 h 30 de plateau à 40 personnes coûte plus cher que l'écart de salaire sur tout le film. Le jeu n'est pédagogique que si cette arithmétique est vérifiable a posteriori — d'où PersonState.ledger (§5).

C'est là que vivent les aléas. Une grue ne tombe pas malade et ne se fâche pas avec l'ensemblier. Objectif de design : ~70 % des Event ont une personne pour sujet ou pour cause ; si le graphe de events.md s'en écarte franchement, les personnes sont sous-exploitées. Dans le pipeline du contrat (§7), elles sont l'entrée principale d'Assignment, produisent de la qualité par critère, consomment du temps, et ne consomment de l'argent que via leur Deal (§6) — jamais directement.

2. PersonDef — le schéma d'auteur

type PersonDef = ContentBase & {
kind: 'person'

identity: {
displayName: string // "Marion Vasseur"
age: number // borne les rôles et la figuration
pronouns: 'il' | 'elle' | 'iel'
portraitId?: string
bio?: string // 2 lignes, pour l'annuaire
}
poste: Poste // enum partagée du contrat §5
/** Niveau dans le poste : borne le tarif et la responsabilité du département. */
grade: 'chef' | 'premier' | 'second' | 'assistant' | 'stagiaire'
/** Poste 'casting' : un comédien est une Person, pas une entité séparée. */
emploi?: 'role-principal' | 'second-role' | 'silhouette' | 'figuration'
| 'doublure-lumiere' | 'doublure-jeu' | 'cascadeur' | 'enfant'
/** Les intermédiaires sont des Person aussi, mais non plateau. */
intermediaire?: 'agent' | 'directeur-casting' | 'delegue-syndical'
agentId?: string // -> PersonDef.id d'un 'agent'
rate: {
dailyAsked_eur: number // tarif affiché — honnête
floor_eur: number // vrai plancher de négociation — CACHÉ
minGuaranteedDays: number // en dessous, refuse le deal
perDiemExpected_eur: number
}
demands: {
clauses: DealClause[] // loge, transport, coach, doublure… (§6)
exclusivityRequired: boolean
creditRank?: number // rang au générique exigé (1 = tête d'affiche)
refusesNight: boolean; refusesNudity: boolean
}
skills: {
metier: Rated
vitesse: Rated
fiabilite: Rated
exigence: Rated
entente: Rated
notoriete: number // HONNÊTE, jamais Rated : c'est public
/** ≤ 2 entrées, delta signé -20..+20 sur `metier` quand le plan sollicite
* ce critère. Seul assouplissement au stat unique (§3). */
specialites?: Partial<Record<CritereScene, number>>
}
traits: TraitId[] // 0 à 4 — au-delà, le personnage est illisible
availability: {
windows: { fromTick: Tick; toTick: Tick }[] // vide = libre partout
/** Concurrents déclarés (la pièce le soir, la pub en octobre) ; `hidden…` est
* la proba qu'un conflit NON déclaré surgisse en cours de partie. */
conflicts: { fromTick: Tick; toTick: Tick; label: string; hard: boolean }[]
hiddenConflictRisk_p: number
}
/** Relations orientées : A→B ne dit rien de B→A. L'asymétrie fait le plateau. */
relations: {
targetId: string
kind: 'mentor' | 'protege' | 'ami' | 'ex' | 'rival' | 'deteste'
| 'famille' | 'a-deja-tourne-avec'
intensity: number // 0–100
known: boolean // visible avant d'engager ?
}[]
social: {
regime: 'intermittent-annexe-8' // techniciens
| 'intermittent-annexe-10' // artistes
| 'cdi' | 'auteur' | 'mineur' | 'hors-cadre'
heuresAcquises: number // vers les 507 h — levier de négo (§8)
syndique: boolean // ouvre les événements `social.*`
}
}

2 bis. Qui ment, qui ne ment pas

ChampMent ?Pourquoi
metieroui, modéré (±15)Le CV est gonflé, jamais délirant : un chef op nul ne serait pas chef op.
vitesseoui, fort (±25)Personne ne se décrit comme lent. Le mensonge le plus fréquent du milieu.
fiabiliteoui, fort (±30)Personne n'annonce ses casseroles. Écart maximal autorisé du jeu.
exigenceoui, extrêmeclaimed ≤ 20 presque toujours« Moi je suis très simple. » Le mensonge structurant du casting.
ententeoui (±20)Se découvre en trois jours de plateau, pas avant.
notorietenonDonnée publique (presse, box-office). Mentir dessus n'est pas crédible.
dailyAsked_eurnonLe prix demandé est un fait. Le secret est ailleurs : floor_eur est caché, pas menti.
availability.windowsnon, mais incompletLe calendrier ne ment pas, il omet — d'où hiddenConflictRisk_p.
traitspartiellement cachéVisibilité définie trait par trait (§4).

Contrainte d'auteur : confidence_p doit baisser quand l'écart grandit. Un claimed très loin de l'actual avec confidence_p: 0.9 est un piège injouable. Le backoffice alerte au-delà d'un écart de 25 avec une confiance > 0.7.

3. Le système de compétences

La matrice poste × critère est rejetée : 18 postes × ~5 critères = 90 cases par personne, inéditables et fausses (un chef op n'a pas de compétence « son »). La matrice appartient au poste, pas à la personne. Le stat unique nu est rejeté aussi : il rend tous les chefs op interchangeables dès le chiffre connu.

Modèle retenu, en trois pièces :

  1. Une compétence brute unique par personne, metier.
  2. Une table de référence content/reference/postes.json qui porte, par poste, un vecteur de poids Record<CritereScene, number> (somme = 1). Un chef op pèse 0.6 sur image, 0.2 sur rythme, 0 sur son. Écrite une fois, pas par personne.
  3. Un correctif individuel minuscule, specialites : ≤ 2 entrées, delta -20..+20. C'est ce qui permet « magnifique en lumière naturelle, perdu en studio » sans ouvrir 90 cases.

⚠️ CritereScene = jeu | image | son | decor | rythme est posé ici comme hypothèse et doit être réconcilié avec scenes.md. S'il y en a sept, seuls les vecteurs de poids grossissent ; le mécanisme ne bouge pas.

La liste FERMÉE — 6 stats

statCe qu'il influence mécaniquement
metierTerme dominant de la qualité produite sur les critères pondérés par le poste (§9). Ne touche jamais au temps.
vitesseMultiplie le temps consommé par le plan. Le stat qui coûte cher sans jamais apparaître sur une facture.
fiabiliteProbabilité de base de déclencher un Event négatif un jour travaillé (retard, maladie, oubli, matériel non préparé).
exigenceGénère des dépenses hors devis (per diem majorés, taxis, hôtel supérieur, caprices) et des Event de blocage. La facture invisible.
ententeModifie le moral des autres présents le même jour ; module la propagation des événements sociaux et le risque de conflit.
notorieteEntre dans le financement (préventes, aides, valeur du film) et dans la valeur perçue du casting ; augmente aussi les caprices tolérés.

polyvalence est écarté : doublon de metier + un trait, et il pousse à un min-maxing sans intérêt. Pourquoi s'arrêter à 6 : au-delà de six barres la carte ne se lit plus d'un coup d'œil, le joueur cesse de comparer et ne regarde plus que le prix — ce qui tue le jeu. Six barres + 0-4 traits + un prix : deux secondes.

4. Traits — le système de cartes

Un trait est une carte nommée : un identifiant, un ou deux modificateurs passifs, des hooks d'événements. Toute la couleur va là ; les stats restent nus.

type TraitDef = ContentBase & {
kind: 'trait' // à ajouter à EntityKind — cf. §11
label: string
flavor: string // la phrase lue sur la carte
visibility: 'public' // sur le CV, dans la rumeur du milieu
| 'revelable' // découvrable en payant de l'info (§7)
| 'cache' // ne se découvre qu'au tournage
modifiers: Partial<Record<SkillKey | 'rate' | 'moralDrift', number>>
hooks: { eventId: string; weight_p: number; when: TriggerCondition }[]
conflictsWith?: TraitId[]
}
idflavorEffet mécaniqueÉvénement déclenchable
pas-avant-dix-heures« Ne descend pas de sa loge avant 10 h. »vitesse -15 sur les plans du premier tick seulementtournage.plateau.attente_comedien (p ≈ 0.35 si un plan est prévu au 1er tick)
chef-op-de-pub« Ancien chef op de pub. Magnifique. Lent. »metier +18, vitesse -22, specialites.image +10tournage.plan.rallonge_lumiere (p ≈ 0.4 en décor nuit)
alcoolique-fonctionnel« Tient parfaitement… jusqu'à jeudi. »metier +8, fiabilite -25, malus croissant avec fatiguetournage.technicien.defaillance (p 0.05 → 0.5 au-delà de 12 jours travaillés)
neveu-du-producteur« On ne peut pas le virer. »rate -40 %, metier -20, entente -10, bloque casting.personne.remercieeproduction.pression.recommandation si on engage un concurrent
trop-bon-pour-le-budget« Il partira si on lui propose mieux. »metier +15 à prix inchangécasting.personne.debauchee (p ≈ 0.25 / semaine sans clause d'exclusivité)
deteste-x« Ne tournera pas avec [X]. »Requiert une relation deteste ; entente -30 les jours de coprésenceplateau.conflit.eclate (p ≈ 0.5 au 2ᵉ jour de coprésence)
syndicaliste« Connaît la convention par cœur. »Rend dures les contraintes narratives du §8 : les dépassements deviennent bloquantssocial.equipe.debrayage après 2 dépassements en 5 jours
bosseur-silencieux« Ne se plaint jamais. Ça se paie. »fiabilite +20, moralDrift -2/jour invisibleequipe.burnout.craque (p ≈ 0.6 si moral < 20) — sans signe avant-coureur
star-fragile« Formidable, si tout va bien. »metier +25, notoriete +30 ; metier chute de 40 % sous moral < 40casting.comedien.claque_la_porte
vieux-de-la-vieille« 200 films. Rien ne l'impressionne. »fiabilite +25, vitesse +10, entente +15, metier plafonné à 70plateau.sauvetage.improvisepositif, rare (p ≈ 0.1)
veut-passer-realisateur« Prend des notes pendant que vous parlez. »entente -10 avec le réalisateurrealisation.autorite.contestee (p ≈ 0.2 / semaine)
agent-vorace« Son agent rappelle tous les jours. »floor_eur +25 % ; chaque renégociation coûte 1 tickdeal.renegociation.demandee à chaque jour supplémentaire imposé
chouchou-de-la-presse« On parlera du film grâce à lui. »notoriete +20, bonus de financement, exigence +15promo.article.publie — positif, augmente la valeur du film
part-a-seize-heures-trente« L'école, c'est non négociable. »Interdit l'assignation au 2ᵉ tick au-delà d'un seuil ; fiabilite +20 sinonplanning.contrainte.violee si le plan de travail l'ignore
casse-cou-non-declare« Fait ses cascades lui-même. Ne le dit pas. »Permet d'économiser une doubluresecurite.accident.plateau (p ≈ 0.15 par plan à risque) + risque d'arrêt assurance

Composition : 4 traits maximum ; deux traits ne peuvent pas viser le même stat avec des signes opposés (le backoffice refuse) ; un trait cache de forte amplitude doit être revelable par au moins un canal du §7 — sinon c'est un piège gratuit, pas un jeu d'information.

5. PersonState — l'état runtime

type PersonState = InstanceBase & {
status: 'repere' // vu dans l'annuaire, rien de plus
| 'demarche' | 'en-negociation' | 'engage' | 'en-poste'
| 'suspendu' // arrêt maladie / accident / conflit
| 'parti' // a claqué la porte ou a été débauché
| 'remercie' | 'remplace'

moral: number // 0–100, init 60
fatigue: number // 0–100, init 0
daysWorked: number
overtimeHours: number // cumul au-delà de l'amplitude
consecutiveDays: number // pour le repos hebdomadaire
dealId?: string // -> DealState.instanceId, au plus un actif

/** Ce que le joueur a découvert. Rien n'est révélé par défaut. */
discovered: {
skills: Partial<Record<SkillKey, Tick>> // stat -> tick de révélation
traits: Record<TraitId, Tick>
relations: string[]
hiddenConflicts: string[]
}

/** Traçabilité pédagogique pour le débriefing : « pris à -140 €/j, il vous a
* coûté 11 400 € de dépassement ». */
ledger: { salaryPaid_eur: number; overrunsCaused_eur: number; timeLostTicks: number }
}

Rien n'est muté directement — la table événement → champ :

ChampÉvénements qui le font bouger
statuscasting.personne.demarchee, deal.negociation.ouverte, deal.signe, tournage.jour.demarre, sante.arret.prescrit, casting.personne.claque_la_porte, casting.personne.remerciee, casting.poste.remplace
moralplateau.journee.terminee (dérive selon amplitude et entente des présents), plateau.conflit.eclate, realisation.compliment.public, budget.per_diem.reduit, planning.contrainte.violee
fatigueplateau.journee.terminee, planning.repos.respecte (décrément), planning.amplitude.depassee
daysWorked, consecutiveDaysplateau.journee.terminee, planning.repos.hebdomadaire.pris (remise à zéro)
overtimeHoursplanning.amplitude.depassee uniquement
discovered.*info.essai.realise, info.rendez_vous.tenu, info.reference.appelee, info.rumeur.entendue, plus toute révélation forcée (tournage.technicien.defaillance révèle fiabilite)
ledger.*agrégé par le réducteur depuis budget.ligne.imputee et tournage.plan.tourne

La révélation est un événement, jamais un flag posé à la volée : sinon la partie n'est plus rejouable et on ne peut pas expliquer au joueur comment il a appris ce qu'il sait.

6. Le lien avec la production n'est PAS la personne : Deal

Trois raisons de sortir le contrat de PersonDef/PersonState :

  1. Une même personne a plusieurs deals dans une partie : la comédienne engagée 8 jours en juin, remerciée, rappelée en octobre pour les raccords ; le machino repris en post-synchro. Un champ contract dans le state écraserait l'historique — inacceptable en event-sourcing.
  2. C'est le deal qui fuit de l'argent, pas la personne. Le dépassement naît d'une clause (« hôtel 4★ », « voiture avec chauffeur ») ou d'un jour garanti non consommé, pas d'un trait de caractère. L'argent dans Deal s'impute proprement au chapitre 2 ou 3 du devis et répond à « où est parti le budget ? ».
  3. Les cycles de vie diffèrent : un deal existe sans personne engagée (une option posée, un préaccord d'agent) et une personne travaille sans deal complet (le stagiaire, le figurant du jour). Les fusionner crée des états impossibles.
type DealClause =
| { kind: 'loge'; standing: 'partagee' | 'individuelle' | 'caravane'; cost_eur: number }
| { kind: 'transport'; mode: 'defraiement' | 'vehicule' | 'chauffeur' | 'avion'; cost_eur: number }
| { kind: 'hebergement'; standing: 1|2|3|4; cost_eur: number }
| { kind: 'coach'; discipline: string; cost_eur: number } // dialecte, danse, arme
| { kind: 'doublure'; personId?: string; cost_eur: number }
| { kind: 'assistant-personnel'; cost_eur: number }
| { kind: 'nu-clause'; refuse: boolean }
| { kind: 'generique'; rank: number; taille: 'egale' | 'premiere' }
| { kind: 'exclusivite'; fromTick: Tick; toTick: Tick }

/** Pas un contrat signé : un MODÈLE d'offre pré-écrit par l'auteur (l'offre standard
* d'un agent, le tarif syndical d'un poste). Les contrats réels de la partie sont
* des DealState créés par le moteur à partir d'un modèle + de la négociation. */
type DealDef = ContentBase & {
kind: 'deal'
personId: string
template: 'standard-cc' | 'star' | 'cachet-journalier' | 'forfait' | 'figuration'
openingRate_eur: number
clausesOffered: DealClause[]
negotiable: { rateFloorPct: number; daysMax: number; clausesRemovable: DealClause['kind'][] }
}

type DealState = InstanceBase & {
personId: string
status: 'option' | 'en-negociation' | 'signe' | 'execute' | 'rompu' | 'expire'
agreedRate_eur: number
guaranteedDays: number // payés même si non travaillés — le piège nº1
daysConsumed: number
exclusivity?: { fromTick: Tick; toTick: Tick }
perDiem_eur: number
clauses: DealClause[]
penalties: {
extraDayMultiplier: number // dépassement des jours garantis, ex. 1.5
dedit_pct: number // si le joueur annule
recoverable_pct: number // si la personne rompt — souvent 0
}

chapitre: 2 | 3 // Personnel (technique) ou Interprétation
committed_eur: number // engagé, réservé au budget
paid_eur: number // décaissé
}

Événements du domaine : deal.option.posee, deal.negociation.ouverte, deal.contre_offre.recue, deal.signe, deal.jour.consomme, deal.jour_supplementaire.impute, deal.dedit.paye, deal.rompu, deal.expire.

Conséquence UI : le joueur doit voir en permanence l'écart guaranteedDaysdaysConsumed par deal. C'est le tableau de bord qui rend lisible le mécanisme central.

7. Le recrutement comme boucle de jeu

C'est la boucle de la pré-production, et elle doit rester jouable pendant le tournage (remplacements). Sa tension : l'information coûte du temps, et le temps de pré-production est fini.

CanalCoûtCe qu'on voitBiais
Annuairegratuitnom, poste, grade, notoriete, dailyAsked_eur, traits publicExhaustif et plat : du bruit, aucune profondeur.
Agent1 ticktous les claimed, disponibilité déclarée, clauses exigéesSystématiquement optimiste ; exigence.claimed toujours bas.
Recommandation du réalisateurgratuite mais contraignantela vérité sur 1 stat, choisi par luiRefuser coûte du moral réalisateur. Souvent hors budget.
Petites annonces1 tick de trides CV, donc des claimed bruitésPeuple les assistants et stagiaires, jamais les chefs.
Ancien collègue (une personne déjà engagée)1 tick1 trait revelable + 1 relationFiltré par la relation : un ami ne dit jamais de mal.
Essai / rendez-vous2 ticks (+ cachet d'essai)metier.actual à ±5 et 1 trait revelableLe plus cher, le plus fiable. Réservé aux rôles principaux et chefs de poste.
Directeur de casting (une Person qu'on engage)son propre dealune présélection dont les claimed sont resserrésLe meilleur achat du jeu, et le premier que les joueurs coupent.

Payer pour réduire l'incertitude est une mécanique chiffrée, pas une saveur :

essai(personne, stat) →
confidence_p := min(0.95, confidence_p + 0.35)
si |actual - claimed| > 20 → émettre info.ecart.decouvert

Le joueur doit pouvoir se dire : « j'ai 6 ticks libres : trois essais sur les chefs de poste, ou des repérages ? » Ce dilemme est le cœur de la pré-production ; sans lui, la pré-production n'est qu'une liste de courses.

Négociation — le joueur propose (rate, days, clauses retirées) ; la personne accepte si offreValeur ≥ floor_eur × f(exigence, notoriete, autresOffres). Chaque contre-offre coûte 1 tick et peut, sur agent-vorace ou trop-bon-pour-le-budget, déclencher casting.personne.debauchee : négocier n'est jamais gratuit, sinon le joueur optimise à l'infini.

8. Contraintes légales et sociales françaises

Tout simuler tue le rythme : le joueur n'est pas gestionnaire de paie. Arbitrage :

RègleStatutJustification
Repos de 11 h entre deux journéessimulé, durLa contrainte qui rend le plan de travail intéressant : finir tard décale mécaniquement le lendemain. Sans elle on tourne 20 h/jour.
Amplitude journalière (~12 h, à confirmer contre la convention collective)simulé, durBorne la journée à 2 ticks. Dépassable, mais émet planning.amplitude.depassee et coûte.
Majoration des heures supplémentairessimulé, agrégéUn multiplicateur par palier sur le cachet du jour, pas un calcul horaire. Le joueur doit sentir la pente, pas remplir un bulletin.
Samedi travaillésimuléMajoration + moral -. Le choix classique : rattraper le retard en payant le samedi.
Dimanche travaillésimulé, quasi interditExige une dérogation → un Event narratif coûteux. La rareté fait la valeur.
Horaires des enfants (autorisation, heures max selon l'âge, répétiteur)simulé, durLe poste enfants existe dans l'enum : il doit servir. Contrainte de planning spectaculaire et vraie.
Coordinateur cascades sur un plan à risquesimulé, durUn plan à risque sans coordinateur est interdit, pas seulement risqué. Le contourner via casse-cou-non-declare doit être un choix conscient.
Animaux : dresseur obligatoire, temps de travail limitésimulé, durL'animal est un Element (production-elements.md), le dresseur une Person ; requis ensemble.
Régime intermittent, 507 h, annexes 8 et 10narratifCompter les cachets ne change rien à la fabrication du film. Mais c'est un levier de négociation : un technicien à 480 h baisse son prix pour finir ses heures → simulé seulement comme modificateur de floor_eur.
Charges sociales (~55 %)simulé, calculéChapitre 4, dérivé, jamais dépensé librement. Sinon le joueur croit qu'un cachet de 400 € coûte 400 € — le contresens nº1 des débutants.
Visite médicale, DPAE, Audiens, congés spectaclesnarratifZéro décision de jeu ; flavor ou événement administratif rare.
Délégué syndical, droit de retraitnarratif déclenchéPas simulé en continu, mais syndicaliste + social.equipe.debrayage rendent les abus visibles.

Principe d'arbitrage réutilisable : une règle est simulée si et seulement si elle change ce que le joueur peut mettre dans la case d'un plan de travail ou le prix de cette case. Sinon, elle est narrative.

9. Participation à la résolution

Deux sorties : la qualité par critère et le temps consommé.

// Contribution d'une personne au critère c d'un plan
function contribution(p: PersonState, def: PersonDef, c: CritereScene): number {
const w = POSTES[def.poste].weights[c] // 0..1, table de référence
if (w === 0) return 0
const base = def.skills.metier.actual + (def.skills.specialites?.[c] ?? 0)
const moral = 0.7 + 0.3 * (p.moral / 100) // 0.70 .. 1.00
const fatig = 1 - 0.25 * (p.fatigue / 100) // 1.00 .. 0.75
const grade = GRADE_FACTOR[def.grade] // chef 1.0 … stagiaire 0.4
return w * base * moral * fatig * grade
}

// Un seul génie ne suffit pas ; une équipe moyenne non plus.
qualite(c) = 0.6 * max(contributions)
+ 0.4 * moyenne(contributions)
+ bonusElements(c)
- penaliteManquant(c) // poste requis non pourvu

temps = tempsBase(plan.difficulte)
* produit_sur_les_postes( 2 - vitesse_effective / 100 ) // 1.0 à 2.0 chacun
* (1 + 0.4 * ratioPostesSousDimensionnes)
* meteoEtLieu

vitesse_effective = vitesse.actual * (1 - 0.3 * fatigue / 100)

Trois propriétés voulues : metier fait la qualité, vitesse fait le coût — deux axes orthogonaux, jamais achetés ensemble gratuitement ; le max à 0.6 fait qu'un chef brillant tire le résultat vers le haut malgré une équipe médiocre, ce qui justifie de payer un chef ; le produit sur les postes fait qu'un seul département lent suffit à faire dériver la journée — exactement la leçon du métier. fiabilite, exigence et entente n'entrent pas dans la formule : ils agissent en amont sur le tirage des Event du jour et en aval sur le budget ; les y mélanger rendrait le calcul opaque.

10. Édition dans le backoffice

L'écran « Personne », quatre onglets :

  1. Fiche — identité, poste, grade, emploi, portrait, bio ; le poste pré-remplit des stats plausibles pour le grade (un stagiaire ne naît pas à 70 de metier).
  2. Stats — six doubles curseurs actual/claimed superposés, écart en rouge, confidence_p dessous. Le contrôle central du jeu, il doit être beau et rapide ; alerte si écart > 25 avec confidence_p > 0.7.
  3. Traits & relations — traits en cartes qu'on glisse (max 4, conflits refusés) ; relations en mini-graphe avec autocomplétion sur les PersonDef du pack.
  4. Argent & disponibilité — tarif, plancher, jours garantis, clauses, fenêtres et conflits sur une frise en Ticks alignée sur le plan de travail.
PopulationVolume / packMode
Rôles principaux~5À la main, intégralement. Chacun est une intrigue.
Chefs de poste~15À la main. Ce sont les vraies décisions de recrutement.
Seconds rôles~20Semi-généré : squelette généré, traits et relations posés à la main sur 1 sur 3.
Assistants, seconds, stagiaires~60Généré, avec 10 % de pépites (un stagiaire à metier 75) et 10 % de boulets injectés — c'est ce qui rend le tri intéressant.
Figuration & silhouettes100–400Généré, jamais individualisé, manipulé en lots (FigurationBatch : 40 figurants d'époque, un cachet unitaire, une fiabilite de groupe).
Doublures & cascadeurs~8À la main : peu nombreux, très contraints légalement, sources d'événements graves.

Le générateur exige ses tables de référence : prénoms/noms par génération, distributions de stats par grade, banque de portraits, et une table de traits pondérée par poste (chef-op-de-pub ne s'attribue qu'au poste image).

11. Questions ouvertes

  1. Un comédien reste-t-il une Person de poste casting (choix de cette fiche : un seul annuaire, un seul système de deals), ou faut-il un discriminant explicite personKind: 'technicien' | 'comedien' | 'intermediaire' pour la lisibilité ?
  2. trait entre-t-il dans EntityKind ? Oui (contenu éditable et versionné, moddable) ou non (table de code, plus rapide mais figée) ?
  3. Le réalisateur est-il une Person comme les autres ? Il a un deal, des stats, des traits, mais il porte aussi la Vision et joue l'antagoniste permanent : Person + Vision séparée, ou une DirectorDef spécialisée ?
  4. Un lot de figuration est-il une Person (avec count) ou un Element ? Il ressemble à une ressource, mais relève du chapitre 3 et du régime artiste.
  5. Combien de traits cache par personne ? La fiche propose « au plus 1 trait caché de forte amplitude ». Trop généreux (jamais de vraie surprise) ou trop dur ?
  6. Le moral est-il visible ? (a) invisible et deviné au comportement, (b) chiffré, (c) qualitatif flou (« tendu », « à bout »). La fiche penche pour (c).
  7. Le dedit_pct est-il toujours > 0, rendant l'erreur de casting irréversible et anxiogène — ce qui est réaliste — ou existe-t-il une période d'essai jouable qui pardonne la première erreur ?
  8. Les stats se révèlent-elles toutes seules en travaillant ? Oui (après N jours confidence_p → 1 : l'information finit par arriver gratuitement) ou non (seuls les canaux payants du §7 révèlent, ce qui valorise la pré-production mais laisse le joueur aveugle tout le tournage) ?