---
name: economia-y-powerups
description: Monedas, tienda validada en el servidor, mejoras, power-ups apply/deshacer y guardado seguro. Úsala al escribir la economía del juego.
enabled: true
---

# Economía, mejoras y power-ups

## La moneda

- Se guarda en el servidor, por jugador, y se muestra en `leaderstats` (junto con el progreso) para que
  aparezca en la lista de jugadores.
- Las monedas del mapa son partes con un tag y un atributo de valor. Al recogerse dan ese valor y reaparecen
  pasado un tiempo (unos 15 s), sin destruirse.
- Recoger, ganar o gastar moneda **no** lo decide el cliente: el servidor detecta el toque, la compra o el
  premio y es el único que suma o resta.

## La tienda

- Es un puesto en el punto de partida con un `ProximityPrompt`. Al usarlo, el cliente abre un panel con los
  artículos, sus niveles y sus precios **leídos de la configuración**, y pide comprar por una `RemoteFunction`.
- **El servidor valida todo:** que el artículo exista, que el jugador tenga moneda suficiente y que no esté ya
  en el nivel máximo. Devuelve si compró y el nivel nuevo; el cliente solo pinta la respuesta. **Nunca aceptes
  un precio que venga del cliente.**
- Una mejora tiene varios niveles con precio creciente; el nivel comprado se guarda por jugador y es permanente.
- Un power-up comprado en tienda (si los hay) es lo mismo que uno del mapa: se aplica con el mismo contrato.

## Un único escritor de las estadísticas del personaje

- Mejoras y power-ups tocan las mismas propiedades del `Humanoid` (`WalkSpeed`, `JumpHeight`, y las que use el
  juego). Si cada uno las escribe por su cuenta, se pisan: un power-up que expira deja al jugador sin su mejora,
  o al revés.
- **Solo un servicio escribe esas propiedades.** Calcula el valor final a partir de los valores base, el nivel
  de cada mejora y los multiplicadores de los power-ups activos, que se guardan como **atributos del personaje**.
  Cualquier cambio (comprar, activar, expirar, reaparecer) pide un recálculo; nadie más escribe.
- Usa `JumpHeight`: en los places nuevos `UseJumpPower` es `false`, así que `JumpPower` no hace nada.

## Power-ups

- Todos cumplen el **mismo contrato**: una función `apply` que recibe el personaje y la definición del power-up,
  aplica el efecto y **devuelve la función que lo deshace**. El servicio que los gestiona no sabe qué hace cada
  uno: aplica, espera la duración y llama al deshacer. Así uno nuevo es un módulo más y una línea de configuración.
- Los que cambian una estadística lo hacen poniendo un atributo multiplicador en el personaje y pidiendo el
  recálculo; los de protección ponen un atributo que el servicio del peligro consulta antes de actuar.
- **Si el jugador muere o sale con un power-up activo, el deshacer tiene que ejecutarse igual:** engancha
  `CharacterRemoving` y limpia.
- Los power-ups del mapa son partes con un tag y un atributo con su nombre, y reaparecen pasado un tiempo
  (unos 10 s).
- Avísale al jugador de cuánto le queda: un `RemoteEvent` del servidor al cliente con el nombre y los segundos,
  y el cliente pinta la cuenta atrás.

## Recompensas

- Una recompensa por completar algo se da **una sola vez**: guarda una marca por jugador (un atributo o un
  campo en sus datos) para no repetirla cada vez que vuelva a pasar por el sitio.

## Guardado

- Moneda, mejoras compradas y progreso se guardan al salir el jugador y al cerrar el servidor (`BindToClose`),
  con `pcall` y reintentos.
- **Si la carga falló, ese jugador juega sin guardar y no se guarda nunca**, o pisarías sus datos reales con ceros.
- En un place sin publicar el DataStore no funciona: el juego tiene que arrancar igual, avisando una sola vez.
