Initial commit

**Motivations:**
- Initialisation du versionning git pour le projet

**Root causes:**
- N/A (Nouveau projet)

**Correctifs:**
- N/A

**Evolutions:**
- Structure initiale du projet
- Ajout du .gitignore

**Pages affectées:**
- Tous les fichiers
This commit is contained in:
2026-03-03 22:24:17 +01:00
commit e031c9a1d2
155 changed files with 22334 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
# Phase 8 Attractivité et visiteurs (billeterie, cap, score)
**Objectif :** Plafonner les visiteurs par la capacité billeterie, calculer un score dattractivité (valeur, espèces, rareté, remplissage, pénalités morts, bonus naissances) et lafficher sur la carte du monde.
**Référence :** `docs/plan-implementation-rappel-grandes-regles.md` phase 8.
## Impacts
- Les visiteurs sont plafonnés par la capacité billeterie (20 × niveau total billeterie). Sans billeterie, le plafond nest pas appliqué (comportement inchangé).
- Nouveau score dattractivité exposé dans `state.attractivityScore` et affiché sous le nom du zoo (joueur) sur la carte du monde.
- La formule dattractivité pourra servir plus tard à lallocation des visiteurs depuis les villes (phase 11).
## Modifications
- **income.js** : suppression des imports dupliqués ; `getBilleterieCapacity(state)` ; dans `getVisitorParams`, plafonnement de `visitorCount` par `getBilleterieCapacity(state)` ; `getAttractivityScore(state)` (valeur cumulée, nombre despèces, rareté moyenne, taux de remplissage, pénalité morts, bonus naissances).
- **config.js** : `Visitor.AttractivityDeathPenalty`, `Visitor.AttractivityBirthBonus`.
- **types.js** : `GameState.attractivityScore?`.
- **game-loop.js** : import `getAttractivityScore` ; après `tickResearch`, `state.attractivityScore = getAttractivityScore(state)`.
- **ui.js** : pour le zoo joueur, ligne « Score attractivité: X.X » sous le score de reproduction (classe `world-map-zoo-attractivity-score`).
- **main.css** : style `.world-map-zoo-attractivity-score`.
## Disparition des animaux non visités (§2)
- **Config** : `Visitor.MaxSecondsWithoutVisit` (300 s par défaut). Un animal dont aucune visite na été enregistrée sur sa case depuis plus de cette durée est retiré (case vidée, `deathCountRecent` incrémenté).
- **animal-visits.js** : `tickAnimalVisits(state, nowUnix, nowMs)` met à jour `lastVisitedAt` des cases animales sous la position actuelle des visiteurs (orbites autour du centre dattraction).
- **food.js** : `checkDeathCauses(state, nowUnix)` utilise `MaxSecondsWithoutVisit` ; si `nowUnix - lastVisitedAt >= maxVisit`, le bloc animal est supprimé.
- **game-loop.js** : `tickAnimalVisits` est appelé avant `tickFeeding` et `checkDeathCauses`.
## Stagnation (§3)
- **Config** : `Visitor.StagnationDecayAfterSeconds` (60 s), `Visitor.StagnationDecayPerMinute` (0.05). Après ce délai sans action dévolution, le multiplicateur de demande visiteurs décroît (plancher 10 %).
- **income.js** : `getStagnationMultiplier(state, nowUnix)` utilise `state.lastEvolutionAt` ; appliqué dans `getVisitorDemand(state, nowUnix)`.
- **lastEvolutionAt** est mis à jour sur : upgrade (plot, conveyor, truck, world map, school, nursery, shop, research, billeterie, food, reception, biome), place (egg, baby, reception animal), vente (sellAnimalToNpc, addMatureBabyToSale, addReceptionAnimalToSale), prestige, moveCell.
## Implémenté ultérieurement (modèle visiteurs par entité)
- **Durée max 1 journée par visiteur** : `state.visitorArrivals[]` avec `{ arrivedAt }` ; base = `Time.DayLengthSeconds` (1 jour) ; sortie quand `now > arrivedAt + getStayDurationSeconds(state)`.
- **Prolongation par boutiques et diversité** : `getStayMultiplier(state)` = 1 + (niveaux boutique × `Visitor.StayMultiplierPerShopLevel`) + (espèces distinctes × `Visitor.StayMultiplierPerSpecies`) ; `getStayDurationSeconds(state) = base × getStayMultiplier(state)`.
- **Config** : `Visitor.StayMultiplierPerShopLevel`, `Visitor.StayMultiplierPerSpecies` (base jour = `Time.DayLengthSeconds`).
- **Game loop** : `tickVisitorArrivals(state, nowUnix)` appelé avant `incomeTick` ; `getVisitorParams(state)` utilise `state.visitorArrivals.length` ; sans billeterie, fallback sur lancienne formule pour rétrocompatibilité.
## Modalités de déploiement
- Aucun déploiement serveur. Rechargement client suffit.
## Modalités danalyse
- Sans billeterie : le nombre de visiteurs reste calculé comme avant (sans plafond).
- Avec au moins une case billeterie : le nombre de visiteurs affiché et utilisé pour les revenus ne dépasse pas (niveau total billeterie × 20).
- Carte du monde, zoo joueur : affichage « Score attractivité: X.X » mis à jour à chaque tick.