Links
Tags
Creators
Details
0.5.3+26.1.2
Compatibility
Required content
Changes
Review of the shipped 0.5.2. It found that the release's headline fix was correct about the branch it covered, silent about a third one, and shipped with no test that executed it at all.
Fixed
recomputePathhas three exits, and 0.5.2 handled two. The bytecode iscanUpdatePath()→ifeq(no recompute) →getfield targetPos→ifnull→ return →path = null→createPath. 0.5.2 moved the claimed-target re-apply into the wrap oncreatePath, which is correct for the recomputing branch and unreachable on thetargetPos == nullearly return. When the pre-dispatch target was null — an idle mob handed its first destination asynchronously — the supersede rollstargetPosback to null, vanilla returns without recomputing, and the claim is dropped: the mob is left with neither a path nor a target while its goal was already told the move succeeded. It re-issues after its own cooldown, so this is a stall of a few ticks rather than 0.5.1's indefinite stale path, but it is a stall PathWeaver caused. The re-apply is now also done at the guard, conditioned onpath == null— which is not a heuristic but the precondition of the 0.5.1 bug, negated: vanilla's reuse short-circuit ispath != null && !path.isDone() && targets.contains(targetPos), so with no path installed there is no route for a re-applied target to contradict.
Changed
- The recompute seam now has tests that can fail. 0.5.2's replacement game-test assertion was a
four-way disjunction beginning with
getPath() == null, and in that fixture the path is null — so it short-circuited on its first term and passed whether the claim was re-applied or not. This was proven by reintroducing 0.5.1's bug and watching all three game tests pass. Separately, no test in the repo executed the wrap's re-apply at all: the claim field was left at its defaultnulleverywhere, so the headline fix of 0.5.2 shipped with zero coverage. There are now two arms — one per branch — and unit coverage of the wrap itself. All of it is mutation-tested: reintroducing 0.5.1's behaviour fails the installed-path arm, and reverting to 0.5.2's fails the no-path arm. - The coverage contract keys on full call signatures and requires redirects to bind. It compared
bare method names, so a
@Redirectwhose target named the wrong owner (LivingEntityforMob) or the wrong descriptor counted as covering a site it could never bind to — and withrequire = 0that is behaviourally identical to deleting the mixin, which is the failure this contract exists to catch. Owner and descriptor are now compared, and every confined-read redirect must declarerequire >= 1. Both forgeries are mutation-tested. FlyNodeEvaluator'sgetRandom()read gained the non-vacuity pin the other two hazards already had; without it, deleting that name from the list and its redirect shrank both sides of the comparison symmetrically and stayed green.
Not changed, and stated
Mob.getPathfindingMalus() reads the live malus map from a worker while AmphibiousNodeEvaluator's
prepare can write it on the main thread — reachable because a synchronous search can run for a mob
that already has an async one in flight. It is an EnumMap, so the worst case is a stale float rather
than structural corruption, and it is already admitted in DESIGN.md as a live read. It is now an
explicit 0.6 item rather than a sentence in prose: it is the largest live-mob read still crossing the
thread boundary and no test pins it.
274 unit tests, four server harnesses, the client harness.
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:ZQJOU3vB:cc4sNXlC"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:ZQJOU3vB:cc4sNXlC"
}


