AnimationBehavior

Defines a single animation rule for a citizen — what triggers it, which animation plays, which slot it occupies, and what happens afterward. A citizen can have multiple AnimationBehavior entries, all stored in a list on CitizenData.

package com.electro.hycitizens.models;

Constructors

AnimationBehavior()

AnimationBehavior(String type, String animationName, int animationSlot,
                  float intervalSeconds, float proximityRange)

AnimationBehavior(String type, String animationName, int animationSlot,
                  float intervalSeconds, float proximityRange,
                  boolean stopAfterTime, String stopAnimationName, float stopTimeSeconds)

The no-arg constructor creates a DEFAULT type animation with empty name on slot 0. Use the full constructor when building animations in code for clarity.

Trigger Types

The type field controls when this animation fires. There are six options:

TypeWhen it firesExtra settings
"DEFAULT" Continuously kept playing as a looping base animation. Re-sent every ~2 seconds to maintain playback. Does not use proximity or interval.
"TIMED" Fires on a repeating timer, regardless of player proximity. intervalSeconds
"ON_INTERACT" Fires when any player interacts with the citizen (F key or left-click).
"ON_ATTACK" Fires when the citizen attacks a player (hostile citizens only).
"ON_PROXIMITY_ENTER" Fires the first time a player enters within proximityRange of the citizen. proximityRange
"ON_PROXIMITY_EXIT" Fires when a player who was within range steps outside proximityRange. proximityRange

getType / setType

@Nonnull String getType()
void setType(@Nonnull String type)

Animation Slots

Hytale plays animations in layers called slots. Each slot operates independently, so a citizen can have a walking animation on slot 0 and a facial expression on slot 3 simultaneously. Often, you will need to use the "Action" slot.

Slot numberLayer nameTypical use
0MovementWalk, run, idle base animations
1StatusDamage reactions, status effect visuals
2ActionAttack swings, tool use
3FaceFacial expressions
4EmoteFull-body emotes (wave, bow, etc.)

getAnimationSlot / setAnimationSlot

int getAnimationSlot()
void setAnimationSlot(int slot)

Default: 0. Values outside 0–4 are clamped to slot 0.

Animation Name

getAnimationName / setAnimationName

@Nonnull String getAnimationName()
void setAnimationName(@Nonnull String name)

The name of the animation asset to play, exactly as it appears in the Hytale animation system. Animation names are model-specific — an animation valid for a Player model may not exist on a Skeleton model. Use animation names from your Emotale mod or from the base Hytale asset pack.

Interval & Proximity

getIntervalSeconds / setIntervalSeconds

float getIntervalSeconds()
void setIntervalSeconds(float seconds)

For TIMED type only. How many seconds between animation plays. Default: 5.0.

getProximityRange / setProximityRange

float getProximityRange()
void setProximityRange(float range)

For ON_PROXIMITY_ENTER and ON_PROXIMITY_EXIT types. The distance in blocks that defines the proximity zone. Default: 8.0.

Auto-Stop

For animations that should play for a fixed duration and then return to a rest animation, use the stop-after-time settings.

isStopAfterTime / setStopAfterTime

boolean isStopAfterTime()
void setStopAfterTime(boolean stopAfterTime)

When true, the stop animation plays after stopTimeSeconds have passed. Default: false.

getStopAnimationName / setStopAnimationName

@Nonnull String getStopAnimationName()
void setStopAnimationName(@Nonnull String name)

The animation to play after the stop timer fires. If empty, HyCitizens falls back to the citizen's DEFAULT animation on the same slot. Default: "".

getStopTimeSeconds / setStopTimeSeconds

float getStopTimeSeconds()
void setStopTimeSeconds(float seconds)

How long to play the main animation before switching to the stop animation. Default: 3.0.

⚠️

Auto-stop only makes sense for non-looping animations

If your animation loops, auto-stop will interrupt it mid-loop. Reserve stopAfterTime for one-shot animations like emotes or attack strikes that you want to play for a fixed time before returning to an idle pose.

Examples

A looping idle animation (DEFAULT)

// Citizen always plays their Idle animation on slot 0
new AnimationBehavior("DEFAULT", "Idle", 0, 0f, 0f)

A wave emote when a player interacts

// Play "Emote_Wave" on slot 4, then return to Idle after 2.5 seconds
new AnimationBehavior(
    "ON_INTERACT",  // trigger
    "Emote_Wave",   // animation to play
    4,              // Emote slot
    0f,             // interval (unused for ON_INTERACT)
    0f,             // proximity (unused for ON_INTERACT)
    true,           // stop after time
    "Idle",         // return to Idle when done
    2.5f            // play for 2.5 seconds
)

A greeting animation when a player walks near

// Wave when a player enters within 8 blocks
new AnimationBehavior(
    "ON_PROXIMITY_ENTER",
    "Emote_Wave",
    4,
    0f,
    8.0f,   // trigger within 8 blocks
    true,
    "Idle",
    2.0f
)

A timed animation every 15 seconds

// Play a stretch animation every 15 seconds
new AnimationBehavior(
    "TIMED",
    "Emote_Stretch",
    4,
    15.0f,  // every 15 seconds
    0f,
    true,
    "Idle",
    3.0f
)

Applying animations to a citizen

List<AnimationBehavior> animations = new ArrayList<>();

// Looping idle base
animations.add(new AnimationBehavior("DEFAULT", "Idle", 0, 0f, 0f));

// Wave on interact
animations.add(new AnimationBehavior("ON_INTERACT", "Emote_Wave", 4, 0f, 0f, true, "Idle", 2.5f));

// Stretch every 20 seconds
animations.add(new AnimationBehavior("TIMED", "Emote_Stretch", 4, 20.0f, 0f, true, "Idle", 3.0f));

citizen.setAnimationBehaviors(animations);
manager.updateCitizenNPC(citizen, true);