Skip to content

feat: expand movement simulation parity - #6

Merged
HashimTheArab merged 10 commits into
mainfrom
agent/boar-movement-parity
Aug 6, 2026
Merged

feat: expand movement simulation parity#6
HashimTheArab merged 10 commits into
mainfrom
agent/boar-movement-parity

Conversation

@HashimTheArab

@HashimTheArab HashimTheArab commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

  • expand bedsim movement parity using Boar as a behavioral reference
  • add bubble columns, Riptide, crawling, movement enchantments, dynamic collision context, and movement-sensitive block behavior
  • correct movement constants and effect amplifier/gravity handling
  • preserve and extend the hardened liquid simulation already present on main

Why

bedsim covered core ground, collision, gliding, and teleport physics but was missing several client movement paths and had a handful of numeric differences. These gaps could produce authoritative position or velocity divergence for players interacting with liquids, special blocks, poses, and movement-affecting equipment.

Impact

World adapters may optionally implement BubbleColumnProvider and MovementCollisionProvider. Player integrations may provide MovementEquipmentProvider for Depth Strider, Soul Speed, Swift Sneak, Riptide, and leather-boots behavior. Existing providers remain supported, including the legacy inventory-based Depth Strider extension.

The README documents the new optional capabilities and pose dimensions.

Validation

  • go test ./...
  • go test -race ./...
  • go vet ./...
  • git diff --check

Summary by CodeRabbit

  • New Features
    • Added crawling, descending, spin-attack, item-use, and inventory movement inputs.
    • Added support for Soul Speed, Swift Sneak, Depth Strider, leather boots, bubble columns, validated Riptide launches, gliding, and teleport movement.
    • Improved movement through honey, sweet berry bushes, powder snow, scaffolding, webs, liquids, and soul sand.
    • Added dynamic collision handling and pose-aware standing, sneaking, and crawling heights.
  • Bug Fixes
    • Improved sneaking, crawling, edge avoidance, jumping, bouncing, gravity, and liquid movement behavior.
  • Documentation
    • Expanded usage guidance and documented optional movement capabilities.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The simulator adds new movement inputs, pose-state fields, collision-provider hooks, block movement semantics, bubble columns, Riptide handling, and block-effect processing. It also updates liquid travel, movement parity, and README coverage for the expanded movement model.

Changes

Movement simulation

Layer / File(s) Summary
Movement contracts and state wiring
input.go, interfaces.go, movement.go, simulator.go, constants.go, README.md
Adds new input flags, movement-state fields, collision and equipment interfaces, simulator equipment wiring, physics constants, and documented optional capabilities.
Block movement effects and Bedrock semantics
block/*.go, block_effects.go, block_effects_test.go, bedrock_semantics_test.go, parity_test.go, simulator_test.go
Maps named blocks to honey, inside-movement, traversal, and soul-speed semantics, then applies the related jump, bounce, web, and traversal effects with tests.
Liquid, bubble-column, and riptide flow
bubble.go, bubble_test.go, liquid.go, liquid_test.go, movement_environment_test.go
Adds bubble-column motion, Riptide activation and stop logic, equipment-aware liquid travel, and the test fixtures that supply world and equipment state.
Pose transitions and collision flow
simulation.go, dynamic_collision_test.go, player_features_test.go
Updates pose changes, collision probing, edge checks, movement impulses, glide and crawl behavior, and the tests that cover those paths.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • oomph-ac/bedsim#2: Both changes extend liquid movement and block-effect handling with new movement-state logic.
  • oomph-ac/bedsim#7: Both changes touch the same movement-state and collision plumbing in simulation.go, movement.go, and related interfaces.
  • oomph-ac/bedsim#11: Both changes extend the block movement-semantics model and its simulator integration.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.96% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the pull request's primary change: expanding movement simulation parity.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/boar-movement-parity

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@bubble.go`:
- Around line 50-60: Update the bubble-column processing loop to apply an
impulse only once per tick: after finding the first applicable column cell,
apply its direction and stop further cell processing. Preserve the existing
liquid-above and air checks, and add an integration test covering an AABB
spanning two bubble-column blocks to verify only one impulse is applied.

In `@liquid.go`:
- Around line 85-89: Update the Depth Strider selection in the equipment branch
to fall back to the legacy DepthStriderProvider when EnchantmentDepthStrider
reports level zero, while preserving equipment as authoritative for positive
levels and the existing clamping to 0–3. Add coverage for equipment with level
zero combined with an inventory DepthStriderProvider.
🪄 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 Plus

Run ID: e24a8f37-fccd-46ee-a2da-e078c2e0e9a6

📥 Commits

Reviewing files that changed from the base of the PR and between 3a517d7 and 456eacb.

📒 Files selected for processing (17)
  • README.md
  • block_effects.go
  • block_effects_test.go
  • bubble.go
  • bubble_test.go
  • constants.go
  • dynamic_collision_test.go
  • input.go
  • interfaces.go
  • liquid.go
  • movement.go
  • movement_environment_test.go
  • parity_test.go
  • player_features_test.go
  • simulation.go
  • simulator.go
  • simulator_test.go

Comment thread bubble.go Outdated
Comment thread liquid.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
liquid.go (1)

53-57: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Honor PressingDescend at the liquid surface.

The new descent impulse can be immediately erased by updateSwimTravel when the player looks upward: that clamp only checks !state.WantDownSlow, while PressingDescend is also set for sneaking and DescendBlock. Skip the surface clamp when state.PressingDescend is true, and add an upward-pitch regression test.

🤖 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 `@liquid.go` around lines 53 - 57, Update the liquid surface clamp in
updateSwimTravel to also skip clamping when state.PressingDescend is true,
preserving the descent impulse for sneaking and DescendBlock while looking
upward. Add an upward-pitch regression test covering PressingDescend at the
liquid surface.
🤖 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.

Outside diff comments:
In `@liquid.go`:
- Around line 53-57: Update the liquid surface clamp in updateSwimTravel to also
skip clamping when state.PressingDescend is true, preserving the descent impulse
for sneaking and DescendBlock while looking upward. Add an upward-pitch
regression test covering PressingDescend at the liquid surface.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c5c2fe3-c5f4-4ca3-9f34-f9f39027144b

📥 Commits

Reviewing files that changed from the base of the PR and between 10c3d99 and 20f1d63.

📒 Files selected for processing (18)
  • bedrock_semantics_test.go
  • block_effects.go
  • block_effects_test.go
  • bubble.go
  • bubble_test.go
  • constants.go
  • dynamic_collision_test.go
  • input.go
  • interfaces.go
  • liquid.go
  • liquid_test.go
  • movement.go
  • movement_environment_test.go
  • parity_test.go
  • player_features_test.go
  • simulation.go
  • simulator.go
  • simulator_test.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • movement_environment_test.go
  • bubble.go
  • bedrock_semantics_test.go
  • bubble_test.go
  • player_features_test.go
  • dynamic_collision_test.go
  • block_effects_test.go

@HashimTheArab

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
player_features_test.go (2)

23-30: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Strengthen the Soul Speed test oracle.

The assertion only checks that with.Vel.Z() is greater than without.Vel.Z(). It does not prove that the unenchanted run receives soul-sand slowdown or that the enchanted run matches normal-ground movement.

Add a normal-ground control run. Assert both expected relationships with a tolerance.

🤖 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 `@player_features_test.go` around lines 23 - 30, Add a normal-ground control
simulation alongside the existing `without` and `with` runs in the Soul Speed
test. Update the assertions to verify, using an appropriate tolerance, that the
unenchanted soul-sand velocity is below normal-ground movement and the Soul
Speed velocity matches normal-ground movement, while preserving the existing
test setup.

76-76: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Exercise crawling through Simulator.Simulate.

Line 76 calls private applyInput, so this test bypasses the documented public path that applies input and advances simulation counters. Add a public-path assertion for crawling. Keep direct helper coverage only as a separate unit-level test.

As per coding guidelines, Simulator.Simulate(state, input) applies input and ticks counters.

🤖 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 `@player_features_test.go` at line 76, Update the crawling test to exercise the
public Simulator.Simulate(state, input) path instead of directly calling
sim.applyInput, and assert the resulting crawling behavior and simulation
counter updates. Keep direct applyInput coverage separate as a focused unit test
if needed.

Source: Coding guidelines

🤖 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 `@block_effects.go`:
- Around line 32-43: Update applyStuckSpeedMultiplier so the NoClip branch
clears state.StuckSpeedMultiplier before returning false. Preserve the existing
behavior for zero multipliers and normal multiplier application.

In `@bubble.go`:
- Around line 53-61: Remove the early return after applyBubbleColumn in the
bubble-column processing loop so every occupied bubble-column cell is processed
during the tick. Update TestBubbleColumnAppliesOnceAcrossMultipleCells to assert
the accumulated impulse from each occupied cell while preserving the existing
per-cell direction and above-liquid checks.

---

Nitpick comments:
In `@player_features_test.go`:
- Around line 23-30: Add a normal-ground control simulation alongside the
existing `without` and `with` runs in the Soul Speed test. Update the assertions
to verify, using an appropriate tolerance, that the unenchanted soul-sand
velocity is below normal-ground movement and the Soul Speed velocity matches
normal-ground movement, while preserving the existing test setup.
- Line 76: Update the crawling test to exercise the public
Simulator.Simulate(state, input) path instead of directly calling
sim.applyInput, and assert the resulting crawling behavior and simulation
counter updates. Keep direct applyInput coverage separate as a focused unit test
if needed.
🪄 Autofix

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 Plus

Run ID: 105faed2-4956-475a-9203-9da49da7d0c4

📥 Commits

Reviewing files that changed from the base of the PR and between 10c3d99 and 27d2738.

📒 Files selected for processing (23)
  • README.md
  • bedrock_semantics_test.go
  • block/contact.go
  • block/environment.go
  • block/ground.go
  • block/semantics.go
  • block_effects.go
  • block_effects_test.go
  • block_semantics_test.go
  • bubble.go
  • bubble_test.go
  • constants.go
  • dynamic_collision_test.go
  • interfaces.go
  • liquid.go
  • liquid_test.go
  • movement.go
  • movement_environment_test.go
  • parity_test.go
  • player_features_test.go
  • simulation.go
  • simulator.go
  • simulator_test.go
🚧 Files skipped from review as they are similar to previous changes (8)
  • README.md
  • bedrock_semantics_test.go
  • parity_test.go
  • simulator.go
  • movement_environment_test.go
  • interfaces.go
  • movement.go
  • constants.go

Comment thread block_effects.go
Comment thread bubble.go Outdated
@HashimTheArab

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@HashimTheArab
HashimTheArab merged commit 4dd3ee6 into main Aug 6, 2026
1 check passed

@HashimTheArab HashimTheArab left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Audit findings for the current head: the Depth Strider formula/fallback, Riptide impulse direction/force, bed bounce coefficient, and bubble impulse constants line up. I found four correctness issues: bubble-column entries are truncated after the first, Riptide lacks the mounted-player eligibility gate, and web/queued inside slowdowns do not scale the pending input request. Inline comments below describe the fixes and regression coverage. Normal tests and vet pass; race testing could not run here because the environment has no C compiler.

Comment thread bubble.go Outdated
above := pos.Side(cube.FaceUp)
_, liquidAbove := s.liquidAt(above)
applyBubbleColumn(state, direction, !liquidAbove && s.blockAir(s.blockAtPos(above)))
return

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The client keeps one bubble-column entry for each intersecting column and processes the complete entry list on a tick. Returning here makes the result depend on scan order and drops every later column. Please continue the scan after applying this impulse, and add a regression test with two overlapping same-direction columns that expects both contributions.

Comment thread bubble.go
}

func (s *Simulator) attemptRiptide(state *MovementState, touchingWater bool) bool {
if s.Equipment == nil || state.RiptideTicks > 0 || !state.RiptideReady || (!touchingWater && !state.RiptideInRain) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Riptide eligibility is missing the mounted-player gate. A validated release while the player is riding a vehicle must not create the spin-attack impulse, but this path has no vehicle state to reject that case. Add an authoritative vehicle/mounted input to MovementState or the provider contract and reject it here; keep it separate from RiptideReady.

Comment thread block_effects.go
if state.NoClip || multiplier.LenSqr() <= 1e-7 {
return false
}
state.SetVel(mgl32.Vec3{

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only scales the existing velocity, but the slowdown also applies to the pending movement request. With a queued berry/powder-snow multiplier, a zero-velocity player with new input reaches moveRelative unchanged, and the later stuckMovement branch only clears velocity after recording the full displacement. Scale the pending horizontal impulse/request too and add a two-tick input-driven regression test.

Comment thread simulation.go
xz, y = 0.5, 0.25
}
}
newVel[0] *= xz

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The web factor is applied only to the pre-existing velocity; moveRelative adds state.Impulse afterward. A zero-velocity player moving into a web therefore records an unscaled input displacement before the later zeroing step. Apply the same factor to the pending horizontal request (or equivalent pre-collision move) and add an input-driven web test.

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.

1 participant