feat: migrate frontend React 18 → Svelte 5 + SvelteKit
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 22s

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)
This commit is contained in:
2026-03-28 20:03:21 +01:00
parent 3de0492631
commit f6bff6e389
125 changed files with 5323 additions and 10373 deletions

View File

@@ -0,0 +1,68 @@
// 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;