People — comédien·ne·s, équipe technique, intermédiaires
Fiche d'entité. Respecte
README.md:Def≠State, stats 0–100, euros entiers suffixés_eur,Tick= demi-journée,Ratedpour 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
| Champ | Ment ? | Pourquoi |
|---|---|---|
metier | oui, modéré (±15) | Le CV est gonflé, jamais délirant : un chef op nul ne serait pas chef op. |
vitesse | oui, fort (±25) | Personne ne se décrit comme lent. Le mensonge le plus fréquent du milieu. |
fiabilite | oui, fort (±30) | Personne n'annonce ses casseroles. Écart maximal autorisé du jeu. |
exigence | oui, extrême — claimed ≤ 20 presque toujours | « Moi je suis très simple. » Le mensonge structurant du casting. |
entente | oui (±20) | Se découvre en trois jours de plateau, pas avant. |
notoriete | non | Donnée publique (presse, box-office). Mentir dessus n'est pas crédible. |
dailyAsked_eur | non | Le prix demandé est un fait. Le secret est ailleurs : floor_eur est caché, pas menti. |
availability.windows | non, mais incomplet | Le calendrier ne ment pas, il omet — d'où hiddenConflictRisk_p. |
traits | partiellement caché | Visibilité définie trait par trait (§4). |
Contrainte d'auteur :
confidence_pdoit baisser quand l'écart grandit. Unclaimedtrès loin de l'actualavecconfidence_p: 0.9est 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 :
- Une compétence brute unique par personne,
metier. - Une table de référence
content/reference/postes.jsonqui porte, par poste, un vecteur de poidsRecord<CritereScene, number>(somme = 1). Un chef op pèse 0.6 surimage, 0.2 surrythme, 0 surson. Écrite une fois, pas par personne. - 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 | rythmeest posé ici comme hypothèse et doit être réconcilié avecscenes.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
| stat | Ce qu'il influence mécaniquement |
|---|---|
metier | Terme dominant de la qualité produite sur les critères pondérés par le poste (§9). Ne touche jamais au temps. |
vitesse | Multiplie le temps consommé par le plan. Le stat qui coûte cher sans jamais apparaître sur une facture. |
fiabilite | Probabilité de base de déclencher un Event négatif un jour travaillé (retard, maladie, oubli, matériel non préparé). |
exigence | Gé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. |
entente | Modifie le moral des autres présents le même jour ; module la propagation des événements sociaux et le risque de conflit. |
notoriete | Entre 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[]
}
| id | flavor | Effet 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 seulement | tournage.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 +10 | tournage.plan.rallonge_lumiere (p ≈ 0.4 en décor nuit) |
alcoolique-fonctionnel | « Tient parfaitement… jusqu'à jeudi. » | metier +8, fiabilite -25, malus croissant avec fatigue | tournage.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.remerciee | production.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ésence | plateau.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 bloquants | social.equipe.debrayage après 2 dépassements en 5 jours |
bosseur-silencieux | « Ne se plaint jamais. Ça se paie. » | fiabilite +20, moralDrift -2/jour invisible | equipe.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 < 40 | casting.comedien.claque_la_porte |
vieux-de-la-vieille | « 200 films. Rien ne l'impressionne. » | fiabilite +25, vitesse +10, entente +15, metier plafonné à 70 | plateau.sauvetage.improvise — positif, rare (p ≈ 0.1) |
veut-passer-realisateur | « Prend des notes pendant que vous parlez. » | entente -10 avec le réalisateur | realisation.autorite.contestee (p ≈ 0.2 / semaine) |
agent-vorace | « Son agent rappelle tous les jours. » | floor_eur +25 % ; chaque renégociation coûte 1 tick | deal.renegociation.demandee à chaque jour supplémentaire imposé |
chouchou-de-la-presse | « On parlera du film grâce à lui. » | notoriete +20, bonus de financement, exigence +15 | promo.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 sinon | planning.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 doublure | securite.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 |
|---|---|
status | casting.personne.demarchee, deal.negociation.ouverte, deal.signe, tournage.jour.demarre, sante.arret.prescrit, casting.personne.claque_la_porte, casting.personne.remerciee, casting.poste.remplace |
moral | plateau.journee.terminee (dérive selon amplitude et entente des présents), plateau.conflit.eclate, realisation.compliment.public, budget.per_diem.reduit, planning.contrainte.violee |
fatigue | plateau.journee.terminee, planning.repos.respecte (décrément), planning.amplitude.depassee |
daysWorked, consecutiveDays | plateau.journee.terminee, planning.repos.hebdomadaire.pris (remise à zéro) |
overtimeHours | planning.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 :
- 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
contractdans le state écraserait l'historique — inacceptable en event-sourcing. - 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
Deals'impute proprement au chapitre 2 ou 3 du devis et répond à « où est parti le budget ? ». - 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
guaranteedDays−daysConsumedpar 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.
| Canal | Coût | Ce qu'on voit | Biais |
|---|---|---|---|
| Annuaire | gratuit | nom, poste, grade, notoriete, dailyAsked_eur, traits public | Exhaustif et plat : du bruit, aucune profondeur. |
| Agent | 1 tick | tous les claimed, disponibilité déclarée, clauses exigées | Systématiquement optimiste ; exigence.claimed toujours bas. |
| Recommandation du réalisateur | gratuite mais contraignante | la vérité sur 1 stat, choisi par lui | Refuser coûte du moral réalisateur. Souvent hors budget. |
| Petites annonces | 1 tick de tri | des CV, donc des claimed bruités | Peuple les assistants et stagiaires, jamais les chefs. |
| Ancien collègue (une personne déjà engagée) | 1 tick | 1 trait revelable + 1 relation | Filtré par la relation : un ami ne dit jamais de mal. |
| Essai / rendez-vous | 2 ticks (+ cachet d'essai) | metier.actual à ±5 et 1 trait revelable | Le 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 deal | une présélection dont les claimed sont resserrés | Le 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ègle | Statut | Justification |
|---|---|---|
| Repos de 11 h entre deux journées | simulé, dur | La 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é, dur | Borne la journée à 2 ticks. Dépassable, mais émet planning.amplitude.depassee et coûte. |
| Majoration des heures supplémentaires | simulé, 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 interdit | Exige 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é, dur | Le poste enfants existe dans l'enum : il doit servir. Contrainte de planning spectaculaire et vraie. |
| Coordinateur cascades sur un plan à risque | simulé, dur | Un 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é, dur | L'animal est un Element (production-elements.md), le dresseur une Person ; requis ensemble. |
| Régime intermittent, 507 h, annexes 8 et 10 | narratif | Compter 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 spectacles | narratif | Zéro décision de jeu ; flavor ou événement administratif rare. |
| Délégué syndical, droit de retrait | narratif 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 :
- 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). - Stats — six doubles curseurs
actual/claimedsuperposés, écart en rouge,confidence_pdessous. Le contrôle central du jeu, il doit être beau et rapide ; alerte si écart > 25 avecconfidence_p> 0.7. - Traits & relations — traits en cartes qu'on glisse (max 4, conflits refusés) ;
relations en mini-graphe avec autocomplétion sur les
PersonDefdu pack. - Argent & disponibilité — tarif, plancher, jours garantis, clauses, fenêtres et conflits sur une frise en Ticks alignée sur le plan de travail.
| Population | Volume / pack | Mode |
|---|---|---|
| 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 | ~20 | Semi-généré : squelette généré, traits et relations posés à la main sur 1 sur 3. |
| Assistants, seconds, stagiaires | ~60 | Gé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 & silhouettes | 100–400 | Gé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
- Un comédien reste-t-il une
Personde postecasting(choix de cette fiche : un seul annuaire, un seul système de deals), ou faut-il un discriminant explicitepersonKind: 'technicien' | 'comedien' | 'intermediaire'pour la lisibilité ? traitentre-t-il dansEntityKind? Oui (contenu éditable et versionné, moddable) ou non (table de code, plus rapide mais figée) ?- Le réalisateur est-il une
Personcomme les autres ? Il a un deal, des stats, des traits, mais il porte aussi laVisionet joue l'antagoniste permanent :Person+Visionséparée, ou uneDirectorDefspécialisée ? - Un lot de figuration est-il une
Person(aveccount) ou unElement? Il ressemble à une ressource, mais relève du chapitre 3 et du régime artiste. - Combien de traits
cachepar personne ? La fiche propose « au plus 1 trait caché de forte amplitude ». Trop généreux (jamais de vraie surprise) ou trop dur ? - Le
moralest-il visible ? (a) invisible et deviné au comportement, (b) chiffré, (c) qualitatif flou (« tendu », « à bout »). La fiche penche pour (c). - Le
dedit_pctest-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 ? - 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) ?