Guía UI dinámica variables

Data Binding

El sistema de data binding permite que los textos de tu UI muestren valores en tiempo real — progreso de eventos, contadores y variables del servidor — sin necesidad de recargar la pantalla.

Sintaxis

Las variables se escriben con dobles llaves: {{variable}}. Puedes navegar propiedades anidadas con puntos.

Formato general
# Variable simple
content: "Eventos activos: {{in_progress_count}}"

# Variable con propiedad anidada
content: "Estado: {{event.state}}"

# Múltiples variables en el mismo texto
content: "Progreso: {{progress.current}} / {{progress.target}}"
El patrón es dobles llaves {{ }} — no simples. Si usas una sola llave el binding no se resuelve y el texto se muestra tal cual en pantalla.

Variables de evento — event.*

Acceden al estado del evento vinculado a la pantalla mediante associated_event_id, o al evento del contexto actual.

VariableAliasValor devuelto
{{event.id}}ID del evento. Ejemplo: matar-zombies
{{event.displayName}}{{event.display_name}}Nombre visible del evento.
{{event.description}}Descripción del evento.
{{event.state}}Estado en mayúsculas: AVAILABLE, IN_PROGRESS, COMPLETED, FAILED, LOCKED.
{{event.currentProgress}}{{event.current_progress}}Progreso actual del objetivo activo (número).
{{event.targetProgress}}{{event.target_progress}}Objetivo total del objetivo activo (número).
{{event.currentObjective}}{{event.current_objective}}Descripción del objetivo actual. Vacío si no hay ninguno activo.
{{event.progressPercentage}}{{event.progress_percentage}}Porcentaje ya formateado con símbolo. Ejemplo: 75%.
{{event.repeatable}}true o false según la configuración del evento.
Ejemplo — texto con progreso del evento
- id: "texto-progreso"
  type: TEXT
  x: 200
  y: 150
  width: 380
  height: 20
  properties:
    content: "{{event.currentObjective}}: {{event.currentProgress}} / {{event.targetProgress}}"
    align: "center"
    shadow: "true"
Ejemplo — mostrar porcentaje
- id: "texto-porcentaje"
  type: TEXT
  x: 200
  y: 170
  width: 380
  height: 20
  properties:
    content: "Completado: {{event.progressPercentage}}"
    align: "center"
    shadow: "true"

Variables de progreso — progress.*

Versión simplificada del progreso del evento, disponible cuando la pantalla tiene un associated_event_id.

VariableValor devuelto
{{progress.current}}Progreso actual (número entero).
{{progress.target}}Objetivo total (número entero).
{{progress.percentage}}Porcentaje como número entre 0 y 100 (sin símbolo %). Útil para cálculos.
Usa {{event.progressPercentage}} cuando quieras mostrar el porcentaje con el símbolo % directamente al jugador. Usa {{progress.percentage}} si necesitas el número sin símbolo para mostrarlo de otra forma.

Variables globales

Disponibles en cualquier pantalla sin necesidad de associated_event_id. Reflejan el estado general de todos los eventos del jugador.

VariableValor devuelto
{{event_count}}Número total de eventos cargados.
{{in_progress_count}}Número de eventos actualmente en progreso.
{{available_count}}Número de eventos disponibles pero no iniciados.
{{completed_count}}Número de eventos completados.
Ejemplo — resumen en el menú principal
- id: "texto-resumen"
  type: TEXT
  x: 200
  y: 50
  width: 380
  height: 20
  properties:
    content: "§7Misiones activas: §e{{in_progress_count}} §7| Completadas: §a{{completed_count}}"
    align: "center"
    shadow: "true"

Variables de estado del servidor

Son variables arbitrarias que el servidor establece por jugador con el comando /eventui setuivar. Se usan principalmente en condiciones visible_if, pero también pueden mostrarse en textos.

Establecer una variable desde el servidor
# Establecer variable para un jugador específico
/eventui setuivar Steve zombie_card_unlocked true

# Leer la variable en un texto
content: "Carta de zombie: {{zombie_card_unlocked}}"
Las variables de estado son por jugador — cada jugador tiene su propio mapa de variables. Se persisten en playerstate/<uuid>.yml y se restauran al reconectar.

Condiciones — visible_if

La propiedad visible_if usa las variables de estado del servidor para mostrar u ocultar elementos. A diferencia del binding de texto, no usa llaves — es solo el nombre de la variable y el operador.

SintaxisCondición
variable == valor Visible si la variable es exactamente igual al valor.
variable != valor Visible si la variable es distinta del valor.
!variable Visible si la variable no existe, es "false" o es "0".
variable Visible si la variable existe y no es "false" ni "0".
Ejemplos de visible_if
# Visible solo si la variable es exactamente "true"
visible_if: "zombie_card_unlocked == true"

# Visible si la variable NO es "true"
visible_if: "zombie_card_unlocked != true"

# Visible si la variable no existe o es false/0
visible_if: "!zombie_card_unlocked"

# Visible si la variable existe y tiene valor positivo
visible_if: "zombie_card_unlocked"

# Visible si el jugador está en una fase específica
visible_if: "fase_actual == fase_3"

Comportamiento cuando una variable no existe

Si usas una variable en content que no está definida en el contexto, el texto se muestra sin resolver — aparece tal cual en pantalla con las dobles llaves:

Variable no encontrada
# Si "puntos" no existe en el contexto:
content: "Puntos: {{puntos}}"

# El jugador verá en pantalla:
Puntos: {{puntos}}

Cuando esto ocurre, el sistema también imprime un warning en los logs del cliente: Variable not found in context: puntos. Úsalo para depurar bindings rotos.

Ejemplo completo

Una pantalla de misión que combina todos los tipos de binding:

uis/pantalla-mision.yml
id: "pantalla-mision"
title: ""
screen_width: 500
screen_height: 350
associated_event_id: "matar-zombies"

screen_properties:
  pause_game: "false"
  transition_in: "scale_up"
  transition_duration: "300"

elements:
  # Nombre del evento resuelto dinámicamente
  - id: "titulo-evento"
    type: TEXT
    x: 250
    y: 30
    width: 480
    height: 20
    properties:
      content: "§6§l{{event.displayName}}"
      align: "center"
      shadow: "true"

  # Objetivo actual
  - id: "objetivo-actual"
    type: TEXT
    x: 250
    y: 60
    width: 480
    height: 20
    properties:
      content: "§7{{event.currentObjective}}"
      align: "center"
      shadow: "true"

  # Progreso numérico
  - id: "texto-progreso"
    type: TEXT
    x: 250
    y: 90
    width: 480
    height: 20
    properties:
      content: "§e{{event.currentProgress}} §7/ §e{{event.targetProgress}}"
      align: "center"
      shadow: "true"

  # Porcentaje
  - id: "texto-porcentaje"
    type: TEXT
    x: 250
    y: 115
    width: 480
    height: 20
    properties:
      content: "§a{{event.progressPercentage}} completado"
      align: "center"
      shadow: "true"

  # Resumen global — siempre visible
  - id: "texto-global"
    type: TEXT
    x: 250
    y: 290
    width: 480
    height: 20
    properties:
      content: "§8Misiones activas: {{in_progress_count}} | Completadas: {{completed_count}}"
      align: "center"
      shadow: "true"

  # Elemento que solo aparece si el jugador desbloqueó contenido extra
  - id: "bonus-desbloqueado"
    type: IMAGE
    x: 400
    y: 30
    width: 50
    height: 50
    properties:
      texture: "eventui:textures/ui/widgets/bonus_badge.png"
      visible_if: "bonus_unlocked == true"