Hytale no recibe entrada directa del teclado. En su lugar, el cliente envía paquetes de interacción que incluyen:
- Eventos del ratón (clics con información de objetivo)
- Estados de movimiento (22 flags booleanas: caminar, saltar, etc.)
- Tipos de interacción (acción que el jugador está realizando)
Limitaciones de las Teclas
Debido al uso de paquetes en lugar de teclas, no puedes asignar directamente, por ejemplo, un hechizo de Fireball a la tecla X.
No puedes:
- Añadir nuevas teclas personalizadas (la asignación es del cliente)
- Remapear teclas existentes
- Tener más de 3 ranuras de habilidad
Puedes:
- Interceptar paquetes y redirigir su uso
- Usar 3 ranuras de habilidad (
Ability1,Ability2,Ability3) - Hacer habilidades dependientes del objeto (varita = fireball, espada = golpe)
- Detectar mantener pulsado vs tap, doble clic, toggle
- Control completo del ratón (5 botones, presionar/soltar, arrastrar)
Ranuras de Entrada Fijas
| Acción | Tecla por defecto | Lo recibe el servidor | Notas |
|---|---|---|---|
| Ataque/romper | LMB | InteractionType.Primary | Click izquierdo |
| Usar/colocar | RMB | InteractionType.Secondary | Click derecho |
| Habilidad arma | Q | InteractionType.Ability1 | Activar habilidad del arma |
| Habilidad 2 | E | InteractionType.Ability2 | Placeholder |
| Habilidad 3 | R | InteractionType.Ability3 | Placeholder |
| Interactuar | F | InteractionType.Use | Interactuar con el mundo |
| Copiar bloque | MMB | InteractionType.Pick | Pick Block |
| Esquivar | LCTRL | InteractionType.Dodge | Roll/Esquivar |
Nota: Solo
Ability1(Q) se usa activamente. Las demás existen pero no tienen funcionalidad por defecto.
Interceptando Paquetes
Esta es la estrategia para crear teclas personalizadas. Al interceptar paquetes, puedes redirigirlos a tu propia lógica.
Cuidado: Esto sobrescribe el comportamiento de la tecla original si no lo rediriges manualmente.
Consulta la Referencia de Entrada del Cliente para ver todos los paquetes cliente → servidor.
Ejemplo: interceptar Q para un Fireball reemplaza la habilidad por defecto de armas.
Ejemplo: Builder Tools → Habilidades de Combate
// 1. Conceder permisos al unirse
PermissionsModule.get().addUserPermission(
playerRef.getUuid(),
Set.of("hytale.editor.builderTools")
);
// 2. Interceptar paquete
void handleBuilderToolAction(BuilderToolGeneralAction packet, PlayerRef playerRef) {
Ref ref = playerRef.getReference();
if (ref == null) return;
Store store = ref.getStore();
Player playerComponent = (Player) store.getComponent(ref, Player.getComponentType());
if (playerComponent.getGameMode() != GameMode.Creative) {
switch (packet.action) {
case ActivateToolMode -> castFireball(playerRef); // B presionada
case DeactivateToolMode -> endFireball(playerRef); // B soltada
case HistoryUndo -> castRewind(playerRef); // Ctrl+Z
case HistoryRedo -> castHaste(playerRef); // Ctrl+Y
case SelectionCopy -> castClone(playerRef); // Ctrl+C
}
return; // Evita ejecutar la lógica original
}
super.handleBuilderToolAction(packet, playerRef); // Creativo: comportamiento normal
}
Nota crítica: Si el jugador cambia las teclas, no lo sabrás. Debes basarte en controles por defecto.
Eventos del Ratón
Escuchar clics del ratón
@Override
protected void setup() {
getEventRegistry().register(PlayerMouseButtonEvent.class, event -> {
MouseButtonEvent mouse = event.getMouseButton();
if(mouse.mouseButtonType == MouseButtonType.Left
&& mouse.state == MouseButtonState.Pressed) {
// Click izquierdo
Entity target = event.getTargetEntity();
Vector3i block = event.getTargetBlock();
}
// Cancelar el clic si se desea
// event.setCancelled(true);
});
}
Tipos de botón del ratón
MouseButtonType.Left // Click primario
MouseButtonType.Right // Click secundario
MouseButtonType.Middle // Scroll
MouseButtonType.X1 // Botón lateral 1
MouseButtonType.X2 // Botón lateral 2
MouseButtonState.Pressed // Presionado
MouseButtonState.Released // Soltado
Propiedades de los eventos del ratón
| Propiedad | Tipo | Descripción |
|---|---|---|
getMouseButton() | MouseButtonEvent | Tipo de botón, estado, clicks |
getTargetEntity() | Entity | Entidad bajo el cursor (o null) |
getTargetBlock() | Vector3i | Posición de bloque bajo cursor |
getItemInHand() | Item | Objeto que sostiene el jugador |
getScreenPoint() | Vector2f | Posición del cursor en pantalla |
getPlayer() | Player | Jugador que hizo click |
Detección de doble clic:
if (mouse.clicks >= 2) {
// Doble clic detectado
}
Imports necesarios
import com.hypixel.hytale.protocol.MouseButtonType;
import com.hypixel.hytale.protocol.MouseButtonState;
import com.hypixel.hytale.protocol.MouseButtonEvent;
import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.server.core.event.events.player.PlayerMouseButtonEvent;
import com.hypixel.hytale.server.core.event.events.player.PlayerMouseMotionEvent;
Eventos del Jugador Disponibles
| Evento | Descripción |
|---|---|
PlayerConnectEvent | Jugador conectándose |
PlayerDisconnectEvent | Jugador desconectándose |
PlayerSetupConnectEvent | Fase de setup de conexión |
PlayerSetupDisconnectEvent | Fase de desconexión |
PlayerReadyEvent | Jugador listo |
PlayerChatEvent | Envío de mensaje |
PlayerInteractEvent | Interacción con mundo/entidades |
PlayerMouseButtonEvent | Click del ratón |
PlayerMouseMotionEvent | Movimiento del ratón |
PlayerCraftEvent | Creación de items |
AddPlayerToWorldEvent | Jugador agregado a un mundo |
DrainPlayerFromWorldEvent | Jugador removido de mundo |
Tips y Buenas Prácticas
- Solo una ranura de habilidad activa:
Ability1(Q), hacerla dependiente de objeto - Cancelar eventos:
event.setCancelled(true) - Estados de movimiento: revisar en sistemas para monitoreo continuo
- Doble clic:
mouse.clicks >= 2 - Mantener pulsado vs tap: trackear manualmente tiempo de presión
- Información de objetivo: incluye bloque o entidad objetivo
- No hay evento de movimiento: usar
TransformComponentoMovementStates
Fuente: Hytale Server build 2026.01.13-dcad8778f
