Mount Configuration
Register standalone rideable mounts — boats, rafts, and other non-creature vehicles.
Mounts are standalone rideable entities (boats, rafts) — always mountable, no taming required. This is the catalog file that registers them.
Which file does my rideable thing go in? A mob can be a mount, but not every mount is a mob. The dividing line is whether the thing is a creature:
A creature that can be ridden — a horse, a giant beetle — is a mob with a
mount:block. It lives its own life: it spawns by biome rules, wanders, has an AI script, can be attacked, and can be tamed.A vehicle — a boat, a raft — is a mount, registered here. It does nothing on its own; it exists to be ridden and is driven entirely by its rider and your steering script.
The mount entity itself is general — build whatever your mod wants with it. Note only that the base game’s own setting stays pre-industrial, so first-party content has no rail carts, tracks, or mechanical mounts.
Both use the same
seatsshape described below. The practical difference is that the mob path adds the creature-only features — spawn rules, AI hooks, and taming — while this path stays deliberately light.
Mounts cannot be tamed. Taming is a creature mechanic: food-items and a feed-progress threshold describe befriending an animal, which has no meaning for a cart. Writing a taming: block here fails the entry at load with a message pointing you to mob-config.yaml. If your rideable thing should be tamed, it’s a mob.
To give a mount a sprite, register it in the mount texture config under the same name you use here.
File Location
Register the file in your mod’s manifest (mods/<YourMod>/<YourMod>.yaml):
mount-config: mount-config.yaml
The key alone is enough — it defaults to mount-config.yaml in your mod folder. Give it a value only to use a different filename.
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
| Field | Default | Description |
|---|---|---|
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. |
interact-range | 10.0 | How far away a player may be and still mount it, in blocks, measured hitbox-to-hitbox. Same key and default as items, interactables and mobs. Worth raising for a physically large vehicle — on a long cart or a wide boat, a seat at the far end can otherwise sit outside the default reach. |
max-speed | 80.0 | A 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-strength | 12.0 | Same 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. |
movement.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, and omitting movement: entirely keeps both defaults. Nested under movement: like a mob’s and the player’s. |
shader | (none) | Client-only. Name of a shader from your shader config to render this mount with, instead of the default entity shader. Same key and behaviour as a mob’s shader. |
health | see health-config.md | Same shape as the standalone health config. |
drop-table | (none) | Items dropped when destroyed — see Shared Blocks → drop-table (same shared block). |
Why the default is higher than a mob’s. A mob and the player default
max-velocityto50; a mount defaults to100. That is deliberate: a mount’s ownmax-speeddefaults to80, so a50ceiling would clamp a default-configured mount to well under its configured speed.
max-speed/jump-strengthvsmovement.max-velocity. These sit at two different layers.max-speedandjump-strengthstay at the top level — mirroring where they sit inside a mob’smount:block — and are inputs to your steering script — the engine only stores them and hands them back throughget_max_speed()/get_jump_strength(); a mount with noserver-updatescript that reads them will not move at all.max-velocityis an engine-enforced ceiling applied directly to the mount’s physics object, independent of any script. So: usemax-speed/jump-strengthto tune how your script drives the mount, andmax-velocityas the safety cap it can never exceed.
Lua Hooks
scripts: key | Called |
|---|---|
server-update | Every tick (server) |
server-on-create | When the mount is created or loaded into the world (server) |
server-on-death | When destroyed, just before it leaves the world (server) |
server-on-mounted | When a rider mounts (server) |
server-on-dismounted | When a rider dismounts (server) |
client-on-interact | When a player interacts with it (client) |
client-update | Every frame (client) |
client-on-create | When received/loaded (client) |
client-on-death | When destroyed (client) |
client-on-mounted | When a rider mounts (client) |
client-on-dismounted | When 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.
server-on-create receives the mount entity and fires on both creation paths — a freshly spawned
mount and one loaded back from a save — so treat it as “this mount now exists in the world” rather
than “this mount was just made”, and make it idempotent.
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
| Field | Default | Description |
|---|---|---|
x-offset / y-offset | 0.0 | Rider’s draw position relative to the mount. |
rider-hidden | false | If true, the rider entity isn’t rendered at all (useful for fully-enclosed mounts). |
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
Last updated