Bedrock has no sit button: how the Missing Blocks stool seats a player
Minecraft Bedrock can't make a player sit, so the stool in LLS Missing Blocks spawns an invisible rideable seat. Why the obvious height maths sank players half a block into the stool, and the one-line rule that works.
Vanilla Bedrock has nowhere to sit that isn’t a boat or a minecart. A chair in a build is decoration: you walk up to it, and nothing happens. The stool in LLS Missing Blocks was meant to fix that, and it turned out to be a lesson in measuring before calculating.
The only way to sit is to ride
A Bedrock player has no sit state a script can switch on. The player model only goes into a seated pose for one reason: it’s riding something. So sitting on a stool means:
- Spawning an invisible, rideable entity inside the stool block.
- Putting the player into its seat with
rideable.addRider(player). - Removing the entity again the moment nobody’s on it.
That’s the same trick the barn doors and gates in the pack use for a different reason: the engine won’t do it with a block, so an entity does it instead.
Standing up needs no code at all. Sneak is Bedrock’s dismount, and it works on the seat the same as on a horse. That leaves the seat empty, and a sweep removes any seat with no rider, or whose stool has been broken.
The click
Right-clicking a stool should sit you down. Sneak + right-click should do what it does on any other block and place against it, otherwise you could never build next to a stool. So the rule is simple: a sneaking player never sits.
Two details made it reliable:
beforeEvents.playerInteractWithBlockis used when it exists, and the interaction is cancelled. That way, right-clicking a stool with a torch in your hand sits you down instead of sticking a torch on the stool. Whether that event exists depends on the script API version, so the code checks rather than assumes, and falls back to the after-event.- One click can arrive twice. Bedrock sometimes raises the interaction more than once for a single press. A per-player tick stamp ignores a second claim within four ticks, so one click never spawns two seats.
The seat is also matched to its stool by the stool’s exact position, stored on the entity when it’s spawned, not by “the nearest seat”. Two stools side by side never share or steal a seat.
The height maths that was wrong
The hard part was one number: how high to put the seat so the player’s backside lands on the stool’s top surface.
My first version worked it out from the player model. The reasoning went like this:
- Bedrock puts the rider’s model origin at the seat position.
- The riding pose only rotates the legs forward, so what rests on the seat is the underside of the thighs.
- The hip pivot is 0.703 blocks up the model, and the leg is about a quarter of a block thick, so the underside of a horizontal thigh is about 0.586 above the origin.
- So: seat position = seat surface − 0.586.
It’s tidy, it uses real numbers from the model, and it was wrong by 0.49 blocks. Players sat sunk into the stool up to their waists.
The 0.703 hip and the other body measurements are real, but they’re clearances: how much room a rider needs around a seat, so a cab roof doesn’t clip their head. They don’t describe where Bedrock actually puts the rider. A riding player sits much higher on the seat point than the model geometry suggests.
Measure it instead
Rather than derive a better guess, I made the stool report what happened. Every time
someone sits down, the script waits ten ticks (the mount doesn’t take effect on the tick
addRider is called), then logs:
[llsmb:sit] block=64 surface=64.750 spot=64.650 rider=... rider-surface=...
That’s the block, the stool’s seat surface, where the seat entity was put, where the player really ended up, and the difference. With that in the content log, a wrong height is a subtraction, not another theory.
The answer it gave matched something I’d already shipped without noticing. Both tractors in the Farm Sim Pack put the driver’s seat 0.1 blocks below the top of the seat pan, and drivers sit correctly in them. The stool needed the same:
const SEAT_SURFACE_PX = 12; // the stool's top, in pixels above the block's base
const RIDER_DROP = 0.1;
const SIT_Y = SEAT_SURFACE_PX / 16 - RIDER_DROP;
Seat position = seat surface − 0.10. That’s the whole rule, for any seat on any block. The wrong derivation is still written up in the source, marked as retracted, so nobody works it out again from the same numbers.
Keeping the model and the code in step
The stool model comes from a build script, and the seat height in the game code has to
match the model’s top surface. Two copies of one number drift apart sooner or later, so the
build script reads SEAT_SURFACE_PX straight out of the game script and refuses to build
if the model it’s about to generate disagrees. Change the stool’s height in one place and
the other complains until they agree.
There’s also a live nudge for testing: a scriptevent that moves the sit point up or down
by a fraction of a block, stored with the world. A nudge is only meaningful against the
built-in height it was measured from, so the base value is stored beside it. When the
built-in height changes, a stale nudge is thrown away instead of quietly stacking its old
error on top of the new number.
The small rules
- No headroom, no sitting. A player’s head ends up in the block above the stool, and a rider suffocates in a solid block like anyone else. Water above is fine: sitting in the shallows is half the point of a stool by a pond.
- You face the way you were looking when you sat. The seat doesn’t lock your rotation, so you can still turn your head and look around.
- Your hands stay free. A rider on this seat is a passenger, not a driver, so a fishing rod cast from a stool works the way it does from a boat.
- Already riding something? You can’t sit, and no stray seat is spawned only to be swept a tick later.
What it opens up
The seat entity doesn’t care what it’s inside. Now that the height rule is measured, not
guessed, a bench or a chair is the same code with a different SEAT_SURFACE_PX.
The stool is in LLS Missing Blocks and the Farm Sim Pack: three oak planks over two sticks. The Missing Blocks guide has the rest of the pack.
The mod
More from the devlog
- Five Bedrock add-on bugs that fail without an error An invisible horse, legs running four times too fast, a mob that forgot how to jump, and a magic pack that broke without being touched. Five Minecraft Bedrock add-on bugs I hit building LLS Equestrian and the Magic Pack, and how to catch them.
- Making it snow on a plains farm: faking winter weather in Minecraft Bedrock Bedrock has no snow weather and decides rain-or-snow from the biome. How LLS Seasons builds a snowy day from fog, a particle and a snow carpet of its own, and the summer freeze a snow sweep caused.
- Making a gate swing in Minecraft Bedrock, when blocks can't animate Bedrock blocks can't move, and a custom block's collision has to fit inside one block. How the double-wide gates in LLS Missing Blocks fake both, and the collision tricks that keep a cow in and let a horse through.