Expand voxel gameplay, lighting, full-height streaming and world imports
MVP checks / mvp (push) Canceled after 0s
MVP checks / mvp (push) Canceled after 0s
Add shared Rust/WASM physics, worker meshing and diagnostics, 64-chunk full-height streaming, atlas texture support, and baseline world import. Document the current implementation and include the supplied in-game lobby screenshot.
This commit is contained in:
+187
@@ -0,0 +1,187 @@
|
||||
# Player physics
|
||||
|
||||
Shacraft uses one Rust player-movement implementation on the authoritative server
|
||||
and in the browser through WebAssembly. It targets the movement of Minecraft
|
||||
Java 26.2, with measured reference cases from the original executable. The
|
||||
measurements establish specific numerical agreements; they do not establish
|
||||
complete Minecraft compatibility.
|
||||
|
||||
## Playing
|
||||
|
||||
- **WASD / arrow keys:** walk; **Ctrl + forward:** sprint.
|
||||
- **Space:** jump, swim upward, or ascend while flying.
|
||||
- **Shift:** crouch and avoid walking off edges; descend in water or flight.
|
||||
- **Double-tap Space / F:** toggle flight when the server permits it. Creative
|
||||
worlds permit flight; ordinary players in other world modes cannot enable it.
|
||||
- **F3:** inspect the active physics mode, pose, unacknowledged input count,
|
||||
and the latest position correction.
|
||||
|
||||
Walking accelerates and retains momentum. Ground friction, air control, the
|
||||
sprint jump impulse, held-jump cooldown, gravity and drag all operate on fixed
|
||||
50 ms ticks. Crouching changes the collision box and eye height. A player who
|
||||
cannot stand or crouch fits into the swimming-sized crawling pose when possible.
|
||||
|
||||
Collision handling uses the catalog's block-state boxes, resolves vertical
|
||||
movement before horizontal movement, and chooses step heights from obstacle
|
||||
surfaces. Slabs, stairs, ceilings, corners and sneak-edge support participate in
|
||||
the same solver. Scaffolding and powder snow have additional player-dependent
|
||||
collision rules.
|
||||
|
||||
The solver also handles ice variants, slime and bed bounces, honey slowing and
|
||||
wall sliding, soul sand, climbable blocks, cobwebs, berry bushes, powder snow,
|
||||
water, lava, waterlogged cells, bubble columns, swimming and creative flight.
|
||||
Water/lava behavior includes acceleration, drag, buoyancy inputs, fluid levels
|
||||
and currents derived from the provided nearby block states.
|
||||
|
||||
`PhysicsSettings` exposes movement and flight speed, step height, launch-pad
|
||||
jump overrides, leather boots and coefficients for speed, slowness, jump boost,
|
||||
levitation, slow falling, Dolphin's Grace and Depth Strider. These are solver
|
||||
inputs for server integrations; their presence does not add an inventory,
|
||||
equipment or potion gameplay system. `apply_impulse` accepts an external
|
||||
velocity change for future combat, explosions or scripted launch effects.
|
||||
|
||||
## Shared simulation and networking
|
||||
|
||||
The implementation is in
|
||||
[`crates/shacraft-physics`](../crates/shacraft-physics/src/lib.rs).
|
||||
Positions use blocks and velocities use blocks per tick. Angles are radians;
|
||||
Shacraft yaw zero faces negative Z. Reference tests convert Minecraft's positive
|
||||
Z convention explicitly.
|
||||
|
||||
The server supplies authoritative nearby block states, shape boxes and settings.
|
||||
The browser runs the same compiled solver immediately for local input. Each
|
||||
server motion update includes a sequence acknowledgement, tick and motion epoch.
|
||||
The client restores the acknowledged state and replays pending inputs. Teleports
|
||||
and world changes reset prediction; render smoothing affects the displayed
|
||||
position without feeding a smoothed position back into physics.
|
||||
|
||||
[`client/player-physics.js`](../client/player-physics.js) samples the swept
|
||||
collision neighborhood, keeps a bounded input history and interpolates display
|
||||
frames between fixed simulation ticks. It suspends prediction when that
|
||||
neighborhood extends into unknown chunks instead of treating missing data as
|
||||
air. A failed or incompatible WebAssembly load falls back to server movement.
|
||||
Server support is negotiated with `movement_prediction_v1` so older clients can
|
||||
continue using authoritative updates.
|
||||
|
||||
## Reference evidence
|
||||
|
||||
[`scripts/physics_reference.java`](../scripts/physics_reference.java) runs
|
||||
against the pinned official 26.2 server executable already used for catalog
|
||||
extraction. It does not start a Minecraft server. Registry initialization is
|
||||
real; player and world constructors are bypassed for an isolated measurement
|
||||
harness. Only factual measurements and the independently authored harness are
|
||||
stored in the repository.
|
||||
|
||||
The committed
|
||||
[`java26.2.json`](../crates/shacraft-physics/tests/fixtures/java26.2.json)
|
||||
contains:
|
||||
|
||||
- Friction, speed, jump and bounce factors for 16 surfaces; default player
|
||||
attributes; five pose dimensions; water/lava heights for all 16 level values.
|
||||
- Thirteen trajectories from original `Player.travel`, `jumpFromGround` and
|
||||
`Entity.collideWithShapes` calls: walking, sprinting, jumping, ice movement,
|
||||
water, lava and creative flight.
|
||||
- Eight original `Entity.collide` measurements, including low-ceiling steps,
|
||||
thin steps, descending into a step and choosing the lowest useful step.
|
||||
- Separate original collision restitution, honey slide, slime step, bubble
|
||||
column and current-application measurements.
|
||||
|
||||
The trajectory harness supplies inputs, small-velocity threshold preparation,
|
||||
the measured sprint attribute modifier, constant medium/depth and flat-plane
|
||||
position/collision bookkeeping. It deliberately does not claim to execute the
|
||||
entire original game tick. Callback samples measure the callbacks separately,
|
||||
not their complete automatic dispatch in a running world. The water sprint
|
||||
kernel keeps the swimming pose disabled to isolate water travel.
|
||||
|
||||
Some details differ from older Minecraft physics descriptions: the sprint
|
||||
attribute modifier is the float-derived `0.30000001192092896`, the player's
|
||||
horizontal small-velocity threshold applies to the vector's squared length,
|
||||
bed restitution is `0.75`, and bounce velocity includes the fraction of motion
|
||||
completed before collision. The measured standing jump reaches
|
||||
`1.2522033402537238` blocks above its starting position.
|
||||
|
||||
Native trajectory tests compare position and velocity on every tested tick with
|
||||
an absolute tolerance of `2e-6`. They exercise twelve of the thirteen kernels:
|
||||
the artificial constant shallow-lava depth is excluded because an integrated
|
||||
world changes immersion as the player falls. Water sprint comparison stops when
|
||||
input is released, because the integrated controller ends sprinting while the
|
||||
isolated kernel keeps its sprint flag set. Separate step cases use `1e-7`, and
|
||||
restitution, honey and bubble callback tests use `1e-12`.
|
||||
|
||||
Browser tests execute the shipped WebAssembly through the actual JavaScript ABI,
|
||||
compare the eight air/ground/flight reference trajectories with `2e-6` tolerance,
|
||||
and exercise replay under delayed acknowledgements. Additional tests cover
|
||||
movement, collision, fluids, body poses, prediction resets, missing chunks and
|
||||
input ordering. These tolerances describe the tested cases, not an error bound
|
||||
for every possible world, angle or interaction.
|
||||
|
||||
The HTTP/WebSocket integration check starts a real release server on an isolated
|
||||
port with a temporary database and loads the WebAssembly it serves. It compares
|
||||
consecutive authoritative states against the same consumed command in the
|
||||
browser solver with `1e-10` tolerance. It also checks burst acknowledgements,
|
||||
duplicate commands, crouching, jumping, flight permissions, reset epochs,
|
||||
continuous movement across chunk boundaries, and a client without prediction
|
||||
support. Only explicit world changes may produce full snapshots during that
|
||||
check. The report records both binary hashes and the largest observed error.
|
||||
|
||||
## Building and verification
|
||||
|
||||
After changing the Rust solver, rebuild the browser artifact before opening the
|
||||
game or running browser physics tests:
|
||||
|
||||
```sh
|
||||
rustup target add wasm32-unknown-unknown
|
||||
bash scripts/build_physics.sh
|
||||
cargo test -p shacraft-physics
|
||||
cd client
|
||||
npm test
|
||||
```
|
||||
|
||||
The complete workspace checks remain `cargo test --workspace`,
|
||||
`cargo fmt --all -- --check` and
|
||||
`cargo clippy --workspace --all-targets -- -D warnings` from the repository root.
|
||||
|
||||
Run the isolated real-network check from the repository root after rebuilding
|
||||
both the native server and browser module:
|
||||
|
||||
```sh
|
||||
cargo build -p shacraft-server --release
|
||||
bash scripts/build_physics.sh
|
||||
node scripts/check_player_physics.mjs \
|
||||
--port 4013 \
|
||||
--binary target/release/shacraft-server \
|
||||
--output artifacts/physics/network-report.json
|
||||
```
|
||||
|
||||
The harness refuses a port already serving HTTP and does not use the running
|
||||
demo server or its database.
|
||||
|
||||
To reproduce measurements with an existing Java 25 JDK and the catalog cache:
|
||||
|
||||
```sh
|
||||
python3 scripts/measure_physics.py \
|
||||
--java /path/to/java25/bin/java \
|
||||
--output crates/shacraft-physics/tests/fixtures/java26.2.json
|
||||
```
|
||||
|
||||
If the cache is absent, prepare it using the catalog generation instructions
|
||||
before running the probe. The measurement runner verifies the pinned official
|
||||
bundle hash and verifies that the extracted executable matches that bundle.
|
||||
The fixture records the source URL, source and executable hashes, Java version,
|
||||
probe hash and reproduction command. Runtime binaries, diagnostic bytecode
|
||||
output and logs remain in ignored `artifacts/`.
|
||||
|
||||
## Remaining scope
|
||||
|
||||
This change implements player locomotion, not Minecraft's complete simulation.
|
||||
It does not add fluid spreading or scheduled fluid/block updates, pistons and
|
||||
moving block machinery, boats/minecarts, entity pushing, an elytra model, or the
|
||||
full combat/damage/knockback system. The external impulse API is a building block
|
||||
for those systems rather than their implementation.
|
||||
|
||||
Collision accuracy also depends on the catalog's measured boxes and on the
|
||||
states supplied by the server. Additional entity-dependent shapes, moving
|
||||
obstacles, complete fluid flow rules, every status-effect interaction and
|
||||
arbitrary input-angle trajectories need further reference cases. The browser
|
||||
and server share the same numerical implementation, but prediction can still
|
||||
be corrected when world edits or authoritative settings arrive after an input.
|
||||
Reference in New Issue
Block a user