Files
builazoo/docs/features/attractivite-visiteurs-phase8.md
Nicolas Cantu e031c9a1d2 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
2026-03-03 22:24:17 +01:00

51 lines
4.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.