Index
Why Does MoLang Exist?
MoLang is a simple expression-based language designed for fast calculation of values at run-time. Its focus is solely to enable script-like capabilities in high-performance systems where JavaScript is not performant at scale. We need scripting capabilities in these low-level systems to support end-user modding capabilities, custom entities, rendering, and animation.Back to topLexical Structure
The language structure is largely based on simple C-style syntax, focusing on handling math expressions. A script is made of either one expression for simple cases, or can be made of several where intermediate values are required or to help reduce compute time.In all cases, the value of the last expression in a script provides the script's value. In a multi-expression script, all but the last expression must assign a value to a variable. The last expression can as well, but doesn't need to as it's value is assumed to be the used as the return value.Values
-Value types are concretely specified, or numeric if not.-All numerical values are floats.-Boolean values such as actor flags are converted to a float value of either 0.0 or 1.0 for values of false or true respectively.-For boolean tests, a float value equivalent to 0.0 is false, and anything not equal to 0.0 is true.-For array indices, floats are c-style cast to ints, and clamped at zero for negative values or wrapped by the array size for large values.-Other supported types are textures, materials, and geometry where they make sense (such as render controllers).-Errors generally return a value of 0.0.Back to topVariables
There are several domains a variable may belong to:Domain | Scope | Example |
---|---|---|
Temp | Current expression | Temp.foo = Math.sin(global.anim_time);return Temp.foo * Temp.foo; |
geometry | Current render controller | "geometry": "array.geos[query.is_sheared]" |
material | Current render controller | "materials": [ { "*": "material.default" }, { "leg*": "material.legs" } ] |
query | Read-only values, usually related to current entity | query.is_baby |
texture | Current render controller | "textures": ["array.skins[query.is_saddled]"] |
variable | Current entity | variable.my_saved_var = variable.my_saved_var + 1; |
Keywords
All identifiers not in a scope listed below are reserved for future useKeyword | Description |
---|---|
Numerical constant value | |
( ) | Parentheses for expression term evaluation control |
Brackets for array access | |
query. |
Access to an entity's properties |
math. |
Various math functions (see below) |
global. |
Access to environment parameters |
temp. |
Store an intermediate value for the duration of the current expression |
variable. |
Store a value on the attached entity for later use |
geometry. |
A reference to a texture named in the entity definition |
material. |
A reference to a texture named in the entity definition |
texture. |
A reference to a texture named in the entity definition |
! && || < <= >= > == != | Logical operators |
* / + - | Basic math operators |
Conditional operator | |
this | The current value before executing the script (context sensitive) |
return | For complex expressions, this evaluates the following statement and stops execution of the script, returns the value computed |
Math Functions
Function | Description |
---|---|
math.abs( |
Absolute value of |
math.sin( |
Sine (in degrees) of |
math.cos( |
Cosine (in degrees) of |
math.exp( |
Elevates Euler to the |
math.ln( |
Natural logarithm of |
math.pow( |
Elevates |
math.sqrt( |
Square root of |
math.random( |
Random value between |
math.ceil( |
Round |
math.round( |
Round |
math.trunc( |
Round |
math.floor( |
Round |
math.mod( |
Return the remainder of value / denominator |
math.min(, ) | Return lowest value of or |
math.max(, ) | Return highest value of or |
math.clamp( |
Clamp |
math.lerp( |
Lerp from |
math.lerprotate( |
Lerp the shortest direction around a circle from |
Global Parameters
Name | Description |
---|---|
global.anim_time | Time since the current animation start |
global.delta_time | Time since the last time this animation was updated |
global.key_frame_lerp_time | Normalized time between current key frames as[0 - 1] |
global.life_time | Lifetime of the current entity |
global.frame_alpha | The render frame interpolation amount between AI frames(assuming the rendering is running at a different rate than the AI) as[0 - 1] |
Types, Values, and Variables
In general, all expression values are floats. In render controllers, some expressions result in a texture or material depending on the context. All array index expressions are processed as floats, and cast to integers when performing the final lookup into the array.Positive array indices wrap by the size of the array.Negative array indices clamp to 0.Back to topSimple vs Complex Expressions
A simple expression is a single statement, the value of which is returned to the system that evaluated the expression. eg:Domain Examples
Entity Definition Scripts
In the definition file there is a section for pre-computing values. These are executed immediately before animation and render controllers are processed, and stored in the entity. The purpose is to pre-compute any expensive and complex values you may want to reuse in your scripts, long-living index variable updates, or generally any one-off computation per render tick.Animation and Animation Controller Files
These are always numerical operations to control which animations are playing and how to animate bones. "variable.Render Controllers
There are a few different kinds of expressions here, where context implies what is allowed. As with animations, the entity accessors refer to the current entity, however depending on the context one also has access to materials, textures, and geometries.There are two sections in a render controller:-Array definitions (optional)-Resource usage (required)The array definition section allows you to create arrays of resources by resource type if you so desire.These can then be referenced in the resource usage section.Array Expressions
For each of the three resource types (materials, textures, and geometry), you can define an array of resources. The name of the resource is the nice-name from the definition file. Using materials as an example:Resource Expression
A resource expression must return a single resource of a specific type depending on the context. For example, in the "geometry" section, you must produce an expression that will result in a single geometry. Some examples: Always use a specific geometryResource Sections
Geometry
The geometry section specifies which geometry to use when rendering. As you can specify as many render controllers as you like in the definition file, a single render controller is only concerned with how to render a single geometry.Note that a geometry can be arbitrarily complex using any number of bones and polygons.Back to topMaterials
The materials section specifies how to map what material to what bone of the geometry. A single material is mapped to a whole bone. Material expressions are evaluated in the order listed. The first part of each statement is the name of the model part to apply the material to, and the second part is the material to use. The model part name can use * for wild - card matching of characters.For example :Query Functions
Query Functions are boolean expressions that allow you to query for values owned by the engine under different circumstances. They can be used in MoLang expressionsUseful for controlling things like changing positions, textures, animations, etc if a mob is a baby. For example:List of Entity Flags
Name | Description |
---|---|
query.can_climb | Mob is able to climb |
query.can_damage_nearby_mobs | Set by the player's spin attack using the Trident |
query.can_fall_through_scaffolding | Set when the player is able to fall through scaffolding, for example when flying or descending in scaffolding |
query.can_fly | Mob is able fly |
query.can_power_jump | Mob can power jump(added with the minecraft : can_power_jump component |
query.can_rider_pick | This is set by the "rider_can_interact" Parameter of the minecraft : rideable component. |
query.can_show_name | This flag is set is the entity can show a name tag |
query.can_swim | Mob is able to swim |
query.can_walk | Mob is able to walk |
query.ground_speed | Entity speed in meters |
query.is_angry | Mob is currently angry(i.e.wolves that been hit, zombie pigman once hit).Added via the minecraft : angry component |
query.is_baby | Mob is a baby |
query.is_breathing | if false, HUD bubbles render(water only) |
query.is_bribed | Added when the mob is bribed(added through the minecraft : bribable component |
query.is_casting | Mob is casting a spell. (i.e.Evoker animation of arms in air and to have particles play next to its hands) |
query.is_charged | This is set on a mob by the charge_charged_trigger parameter on the minecraft : behavior.ranged_attack component(i.e.the blaze's fireball attack) |
query.is_charging | Mob is using a charge attack(i.e.the vex's charge attack) |
query.is_chested | If the Mob has a chest on them(i.e.Horses and Donkey chests) |
query.is_critical | When a critical attach is achieved(i.e.when the player firs a fully charged bow or gets a critical melee attach this causes the particles to play |
query.is_dancing | When a mob is dancing(i.e.used by parrots to indicate they should dance) |
query.is_eating | If the mob is eating(i.e.When horses are fed hay or pandas eating) |
query.is_elder | If the Mob is an elder version(only used on Elder Guardian) |
query.is_fire_immune | If the mob has minecraft : fire_immune component or the fire resistance potion applied |
query.is_gliding | Player is gliding(using elytra) |
query.is_idling | Used when the Agent is idling |
query.is_ignited | If a mob is ignited.Added through the is_ignited and explode components |
query.is_in_love | Mob is in its "Love" state by being fed it's tempt item |
query.is_in_scaffolding | Managed by the minecraft : scaffolding_climber component for when a mob is in scaffolding |
query.is_in_transition_sitting | If the mob is currently transitioning from sitting or standing(i.e.Pandas when randomly sitting or snacking) |
query.is_in_water | Is entity in water |
query.is_interested | Mob is attracted to food the player is holding food they like(added via the minecraft : behavior.beg.) (i.e.tamed wolf sits and turn its head) |
query.is_invisible | Mob is invisible / affected by Invisibility potion effect |
query.is_laying_down | Managed by the minecraft : behavior.lay_down goal(i.e.lazy pandas) |
query.is_laying_egg | If the turtle is laying an egg |
query.is_leashed | Mob currently has a leash on it. |
query.is_lingering | Used on potions that are thrown to know it creates a lingering effect. |
query.is_moving | Mob is currently swimming through water |
query.is_onfire | Mob is on fire |
query.is_orphaned | Pets that have lost their owners. |
query.is_over_scaffolding | Managed by the minecraft : scaffolding_climber component for when a mob is over scaffolding |
query.is_powered | If mob is charged(i.e.Creeper's blue shield). Added via minecraft:charged component |
query.is_pregnant | Set by some turtle behavior goals.Used to make pregnant turtles render larger |
query.is_resting | Pet sleeping with its owner or boat is resting |
query.is_riding | Player / Mob is riding another Mob |
query.is_rolling | Set by the minecraft : behavior.roll goal(i.e.baby or playful pandas) |
query.is_saddled | Mob has a saddle on its back(i.e.pigs and horses) |
query.is_scared | Managed by the minecraft : behavior.scared goal for when the mob is scared(i.e.scared pandas) |
query.is_shaking | When Mobs shake off water(i.e.Wolves shaking off water when wet from swimming / rain |
query.is_sheared | Mob has been sheared.Set with the minecraft : sheared component |
query.is_sitting | Mob is currently sitting(i.e.dogs and cats) |
query.is_sneaking | Mob is Sneaking(i.e.players and ocelots) |
query.is_sneezing | Set by the minecraft : behavior.sneeze goal when the mob is sneezing |
query.is_sprinting | Mob is Sprinting |
query.is_stackable | Used on minecarts and boats so that they don't collide through each other. Set via minecraft:stackable component |
query.is_standing | Mob is stomping(i.e.zombie's minecraft:behavior.stomp_turtle_egg, or Horses and the player jumping ) |
query.is_swimming | True if the Mob is currently swimming |
query.is_tamed | If Mob is currently tamed(i.e.Dogs use this to draw their collars) |
query.is_tempted | Mob is tempted by a food item |
query.is_transforming | This flag is set by the minecraft : transformation component(i.e.Zombie villagers when they are transforming back to villagers) |
query.is_using_item | Mob is using an item(i.e.players eating food, or players and witches using potions) |
query.is_wall_climbing | Mob is currently climbing a wall(i.e.spiders) |
query.is_wasd_controlled | When the mob is being controller by a player riding it |