Skip to content

Add shared vehicle support and craftable oak boats - #182

Merged
fredboy merged 4 commits into
developfrom
feature/vehicles
Oct 24, 2026
Merged

fredboy merged 4 commits into
developfrom
feature/vehicles

Conversation

@fredboy

@fredboy fredboy commented Oct 24, 2026

Copy link
Copy Markdown
Owner

Adds a craftable oak boat with one player seat and shared vehicle support. Players can place boats on water or clear ground, row and coast, dismount into clear space, and recover a boat item when it breaks in Survival.

  • Add fixed-step buoyancy using partial water overlap, terrain and passenger collision, finite-world wrapping, and infinite-world chunk residency.
  • Add seated rendering, animated oars, water sounds, and a small bob on melee hits. Integrate weapon, projectile, explosion, fire, and lava damage, with passenger cleanup on destruction, death, and respawn.
  • Persist boats and mounted-player references in finite saves and streamed chunk records; older saves default to no vehicles.
  • Add the oak boat item, five-plank U-shaped recipe, textures and attribution, and names in every existing locale.
  • Clear held movement when riding or opening windows while keeping inventory open.

Controls: on desktop, right-click to board, use A/D or arrow keys to row, Space/W to dismount, and attack to damage the boat. On touch, aim at the boat and hold for half a second to board or tap quickly to attack; use the left joystick to row and a quick tap in its area to dismount.

Validation:

  • testCore
  • ktlintCheck buildSrc:ktlintCheck
  • desktop:classes
  • :android:assembleFossDebug
  • html:buildJs
  • Desktop native smoke checks in keyboard and touch modes: placement, partial water, buoyancy/coasting, hit bob and recovery, rider collision, dismount/destruction, inventory, mounted save/load, finite wrapping, and infinite-world residency/eviction/restoration. Touch checks cover tap-to-attack, hold-to-board, and releasing a hold without attacking.

Builds use JDK 17. Android and web were build-checked; runtime checks used desktop. Minecarts, mob passengers, cargo, and other wood variants are outside this PR.

@fredboy

fredboy commented Oct 24, 2026

Copy link
Copy Markdown
Owner Author

Reviewed 7638946e283d48d67cb12f964fc29af77c980621. I found four gameplay issues that should be fixed before merging. All four were reproduced with the desktop game and native Box2D through a temporary harness.

  1. [P2] Resolve the saved passenger after loading the player's chunk. ChunkEntityStreamer.kt:68–72

    Infinite-world initialization restores the initial chunks around the origin, then calls resolvePassenger(). A saved boat outside that region is not in live yet, so this clears mountedVehicleId. Loading the boat later does not retry passenger resolution. Reproduction: board at x=504, save, and reload. Before reload: mounted=far-boat; afterward: mounted=null, despite boats=[far-boat]. The player resumes unmounted over the water. Load/restore the saved player's region before resolving the reference, or retain the reference until its chunk has been restored.

  2. [P2] Use wrapped coordinates for targeting and reach checks. VehicleController.kt:101–110

    BoatRenderer displays boats across the finite-world seam, but target() tests the original hitbox and reachable() measures the unwrapped distance. In a 1024-block world, a player at x=1 sees a boat at x=1022 rendered at x=-2, only three blocks away. Aiming there makes both boardTarget() and attackTarget() return false. Translate the hitbox and raycast endpoint into the player's nearest world image before testing them.

  3. [P2] Include boats in the block-placement collision checks. PlaceBlockItemToForegroundAction.kt:38–45

    The new vehicle collision checks prevent placing a boat inside blocks, but the existing block-placement path still checks only the player and mobs. It accepts a solid block inside a live boat. Reproduction: a grounded boat centered at (33.5, 20.75), then place stone at (33, 20) through the normal placement action. Placement returns true, and the hull remains embedded in the stone after two seconds of physics. Add vehicle overlap checks to ordinary block placement and the slab-placement path, which has the same omission.

  4. [P2] Make sleeping and riding mutually exclusive in both directions. VehicleController.kt:197–201

    Boarding rejects a sleeping player, but using a nearby bed while already mounted still succeeds. The bed action sets isInBed and queues the move to the bed; syncPassenger() then moves the player back into the boat. Reproduction at night produced inBed=true, mounted=true, with the player still at the boat rather than the bed. The sleep pose and movement suppression now apply in the boat. Either safely dismount before accepting the bed action or reject sleeping while mounted.

Validation: all GitHub checks are green. Targeted JDK 17 Gradle checks for vehicle entities/controller, save, controls, and world completed successfully (existing test results were up-to-date). The native reproductions above were executed separately; no repository source files were changed. Please add regression coverage for these cases—the current happy-path smoke checks miss them.

@fredboy
fredboy merged commit d2c6a3d into develop Oct 24, 2026
7 checks passed
@fredboy
fredboy deleted the feature/vehicles branch October 24, 2026 15:50
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