Repository navigation
feat(boats): integrate controlled boat physics and rendering - #590
Conversation
Allow right-click interaction with vehicle entities so players can mount and control boats through the web client.
Inline BOAT_PHYS_DEBUG into browser builds so controlled-boat diagnostics can be enabled during live testing.
Mark the controlled vehicle and derive water-mask visibility before forwarding entity updates. Cover local status, remote water sampling, and unloaded-world behavior.
Build and data scripts imported glob and ws through transitive pnpm hoisting, so local file links could change whether those packages resolved. Declare both directly and migrate the build helper to the glob v10 globSync API.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds boat, minecart, and horse render hints, passenger refresh handling, minecart-specific camera movement modes, centralized movement animation selection with horse riding support, build glob updates, a debug environment value, dependencies, and explicit mouse vehicle interaction behavior. ChangesVehicle rendering
Vehicle camera modes
Movement animation resolution
Build and interaction updates
Estimated code review effort: 3 (Moderate) | ~30 minutes Sequence Diagram(s)sequenceDiagram
participant Bot
participant WorldRenderer
participant getCameraMovementMode
participant Backend
Bot->>WorldRenderer: Emit move or forcedMove
WorldRenderer->>getCameraMovementMode: Inspect current vehicle
getCameraMovementMode-->>WorldRenderer: Return movementMode
WorldRenderer->>Backend: updateCamera with movementMode
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/boatRenderHints.test.ts (1)
29-40: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueESLint:
| 0and== nullin test helpers.Static analysis flags
| 0(preferMath.trunc) on line 32 and== null(prefer strict equality) on line 36. These are minor and don't affect test correctness, but would fail a strict lint gate.♻️ Proposed fixes
function makeWorld (blocks: Record<string, number | StubBlock | null>) { return { getBlock (pos: Vec3) { - const key = `${pos.x | 0},${pos.y | 0},${pos.z | 0}` + const key = `${Math.trunc(pos.x)},${Math.trunc(pos.y)},${Math.trunc(pos.z)}` const entry = blocks[key] if (entry === null) return null if (typeof entry === 'object') return entry - if (entry == null) return makeBlock(airId) + if (entry === null || entry === undefined) return makeBlock(airId) return makeBlock(entry) }, } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/boatRenderHints.test.ts` around lines 29 - 40, Update the makeWorld.getBlock helper to replace bitwise | 0 coordinate coercion with Math.trunc and replace the loose == null check with an explicit strict null/undefined check, preserving the existing block lookup behavior.Source: Linters/SAST tools
src/boatRenderHints.ts (1)
37-42: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueESLint: simplify nullish checks and unnecessary ternary.
Static analysis flags multiple
== nullcomparisons (no-eq-null,eqeqeq) and an unnecessary ternary on line 90. The== nullchecks are intentional for nullish (null | undefined) detection, but the project's ESLint config requires strict equality. The ternary on line 90 is a clear simplification.♻️ Proposed fixes
// Line 40: use explicit nullish check - if (ids.flowingWaterId != null && block.type === ids.flowingWaterId) return true + if (ids.flowingWaterId !== undefined && ids.flowingWaterId !== null && block.type === ids.flowingWaterId) return true // Line 90: simplify ternary - return foundSource ? true : false + return foundSource // Lines 77, 106, 127, 130: use strict null checks - if (block == null) return null + if (block === null || block === undefined) return nullAlso applies to: 77-77, 90-90, 106-106, 127-127, 130-130
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/boatRenderHints.ts` around lines 37 - 42, Replace all nullish comparisons in the affected code, including the ids.flowingWaterId check in isWaterBlock, with explicit strict checks for null and undefined while preserving nullish behavior. Simplify the unnecessary ternary at line 90 to its direct equivalent, and apply the same ESLint-compliant changes at the other flagged locations.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/boatRenderHints.test.ts`:
- Around line 29-40: Update the makeWorld.getBlock helper to replace bitwise | 0
coordinate coercion with Math.trunc and replace the loose == null check with an
explicit strict null/undefined check, preserving the existing block lookup
behavior.
In `@src/boatRenderHints.ts`:
- Around line 37-42: Replace all nullish comparisons in the affected code,
including the ids.flowingWaterId check in isWaterBlock, with explicit strict
checks for null and undefined while preserving nullish behavior. Simplify the
unnecessary ternary at line 90 to its direct equivalent, and apply the same
ESLint-compliant changes at the other flagged locations.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a76ae778-3ec5-466a-bd40-5efe354190ba
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (7)
package.jsonrsbuild.config.tsscripts/build.jssrc/appViewer.tssrc/boatRenderHints.test.tssrc/boatRenderHints.tssrc/mineflayer/plugins/mouse.ts
Include boat passenger IDs in entity render hints and refresh affected vehicles when remote passengers attach or detach.
Forward ordered minecart passenger data while keeping boat-specific local prediction hints separate. Select server-vehicle camera smoothing while mounted and apply forced position corrections immediately.
Suppress walking and running animations while a player is mounted so vehicle movement is not interpreted as player locomotion. Mark locally ridden minecarts for camera-synced rendering and correct flowing-water source classification.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/entityMovementAnimation.test.ts (1)
48-54: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd test for unmounted idle and crouched-at-sprint-speed.
Two paths are untested:
- Unmounted, not crouched, zero velocity →
return 'idle'(line 25 ofentityMovementAnimation.ts). Current idle tests only exercise the mounted early return (line 13).- Crouched at sprinting speed → should return
'crouchWalking', confirming crouch suppresses sprinting animation.🧪 Suggested additional tests
test('unmounted stationary crouch uses crouch', () => { expect(getEntityMovementAnimation({ isMounted: false, isCrouched: true, horizontalVelocity: { x: 0, z: 0 }, })).toBe('crouch') }) + +test('unmounted stationary uses idle', () => { + expect(getEntityMovementAnimation({ + isMounted: false, + isCrouched: false, + horizontalVelocity: { x: 0, z: 0 }, + })).toBe('idle') +}) + +test('crouched at sprinting speed uses crouchWalking not running', () => { + expect(getEntityMovementAnimation({ + isMounted: false, + isCrouched: true, + horizontalVelocity: sprintingVelocity, + })).toBe('crouchWalking') +})🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/entityMovementAnimation.test.ts` around lines 48 - 54, Add tests in the entity movement animation test suite covering unmounted, non-crouched entities with zero horizontal velocity expecting “idle”, and crouched entities moving at sprint speed expecting “crouchWalking”.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/entities.ts`:
- Line 78: Update the isMounted expression in the entity mapping to avoid the
forbidden loose null comparison while preserving its current true/false behavior
for both null and undefined vehicle values, using an explicit
null-and-undefined-safe check.
---
Nitpick comments:
In `@src/entityMovementAnimation.test.ts`:
- Around line 48-54: Add tests in the entity movement animation test suite
covering unmounted, non-crouched entities with zero horizontal velocity
expecting “idle”, and crouched entities moving at sprint speed expecting
“crouchWalking”.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 57be005e-fd0b-48ca-8568-434f8c06f0f2
📒 Files selected for processing (5)
src/boatRenderHints.test.tssrc/boatRenderHints.tssrc/entities.tssrc/entityMovementAnimation.test.tssrc/entityMovementAnimation.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/boatRenderHints.test.ts
- src/boatRenderHints.ts
Expose horse passenger layout and local-vehicle hints for supported rideable horse variants. Keep the local horse camera client-authoritative and use the riding animation for mounted players.
Pass an explicit horse-only vertical camera lock hint while local horse physics is active.
- Drive local animations from bot velocity instead of tracker lifecycle. - Apply riding to every mounted vehicle and refresh on mount, dismount, and respawn. - Sanitize velocity, avoid duplicate local processing, and cache only delivered animations. - Add regression coverage for local and remote animation pipelines.
Add paddle state to boat render hints for local and remote entities. Use local physics state without waiting for a metadata roundtrip and resolve remote paddle flags from named metadata or the 1.17.1 raw indices. Reset paddles for empty boats and malformed metadata.
Expose render hint so the renderer can predict horse model yaw from camera without affecting boat or minecart passengers.
Integrate controlled vehicle physics and rendering
Context
This PR connects the Mineflayer vehicle simulation to the renderer and enables
mounted vehicle interaction in the browser client.
It is the integration layer for the related physics, Mineflayer, and renderer
PRs, covering boats, horses, and minecarts.
Implementation
Vehicle interaction
vehicles (boats and horses; minecarts are server-driven).
Renderer hints
boat/minecart/horse)and the passenger IDs so the renderer can seat riders.
remote boats from world blocks;
solid blocks, and unloaded world data.
controlling the horse.
mode (
server-vehicle), keeping the local-player mode otherwise.Passenger rendering
animated consistently.
Diagnostics
BOAT_PHYS_DEBUGto browser builds for live controlled-boatdiagnostics.
Build correctness
globandwsas direct dependencies because client scripts importthem directly.
scripts/build.jsto theglob@10globSyncAPI.Previously these packages were available only through incidental pnpm transitive
hoisting. Changing the dependency graph for local
file:development exposedthat undeclared dependency.
Testing
src/boatRenderHints.test.ts— 20 passing tests.src/cameraMovementMode.test.ts— 2 passing tests.src/entityMovementAnimation.test.ts— 7 passing tests.BoatStatus;unloaded world data; local versus remote vehicle hints;
Version support
The client itself has no version gate; it forwards whatever the physics,
Mineflayer, and renderer layers support and was validated on Minecraft 1.17.1.
The 1.17.1 limit for locally controlled boats and horses comes from Mineflayer
(vehicle control protocol and boat physics model); minecart riding is
server-authoritative and version-neutral.
Dependencies
This PR should merge after the following PRs are merged and released or otherwise
made available to the client:
Merge order
mineflayer-physics-utilsmineflayerandminecraft-rendererminecraft-web-client