Skip to content

feat(simulated): nav table waypoint names, bearing rate and range limit - #31

Merged
SolAstrius merged 2 commits into
mainfrom
feat/nav-table-waypoint-readouts
Oct 27, 2026
Merged

SolAstrius merged 2 commits into
mainfrom
feat/nav-table-waypoint-readouts

Conversation

@SolAstrius

Copy link
Copy Markdown
Owner

Adds three readouts to the navigation_table peripheral:

  • Waypoint names: the display name of the held item, so a renamed compass or map labels its target.
  • getBearingRate / getBearingRateRad: how fast the needle is swinging, handling the ±180° seam. A rate near zero with the target ahead means the current course intercepts it.
  • getMaxRange: the range at which the held item's signal cuts off, with math.huge for unlimited targets (compass, map) instead of upstream's 0.

Closes #28.

Every nav item that carries a per-item destination was anonymous to a
program. A lodestone-bound compass reported only the tracker UUID
Simulated stamps on it at binding time, a marked map only the numeric
MAP_ID, and the Explorer's/Nature's Compass compat targets expose no
metadata at all. A display could say where the table was pointing but
never what the waypoint was called, which is the one identity a player
actually chose.

getTargetName returns the anvil-given custom name of the held stack and
nil when the item was never renamed, so a readout can fall back
deliberately rather than printing a UUID. getTargetDisplayName adds the
item's own name behind that fallback so there is always something to
print; its fallback resolves against whatever language table the server
has loaded, which on a dedicated server is vanilla English only, so a
modded item with no custom name can surface its raw translation key.

Both read the held stack rather than the resolved target, matching
getTargetType and getTargetMetadata: they answer while no target is
locked, and the naming is meaningless only for the single-destination
types (an unbound compass always resolves to world spawn).
Bearing alone does not say whether a course arrives. The intercept
signal is the rate the needle swings: with the target ahead and
closing, a bearing rate near zero means the current heading reaches it,
while a steady non-zero rate means it misses by a margin that only
grows as range falls. Upstream never computes it, so programs
differenced getBearing() in Lua and had to handle the +/-180 seam
themselves, where a needle sweeping past dead astern reads as a full
turn the other way.

The table recomputes relativeAngle every server tick -- only the
distance pair is on the 11-tick cycle -- so NavTableBlockEntityMixin
differences it at that cadence and scales to degrees per second, the
same shape as the existing vertical-speed derivation on the altitude
sensor. Bearing is relativeAngle minus a constant, so their rates are
identical and the delta is wrapped to +/-180. Two discontinuities are
not vehicle motion and are suppressed rather than reported: a swap of
the held item re-aims the needle in one tick (detected with
ItemStack.matches, copying only when it changes), and an unresolved
target leaves the angle stale. The value still grows without bound as
range goes to zero, which is documented on the getter, since bearing is
undefined at the target itself.

getMaxRange covers the other way a needle lies. Past the cutoff the
block stops emitting on every side, which reads identically to sitting
on the target, so steering on bearing without checking range can chase
a dead needle. Upstream spells "no limit" as a max range of zero, which
is not comparable against a distance, so this reports math.huge -- CC
converts any Number through ValueFactory.valueOf(double) with no
finiteness check, so it arrives in Lua intact. The two most common
items are the unlimited ones (compass and map both override to zero)
while everything else takes the 200-block default, so neither constant
was safe for a program to assume.

Deliberately not exposed: getDeadzone, getModulatingRange and the
per-side redstone strength. A computer already has getDistanceToTarget
and hasTarget, so it can pick its own arrival radius; and upstream
gates those on the offset projected into the plane perpendicular to the
block's facing, not the 3D distance reported here, so the numbers would
invite programs to reproduce the block's redstone behaviour slightly
wrong.
@SolAstrius
SolAstrius merged commit 436599a into main Oct 27, 2026
5 checks passed
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.

Feature Request: Ability to get the name of an item in the nav table (Renamed Compasses!)

1 participant