Skip to content

Molang 脚本

Mojang基岩版脚本的镜像自实现,客户端/服务端的轻量表达式语言,用于动画/特效/曲线驱动。

Molang 在 Behemiron 用于动画/特效/表达式驱动的轻量脚本语言。 在本项目里,Behemiron 的 Molang 支持同时在客户端/服务端运行,实现了 95% 左右的 Molang 语法

  • 标准运算(数学四则,布尔,条件,for each循环)
  • 局部变量表,变量赋值 / 注入
  • 函数调用栈 / Function call
  • 数组与数组访问
  • 与 Java 对象的互操作
  • 编译优化(常量折叠、死变量消除)与 JIT 编译,在 Double 表达式被大量求值时,自动将语句编译为 JVM 汇编以提高运行速度
  • 支持注入自定义函数Call与Java对象 Binding

Behemiron 的 Molang 在冷路径运行在解释模式下(词法分析->语法分析->中端优化->直接执行),热路径的 Double 数学表达式运行在 JIT 模式 (词法分析->语法分析->中端优化->编译为 ASM->JVM直接执行)

Quick Start

molang
// 移动判定 -- 地面且有速度
query.is_on_ground && query.ground_speed > 0.02

// 技能蓄力 -- 每帧递增,clamp 到 [0, 1]
variable.charge = math.clamp(variable.charge + 0.02, 0, 1)

// 动画权重 -- 根据速度插值
math.lerp(0.0, 1.0, query.ground_speed)

1. 命名空间与别名

Molang 内置命名空间(均可用英文/缩写/中文):

命名空间作用常用写法中文别名
query只读查询query.xxx / q.xxx查询.xxx
variable实体变量variable.xxx / v.xxx局部变量.xxx
context上下文变量context.xxx / c.xxx上下文变量.xxx
temp临时变量temp.xxx / t.xxx临时变量.xxx
math数学函数math.xxx数学.xxx
func脚本函数func.xxx方法.xxx

2. 变量生命周期

命名空间生命周期读写说明
variable.*实体级读写实体销毁后消失(不持久化)
temp.*表达式执行期间读写仅当前表达式内有效
context.*运行时注入只读由运行时注入
query.*实体与世界状态只读由实体与世界状态推导

3. 常用 Query 变量(完整清单)

3.1 Context 变量

变量说明
query.anim_time当前动画时间
query.life_time实体存活时间
query.actor_count场景实体数量
query.is_first_person是否第一人称

3.2 Level 变量

变量说明
query.time_of_day一天中的时间
query.time_stamp时间戳
query.moon_phase月相

3.3 Entity 变量

变量说明
query.position_x / y / z实体坐标
query.eye_target_x_rotation / y_rotation视线旋转
query.head_x_rotation / y_rotation头部旋转
query.yaw_speed偏航速度
query.ground_speed地面速度
query.vertical_speed垂直速度
query.cardinal_facing_2d2D 朝向
query.distance_from_camera距摄像机距离
query.modified_distance_moved修正移动距离
query.walk_distance行走距离
query.has_rider是否有骑乘者
query.is_in_water是否在水中
query.is_in_water_or_rain是否在水中或雨中
query.is_on_fire是否着火
query.is_on_ground是否在地面
query.is_riding是否骑乘中
query.is_sneaking是否潜行
query.is_jumping是否跳跃
query.is_spectator是否旁观者
query.is_sprinting是否疾跑
query.is_swimming是否游泳

3.4 LivingEntity 变量

变量说明
query.body_x_rotation / y_rotation身体旋转
query.health / query.max_health当前 / 最大生命值
query.hurt_time受伤时间
query.is_playing_dead是否装死
query.is_eating是否进食
query.is_sleeping是否睡觉
query.is_using_item是否使用物品
query.item_in_use_duration物品使用时长
query.item_max_use_duration物品最大使用时长
query.item_remaining_use_duration物品剩余使用时长
query.equipment_count装备数量

3.5 Player 变量

变量说明
query.has_cape是否有披风
query.cape_flap_amount披风飘动程度
query.player_level玩家等级

4. Query 函数

函数说明
query.biome_has_all_tags(...)当前生物群系是否包含所有指定标签
query.biome_has_any_tag(...)当前生物群系是否包含任一标签
query.relative_block_has_all_tags(...)相对方块是否包含所有标签
query.relative_block_has_any_tag(...)相对方块是否包含任一标签
query.is_item_name_any(...)物品名称是否匹配
query.equipped_item_all_tags(...)装备物品是否包含所有标签
query.equipped_item_any_tag(...)装备物品是否包含任一标签
query.position(...)获取坐标分量
query.position_delta(...)获取坐标增量
query.max_durability(...)最大耐久度
query.remaining_durability(...)剩余耐久度
query.debug_output(...)调试输出

示例:

molang
query.is_on_ground && query.ground_speed > 0.02

5. Math 函数与常量

常量

常量
math.pi3.14159...
math.e2.71828...

函数

函数说明
abs(x)绝对值
acos(x) / asin(x) / atan(x)反三角函数
atan2(y, x)二元反正切
ceil(x) / floor(x) / round(x) / trunc(x)取整
clamp(value, min, max)区间限制
cos(x) / sin(x)三角函数
die_roll(n, low, high)掷骰(浮点)
die_roll_integer(n, low, high)掷骰(整数)
exp(x) / ln(x)指数 / 自然对数
hermite_blend(t)Hermite 混合
lerp(a, b, t)线性插值
lerprotate(a, b, t)角度线性插值
max(a, b) / min(a, b)最大 / 最小值
min_angle(a)最小角度
mod(a, b)取模
pow(base, exp)幂运算
random(low, high)随机浮点
random_integer(low, high)随机整数
sqrt(x)平方根
to_deg(rad) / to_rad(deg)角度/弧度转换

6. 内置函数

函数说明限制
loop(count, expression)循环执行表达式最多 1024 次
for_each(var, array, expression)遍历数组--
print(...)调试输出--

7. 常见问题

问题回答
为什么服务端不解析 Molang?Molang 运行依赖渲染/实体状态,在客户端执行更稳定且性能更好
变量从哪里来?相关运行时模块会把服务端下发的 vars / flags 注入到 variable.*
可以自定义函数吗?可以。通过脚本注册机制挂到 func.* 命名空间