github Xian55/HermesProxy v4.4.0-feature-perf-object-update-and-movement-e865398
Pre-release: feature/perf/object-update-and-movement @ e865398 — perf(movement): size MonsterMove's span buffer from its own spline

latest release: v4.4.3
pre-release2 hours ago

Branch: feature/perf/object-update-and-movement
Commit: e86539808dc025215ecece4ffe66605f4303f081


perf(movement): size MonsterMove's span buffer from its own spline

MonsterMove.MaxSize was a constant derived from MaxSplinePoints, and WriteToSpan
returned -1 whenever the spline was longer than that, falling back to the
ByteBuffer path. The cap had been lowered from 64 to 16, its comment recording
the reason: "based on actual usage data (74-116 bytes observed)". That data came
from light traffic. Under a bot-populated battleground the fallback fired 370
times in ten minutes, and each miss rented a pooled buffer it discarded, re-wrote
the packet through ByteBuffer, and emitted a Warn-level log -- Warn routes to
Information, so this was per-packet logging enabled in production, and the
docs/perf.md baseline already attributed ~22% of proxy CPU to Serilog with
"MonsterMove exceeded MaxSize" named as a source.

A larger constant would only move the cliff. SplineCount is read straight off
the legacy wire (MovementHandler.cs:563) and is unbounded, so no constant is
correct. MaxSize is now computed from the spline the packet actually carries:
Points write as Vector3 (12 B) and PackedDeltas as PackXYZ (4 B), and both lists
are filled in the constructor, so the count is known before WritePacketData
rents. ArrayPool rounds the rent up to its bucket, so exact sizing costs nothing
against a constant and can never under-provision.

MaxSplinePoints survives at 4096 as a corruption guard only: a garbage
SplineCount must fall back rather than drive a huge rent.

Because 20-point splines now take the span path, byte-for-byte equivalence with
Write() became load-bearing for long splines rather than just short ones. The
test that pinned the old fallback contract is replaced by one asserting the span
output is identical to Write() for a 20-point spline, plus one asserting the
guard still trips at 5000.

Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_019p1wW7nkNtVwYdvxmo7PVq

Don't miss a new HermesProxy release

NewReleases is sending notifications on new releases.