Hytale Modding
Server Plugins

Player Input and Keybind Guide

How to handle player input.

The Basics

Hytale Servers do not receive raw keyboard input. Instead, clients send packets of Interaction types:

  • Mouse events - clicks with target info
  • Movement states - 22 boolean flags (walking, jumping, etc.)
  • Interaction types - what action the player is performing

Keybind Limitations

Due to the use of packets not key inputs, you cannot assign your custom Fireball spell to X.

There is a workaround addressed below, but first let's understand the baseline:

You CANNOT:

  • Add new keybinds (keyboard mapping is client-side)
  • Remap existing keys
  • Add more than 3 ability slots

You CAN:

  • Intercept packets and hijack their purpose
  • Use 3 built-in ability slots (Ability1, Ability2, Ability3)
  • Make abilities item-dependent (wand = fireball, sword = slash)
  • Detect hold vs tap, double-click, toggle (via timing)
  • Full mouse control (all 5 buttons, press/release, drag)

Fixed Input Slots

ActionDefault KeyServer ReceivesNotes
Left MouseLMBInteractionType.PrimaryAttack/break
Right MouseRMBInteractionType.SecondaryUse/place
Weapon AbilityQInteractionType.Ability1Active - weapon special
Ability Slot 2InteractionType.Ability2Unused placeholder
Ability Slot 3InteractionType.Ability3Unused placeholder
InteractEInteractionType.UseInteract with world
Pick BlockMMBInteractionType.PickCopy block type
DodgeInteractionType.DodgeDodge roll mechanic

Note: Only Ability1 (Q key) is actively used for weapon abilities. Ability2 and Ability3 exist in the enum but have no default keybinds and nothing in the codebase references them: they appear to be reserved for future use.

These are the only keyboard actions the server sees.


Intercepting Packets

This is the work around to Custom Player Keybinds. By intercepting the input packets you can redirect the event trigger to your own class. There is a major caveat with this strategy: This will override the default Key Mapping unless you otherwise redirect it.

See Client Input Reference for a comprehensive list of all client-to-server packets.

For instance, intercepting Q to use for custom Fireball spell = Hytale Weapon Abilities becoming unusable.

This is because you aren't intercepting Q, but rather InteractionType.Ability1. You would need to redirect a different packet into those recreated abilities in your own mod (this will also of course hijack another packet). The Client Input Reference above shows all packets. Pro Tip: Builder tools when not in creative are a great starting point.

Example: Builder Tools -> Combat Abilities

This is one of the better systems to capture, as it intercepts packets not even used during standard play.

// 1. Grant permission on join (in PlayerReadyEvent handler)
PermissionsModule.get().addUserPermission(
    playerRef.getUuid(),
    Set.of("hytale.editor.builderTools")
);

// 2. Intercept in packet handler
void handleBuilderToolAction(BuilderToolGeneralAction packet, PlayerRef playerRef) {
    Ref<EntityStore> ref = playerRef.getReference();
    if (ref == null) return;
    
    Store<EntityStore> store = ref.getStore();
    Player playerComponent = (Player) store.getComponent(ref, Player.getComponentType());
    
    if (playerComponent.getGameMode() != GameMode.Creative) {
        // Hijack for abilities
        switch (packet.action) {
            case ActivateToolMode -> castFireball(playerRef);   // B pressed
            case DeactivateToolMode -> endFireball(playerRef);  // B released
            case HistoryUndo -> castRewind(playerRef);          // Ctrl+Z
            case HistoryRedo -> castHaste(playerRef);           // Ctrl+Y
            case SelectionCopy -> castClone(playerRef);         // Ctrl+C
        }
        return;  // Don't run actual builder tool logic
    }
    // Creative players get normal behavior
    super.handleBuilderToolAction(packet, playerRef);
}

You can do this with anything, so a custom keybind for UI, gameplay, etc.

Critical Note: If the player changes keybinds you won't know, so your guides have to reference Default Hytale Controls. Also if they change key binds due to your mod (disliking Ctrl+C as an ability for example) the setting follows them, and may impact their experience outside of your ecosystem. Important to consider while choosing packets.


Mouse Inputs

Some useful info about mouse inputs

Listening to Mouse Clicks

@Override
protected void setup() {
    getEventRegistry().register(PlayerMouseButtonEvent.class, event -> {
        MouseButtonEvent mouse = event.getMouseButton();

        if (mouse.mouseButtonType == MouseButtonType.Left
                && mouse.state == MouseButtonState.Pressed) {
            // Left click!
            Entity target = event.getTargetEntity();
            Vector3i block = event.getTargetBlock();
        }

        // Cancel the click
        // event.setCancelled(true);
    });
}

Mouse Button Types

MouseButtonType.Left    // Primary click
MouseButtonType.Right   // Secondary click
MouseButtonType.Middle  // Scroll wheel click
MouseButtonType.X1      // Side button 1
MouseButtonType.X2      // Side button 2
MouseButtonState.Pressed   // Button down
MouseButtonState.Released  // Button up

What You Get From Mouse Events

PropertyTypeDescription
getMouseButton()MouseButtonEventButton type, state, click count
getTargetEntity()EntityEntity under cursor (or null)
getTargetBlock()Vector3iBlock position under cursor
getItemInHand()ItemCurrently held item
getScreenPoint()Vector2fCursor screen position
getPlayer()PlayerThe player who clicked

Double-click detection:

if (mouse.clicks >= 2) {
    // Double-clicked!
}

Imports

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;

Available Player Events

All player events that can be registered via getEventRegistry():

EventDescription
PlayerConnectEventPlayer connecting to server
PlayerDisconnectEventPlayer disconnecting
PlayerSetupConnectEventConnection setup phase
PlayerSetupDisconnectEventDisconnect setup phase
PlayerReadyEventPlayer fully loaded and ready
PlayerChatEventChat message sent
PlayerInteractEventInteraction with world/entities
PlayerMouseButtonEventMouse button press/release
PlayerMouseMotionEventMouse movement
PlayerCraftEventItem crafted
AddPlayerToWorldEventPlayer added to a world
DrainPlayerFromWorldEventPlayer removed from world

Tips

  • 1 ability slot active: Only Ability1 (Q) is currently used - make it item-dependent
  • Cancel events: Use event.setCancelled(true) to block the action
  • Movement states: Check these in systems for continuous monitoring
  • Double-click: Check mouse.clicks >= 2
  • Hold vs tap: Track press/release timing yourself
  • Target info: Events include what block/entity the player was targeting
  • No move event: Poll TransformComponent or check MovementStates instead

From Hytale Server build 2026.01.13-dcad8778f

Geschrieben von Vibe Theory