Implement attack handler#342
Open
ch-iv wants to merge 13 commits into
Open
Conversation
Author
|
I think the formatter is failing due to an inconsistency on main. |
6794c20 to
c9ec7e9
Compare
The cave pass was ~47% of all chunk generation time (~660us of ~1.4ms). Two changes roughly halve it, with no correctness regression (the full world_gen suite — trees-not-undercut-by-caves, snow-never-floats, not-all-air, etc. — passes unchanged): - Sample the 3D cave noise with three RidgedMulti octaves instead of five and a coarser vertical grid step (8 instead of 6). The noise is taken on a coarse grid and trilinearly interpolated, which already smooths away the finest octaves, so the large-scale tunnel/chamber structure is effectively the same for ~40% fewer (the priciest, 3D) noise evaluations. `generate_caves` and `cave_opening_at_surface` share the same `cave_noise`, so they stay consistent and the tree/cave-mouth gate margin is preserved. - Collapse the per-cell trilerp in the fill loop. Trilinear interpolation is separable, so the X interpolation at the two bracketing Z edges is computed once per column for each grid-Y level and reused, turning the inner Y loop (160 cells/column) from eight grid fetches plus a full trilerp into two Y-lerps and one Z-lerp — the same operations in the same X->Y->Z order, so the carved result is identical. The now-unused `trilerp` helper is removed. Measured on one machine: cave pass ~662us -> ~283us, full generate_chunk ~1.41ms -> ~937us.
A dev-only load-testing tool that spawns a swarm of offline-mode azalea bots to connect to a running FerrumC server and (optionally) wander, reproducing the chunk-loading, movement, and broadcast load of many simultaneous players for measuring server tick performance under real concurrency. - Standalone crate (its own `[workspace]`, listed under `exclude` in the root Cargo.toml) so azalea's large dependency tree never compiles as part of the main build, CI, or release. - Pinned to `azalea = "=0.14.0"` (Minecraft 1.21.8 / protocol 772) to match FerrumC's protocol. azalea 0.14 transitively depends on a set of pre-release RustCrypto crates whose newer published versions have incompatible APIs; the committed Cargo.lock pins the whole stack back to the working versions (documented in the README, with restore commands). - Configurable bot count, join stagger, idle vs wandering, reconnect-on-drop, and a periodic connected/peak/joins/disconnects metrics line. Transport and login are verified end to end against a local server (bots reach the server and begin the login sequence). Note: a strict client cannot yet fully join because FerrumC's registry NBT encodes some `dimension_type` fields with the wrong tag width (e.g. `height` as Long instead of Int; `ambient_light` /`coordinate_scale` as int instead of float/double). The vanilla Java client coerces these leniently; azalea deserializes into typed structs and rejects them. Making that registry data wire-conformant is a separate server-side fix.
Rivers are driven by a dedicated low-frequency noise whose 0.5 contour traces each river's centreline, independent of the climate axes so they wander across biomes rather than following them (mirroring vanilla's use of rivers as biome separators). - climate: a `river` noise field and a per-column `river` factor on ClimateSample (0 away from rivers, rising to 1 at the centreline). - carving: in `column`, the river factor lowers the surface into a channel that the existing global sea-level flood then fills with water. The carve is gated to lowland columns above sea level and fades out toward mountain height, so rivers stay valleys winding through plains/forests instead of gashing peaks. - classify: a column is a river biome only where its channel was actually carved below sea level, so the river biome coincides with the visible water and dry banks keep their surrounding land biome. Cold columns record `frozen_river` (id 24), others `river` (id 41); both share one bed decorator. - a new `RiverBiome` decorator lays a gravel bed over dirt on the channel floor. Over a sampled region rivers cover ~3% of columns, every one water-filled, and the server generates spawn chunks with rivers without error. Frozen rivers are not yet ice-capped — a follow-up.
… no beaches Addresses several issues with the first river pass: - Consistent width: the river centreline distance is now normalised by the noise gradient, so rivers are a fixed handful of blocks wide everywhere instead of ballooning into lakes wherever the noise plateaued near its contour. The river noise gains an octave (and a gradient floor) so those plateaus do not occur in the first place. - Continuity: the channel is carved to a fixed depth along its centreline (deeper than it is wide) rather than scaling the depth by land height, so the bed stays below sea level — and the river unbroken — as the lowland surface rises and falls. Earlier the height scaling lifted the centreline above sea level on raised ground, breaking the river into disconnected pools. - Stays off mountains with a visible source: rivers carve at full depth across the lowlands and taper to nothing in a band just below a height ceiling, so a river peters out at the foot of high ground instead of gouging a canyon into it; no river is carved at or above the ceiling. - Inland only: a continentalness gate keeps rivers off the immediate coast, so they no longer spawn as a redundant strip of water beside the ocean. - River banks are no longer beaches: beach classification now requires ocean-coast continentalness, so inland river edges keep their surrounding land biome (grassy plains) with the gravel riverbed showing through at the shallow margins, rather than turning into a wide sand beach. Rivers cover ~2.4% of columns, are essentially fully connected, and widen naturally toward the sea where they reach it. Triangular alluvial deltas at river mouths and ice-capped frozen rivers remain follow-ups.
perf: speed up cave generation by ~57% (half of chunk-gen cost)
Feature/rivers
Brings in ch-iv's attack-handling work from ferrumc-rs#342: - Correct `InteractEntity` decoding. The packet's optional fields (target x/y/z, hand) depend on the interaction type, so a derived decoder mis-read every non-attack interaction and left unconsumed bytes in the stream. Decoding is now done by hand, reading the trailing fields only for the variants that carry them. - An attack handler that applies invulnerability frames, decrements health, applies knockback, and broadcasts the hurt animation. - A per-tick combat system that ticks `CombatProperties`. - A general ground/air friction system for the physics pipeline. The PR also removed `#![feature(const_cmp)]` from `ferrumc-data`; that file has since diverged on master (all of its feature attributes were already dropped), so the conflict is resolved by keeping master's version and discarding the now-obsolete change. Review fixes are applied in the following commit.
Follow-up to the PR ferrumc-rs#342 merge: - Reject attacks from outside reach. The attack handler fetched the attacker's position but never used it, so a modified client could send `InteractEntity` for any entity id at any distance. Attacks beyond the vanilla six-block server-side interaction range are now dropped, and a target without a position is treated as out of reach. - Stop scanning once the target is found. Entity ids are unique, so the handler breaks out of the entity loop after applying an attack instead of walking every remaining entity. - Gate the friction system on `HasGravity`, matching how gravity and water drag are gated. It previously damped the velocity of every entity with a velocity and ground flag, including ones deliberately spawned without physics. - Drop the obsolete `#[expect(unused_parens)]` and single-element tuple in the mob system registration; register the combat system directly. - Restore the doc comment on `InteractEntity::is_attack`.
Brings the reviewed attack-handling work onto master. It had been prepared on `feature/attack-handler` (upstream ferrumc-rs#342 plus review fixes) but was not part of the earlier integration, so attacks were not handled at all: the old derived `InteractEntity` decoder mis-read non-attack interactions, and the attack, combat-tick and friction systems were never registered. This merge is clean against master's later work (the LMDB reopen fix and the river/cave generation changes); it touches only the attack-handler files.
Spawned mobs carried combat properties but no health, so the attack handler could decrement nothing and entities could not die. This adds health to every entity bundle (from the vanilla `max_health`, falling back to twenty) and a death sequence: - `detect_deaths` finds entities whose health has reached zero, broadcasts the vanilla death status (Entity Event 3) so clients play the death animation, marks them non-attackable, and tags them `Dying`. - `tick_dying` counts the death-animation timer down and, once it elapses, despawns the entity and broadcasts `RemoveEntities` so clients drop it. Removal is deferred by `Dying::DEATH_ANIMATION_TICKS` so the animation has time to play rather than the entity vanishing on the killing blow. Only entities with an `EntityIdentity` are affected, so players are never despawned. `ferrumc-entities` gains a dependency on `ferrumc-components` for the health component (acyclic: components does not depend on entities).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR enables attack events to be handled properly.
This pull request updates the decoding logic for the
InteractEntitypacket in the networking layer. It also adds a friction handler to make sure an entity slows down over time.Note: I came up with velocity constants on my own. If you have a reference to an implementation in a more mature project, please let me know.
Screen.Recording.2026-03-23.at.12.58.40.PM.mov