Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/SkyFangames/La-Base-de-Sky/llms.txt

Use this file to discover all available pages before exploring further.

Descripción

Modular UI Scenes (MUI) es un framework completo que permite crear interfaces de usuario modulares y extensibles para Pokémon Essentials. Proporciona un sistema de handlers que facilita añadir, modificar y gestionar páginas y opciones de menú de forma dinámica.
Versión: 2.0.9
Requisitos: v21.1 Hotfixes v1.0.6+
Autor: Lucidious89
Enlace: Relic Castle
Plugin Fundamental: Este es un plugin base requerido por muchos otros plugins del ecosistema La Base de Sky. No debe deshabilitarse si tienes plugins que dependen de él.

Sistema UIHandlers

El núcleo de MUI es el módulo UIHandlers, que proporciona un sistema de gestión de menús y opciones modulares.

Estructura Básica

module UIHandlers
  # Añadir una nueva opción de menú
  def self.add(ui, option, hash)
    # ui: Identificador del menú (símbolo)
    # option: Identificador de la opción (símbolo)
    # hash: Configuración de la opción
  end
end

Configuración de Handlers

Añadir Páginas/Opciones

# Ejemplo: Añadir página personalizada al resumen de Pokémon
UIHandlers.add(:summary, :page_custom, {
  "name"      => "Mi Página",              # Nombre mostrado
  "suffix"    => "custom",                 # Sufijo del icono
  "order"     => 50,                       # Orden de aparición
  "condition" => proc { |pkmn| true },     # Condición para mostrar
  "layout"    => proc { |pkmn, scene| },  # Layout de la página
  "options"   => [:option1, :option2],    # Opciones disponibles
  "options_labels" => {                    # Etiquetas de opciones
    :option1 => "Opción 1",
    :option2 => "Opción 2"
  }
})

Propiedades del Hash de Configuración

PropiedadTipoDescripción
nameString/ProcNombre de la opción mostrado al usuario
suffixStringSufijo para identificar gráficos
orderIntegerOrden de aparición (menor = primero)
conditionProcCondición para mostrar la opción
layoutProcCódigo para dibujar el layout
optionsArrayArray de símbolos con opciones
options_labelsHashHash con etiquetas de opciones
pluginArray["NombrePlugin", booleano] para condicionar por plugin

Eliminar Opciones

# Eliminar una opción específica
UIHandlers.remove(:summary, :page_moves)

# Limpiar todas las opciones de un menú
UIHandlers.clear(:summary)

Sistema de Pantalla de Resumen

MUI incluye un sistema completo para personalizar la pantalla de resumen de Pokémon.

Configuración de Iconos de Página

class PokemonSummary_Scene
  # Máximo de iconos visibles simultáneamente
  MAX_PAGE_ICONS = 5
  
  # Mostrar flechas de navegación
  PAGE_ICONS_SHOW_ARROWS = true
  
  # Posición de los iconos [X, Y]
  PAGE_ICONS_POSITION = [226, 2]
  
  # Alineación de iconos (:left, :right, :center)
  PAGE_ICONS_ALIGNMENT = :center
  
  # Tamaño de cada icono [Ancho, Alto]
  PAGE_ICON_SIZE = [52, 60]
end

Opciones Personalizadas por Página

class PokemonSummary_Scene
  # Ejecutar cuando se presiona USE en una página
  def pbPageCustomUse(page_id)
    case page_id
    when :page_custom
      pbMessage("¡Ejecutando acción personalizada!")
      # Tu código aquí
      return true  # Retornar true si se ejecutó correctamente
    end
    return false
  end
  
  # Opción de menú personalizada
  def pbPageCustomOption(cmd)
    case cmd
    when "Reset EV's"
      pbMessage("Se han reseteado los EVs de #{@pokemon.name}.")
      GameData::Stat.each_main { |s| @pokemon.ev[s.id] = 0 }
      @pokemon.calc_stats
      return true
    end
    return false
  end
end

Sistema de Pokédex UI

MUI proporciona handlers para personalizar la interfaz de la Pokédex.

Añadir Páginas a la Pokédex

# Configuración de página de Pokédex
UIHandlers.add(:pokedex, :page_area, {
  "name"   => "Área",
  "suffix" => "area",
  "order"  => 30,
  "layout" => proc { |species, scene|
    # Dibujar información de área
    overlay = scene.sprites["overlay"].bitmap
    pbDrawTextPositions(overlay, [
      ["Área de hábitat:", 10, 10, 0, Color.black, Color.white]
    ])
  }
})

Configuración de Pokédex

# En [000] Pokedex Settings.rb
class Pokedex_Scene
  # Configuraciones similares a Summary
  MAX_PAGE_ICONS = 5
  PAGE_ICONS_SHOW_ARROWS = true
  PAGE_ICONS_POSITION = [226, 2]
  PAGE_ICONS_ALIGNMENT = :center
  PAGE_ICON_SIZE = [52, 60]
end

Gestión Dinámica de Opciones

Iterar sobre Opciones

# Iterar sobre todas las opciones de un menú
UIHandlers.each(:summary) do |option, hash|
  puts "Opción: #{option}"
  puts "Nombre: #{hash['name']}"
end

# Iterar solo sobre opciones disponibles
UIHandlers.each_available(:summary, pokemon) do |option, hash, name, icon, menu|
  # option: ID de la opción
  # hash: Configuración completa
  # name: Nombre traducido
  # icon: Sufijo del icono
  # menu: Array de opciones
  puts "#{name} está disponible"
end

Obtener Información de Opciones

# Obtener nombre de una opción
name = UIHandlers.get_info(:summary, :page_stats, :name)

# Obtener sufijo
suffix = UIHandlers.get_info(:summary, :page_stats, :suffix)

# Obtener opciones disponibles
options = UIHandlers.get_info(:summary, :page_stats, :options)

# Obtener etiquetas de opciones
labels = UIHandlers.get_info(:summary, :page_stats, :options_labels)

Editar Handlers Existentes

# Cambiar el orden de una página
UIHandlers.edit_hash(:summary, :page_stats, "order", 10)

# Cambiar el nombre
UIHandlers.edit_hash(:summary, :page_stats, "name", "Estadísticas")

# Añadir nueva condición
UIHandlers.edit_hash(:summary, :page_stats, "condition", 
  proc { |pkmn| !pkmn.egg? }
)

Sistema de Etiquetas de Opciones

Definir Etiquetas Individuales

# Definir una etiqueta para una opción
UIHandlers.define_option_label(:summary, :page_stats, :view_graph, "Ver Gráfico")

Definir Múltiples Etiquetas

# Definir varias etiquetas a la vez
UIHandlers.define_options_labels(:summary, :page_stats, {
  :view_graph  => "Ver Gráfico",
  :compare     => "Comparar",
  :reset_evs   => "Resetear EVs"
})

Comandos de Menú del Equipo

MUI incluye sistema de comandos para el menú del equipo.
# Ejemplo de uso interno
class PokemonPartyScreen
  def pbPokemonCommands(pkmnid)
    commands = []
    
    # El sistema MUI maneja los comandos automáticamente
    UIHandlers.each_available(:party_commands, @party[pkmnid]) do |cmd, hash, name, icon, menu|
      commands << name
    end
    
    return commands
  end
end

Integración con Plugin Manager

MUI extiende el PluginManager para verificar compatibilidad de versiones.
# Verificación automática de plugins MUI
PluginManager.plugin_check_MUI("2.0.8")

# Lista de plugins verificados automáticamente:
# - [MUI] Enhanced Pokemon UI (1.0.6+)
# - [MUI] Pokedex Data Page (2.0.1+)
# - [MUI] Improved Mementos (1.0.3+)
# - [MUI] Improved Field Skills (1.0.1+)

Ejemplos Prácticos

Ejemplo 1: Página de Biografía de Pokémon

UIHandlers.add(:summary, :page_bio, {
  "name"   => "Biografía",
  "suffix" => "bio",
  "order"  => 60,
  "condition" => proc { |pkmn| !pkmn.egg? },
  "layout" => proc { |pkmn, scene|
    overlay = scene.sprites["overlay"].bitmap
    base_x = 20
    base_y = 80
    
    # Dibujar información biográfica
    textpos = [
      ["Nombre:", base_x, base_y, 0, Color.black, Color.white],
      [pkmn.name, base_x + 100, base_y, 0, Color.new(0, 80, 160), Color.white],
      
      ["Entrenador original:", base_x, base_y + 30, 0, Color.black, Color.white],
      [pkmn.owner.name, base_x + 100, base_y + 30, 0, Color.new(0, 80, 160), Color.white],
      
      ["Fecha de captura:", base_x, base_y + 60, 0, Color.black, Color.white],
      [pbGetTimeText(pkmn.timeReceived), base_x + 100, base_y + 60, 0, Color.new(0, 80, 160), Color.white],
      
      ["Lugar de captura:", base_x, base_y + 90, 0, Color.black, Color.white],
      [pbGetMapNameFromId(pkmn.obtain_map), base_x + 100, base_y + 90, 0, Color.new(0, 80, 160), Color.white]
    ]
    
    pbDrawTextPositions(overlay, textpos)
  },
  "options" => [:view_ribbon, :view_memories],
  "options_labels" => {
    :view_ribbon   => "Ver Cintas",
    :view_memories => "Ver Recuerdos"
  }
})

Ejemplo 2: Sistema de Logros en Resumen

# Añadir página de logros
UIHandlers.add(:summary, :page_achievements, {
  "name"   => proc { "Logros (#{count_achievements(@pokemon)})" },
  "suffix" => "achievements",
  "order"  => 70,
  "condition" => proc { |pkmn| has_achievements?(pkmn) },
  "layout" => proc { |pkmn, scene|
    overlay = scene.sprites["overlay"].bitmap
    achievements = get_achievements(pkmn)
    
    y = 80
    achievements.each_with_index do |achievement, i|
      icon = achievement[:unlocked] ? "unlocked" : "locked"
      # Dibujar icono de logro
      pbDrawImagePositions(overlay, [[
        "Graphics/Pictures/Achievements/#{icon}",
        20, y, 0, 0, 32, 32
      ]])
      
      # Dibujar nombre del logro
      pbDrawTextPositions(overlay, [[
        achievement[:name],
        60, y + 8, 0,
        achievement[:unlocked] ? Color.new(0, 120, 0) : Color.gray,
        Color.white
      ]])
      
      y += 40
    end
  },
  "options" => [:view_all, :share],
  "options_labels" => {
    :view_all => "Ver Todos",
    :share    => "Compartir"
  }
})

# Funciones auxiliares
def count_achievements(pokemon)
  return 0 unless pokemon.achievements
  pokemon.achievements.count { |a| a[:unlocked] }
end

def has_achievements?(pokemon)
  return false unless pokemon.achievements
  return pokemon.achievements.length > 0
end

def get_achievements(pokemon)
  return pokemon.achievements || []
end

Ejemplo 3: Menú Contextual Condicional

# Opciones de menú que cambian según el contexto
UIHandlers.add(:summary, :page_training, {
  "name"   => "Entrenamiento",
  "suffix" => "training",
  "order"  => 40,
  "condition" => proc { |pkmn| !pkmn.egg? && pkmn.level < GameData::GrowthRate.max_level },
  "layout" => proc { |pkmn, scene|
    # Layout de entrenamiento
    overlay = scene.sprites["overlay"].bitmap
    
    # Mostrar EVs restantes
    total_evs = 0
    GameData::Stat.each_main { |s| total_evs += pkmn.ev[s.id] }
    remaining_evs = Pokemon::EV_LIMIT - total_evs
    
    pbDrawTextPositions(overlay, [[
      "EVs restantes: #{remaining_evs}",
      20, 80, 0, Color.black, Color.white
    ]])
  },
  "options" => proc { |pkmn|
    # Opciones dinámicas basadas en el estado del Pokémon
    opts = [:view_evs, :view_ivs]
    
    # Solo permitir resetear EVs si tiene alguno
    total_evs = 0
    GameData::Stat.each_main { |s| total_evs += pkmn.ev[s.id] }
    opts << :reset_evs if total_evs > 0
    
    # Solo permitir entrenar si no está al máximo
    opts << :boost_evs if total_evs < Pokemon::EV_LIMIT
    
    opts
  },
  "options_labels" => {
    :view_evs  => "Ver EVs",
    :view_ivs  => "Ver IVs",
    :reset_evs => "Resetear EVs",
    :boost_evs => "Entrenar"
  }
})

Verificación de Existencia

# Verificar si existe un handler
if UIHandlers.exists?(:summary, :page_stats)
  puts "La página de stats existe"
end

# Usar con seguridad
if UIHandlers.exists?(:summary, :page_custom)
  UIHandlers.edit_hash(:summary, :page_custom, "order", 99)
end

Llamar Funciones de Handlers

# Ejecutar una función específica de un handler
result = UIHandlers.call(:summary, :page_stats, "layout", pokemon, scene)

# Ejemplo con condition
should_show = UIHandlers.call(:summary, :page_moves, "condition", pokemon)

Mejores Prácticas

Orden Lógico

Usa números espaciados (10, 20, 30) para facilitar inserción de nuevas páginas

Condiciones Claras

Siempre proporciona condiciones claras para evitar opciones inválidas

Nombres Descriptivos

Usa nombres de opciones descriptivos y consistentes

Verificar Existencia

Verifica que los handlers existan antes de editarlos
Cuidado con:
  • No sobrescribir handlers existentes sin intención
  • Verificar que las condiciones retornen booleanos
  • Disponer correctamente los recursos gráficos en layouts
  • Mantener el orden de las páginas consistente

Solución de Problemas

Error: “UIHandlers not found”Asegúrate de que Modular UI Scenes esté cargado antes que tu plugin. Añade a tu meta.txt:
Requires = Modular UI Scenes,2.0.8
Las opciones no aparecenVerifica que:
  1. La condición retorne true
  2. El plugin requerido esté instalado (si usas "plugin")
  3. El orden no coloque la opción fuera de rango visible

Recursos y Enlaces

Autor: Lucidious89
Versión: 2.0.9
Compatible con: Pokémon Essentials v21.1
Enlace oficial: Relic Castle - Modular UI Scenes

Plugins que Requieren MUI

Enhanced Pokemon UI

Sistema de UI mejorada (v1.0.6+)

Pokedex Data Page

Página de datos detallados (v2.0.1+)

Lin's IV EV Summary

Pantalla de IVs/EVs (v1.2.1+)

Improved Mementos

Sistema de mementos mejorado (v1.0.3+)

Páginas Relacionadas

Descripción General

Volver al catálogo de plugins

Luka's Utilities

Utilidades complementarias para MUI

Build docs developers (and LLMs) love