Skip to content

feat(physics): add boat and horse physics - #56

Open
sandexzx wants to merge 4 commits into
nxg-org:masterfrom
sandexzx:feat/boat-physics-1.17.1
Open

sandexzx wants to merge 4 commits into
nxg-org:masterfrom
sandexzx:feat/boat-physics-1.17.1

Conversation

@sandexzx

@sandexzx sandexzx commented Jul 12, 2026 •

Copy link
Copy Markdown
Contributor

Add boat and horse physics

Context

This is the foundational physics PR for the controlled-vehicle implementation
(boats and ridden horses).

The existing entity physics did not model vanilla boat or horse behavior. Boats
need water-state detection, buoyancy, steering, land friction, and paddle state;
ridden horses need attribute-driven speed/jump, a jump-charge mechanic, ground
friction, and fluid handling. Both require dedicated, entity-specific simulation.

The horse movement matches the current (1.21.x) vanilla physics and behaves well
in testing. It is also intended to work on 1.17.

Implementation

Boats

  • Add BoatState with:
    • current and previous water/land status;
    • water level and land friction;
    • yaw velocity and last vertical velocity;
    • controlling-player and world-readiness state.
  • Add BoatPhysics behavior for:
    • source and flowing water detection;
    • underwater, in-water, on-land, and in-air states;
    • gravity, buoyancy, and water-entry transitions;
    • forward/backward acceleration and steering;
    • paddle state calculation;
    • collision handling;
    • stone and ice friction.
  • Skip simulation when required world blocks are not loaded.

Horses

  • Add HorseState with:
    • movement speed and jump strength read from entity attributes
      (generic.movement_speed, horse.jump_strength), with vanilla defaults
      used until attributes arrive;
    • saddle status from entity metadata;
    • a jump-charge model (charge ticks/scale, pending jump scale, jump-boost
      output) matching the vanilla charge-and-release curve;
    • rider-driven yaw/pitch and travel input (forward/back/strafe scaling,
      reduced backward speed);
    • rebaseFromEntity / applyToEntity sync and world-readiness state.
  • Add HorsePhysics behavior (extending the shared entity physics) for:
    • gravity, air/ground inertia, and vertical drag;
    • attribute-driven ground acceleration influenced by block friction;
    • ground jump with charge-scaled height, jump-boost, honey-block jump factor,
      and forward horizontal impulse when jumping while moving forward;
    • 1-block auto step-up and horizontal-collision handling;
    • stone-vs-ice ground friction;
    • travel in water and lava (buoyancy, slowdown, ledge escape);
    • world-readiness gating over the swept/step block range.

Shared / housekeeping

  • Export BoatPhysics, BoatState, BoatStatus, HorsePhysics, and
    HorseState from the public package entry point.
  • Move getPose into poses.ts and switch several cross-module imports to
    type-only to avoid circular-import issues introduced by the new states.

Testing

Focused unit coverage was added for:

  • Boats: water and land status detection; source and flowing water;
    buoyancy and water entry; acceleration, steering, and input release; paddle
    states; shore collisions; stone versus ice friction; unloaded world data;
    state cloning and mutable-state isolation.
  • Horses: jump charge/hold/release curve and pending-scale minimums;
    charge-dependent vertical jump; forward jump impulse; repeated jumps after
    landing; honey-block jump factor; attribute-driven speed and jump strength
    (including modifier application without mutating the source); no sprint
    multiplier; forward/backward/strafe movement; 1-block step-up; wall
    collision; ice-vs-stone friction; world-readiness pausing; rebaseFromEntity
    without corrupting jump charge; finite-state stability.

Related PRs

Scope

This PR provides the reusable boat and horse simulation only. Mineflayer
lifecycle, protocol packets, client integration, and rendering are handled in
the related PRs.

Minecart physics is intentionally not part of this PR. In our testing minecarts
already behave well through the existing generic entity-physics path, so no
changes were needed here. If review surfaces any issues, we'll look into them
and follow up with fixes.

sandexzx added 2 commits July 12, 2026 11:08
Implement boat state, buoyancy, controls, collisions, and water and land
status handling with focused regression coverage.
Keep world-readiness and water-entry handling collision-safe while preserving vanilla land friction behavior for controlling players.
@zardoy

zardoy commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@sandexzx do you think that logic would work fine on newer versions as well? I don't see anything that would make it not run on like 1.21 so I think we can safely drop that part from the title of that PR

@zardoy

zardoy commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

thats a maintainer ask to not introduce breakages on other (mostly newer) versions
(since mineflayer-physics-utils is multi-version lib)

@zardoy

zardoy commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

/deploy

@sandexzx sandexzx changed the title feat(physics): add boat simulation for Minecraft 1.17.1 feat(physics): add boat simulation Jul 13, 2026
sandexzx added 2 commits July 13, 2026 10:50
Use consistent exclusive world-query bounds so an unused block layer
above the boat does not unnecessarily pause simulation.

Reuse the forward acceleration constant and remove unused underwater
state while preserving vanilla movement values.
Add HorseState and HorsePhysics with vanilla-compatible movement,
jump charging, collisions, fluid handling, and world readiness checks.

Fix Mineflayer yaw conversion for horse movement and add focused
unit coverage for movement, jumping, attributes, and unloaded chunks.
@zardoy

zardoy commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@sandexzx perfect, I think new minecart physics would be the last step (I think 1.21+ new physics should be used for porting, it should be compatible with some limitations with 1.17)

Also don't forget to update pr title as it now add not only boat physics

@zardoy

zardoy commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

If minecart physics was done let's rename the pr

@GenerelSchwerz

Copy link
Copy Markdown
Contributor

that failing check looks like me potentially

and yes, please change the name so I can keep track of what exactly is being merged.

@sandexzx sandexzx changed the title feat(physics): add boat simulation feat(physics): add boat and horse physics Jul 15, 2026
@zardoy

zardoy commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

So does it look like it's not going to work on any other version besides 1.17.1? Is it gated? And what would need to be done for newer versions support? Just so we know

@zardoy

zardoy commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Let's start finishing working on that

@GenerelSchwerz

Copy link
Copy Markdown
Contributor

So does it look like it's not going to work on any other version besides 1.17.1? Is it gated? And what would need to be done for newer versions support? Just so we know

I do not know whether or not it only works on this version, but that is not my responsibility as it has not been merged into my repository yet. I need linked files for each version physics are written for, and their differences.

if there is an impl difference between 1.17 and 1.21, I need both instances covered + exact line/link references from source code to explain the change. that is why I merged #55

@sandexzx

Copy link
Copy Markdown
Contributor Author

@GenerelSchwerz @zardoy — status update, and to set expectations: this PR is
still WIP and not merge-ready yet.

First, some context on scope. This PR was originally opened for one thing:
boat physics on 1.17.1. That's the version I built against and the only version
I've actually tested on. @zardoy then asked to also cover horses and minecarts
in the same PR, so it grew well past its original scope — which is why it's been
sitting in a WIP state.

On the version question (@zardoy): I haven't answered it until now because I
genuinely didn't know — I hadn't investigated other versions yet, and I didn't
want to guess. Here's the honest state of it.

Nothing in this PR is version-gated. It's a single implementation with no
version branches anywhere in the new files. That was never a deliberate
multi-version design; it's just how it came out of building against 1.17.1.

Reading my code against the vanilla source (rather than testing it), two things
are now clear:

Boats look genuinely version-independent. The friction and buoyancy constants
I use (0.9 / 0.45 / 0.9, and landFriction /= 2) match vanilla, and the
logic appears unchanged between 1.17 and current — the class was renamed and
refactored (Boat.java → AbstractBoat.java in 1.21.2), but floatBoat()
itself is the same math. On paper this should behave the same on newer versions.
I have not verified that at runtime yet.

Horses have a real version difference. I read attributes by the keys
generic.movement_speed and horse.jump_strength. Those names changed in
1.20.5+ — vanilla now registers them as movement_speed and jump_strength,
and jump_strength became a general attribute rather than a horse-specific one.
Since mineflayer keys entity.attributes by whatever the server sends, that
lookup would miss on newer versions and silently fall back to my hardcoded
vanilla defaults. So the horse would still move on 1.21, but without honouring
server attributes. This needs a version-aware key mapping with both key sets
covered.

On the multi-version documentation requirement (@GenerelSchwerz):
understood, and I agree it's the right bar — same as #55. Before I ask for
review again I'll deliver:

  1. A version-difference document in the fix: coordinate-dependent block collision bypass #55 format: vanilla file and line
    references per version for each behaviour where 1.17 and 1.21 diverge, and an
    explicit "identical here" note where they don't.
  2. The horse attribute-key fix, covering both old and new key sets.
  3. Working examples for boat and horse.

On timing — I want to be upfront. This work now spans four repos (this one,
zardoy/mineflayer#9, zardoy/minecraft-web-client#590, and the renderer), and I'm
doing it in limited time. My sequencing is to first get the chain working
end-to-end on the main mcraft.fun server, then do the multi-version pass. I'd
rather document version differences against something I've actually run than
write the matrix from source-reading alone and have to redo it.

Thanks for the patience.

@GenerelSchwerz

Copy link
Copy Markdown
Contributor

No worries, I appreciate the effort. I personally don't have any concerns about time, that's more of a Zardoy issue.

I personally care about multi version coverage more than anything else. I would honestly split individual features into separate PRs (boat, horse, minecart, etc) as this is growing into a monster PR.

There is also the concern about boat's versioning support. Board were added all the way back in Alpha version 1.0.6. I don't expect you to review and support backwards to that point, but there is a clear difference between pre and post 1.9 boats. So 1.17 is not the actual cutoff point for support.

It is my opinion that you focus solely on one feature and implement it fully, one at a time, rather than attempting to deliver everything at once. This is largely our fault for having this PR grow in scope so much, so I apologize.

@GenerelSchwerz

Copy link
Copy Markdown
Contributor

Having the chain work end-to-end is understandable, just know that I cannot merge this (or related future PRs) until proper multiversioning support is added. I do not mind waiting until you finish with mcraft.fun though.

@zardoy

zardoy commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Having the chain work end-to-end is understandable, just know that I cannot merge this (or related future PRs) until proper multiversioning support is added. I do not mind waiting until you finish with mcraft.fun though.

Since mcraft.fun depends on your physics version, it's not possible to test it until it's merged.

@GenerelSchwerz Also about multiversion support: since some modules might be too complex to implement truly multiversional (like different implementations), why can't we gate these implementations eg by enabling them only on specific (supported) versions. This would also allow to split the work

@zardoy

zardoy commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@sandexzx lets just merge it into https://github.com/zardoy/mineflayer-physics-utils and merge all other blocking prs (though I can also do it this weekend)

@GenerelSchwerz

Copy link
Copy Markdown
Contributor

I already merged #57 , this PR just needs the same formatting as that PR (no hardcoded values), and to have the outdated boat setup from this PR removed to prevent conflicts.

@GenerelSchwerz

Copy link
Copy Markdown
Contributor

Also about multiversion support: since some modules might be too complex to implement truly multiversional (like different implementations), why can't we gate these implementations eg by enabling them only on specific (supported) versions. This would also allow to split the work

This alreaady happens in the engines. Typically, changes are minor so multi-version is not an issue. If there are significant changes across versions then I understand--I simply haven't come across an update where that is the case.

@zardoy

zardoy commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@sandexzx yeah let's remove at least already implemented boat support from here

@sandexzx

Copy link
Copy Markdown
Contributor Author

@sandexzx yeah let's remove at least already implemented boat support from here

@zardoy A separate PR with horses is almost ready, I will open it today. This PR can be closed afterwards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants