GUI
Descripción general
GUI convierte una sola entrada de TypeWriter, Open GUI, en un menú de inventario completo. Eliges el tipo de contenedor (un cofre, un yunque, una ventana de comerciante, un libro escrito...), escribes un título en MiniMessage y describes el contenido como un árbol de layouts almacenado en el layoutPool de la entrada. Cada layout coloca items: un material, un nombre, algo de lore y lo que ocurre cuando un jugador hace clic en él.
Todo se edita en el panel web: no hay archivos de menú que escribir a mano. Un menú se abre como cualquier otra acción, desde un paso de misión, un diálogo de NPC, un evento de comando u otro menú. Los clics ejecutan comandos de consola, activan otras entradas y modifican facts, de modo que un menú es solo otra forma de dirigir tus páginas de TypeWriter.
GUI es también la base de las demás extensiones de menús de BTC. Shops y Quest Codex no incluyen su propia ventana: colocan items marcadores en un layout de open_gui y la extensión los rellena con productos o misiones.
Características
- Diez layouts —
simple,flex,paginated,scrollable,frame,composite,book,merchant,storageyleaderboard. - 24 tipos de contenedor — cofres de 9 a 54 ranuras, además de yunque, mesa de encantamientos, mesa de herrería, cortapiedras, piedra de afilar, telar, mesa de cartografía, comerciante, libro, tolva, hornos y más.
- MiniMessage en todas partes — colores, degradados y placeholders de PlaceholderAPI en títulos, nombres de items y lore.
- Acciones de clic por tipo de clic — izquierdo, derecho, con shift, central, doble clic, teclas numéricas, soltar e intercambio con la mano secundaria, cada uno con sus propios comandos y triggers.
- Permisos de ranura — oculta una ranura con
viewPermissiono déjala visible pero inerte conclickPermission. - Repetición de ranuras — rellena una fila o un bloque con
count,direction,gapyrepeatYen lugar de copiar items. - Vistas y pestañas — un solo armazón de menú, varias pantallas, con un título de ruta de navegación y pestañas que se iluminan.
- Almacenamiento persistente — ranuras que conservan sus items por jugador o por grupo, con cuotas, placeholders y soltado opcional al cerrar.
- Clasificaciones — ordena jugadores, mundos o grupos según uno o más facts, incluidos los jugadores desconectados, o muestra las filas que aporta otra extensión mediante el campo
source(por ejemplo, las estadísticas de Dungeon). - Inventario extendido — convierte el inventario del propio jugador en cuatro filas extra de menú para un lienzo de diez filas.
Instalación
- Instala TypeWriter en un servidor Paper o Folia. PacketEvents, que TypeWriter ya requiere, debe estar presente.
- Descarga el JAR desde las versiones en GitHub de GUI (el botón del panel de resumen de arriba).
- Colócalo en
plugins/Typewriter/extensions/y reinicia el servidor. - Opcional: instala CraftEngine si tus títulos usan etiquetas
<image>o<shift>para dibujar fondos personalizados.
Instala GUI antes que las extensiones que dependen de ella, como Shops y Quest Codex.
La versión pública de GUI no incluye un editor de menús independiente ni su servidor web: los menús se editan en el panel web de TypeWriter. La versión solo incluye una comprobación de inicio que lee tus entradas open_gui publicadas e informa en la consola de los menús defectuosos (consulta Solución de problemas).
Primeros pasos
Crea un pequeño menú de tres botones:
- En el panel web, abre una página de sequence y añade una entrada Open GUI. Llámala
main_menu. - Establece
guiTypeenCUSTOM,sizeenSIZE_27ytitleen<gold>Main menu. - En
layoutPool, añade un layout de tiposimple, dale elidmainy escribemainenmainLayoutId. - En los
itemsdel layout, añade un item enx4,y1. Elige unDIAMONDenitem, establecedisplayNameen<aqua>Rewardsy añade una línea delore<gray>Click to claim. - En
interactionList, añade una interacción contypeLEFT_CLICK. Añade acommandsun comando de consola comogive %player% diamond 1, o enlaza una entrada entriggers. ActivacloseMenupara cerrar el menú tras el clic. - Añade un segundo item
simpleconcount9,directionrighty un panel de cristal tintado gris para dibujar una fila de borde. Establece sudisplayNameen un solo espacio. - Enlaza la entrada Open GUI con algo que la lance, por ejemplo el trigger de una opción de diálogo o un evento de comando, y luego Publish.
Haz que un único layout simple funcione en el juego antes de añadir capas frame, scrollable o paginated. Cada layout se identifica por su id, así que un mainLayoutId mal escrito es lo primero que hay que revisar cuando un menú se abre vacío.
Cómo funciona
Cuando se lanza la acción, la extensión construye el árbol de layouts para ese jugador (los criterios y permisos se evalúan en ese momento), registra una sesión de menú y muestra el inventario. Cada clic se resuelve contra la ranura de esa posición y luego ejecuta la interacción correspondiente. La sesión recuerda los menús anteriores, así que gui:back vuelve al menú del que venía el jugador.
Menús
Tipos de contenedor
guiType selecciona la ventana. CUSTOM es un inventario sencillo similar a un cofre cuya altura eliges con size. size solo se aplica a CUSTOM y por defecto es de seis filas; los demás tipos usan el tamaño de vanilla de su ventana.
guiType | Ventana |
|---|---|
CUSTOM, CHEST, ENDER_CHEST, BARREL, SHULKER_BOX | Cuadrículas de estilo cofre. Para CUSTOM, size es SIZE_9, SIZE_18, SIZE_27, SIZE_36, SIZE_45 o SIZE_54. |
HOPPER, DISPENSER, DROPPER | Contenedores pequeños de tamaño fijo. |
FURNACE, BLAST_FURNACE, SMOKER, BREWING_STAND, BEACON | Ventanas de máquinas. |
CRAFTING_TABLE, ENCHANTING_TABLE, ANVIL, SMITHING_TABLE, GRINDSTONE, LOOM, CARTOGRAPHY_TABLE, STONECUTTER | Mesas de trabajo de vanilla. Sin layout se comportan como la pantalla de vanilla; GUI solo gestiona la apertura y el cierre. |
MERCHANT, VILLAGER_TRADE | La ventana de intercambio de aldeanos, rellenada por un layout merchant. |
BOOK | Un libro escrito, rellenado por un layout book. |
Layouts
Cada layout es una entrada con nombre de layoutPool. El indicado en mainLayoutId es la raíz; a los demás se llega mediante referencias (hijos de composite, innerId de scrollable, layoutId de frame).
| Layout | Úsalo para | Campos clave |
|---|---|---|
simple | Botones fijos y decoración en posiciones x/y. | items |
flex | Items distribuidos automáticamente en filas. | justifyContent (START, CENTER, END, SPACE_BETWEEN), alignItems, wrap, virtualHeight |
paginated | Una lista larga dividida en páginas. | itemsPerPage, slots, items, navigationButtons (NEXT, PREVIOUS, BACK, INDICATOR) |
scrollable | Contenido más alto o más ancho que la ventana. | innerId, virtualWidth, virtualHeight, buttons (direction, step), showDefaultButtons, defaultStep |
frame | Varios rectángulos independientes, por ejemplo pestañas, contenido y un pie. | frames (id, x, y, width, height, layoutId) |
composite | Apilar capas: fondo, contenido, botones. | children (ids de layouts, los últimos se dibujan encima) |
book | Las páginas de un libro escrito. | pages (MiniMessage) |
merchant | Intercambios de aldeanos con items personalizados. | trades (result, costOne, costTwo, maxUses, criteria) |
storage | Ranuras persistentes respaldadas por un artefacto GUI Storage. | entry, groupKey, slots |
leaderboard | Filas de clasificación con páginas, a partir de facts o de la source de otra extensión. | leaderboard, x, y, width, height, previousButton, nextButton |
Un layout book o merchant solo funciona como layout principal, y guiType se sustituye por la ventana correspondiente. Un layout scrollable recibe flechas por defecto mientras showDefaultButtons está activado (valor por defecto): una por cada dirección sin entrada en buttons, consulta Layouts, marcos y ranuras.
Consulta Layouts, marcos y ranuras para un recorrido detallado por cada layout.
Items y ranuras
Cada item de un layout es una descripción de ranura con los mismos campos:
| Campo | Función |
|---|---|
item | El objeto que se muestra. Si se deja vacío, la ranura muestra el objeto que el jugador tiene en la mano principal. |
displayName, lore | Texto MiniMessage con soporte de PlaceholderAPI. Los nombres van en vertical por defecto; añade <italic> si quieres cursiva. Un displayName vacío conserva el nombre del objeto en lugar de sustituirlo por uno vacío. |
x, y | Columna de 0 a 8 y fila desde 0 arriba. |
rollPerSlot | Para un objeto repetido en varios slots cuyo item es aleatorio: desactivado (por defecto), se sortea una vez y todos los slots muestran ese resultado; activado, cada slot sortea por su cuenta al abrir el menú. El resultado se conserva mientras el menú sigue abierto, salvo que liveItem esté activado. |
liveItem | Desactivado (por defecto): el objeto se sortea al abrir el menú y se conserva toda la sesión; al actualizar, solo siguen su nombre y su descripción. Activado: el objeto se evalúa de nuevo en cada actualización, así que un objeto aleatorio se sortea otra vez cada vez. Con rollPerSlot activado, cada slot repetido sortea por su cuenta en cada actualización; si no, todos los slots repetidos comparten un sorteo por actualización. Un nombre vacío sigue ignorándose. |
count, direction, gap, repeatY | Repetición de ranuras, ver más abajo. |
criteria | La ranura no se dibuja para los jugadores que no la cumplen. |
viewPermission | Permiso necesario para ver la ranura. |
clickPermission | Permiso necesario para usar la ranura; sin él, la ranura se dibuja pero queda inerte. |
allowPickup, isGhost | Si el objeto se puede sacar del menú. Ambos están desactivados por defecto; los items fantasma se pueden pulsar pero nunca mover ni copiar. |
cooldownTicks | Ticks antes de que se pueda volver a hacer clic en la misma ranura. |
interactionList, triggers, modifiers | Lo que hace un clic. |
input | Abre un diálogo de entrada de texto al hacer clic. |
storageId | Convierte la ranura en una ranura de almacenamiento persistente de storagePool. |
buttonType, buttonPrefix | Marca la ranura como un botón proporcionado por otra extensión. |
animation | Mueve la ranura a una posición objetivo durante una duración en milisegundos cuando se abre el menú. |
Repetición de ranuras. count repite un item a lo largo de direction (right, left, down, up). gap es un paso, no un espaciado: 1 es adyacente, 2 deja una ranura vacía entre copias y 0 se comporta como 1. repeatY repite toda la línea en el eje perpendicular. Sin direction, count, gap y repeatY se ignoran y se coloca una sola ranura. Estos campos cuentan ranuras, nunca el tamaño de la pila del objeto.
Solapamientos. Cuando dos ranuras comparten una celda, la que hace algo (una acción de clic, una etiqueta, una ranura de almacenamiento) prevalece sobre una puramente decorativa, sea cual sea el orden. Entre dos del mismo tipo gana la última declarada. Se registra una vez una advertencia con el nombre de la celda.
Acciones de clic
interactionList asocia un tipo de clic a comandos y triggers. Los tipos disponibles son LEFT_CLICK, RIGHT_CLICK, SHIFT_LEFT_CLICK, SHIFT_RIGHT_CLICK, MIDDLE_CLICK, DOUBLE_CLICK, NUMBER_KEY_1 a NUMBER_KEY_9, DROP, DROP_ALL y SWAP_OFFHAND.
commandsse ejecutan desde la consola.%player%se sustituye por el nombre del jugador, y los placeholders de PlaceholderAPI se resuelven primero.triggersactivan entradas de TypeWriter para el jugador. Lostriggersymodifierspropios de la ranura se activan en cada clic izquierdo o derecho, o siempre que coincida una interacción concreta.closeMenucierra la ventana después de la acción.executeReturnvuelve al menú anterior.
Los comandos que empiezan por gui: los gestiona la propia GUI:
| Comando | Efecto |
|---|---|
gui:close | Cierra el menú. |
gui:back | Reabre el menú anterior de la sesión. |
gui:open <entry_id> o gui:action <entry_id> | Activa otra entrada, normalmente otro Open GUI. |
gui:view <view_id> | Cambia a otra vista sin cerrar el inventario. |
gui:page <delta> [layout_id] | Mueve un layout paginated o leaderboard esa cantidad de páginas. |
gui:scroll <dx> <dy> [layout_id] | Desplaza un layout scrollable. |
gui:refresh | Vuelve a dibujar el menú ahora. |
gui:sound <sound_key> | Reproduce un sonido al jugador. |
Abrir, volver y cerrar
Un Open GUI abierto desde otro menú se añade al historial de la sesión, de modo que gui:back o executeReturn vuelve a él. Cerrar con Escape termina la sesión. Abrir un layout book termina antes la sesión actual.
Establece audio para reproducir sonidos al abrir, cerrar, desplazar y hacer clic. Establece autoRefreshTicks para volver a dibujar el menú cada N ticks mientras está abierto, que es lo que hace que los placeholders de nombres y lore avancen como un contador o un temporizador.
Vistas, pestañas y herencia
views convierten un open_gui en varias pantallas que comparten el mismo armazón. Un frame cuyo layoutId es @view se rellena con el layout de la vista activa: primero la asignación explícita frames de la vista, luego el layout llamado <view id>_<frame id> y después las mismas búsquedas en el parentId de la vista. Marca un item de pestaña con buttonPrefix view: y buttonType con el id de la vista, y cambia de vista al hacer clic y se ilumina mientras está activa. El título de la vista acepta {breadcrumb}, {view} y {root}.
baseMenuId apunta a otro Open GUI y combina su layoutPool, views y storagePool bajo los tuyos: un layout con el mismo id sustituye al heredado. Detalles en Vistas, pestañas y herencia.
Ranuras de almacenamiento
Un artefacto GUI Storage guarda los items, por jugador o por grupo. Declara configuraciones reutilizables en el storagePool de la entrada y luego dale a un item un storageId, o usa un layout storage. Los nombres y el lore de los items de una ranura de almacenamiento aceptan {stored_name}, {stored_amount} y {stored_max}. {score_raw} y {value_<key>} también existen para las filas de una clasificación con source.
Asignaciones de clic por defecto, que puedes cambiar en GUI Global Settings:
| Acción | Clic por defecto |
|---|---|
| Colocar un item del cursor | Clic izquierdo |
| Colocar toda la pila del cursor | Shift + clic izquierdo |
| Tomar un item | Clic derecho |
| Tomar todo | Clic izquierdo |
| Tomar una pila | Shift + clic derecho |
| Rellenar desde el inventario | Intercambiar mano secundaria (F) |
| Soltar todo en el suelo | Soltar (Q) |
dropOnClose suelta a los pies del jugador lo que aún está almacenado cuando el menú se cierra de verdad, con Escape o al desconectarse, pero no cuando el jugador pasa a otro menú.
Inventario extendido
extendToPlayerInventory muestra las 36 ranuras del propio jugador como cuatro filas extra, para un lienzo de diez filas (y de 0 a 9). Solo funciona en el lado del cliente: el inventario real nunca se modifica y se restaura al cerrar el menú, y no se pueden recoger items de las filas inferiores. Requiere guiType CUSTOM con size SIZE_54. Un layout raíz cuyo id termina en _extended lo activa por sí mismo.
Configuración
GUI no tiene archivo de configuración. Dos entradas de manifest opcionales la ajustan:
- GUI Extension Configuration activa el registro
debugy la opciónhideVanillaItemStats, activada por defecto, que oculta las líneas de daño de ataque, durabilidad y encantamientos en los botones del menú. - GUI Global Settings establece las asignaciones de clic del almacenamiento y los items conectores del árbol de habilidades.
Placeholders
| Placeholder | Devuelve |
|---|---|
%typewriter_gui_storage_amount_<entry_id>_<slot_index>% | Número de items almacenados para el jugador en una entrada GUI Storage, 0 si está vacía. |
%typewriter_gui_storage_has_<entry_id>_<slot_index>% | true cuando la ranura contiene un item, false en caso contrario. |
<slot_index> es y * 9 + x de la ranura de almacenamiento. Estos placeholders leen siempre el almacenamiento propio del jugador, nunca un almacenamiento de grupo compartido.
Dentro de los menús, la extensión sustituye los siguientes tokens: {stored_name}, {stored_amount}, {stored_max} (ranuras de almacenamiento), {page}, {next_page}, {prev_page}, {total_pages} y {page_indicator} (el botón INDICATOR de un layout paginated), y {rank}, {name}, {score}, {group}, {world} y {score_<fact_id>} (filas de leaderboard).
Entradas
6 entradas, generadas a partir del código fuente de la extensión.
Acciones1
- Open GUIOpen a GUI for the player
Artefactos2
- GUI Leaderboard PopulationOffline population data for GUI leaderboards
- GUI StoragePersistent storage artifact for GUI storage slots
Manifiestos3
- GUI ConfigGUI Extension Configuration
- GUI LeaderboardGUI leaderboard backed by Typewriter facts
- GUI SettingsGUI Global Settings
Solución de problemas
El menú se abre vacío. mainLayoutId está en blanco o no coincide con ningún id de layout en layoutPool (los ids distinguen mayúsculas de minúsculas). Al usar baseMenuId, un mainLayoutId en blanco recurre al del padre. La comprobación de inicio informa en la consola de un layout principal sin resolver.
Falta una ranura y la consola dice "falls outside the grid". El item quedó en una x o y negativa, o más allá de la columna 8. Normalmente se debe a un count demasiado grande, que cuenta ranuras. El registro indica el layout y las coordenadas rechazadas.
La consola dice "Slot overlap ... gap". Dos ranuras comparten una celda. gap es un paso: 1 coloca ranuras adyacentes y 2 deja una ranura vacía entre cada una, así que quien interpreta gap: 1 como "un hueco" obtiene copias encima de las vecinas. Cambia gap o mueve una ranura.
Una ranura es visible para los admins pero no para los jugadores. viewPermission nombra un permiso que solo tienen los operadores. Los valores en blanco se ignoran, pero un error tipográfico es un nodo real, solo para operadores. La misma regla se aplica al viewPermission de una vista.
Un botón se muestra pero no hace nada. Revisa clickPermission, luego cooldownTicks y luego criteria. Si la ranura tiene un buttonType, su buttonPrefix debe coincidir con la extensión que lo proporciona; una etiqueta no reclamada conserva tu propio interactionList pero nada más. Los comandos se ejecutan desde la consola, así que un comando que necesita un jugador como emisor falla en silencio.
El contenido desplazable no se mueve. Comprueba que el contenido es mayor que la ventana (virtualWidth y virtualHeight): una flecha solo se muestra mientras haya algo que desplazar en su dirección. Con showDefaultButtons desactivado y sin buttons, no hay ninguna flecha. Una flecha por defecto también cede su casilla cuando ya contiene un objeto de contenido, un botón o una decoración: no se registra nada en la consola, así que muévela con scrollArrows en GUI Settings o añade tus propios buttons con una direction y un step, fuera del área desplazada.
La clasificación solo lista a los jugadores conectados. Enlaza un artefacto GUI Leaderboard Population en el campo population de la clasificación para conservar los últimos valores conocidos de los jugadores desconectados.
El menú extendido no muestra diez filas. extendToPlayerInventory necesita guiType CUSTOM y size SIZE_54.
Extensiones relacionadas
- Shops — menús de tienda construidos sobre layouts de GUI y el marcador
shop_button:. - Quest Codex — el menú del diario de misiones, construido sobre el mismo chasis
open_gui.