Builds on Cosmic's #59 (player fluid travel, swimming, air supply) and
changes only what differs from vanilla 26.3 or what it lacks:
- BubbleColumnBlock.entityInside for the player (isPrecise, onAbove /
onInsideBubbleColumn, not while flying) with its splash/bubble particles.
- LocalPlayer.goDownInWater before LivingEntity.aiStep's velocity cleanup.
- The aiStep jump phase as vanilla: nothing while flying, the fluid jump
threshold from the eye height (also in travelInLava).
- Player.travel: swim steering samples y + 1.0 - 0.1, and LivingEntity.travel
checks fluids before gliding; water and lava no longer end a glide.
- LocalPlayer.isUnderWater is wasUnderwater; sprint conditions get shallow
water, flight and gliding; no flight toggle while swimming; the base tick
runs before local crouching; the desired pose puts swimming before gliding.
- decreaseAirSupply creates the oxygen_bonus instance (getAttribute).
- Swim sounds and muffled steps in water; entity event 67 drown bubbles.
- Scene motion harness: swim_corpus (player travel in water and lava, bubble
columns, air supply) and sprint-swim cases for --sprint-input.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The player's movement treated every fluid as empty: is_in_water was
always false, LivingEntity.checkFallDamage's updateFluidInteraction was
a no-op and Entity.move's fall-reset ray ignored water. A player landing
in water (or a waterlogged block, a bubble column, kelp) still took the
whole fall.
Bind vanilla's Entity.updateFluidInteraction to the player over the
existing horizon-world kernels (EntityFluidInteraction heights, eyes and
currents, entity_fluid_tick, water_splash, fluid_flow): run it in the
base tick and from checkFallDamage, read wasTouchingWater for
isInWater, query the water's (first-query cached) shape in the
FALLDAMAGE_RESETTING ray, halve the fall in lava after the first tick,
and play the splash sound with bubble and splash particles.
The scene motion harness gains water/lava fixtures (fluid_tick plus
scripted falls through the real Entity.move) against the real vanilla
updateFluidInteraction with the #water/#lava tags bound.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The player's portal timer reset to zero on any tick outside a portal and
came back from a trip with a 300-tick cooldown that only ran down outside
portals; the overworld exit search covered 32 blocks of loaded chunks;
nothing but the player could use a portal.
The player now follows Entity.setAsInsidePortal / handlePortal with
PortalProcessor (decay by 4, the cooldown of 10 that a portal keeps
resetting, players_nether_portal_default/creative_delay), and
NetherPortalBlock.getPortalDestination through the new
horizon_world::level::portal_travel: PortalForcer.findClosestPortalPosition
(16 / 128 blocks, loaded and saved chunks), createPortal,
BlockUtil.getLargestRectangleAround, PortalShape.getRelativePosition and
findCollisionFreePosition, with the turned yaw and motion and
block.portal.travel. LocalPlayer.handlePortalTransitionEffect closes
screens and plays block.portal.trigger. Items and mobs go through after one
tick with a 300-tick cooldown and wait as saved entities until their
dimension loads around the exit.
tools/test_nether_portal_parity.py compares the destination with vanilla's
getPortalDestination over two headless levels; the scene motion harness
gains portal fixtures for the player's processor and cooldown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entity.applyEffectsFromBlocks now runs WebBlock.entityInside and
SweetBerryBushBlock.entityInside for the player through
Player.makeStuckInBlock (no slowdown while flying, impulse context reset),
with Weaving's lighter cobweb hold and the sweet_berry_bush damage of a
grown bush while the known movement is at least 0.003 on X or Z. The scene
motion harness gains cobweb and berry-bush fixtures run through vanilla's
real applyEffectsFromBlocks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Powder snow was inert: the player's collision context never carried its
fall distance or boots, block-inside effects never ran for the player,
frozen ticks stayed 0 and the empty bucket only took fluids.
Player (PlayerMotion, LivingEntity.aiStep order):
- PowderSnowBlock.getCollisionShape gets the player's fall distance and
leather boots: it sinks through, walks on top in leather boots (sinks
when crouching), lands on the 0.9-high shape after a fall of more
than 2.5 blocks.
- Entity.applyEffectsFromBlocks over this tick's movement path (the
ported block sweep, StepBasedCollector steps): entityInside makes it
stuck (0.9, 1.5, 0.9) while its feet are in powder snow and sends the
server's snowflake from the level random; FREEZE sets isInPowderSnow
and adds a frozen tick per step; EXTINGUISH destroys the snow if the
player burns and puts the fire out. ServerPlayer.onInsideBlock fires
enter_block for every block entered (which also unlocks the boat
recipes in water, and the end gateway advancement).
- baseTick's wasInPowderSnow lets leather boots climb out (living_air).
- Server freezing: thawing 2 a tick, the powder_snow frost modifier
(-0.05 x percent frozen, not over air), freeze damage every 40 ticks
when fully frozen; leather armor (#freeze_immune_wearables) and
spectators don't freeze.
- HUD: the powder snow outline overlay and frozen hearts.
Items and blocks:
- BucketItem.use on powder snow: pickupBlock (2001), used statistic,
fill sound, FLUID_PICKUP, createFilledResult, filled_bucket trigger.
- SolidBucketItem: the empty_powder_snow place sound and an empty bucket
back in survival.
- Falling blocks land on powder snow, or end up inside it and break
after a fall of more than 2.5 blocks.
test_native_scene_motion gains powder snow fixtures ("snow_tick": the
oracle runs vanilla's real applyEffectsFromBlocks and freezing) and
prints frozen ticks, the snow flags and the stuck multiplier.
Fixes#62
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The --sprint-input scene drives the real LocalPlayer.aiStep sprint and
jump path from keyboard state. Add sprint-jump runs: sprint held or
started by double-tapping forward, jump tapped, held through landings or
pressed first, at five headings, with too little food to sprint, under a
two-block ceiling and up onto a slab. All 293,175 states match.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refresh scale dimensions and clamp health and absorption after movement, preserving native callback order and queued synchronization. Replay per-reference JVM identities in the scene comparison and cover changing limits, modifiers and low tunnels. Waypoint callbacks remain explicit requests for the future manager runtime.
Connect Shift input timing, dry pose fit, movement slowdown and eye height to the resident walking scene. Compare exact evolving state against pinned native client/server methods and record Linux window validation. Full gameplay and release acceptance remain unfinished.
Back up current movement composition work. Both reference JARs match 48,078 kinematic snapshots; full tick side effects and playable integration remain unfinished.