Skip to main content
Version: GeckoLib5

Molang

Molang is a powerful expression-based language that can be used to make complex and impressive animations. It does require surpassing a small learning curve to initially pick up, but once learned, it becomes intuitive and a very useful tool.

What is it exactly?

Molang allows you to type directly write mathematical expressions into your animation keyframe, allowing you to dynamic animations with minimal effort.
For example, instead of typing 20 into your keyframe animation value, you could type 5 * 4, which would automatically evaluate to 20.

That doesn't seem very useful at face value, but when you add in the ability to use mathematical functions and queries, it becomes much more powerful.
For example, you could use the math.cos function to automatically calculate the cosine of a value: math.cos(5).

Or you can use queries, which are a way to retrieve in-game values as doubles for direct magic use in your expressions.
For example, you could use the query.anim_time query to base your animation off the time in seconds the animation has been running:
math.cos(query.anim_time) would cause your animation to automatically move back and forth smoothly, without any further effort

You can start to see from here where this is going. When you allow for both queries and functions, and full mathematical expression, it becomes obvious how powerful this can be, especially when you start to consider more complex expressions.

E.G.
((-0.2 + 1.5 * (math.abs(math.mod(query.ground_speed, 13) - 6.5) - 3.25) / 3.25) * query.ground_speed) * 57.3

More Info

You can read more information on Molang here.
Note that GeckoLib's implementation of Molang is slightly different to Microsoft's, in that some queries or functions may take slightly different arguments, or some may be added or missing.

Expressions

GeckoLib supports most basic logical and mathematical operators, as well as most standard queries and functions, which can be combined in any sensible way. See below for supported feature components in GeckoLib

Operators

Operators are expression symbols that represent an action to take in the expression.

Supported Operators
OperatorFunctionDescription
+AdditionAdds two values together
-SubtractionSubtracts one value from another
*MultiplicationMultiplies one value by another
/DivisionDivides one value by another
%ModulusReturns the modulo (remainder) when dividing one number by another
^ExponentRaise one value to the power of another
&&Logical ANDReturns 1 if both conditions return a non-zero value, otherwise 0
||Logical ORReturns 1 if either condition returns a non-zero value, otherwise 0
!Logical NOTReturns 1 if the following value returns 0, otherwise 1
<Less ThanReturns 1 if the left value is smaller than the right value, otherwise 0
<=Less Than or EqualReturns 1 if the left value is smaller than or equal to the right value, otherwise 0
>Greater ThanReturns 1 if the left value is larger than the right value, otherwise 0
>=Greater Than or EqualReturns 1 if the left value is larger than or equal to the right value, otherwise 0
==EqualReturns 1 if the left value is equal to the right value, otherwise 0
!=Not EqualReturns 1 if the left value is not equal to the right value, otherwise 0
=Variable AssignmentSets a user-determined variable to the given value, for arbitrary use elsewhere
? :TernaryEvaluates the left expression. If a non-zero value given, return the middle expression, otherwise return the right expression
()BracketsEvaluates the expression inside the brackets before exposing it to outside expression conditions
;Compound Expression SeparatorDelimiter to split your expression into multiple expressions that run in order before returning the final expression's value. Typically used for variable assignments

Functions

Functions are expression components that allow the provision of one or more numerical parameters to generate a resultant value.

Supported Functions
NameFunctionDescriptionParameters
math.absAbsoluteReturns the absolute (non-negative) equivalent of the input valueinput
math.acosArc-cosineReturns the arc-cosine of the input value angle, with the input angle converted to radiansinput (degrees)
math.asinArc-sineReturns the arc-sine of the input value angle, with the input angle converted to radiansinput (degrees)
math.atanArc-tangentReturns the arc-tangent of the input value angle, with the input angle converted to radiansinput (degrees)
math.atan2Arc-tangent (theta)Returns the arc-tangent theta of the input rectangular coordinate values (y,x), with the output converted to degreesy, x
math.ceilCeilingReturns the smallest value that is greater than or equal to the input value and is equal to an integerinput
math.clampClampReturns the first input value if is larger than the second input value and less than the third input value; or else returns the nearest of the second two input valuesvalue, min, max
math.cosCosineReturns the cosine of the input value angle, with the input angle converted to radiansinput (degrees)
math.die_rollDice RollReturns a random value determined by the sum of n random values generated within in a given range, optionally seededrolls, minroll, maxroll, seed (Optional)
math.die_roll_integerDice Roll (Integer)Returns a random value determined by the sum of n random values generated within in a given range, optionally seeded, with the resultant value being an integerrolls, minroll, maxroll, seed (Optional)
math.expEuler's ExponentReturns euler's number raised to the power of the input valueinput
math.floorFloorReturns the largest value that is less than or equal to the input value and is equal to an integerinput
math.hermite_blendHermite InterpolationReturns the Hermite Polynomial (basis 3t^2 - 2t^3) curve interpolation value based on the input valueinput
math.lerpLinear-InterpolateReturns the first value plus the difference between the first and second input values multiplied by the third input valuemin, max, delta
math.lerprotateRotational Linear-InterpolationReturns the first value plus the difference between the first and second input values multiplied by the third input value, wrapping the end result as a degrees valuemin, max, delta
math.lnEuler-LogarithmicReturns the log value (euler base) of the input valueinput
math.maxMaxReturns the greater of the two input valuesinputA, inputB
math.minMinReturns the lesser of the two input valuesinputA, inputB
math.modModulusReturns the remainder value of the input value when modulo'd by the modulus valueinput, modulus
math.piPIReturns PI (π)None
math.powExponentReturns the input value raised to the power of the second input valueinput, exponent
math.randomRandomReturns a random value between 0 and inputA, or between inputA and inputB, optionally seededinputA, inputB (Optional), seed (Optional)
math.random_integerRandom IntegerReturns a random value between 0 and inputA, or between inputA and inputB, optionally seeded, with the resultant value being an integerinputA, inputB (Optional), seed (Optional)
math.roundRoundReturns the closest integer value to the input valueinput
math.sinSineReturns the sine of the input value angle, with the input angle converted to radiansinput (degrees)
math.sqrtSquare-rootReturns the square root of the input valueinput
math.to_degRadians-to-DegreesConverts the input radians value to degreesinput (radians)
math.to_radDegrees-to-RadiansConverts the input degrees value to radiansinput (degrees)
math.truncTruncateReturns the closest value that is equal to the input value or closer to zero, and is equal to an integerinput

Custom Functions

GeckoLib supports users adding their own functions for use in Molang expressions. This is done via MathParser#registerFunction

warning

Custom functions must be registered in your mod constructor.

Queries

Queries are expression components that allow for in-code values to be provided to animations dynamically at runtime, allowing for expressions to take advantage of live data Note that some queries only apply to certain animatable types, and attempting to use them on an incompatible animatable will return 0 and error in the log.

All expressions below have their values automatically provided by GeckoLib.

Supported Queries
NameQueryDescriptionApplies To
query.actor_countActor CountNumber of rendered entities in the last render passGlobal
query.anim_timeAnimation TimeTime (in seconds) that the current animation has been running forAny animatable
query.block_stateBlockstate IndexThe index of the current blockstate variantBlockEntity
query.blockingBlockingReturns 1 if the entity is blocking, otherwise 0LivingEntity
query.body_x_rotationX Body RotationThe pitch rotation of the entityEntity
query.body_y_rotationY Body RotationThe yaw rotation of the entityEntity
query.can_climbCan ClimbReturns 1 if the entity doesn't have its AI disabled and uses WallClimberNavigation, otherwise 0Mob
query.can_flyCan FlyReturns 1 if the entity doesn't have its AI disabled and uses FlyingPathNavigation, otherwise 0Mob
query.can_swimCan SwimReturns 1 if the entity doesn't have its AI disabled and uses WaterBoundPathNavigation or AmphibiousPathNavigation, otherwise 0Mob
query.can_walkCan WalkReturns 1 if the entity doesn't have its AI disabled and uses GroundPathNavigation or AmphibiousPathNavigation, otherwise 0Mob
query.cardinal_facingEntity Facing DirectionThe direction the entity is facing, as an ordinal (0=Down, 1=Up, 2=North, 3=South, 4=West, 5=East)Entity
query.cardinal_facing_2dEntity Lateral Facing DirectionThe direction the entity is facing, as an ordinal, ignoring vertical directions (2=North, 3=South, 4=West, 5=East, 6=Down, 6=Up)Entity
query.cardinal_player_facingPlayer Facing DirectionThe direction the client player is facing, as an ordinal (0=Down, 1=Up, 2=North, 3=South, 4=West, 5=East)Global
query.controller_speedController SpeedThe current speed multiplier for the controller this animation is on (1 = default, 2 = 2x speed)Any animatable
query.dayDay NumberThe current day of the world, as a non-integerGlobal
query.death_ticksDeath TimeAmount of time (in ticks) that the entity has been deadLivingEntity
query.distance_from_cameraDistance From CameraThe distance in blocks the center of the entity is from the cameraEntity
query.equipment_countEquipment CountNumber of worn items (not including items in mainhand or offhand)LivingEntity
query.frame_alphaPartial TickReturns the fraction of a tick that has passed since the last tick (partialtick)Any animatable
query.get_actor_info_idEntity IDThe numerical ID of the entityEntity
query.ground_speedLateral SpeedThe current lateral velocity of the entity in blocks/tickLivingEntity
query.has_capePlayer Has CapeReturns 1 if the client player has a cape, otherwise 0Global
query.has_collisionHas CollisionReturns 1 if the entity has noclip enabled (no collisions), otherwise 0Entity
query.has_gravityHas GravityReturns 1 if the entity has gravity enabled, otherwise 0Entity
query.has_head_gearHas HeadgearReturns 1 if the entity is currently wearing something on its head, otherwise 0LivingEntity
query.has_ownerHas OwnerReturns 1 if the entity is an OwnableEntity and has an owner, otherwise 0Entity
query.has_player_riderHas Player PassengerReturns 1 if the entity has a passenger riding it that is a player, otherwise 0Entity
query.has_riderHas PassengerReturns 1 if the entity has a passenger riding it, otherwise 0Entity
query.head_x_rotationX Head RotationThe lerped pitch of the entity's headLivingEntity
query.head_y_rotationY Head RotationThe lerped yaw of the entity's headLivingEntity
query.healthHealthThe current health of the entityLivingEntity
query.hurt_timeHurt TimeAmount of time (in ticks) the entity has remaining on its hurt overlayLivingEntity
query.invulnerable_ticksInvulnerable TimeAmount of time (in ticks) the entity has remaining of invulnerability after taking damageLivingEntity
query.is_aliveIs AliveReturns 1 if the entity is alive, otherwise 0Entity
query.is_angryIs AngryReturns 1 if the entity is a NeutralMob and is angry, otherwise 0Entity
query.is_babyIs BabyReturns 1 if the entity is a baby, otherwise 0LivingEntity
query.is_breathingIs BreathingReturns 1 if the entity has full air, otherwise 0Entity
query.is_enchantedIs EnchantedReturns 1 if the itemstack has any enchantments, otherwise 0Item
query.is_fire_immuneIs Fire ImmuneReturns 1 if the entity's type is immune to fire, otherwise 0Entity
query.is_first_personIs in First PersonReturns 1 if the client player is in first person perspective, otherwise 0Global
query.is_in_contact_with_waterIs Contact With WaterReturns 1 if the entity is in water, rain, or a bubble column, otherwise 0Entity
query.is_in_lavaIn LavaReturns 1 if the entity is in lava, otherwise 0Entity
query.is_in_waterIn WaterReturns 1 if the entity is in water, otherwise 0Entity
query.is_in_water_or_rainIn Water Or RainReturns 1 if the entity is in water or rain, otherwise 0Entity
query.is_invisibleIs InvisibleReturns 1 if the entity is invisible, otherwise 0Entity
query.is_leashedIs LeashedReturns 1 if the entity is Leashable and currently has a leash, otherwise 0Entity
query.is_movingIs MovingReturns 1 if the entity is currently moving, otherwise 0Entity
query.is_on_fireIs On FireReturns 1 if the entity is on fire, otherwise 0Entity
query.is_on_groundIs On GroundReturns 1 if the entity is on the ground, otherwise 0Entity
query.is_ridingIs RidingReturns 1 if the entity is currently a passenger, otherwise 0Entity
query.is_saddledIs SaddledReturns 1 if the entity is Saddleable and is saddled, otherwise 0Entity
query.is_silentIs SilentReturns 1 if the entity is marked as silent, otherwise 0Entity
query.is_sleepingIs SleepingReturns 1 if the entity is sleeping, otherwise 0LivingEntity
query.is_sneakingIs SneakingReturns 1 if the entity is crouching, otherwise 0Entity
query.is_sprintingIs SprintingReturns 1 if the entity is sprinting, otherwise 0Entity
query.is_stackableIs StackableReturns 1 if the itemstack is stackable, otherwise 0Item
query.is_swimmingIs SwimmingReturns 1 if the entity is swimming, otherwise 0Entity
query.is_using_itemIs Using ItemReturns 1 if the entity is current using an item, otherwise 0LivingEntity
query.is_wall_climbingIs Wall ClimbingReturns 1 if the entity is currently on a climbable block, otherwise 0LivingEntity
query.item_max_use_durationMax Use DurationThe number of ticks the item can be used for at a maximumItem
query.life_timeRendering TimeThe amount of time (in seconds) that the entity has been rendering for since the game startedAny animatable
query.limb_swingWalk Animation SwingThe position in the 'walk animation' cycle that vanilla uses for walking animationsLivingEntity
query.limb_swing_amountWalk Animation Swing SpeedThe current speed of vanilla's walk animation handler (based on current velocity)LivingEntity
query.main_hand_item_max_durationMainhand Item Max DurationThe number of ticks the entity's mainhand item can be used for at a maximum, or 0 if not holding an itemLivingEntity
query.main_hand_item_use_durationMainhand Item Use DurationThe number of ticks the entity's mainhand item has been in use, or 0 if not using an itemLivingEntity
query.max_durabilityMax DurabilityReturns the maximum durability of the itemstackItem
query.max_healthMax HealthThe max health of the entityLivingEntity
query.moon_brightnessMoon BrightnessThe brightness value of the moon's current phase, in 0.25 increments, with full moon as 1Global
query.moon_phaseMoon PhaseThe ordinal value of the moon's current phase (0->7 inclusive)Global
query.movement_directionDirection MovingThe direction ordinal closest to the entity's velocity (0=Down, 1=Up, 2=North, 3=South, 4=West, 5=East)Entity
query.player_levelXP LevelThe client player's current XP levelGlobal
query.remaining_durabilityRemaining DurabilityReturns the amount of durability remaining before breaking, or 1 if the item isn't breakableItem
query.rider_body_x_rotationPassenger X Body RotationThe pitch of the entity's rider if it is a non-living entity, otherwise 0Entity
query.rider_body_y_rotationPassenger Y Body RotationThe yaw of the entity's rider, otherwise 0Entity
query.rider_head_x_rotationPassenger X Head RotationThe head pitch of the entity's rider if it is a LivingEntity, otherwise 0Entity
query.rider_head_y_rotationPassenger Y Head RotationThe head yaw of the entity's rider if it is a LivingEntity otherwise 0Entity
query.scaleScaleThe scale attribute value of the entityLivingEntity
query.sleep_rotationSleep RotationThe current Y rotation of the entity based on the bed it is sleeping in, or 0 if not sleepingLivingEntity
query.time_of_dayTime of DayThe fraction of the day that the client player's level is currently in (0->1 inclusive)Global
query.time_stampGame TimeThe total tick count of the client player's worldGlobal
query.vertical_speedVertical VelocityThe entity's current vertical velocityEntity
query.yaw_speedYaw Rotation SpeedThe entity's current yaw rotation deltaEntity

Custom Queries

GeckoLib supports users adding their own queries for use in Molang expressions.

Query Name

Default GeckoLib variables are typically named query.variable_name.

When registering your own variable, however, it's recommended that you name your variable to include your modid or something similar, to prevent clashes with other mods also registering variables

E.G. query.mymod_variable_name

Standard Variable

Registering your custom variable only requires a single line of code, put in your mod's constructor, or client entrypoint.

To do this, we use the MolangQueries#setActorVariable method.

This takes a generic (which should be your animatable's base type), the query name, and a function that returns the variables value.

Example Query Registration

This example registers a variable called "query.mymod_entity_bouncing" for an animatable of type MyAnimatable, using the MyAnimatable#getBouncing method to determine its value.

MolangQueries.<MyAnimatable>setActorVariable("query.mymod_entity_bouncing", actor -> actor.animatable.getBouncing());

Multi-type Variable

If your variable is used across multiple types of animatables, and they can't share a parent class that provides the value, then you will need to register a generic variable instead.

This is done via MathParser#registerVariable, using a default value of 0.

Example Generic Query Registration

This example registers a variable called "query.mymod_entity_bouncing", with its value to be set manually later.

MathParser.registerVariable(new Variable("query.mymod_entity_bouncing", 0))

Custom queries must be registered in your mod constructor, and you do not need to keep the Variable instance you create here, since it'll be automatically retrieved later when setting the value.

Once you have registered your query, you must provide its value during runtime, via overriding GeoModel#applyMolangQueries in the relevant model, and setting the value via MathParser#setVariable.
setVariable takes the same query name as your registered variable, and a supplier of the value the query should be.

E.G.
MathParser.setVariable("query.mymod_entity_bouncing", () -> myEntity.getBouncing())

Compound Expressions

Compound expressions are a Molang feature that allows you to evaluate multiple expressions in a single animation keyframe. This is mostly useful for setting and getting variable whilst still returning an animation value.

To perform compound expressions, split your expressions with the ; delimiter.
Each split will be evaluated as its own expression in order, with the last expression returning the value for the animation.

E.G.
v.is_animating_walk = 1;math.sin(query.anim_time)

This will result in a 2-part compound expression with the first part setting a local variable is_animating_walk to 1, and then returning math.sin(query.anim_time) from the expression

Variables

Variables are an expression component that allow you to store arbitrary data from within an expression, to retrieve it in a further animation or keyframe. This is useful in compound expressions, where you may need to evaluate some data in sequence before utilising it, or for otherwise temporarily storing data.

Note that variables are global in GeckoLib, so any variable you store will be shared with all other animatables using the same variable. Keep this in mind when designing your variable usage, either using unique names, or by only using the variables within the same animation frame pass.