Mount Configuration

Register standalone rideable mounts — boats, carts, and mechanical mounts.

Mounts are standalone rideable entities (boats, carts, mechanical mounts) — always mountable, no taming required. This is the catalog file that registers them. For making a mob rideable/tameable instead, see mob-config.md — it uses the same seats shape described here, plus an optional taming step mounts don’t have.

To give a mount a sprite, register it in the mount texture config under the same name you use here.

A note on “mount” vs “mount”. The engine uses these two words for the same thing. The internals, the manifest key (mount-config), and some APIs say mount; the config file, its top-level mounts: list, and this doc say mount. They are interchangeable — wherever you see one, read it as the other. Only the manifest key spelling is load-bearing (see File Location); everywhere else the difference is cosmetic.


File Location

Register the file in your mod’s manifest (mods/<YourMod>/<YourMod>.yaml):

mount-config: mount-config.yaml

The manifest key is mount-config (a naming holdover), even though the file itself is conventionally named mount-config.yaml.

Then create the file it points to, relative to your mod’s folder:

mods/<YourMod>/mount-config.yaml

The file is a single list of mount entries:

mounts:
  - name: my_boat
    hitbox:
      width: 2.0
      height: 3.0
    seats:
      - x-offset: 0.0
        y-offset: 2.5

Names are automatically prefixed with your mod name unless you write one already containing a colon.


Minimal Example

mounts:
  - name: my_boat
    hitbox:
      width: 2.0
      height: 3.0
    seats:
      - x-offset: 0.0
        y-offset: 2.5

Fields

FieldDefaultDescription
name(required)The mount’s identifier.
hitbox(required){ width, height } in blocks.
seats(required — at least one)Where riders sit — see Seats below.
display-name(none)Name shown in UI.
max-speed80.0A steering value for your Lua script — not applied by the engine. Your server-update reads it with entity:get_max_speed() to decide how fast to drive the mount (see Steering a mount). Changing it only matters if your script actually uses it.
jump-strength12.0Same as max-speed — a value your script reads via entity:get_jump_strength() and applies itself. The engine does not make the mount jump on its own.
max-velocity{x: 100.0, y: 100.0}A hard per-axis clamp (blocks/sec) that the engine does enforce on the mount’s physics — the mount can never move faster than this on either axis, no matter what a script (or a shove, or a fall) tries. x/y each default independently if only one is set.
healthsee health-config.mdSame shape as the standalone health config.
drop-table(none)Items dropped when destroyed — see Shared Blocks → drop-table (same shared block).

max-speed/jump-strength vs max-velocity. These sit at two different layers. max-speed and jump-strength are inputs to your steering script — the engine only stores them and hands them back through get_max_speed() / get_jump_strength(); a mount with no server-update script that reads them will not move at all. max-velocity is an engine-enforced ceiling applied directly to the mount’s physics object, independent of any script. So: use max-speed/jump-strength to tune how your script drives the mount, and max-velocity as the safety cap it can never exceed.

Lua Hooks

scripts: keyCalled
server-updateEvery tick (server)
server-on-deathWhen destroyed, just before it leaves the world (server)
server-on-mountedWhen a rider mounts (server)
server-on-dismountedWhen a rider dismounts (server)
client-on-interactWhen a player interacts with it (client)
client-updateEvery frame (client)
client-on-createWhen received/loaded (client)
client-on-deathWhen destroyed (client)
client-on-mountedWhen a rider mounts (client)
client-on-dismountedWhen a rider dismounts (client)

server-on-death receives the mount entity, and runs before it is removed from the world so the hook can still read its position and state. client-on-mounted / client-on-dismounted receive (rider, mount) — the same pair their server-side counterparts get.

One key is still accepted but not invoked. The engine accepts server-on-create without error but does not call it, so a script declared under it never runs. It is omitted from the table above so you don’t rely on it; put spawn-time logic in server-update guarding on state, or in the live client-on-create hook.

Each hook is declared under a single scripts: block, keyed by the event name, with the bare path to a .lua file that returns its handler function (the same shape as items’ server-on-primary-use):

scripts:
  server-update: /mounts/my_boat/scripts/server_update.lua

Steering a mount

Mounts do not move on their own — the engine only records rider input and enforces the max-velocity clamp. All actual movement is up to your server-update script, which runs every tick for each mount. Inside it you read the rider’s input and your own config values, then set the mount’s velocity:

Method (on the mount entity)Returns
entity:get_rider_input_x() / get_rider_input_y()The current rider’s steering input on each axis (0.0 when no input).
entity:get_max_speed()The max-speed value from this mount’s config.
entity:get_jump_strength()The jump-strength value from this mount’s config.
entity:get_riders()The list of mounted rider entity IDs (empty when nobody is aboard).

A minimal ground-mount loop:

return function(entity, delta_time_ns)
    if #entity:get_riders() == 0 then
        entity:set_applying_x_velocity(false)
        return
    end

    local input_x = entity:get_rider_input_x()
    local max_speed = entity:get_max_speed()   -- reads max-speed from config

    entity:set_max_x_velocity(max_speed)
    if input_x ~= 0.0 then
        entity:set_x_velocity(input_x / math.abs(input_x) * max_speed)
        entity:set_applying_x_velocity(true)
    else
        entity:set_x_velocity(0.0)
        entity:set_applying_x_velocity(false)
    end
end

Because max-speed and jump-strength are read from config here, a modder (or player) can retune the mount by editing the YAML alone — no script change needed. The shipped test_mount mount’s server_update.lua is a fuller worked example (ground movement plus jump/descend handling).


Seats

seats:
  - x-offset: 0.0
    y-offset: 2.5
    rider-hidden: false
    constrained: false
FieldDefaultDescription
x-offset / y-offset0.0Rider’s draw position relative to the mount.
rider-hiddenfalseIf true, the rider entity isn’t rendered at all (useful for fully-enclosed mounts).
constrainedfalseIf true, the rider can’t move independently while mounted.

A mount can have multiple seats — the first free one is assigned when a player mounts.


Complete Example

mounts:
  - name: sailboat
    display-name: Sailboat
    hitbox:
      width: 4.0
      height: 3.0
    max-speed: 30.0
    health:
      max: 50.0
      regen-per-second: 0
      takes-damage: true
    seats:
      - x-offset: 0.0
        y-offset: 1.0
      - x-offset: 1.5
        y-offset: 1.0
        rider-hidden: true
    drop-table:
      drops:
        - item: MyMod:sailboat
          min-amount: 1
          max-amount: 1
          chance: 1.0
    scripts:
      server-update: /mounts/sailboat/scripts/server_update.lua