Files
ClickerZ/Frontend/src/lib/core/balance.ts
Tetardtek f6bff6e389
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 22s
feat: migrate frontend React 18 → Svelte 5 + SvelteKit
Core logic portable (economy, balance, cosmetics, migrateSave) — zero rewrite.
136 tests green, identiques. Backend inchangé.

- Svelte 5 runes stores (game, auth, toast) remplacent Zustand
- SvelteKit adapter-static SPA (dist/ output, fallback index.html)
- Tailwind v4 conservé, design system .gp-* porté
- Transitions natives : slide, fly, scale, fade sur toute l'UI
- Sidebar tabbée (Production/Evolution/Collection) + CollapsiblePanel
- Mobile bottom sheet avec FAB toggle + backdrop blur
- Click particles réactifs Svelte (plus de DOM impératif)
- TadpoleSprite bounce + glow ring au clic
- Guide refait en accordéon, Achievements avec filtres
- a11y : focus-visible, Escape modals, aria-current, aria-labels
- CI/CD adapté (tests + build + rsync)
- Build 504K (vs ~1.2MB React)
2026-03-28 20:03:21 +01:00

69 lines
2.3 KiB
TypeScript
Raw 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.
// balance.ts — Constantes d'équilibrage centralisées
// Toutes les valeurs de tuning en un seul fichier pour faciliter le playtest.
// Sprint 3 — session brainstorm 2026-03-28
// --- Formule ADN prestige ---
export const PRESTIGE_ADN_BASE = 50;
export const PRESTIGE_ADN_THRESHOLD = 1e6; // 1M têtards minimum pour prestige
export const PRESTIGE_BONUS_PER_PRESTIGE = 0.05; // +5% par prestige
export const PRESTIGE_BONUS_CAP = 3.0; // cap à ×4 total (80 prestiges)
export const PRESTIGE_ADN_MIN = 1; // clamp : jamais 0 ADN si seuil atteint
// --- Seuil prestige ---
export const BASE_PRESTIGE_THRESHOLD = 1_000_000; // 1M têtards
// --- Post-capstone scaling par tranche ---
export const POST_CAPSTONE_TIERS = [
{ maxPurchases: 5, multiplier: 1.5 }, // achats 1-5
{ maxPurchases: 10, multiplier: 1.8 }, // achats 6-10
{ maxPurchases: Infinity, multiplier: 2.0 }, // achats 11+
] as const;
/**
* Calcule le coût du N-ième achat post-capstone repeatable (0-indexed).
* Scaling par tranche : ×1.5 (achats 0-4), ×1.8 (5-9), ×2.0 (10+)
*/
export function postCapstoneCost(baseCost: number, purchased: number): number {
let cost = baseCost;
for (let i = 0; i < purchased; i++) {
if (i < 5) cost *= 1.5;
else if (i < 10) cost *= 1.8;
else cost *= 2.0;
}
return Math.floor(cost);
}
// --- Reset arbre ---
export const TREE_RESET_FREE_PER_PRESTIGE = 1; // 1 gratuit par prestige
export const TREE_RESET_EXTRA_COST = 5; // 5 ADN × n pour les resets supplémentaires
/**
* Coût du prochain reset arbre.
* 1 gratuit par prestige, puis linéaire (5 × n) au-delà.
*/
export function treeResetCost(freeResetAvailable: boolean, extraResetsUsed: number): number {
if (freeResetAvailable) return 0;
return TREE_RESET_EXTRA_COST * (extraResetsUsed + 1);
}
// --- Offline ---
export const OFFLINE_THRESHOLD_MS = 60_000; // 60s
export const OFFLINE_FULL_MS = 15 * 60_000; // 0-15min : 100%
export const OFFLINE_DECAY_END_MS = 60 * 60_000; // 15min-1h : 100% → 25%
export const OFFLINE_ZERO_MS = 2 * 60 * 60_000; // 1h-2h : 25% → 0%
export const OFFLINE_FLOOR = 0.25; // plancher decay
// --- Anti-cheat ---
export const MAX_PRODUCTION_PER_SECOND = 750_000;
export const CHEAT_MARGIN = 1.1;
// --- Save version ---
export const CURRENT_SAVE_VERSION = 2;