PathWeaverСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачать
ВЕРСИИ (18)
beta
0.9.0 - Correctness, Cloth optional, distance LOD (26.3)
0.9.0+26.313 окт. 2026 г.190Minecraft: 26.3fabric
Что нового
Minecraft **26.3** build of 0.9.0. Everything the 26.1.2 changelog describes applies here, with one
exception that matters on a performance pack, and one change to the navigation hook that 26.3 forced.
### The hook moved, because vanilla moved
26.3 added `PathNavigation.moveTo(Entity, int, double)`. The old `moveTo(Entity, double)` now does
nothing but delegate to it, and `MeleeAttackGoal`, which is what a hostile mob chasing a player runs,
calls the new overload directly. PathWeaver's three hooks for entity-target movement therefore sit on
the inner overload on this branch: the speed capture, the deferred-acceptance return, and the wrapper
around `createPath`. On 26.1.2 and 26.2 they sit on the two-argument method.
Nothing about which path a mob gets changes. The request is claimed one level further down the same
call, and the delegate returns the inner result unchanged.
Left alone, the wrapper would have had no call site to bind to on 26.3. It is declared `require = 1`,
so that is a refusal to load rather than a mod that runs with a hole in it.
### `AUDITED` does not cover Lithium on 26.3
Lithium 0.26.2 is the build a 26.3 pack installs, and this release does not audit it. Five of the
eight audited classes are byte-identical to the 0.25.3 build audited for 26.2. Three are not: two
gained a field writer, and one differs only because 26.3's Mixin declares an injection point as an
array. The exemption allows field writes only in constructors, static initializers and one named
initializer per class, and the two new writers are not in that set, so certifying 0.26.2 needs an
argument about when they run and whether a worker can reach them. Nobody has written that argument.
The audit is a statement about exact bytes, so it refuses 0.26.2 by version and says so in the log
rather than being re-pinned on a proof nobody ran.
What this means in practice. At `compatibilityTier=AUDITED` on 26.3, any pack containing Lithium has
every movement family denied, so PathWeaver does nothing. The shipped default is `UNSAFE`, which reads
none of this and is unaffected. `LithiumPathfindingCompatibility` states what a 26.3 re-pin has to
prove, for whoever picks it up.
Diagonal Blocks 26.3.0, ServerCore 1.5.20+26.3, rabbit-pathfinding-fix 1.5.0 and both Fabric API
modules are audited on 26.3, all re-derived against the artifacts a 26.3 install resolves.
### Verified on 26.3
- 69 suites, 515 unit tests, 0 failures
- 9 of 9 game-test harnesses, one attempt each and no reruns, every row checked against the
manifest it actually consumed and the providers on its classpath at launch: 21 tests
(`docs/evidence/port-26.3/HARNESS-26.3.txt`)
- a real 26.3 client with an integrated server: searches dispatch and install, and the settings
screen draws (`docs/evidence/port-26.3/CLIENT-26.3.txt`)
- a clean 26.3 server without Cloth Config starts with PathWeaver active, and a control build with
the old Cloth dependency put back fails to start (`docs/evidence/port-26.3/no-cloth/`)
- all 36 of the 0.9.0 four-state witnesses re-run here, each fix reverted and its test seen to fail
for the expected reason (`docs/evidence/port-26.3/WITNESS-26.3.txt`), plus two more for the two
things 26.3 broke: the navigation hook and the manifest range
- the jar was built from a fresh clone, and its declared versions were read back out of the built
jar (`docs/evidence/port-26.3/RELEASE-JAR.txt`)
### Also worth knowing
26.3's Mixin declares `@Redirect.at()` as an `At[]` rather than a single `At`. That is invisible in
production code and broke three of our own annotation readers, which now reject a redirect declaring
more than one injection point instead of reading the first of several.
Two dependency traps, in case they bite you too. ServerCore publishes `1.5.20+26.3` twice on Modrinth,
once for Fabric and once for NeoForge, and a Maven coordinate on the version number can resolve the
NeoForge jar: it carries the same mixin class and no `fabric.mod.json`. And both Fabric API modules
this mod audits now differ byte-for-byte between the standalone artifact and the copy nested inside
the aggregate `fabric-api` jar, so the audit accepts either packaging and pins the mixin bytes exactly.
If you run ServerCore, make sure it is the 26.3 Fabric build.
---
# Everything in 0.9.0
Correctness and honesty, a per-search cost removed from searches that stay on the server thread, and two changes you will notice: Cloth Config is no longer required, and there is a new optional setting for distant mobs.
## Searches PathWeaver leaves on the server thread no longer pay for it
Some path searches stay on the server thread: villagers looking for a bed or a workplace, which use the
answer straight away, and any mob PathWeaver decides not to take. Those searches were slower than with no
PathWeaver at all. Two checks ran once for every node of every search, on every thread, including the
ones they had nothing to say about: a thread-local lookup, and a hook that created a small object on
every call. Both are in 0.8.0 too; only the 0.9.0 build was measured.
Both are gone. In a 317-mod client with a village, villager point-of-interest searches took 24 to 30% of
the server tick in every run with the old build, 20 to 24% with no PathWeaver, and 23 to 26% with this
one. It is a few percent of tick, not a lag spike, but it was a cost on exactly the searches this mod
cannot move off the thread.
**The lag report that led here was not PathWeaver.** In that pack, Enhanced Cats sends every villager
within 10 blocks of a cat towards it, every tick, on the client as well as the server, and the game
lagged with PathWeaver removed too. If your game lags when cats are near villagers, try without
that mod before blaming this one.
## Route sharing survives a settings change
Switching route sharing or the master switch off and on again could leave a stored route in play across changes made while it was off. PathWeaver stops watching for block changes when either switch is off, but stored routes were only discarded when the server stopped, so a route could be handed out after terrain nobody had been watching moved underneath it.
Both switches now discard what was learned under the previous settings, including searches that were already in flight when you changed them. This was reachable from the settings screen in 0.8.0 and 0.8.1 with no restart, and it is the reason to update if you had turned route sharing on.
## Villager paths at the age limit are no longer thrown away
A finished search that arrived at exactly the configured age limit was accepted by one part of the mod and rejected by another, so the work was done and discarded and the mob ran its own search anyway. At `maxResultAgeTicks=1`, which the settings allow, that was every result except the ones that finished within the same tick they were dispatched.
Default settings were affected far less than that, but the wasted searches were real.
## A villager path from the future
If server time moved backwards, on a world reload or a rollback, a finished path already set aside for
a villager could still be handed to it, answering a question asked before the search was dispatched.
The check that refuses a result from the future ran when the result arrived and not when it was
collected, and those are the same rule at two different moments.
## `/pathweaver status` stops overstating route sharing
The line reporting how many searches route sharing skipped was adding together searches that really did not run and cache hits that saved nothing. Hits recorded while the cache was measuring have no stored route to hand out, so they skip nothing. They are now on their own line, and only the first number is a saving.
The cache capacity shown was the one in your settings file rather than the one in use. Capacity is fixed when the server starts, so if you changed it since, the screen now says the change is waiting for a restart.
**If you decided against `SERVE` on the old number, the honest one is smaller.** If you decided for it, look again.
## The route sharing tooltip was too strong
The settings screen said a reused route "is never a stale one". It now says what actually holds: a route is dropped when a block changes along it, and a change away from the route is not noticed, exactly as vanilla does not notice it either. The old wording is in the 0.8.0 and 0.8.1 jars where no page edit could reach it.
## Settings files are checked properly
`resultCacheMode`, `resultCacheMaxAgeTicks` and `resultCacheMaxEntries` were not type-checked when the config was read, so a hand-edited mistake in one of them was quietly coerced instead of reported. Every persisted setting is now checked, and the check is derived from the settings themselves rather than a list that had already fallen behind three times.
## Compatibility checking
The Lithium audit now pins the vanilla pathfinding class it inspects by hash, like the other audits do. It previously inspected whatever was loaded, on the argument that re-deriving the check each time was stronger than pinning it. It is not: that check reads one class and does not follow what that class calls, so on a changed class it would have reported nothing while proving less than it looked like it proved.
No compatibility outcome changes as a result, on any version. Both downloads verify all seven audits on the Minecraft version they are built for; see the project page for what happens if you install the wrong one.
## New: is pathfinding even your problem?
[A ten-minute check](https://github.com/zimdin12/PathWeaver/blob/master/docs/IS-IT-YOUR-BOTTLENECK.md) you can run before installing this mod, using spark. PathWeaver only helps a server whose tick time is going into mob path searches, and plenty of struggling servers are slow for some other reason. It also says how to read the profile without the two mistakes that are easy to make with it.
## Cloth Config is no longer required
PathWeaver needed Fabric API and Cloth Config. Cloth Config draws the settings screen, which a
dedicated server never shows, so every server owner was installing a GUI library to run a server-side
mod.
It now needs Fabric API and nothing else. Install Cloth Config if you want the settings screen; without
it the mod reads and writes the same `config/pathweaver.json` and behaves identically. Nothing about
your existing config file changes and no setting is lost.
## New, and off by default: redo distant path searches less often
When a block changes on the route a mob is walking, the game redoes that mob's whole path search. It
will not do it more often than once a second for any one mob, but in a place where terrain keeps
changing, every mob whose route crosses the change pays for it, whether anyone is near enough to see
it or not.
`lodEnabled` widens that limit for mobs beyond 64 blocks from every player: one search every 40 ticks
instead of the game's once a second. Both numbers are settings. A mob picking a new destination is
never affected; this only delays redoing a route the mob already has.
**It ships off, and that is deliberate.** It is the only setting in this mod that keeps a mob walking a
route after the ground under it has changed. (An earlier version of this changelog said everything else
gives a mob the path it would have had anyway. That was too strong: by default a mob whose target moved
by a block or less keeps its current path, `repathToleranceBlocks=1`.) This lets a distant mob keep
walking an out-of-date route for longer after the ground under it changes. That is bounded and remote, but it is a real difference, so it is offered rather than
taken.
Worth turning on for mob farms, penned herds near redstone, or a high simulation distance. It does
nothing at all for mobs whose surroundings are not changing, because the game never redoes their
search in the first place.
## Not in this release
No change to the mod's core numbers. This exact jar was put back through the benchmark against 0.8.0
and against no mod: it is no slower than 0.8.0. Re-measured on 2026-10-13 with the zombies really
chasing a player (the September runs had lost their test player), it saves 4 to 5.5% of tick time at
2500 to 10000 zombies and 8 to 12% at 500 to 1000. This line used to say 5 to 9%.
For LOD there is only a best case. In a test built to favour it, 400 zombies at least 70 blocks from the
player with terrain changing among them all the time, turning it on cut the path searches PathWeaver
started by 13 to 19% and did not measurably change tick time. What it saves on your server depends on
how much terrain changes around mobs nobody is standing near, and in a world where it does not change,
it saves nothing.
beta
0.9.0 - Correctness, Cloth optional, distance LOD (26.2)
0.9.0+26.214 сент. 2026 г.270Minecraft: 26.2fabric
Что нового
Correctness and honesty, a per-search cost removed from searches that stay on the server thread, and two changes you will notice: Cloth Config is no longer required, and there is a new optional setting for distant mobs.
## Searches PathWeaver leaves on the server thread no longer pay for it
Some path searches stay on the server thread: villagers looking for a bed or a workplace, which use the
answer straight away, and any mob PathWeaver decides not to take. Those searches were slower than with no
PathWeaver at all. Two checks ran once for every node of every search, on every thread, including the
ones they had nothing to say about: a thread-local lookup, and a hook that created a small object on
every call. Both are in 0.8.0 too; only the 0.9.0 build was measured.
Both are gone. In a 317-mod client with a village, villager point-of-interest searches took 24 to 30% of
the server tick in every run with the old build, 20 to 24% with no PathWeaver, and 23 to 26% with this
one. It is a few percent of tick, not a lag spike, but it was a cost on exactly the searches this mod
cannot move off the thread.
**The lag report that led here was not PathWeaver.** In that pack, Enhanced Cats sends every villager
within 10 blocks of a cat towards it, every tick, on the client as well as the server, and the game
lagged with PathWeaver removed too. If your game lags when cats are near villagers, try without
that mod before blaming this one.
## Route sharing survives a settings change
Switching route sharing or the master switch off and on again could leave a stored route in play across changes made while it was off. PathWeaver stops watching for block changes when either switch is off, but stored routes were only discarded when the server stopped, so a route could be handed out after terrain nobody had been watching moved underneath it.
Both switches now discard what was learned under the previous settings, including searches that were already in flight when you changed them. This was reachable from the settings screen in 0.8.0 and 0.8.1 with no restart, and it is the reason to update if you had turned route sharing on.
## Villager paths at the age limit are no longer thrown away
A finished search that arrived at exactly the configured age limit was accepted by one part of the mod and rejected by another, so the work was done and discarded and the mob ran its own search anyway. At `maxResultAgeTicks=1`, which the settings allow, that was every result except the ones that finished within the same tick they were dispatched.
Default settings were affected far less than that, but the wasted searches were real.
## A villager path from the future
If server time moved backwards, on a world reload or a rollback, a finished path already set aside for
a villager could still be handed to it, answering a question asked before the search was dispatched.
The check that refuses a result from the future ran when the result arrived and not when it was
collected, and those are the same rule at two different moments.
## `/pathweaver status` stops overstating route sharing
The line reporting how many searches route sharing skipped was adding together searches that really did not run and cache hits that saved nothing. Hits recorded while the cache was measuring have no stored route to hand out, so they skip nothing. They are now on their own line, and only the first number is a saving.
The cache capacity shown was the one in your settings file rather than the one in use. Capacity is fixed when the server starts, so if you changed it since, the screen now says the change is waiting for a restart.
**If you decided against `SERVE` on the old number, the honest one is smaller.** If you decided for it, look again.
## The route sharing tooltip was too strong
The settings screen said a reused route "is never a stale one". It now says what actually holds: a route is dropped when a block changes along it, and a change away from the route is not noticed, exactly as vanilla does not notice it either. The old wording is in the 0.8.0 and 0.8.1 jars where no page edit could reach it.
## Settings files are checked properly
`resultCacheMode`, `resultCacheMaxAgeTicks` and `resultCacheMaxEntries` were not type-checked when the config was read, so a hand-edited mistake in one of them was quietly coerced instead of reported. Every persisted setting is now checked, and the check is derived from the settings themselves rather than a list that had already fallen behind three times.
## Compatibility checking
The Lithium audit now pins the vanilla pathfinding class it inspects by hash, like the other audits do. It previously inspected whatever was loaded, on the argument that re-deriving the check each time was stronger than pinning it. It is not: that check reads one class and does not follow what that class calls, so on a changed class it would have reported nothing while proving less than it looked like it proved.
No compatibility outcome changes as a result, on any version. Both downloads verify all seven audits on the Minecraft version they are built for; see the project page for what happens if you install the wrong one.
## New: is pathfinding even your problem?
[A ten-minute check](https://github.com/zimdin12/PathWeaver/blob/master/docs/IS-IT-YOUR-BOTTLENECK.md) you can run before installing this mod, using spark. PathWeaver only helps a server whose tick time is going into mob path searches, and plenty of struggling servers are slow for some other reason. It also says how to read the profile without the two mistakes that are easy to make with it.
## Cloth Config is no longer required
PathWeaver needed Fabric API and Cloth Config. Cloth Config draws the settings screen, which a
dedicated server never shows, so every server owner was installing a GUI library to run a server-side
mod.
It now needs Fabric API and nothing else. Install Cloth Config if you want the settings screen; without
it the mod reads and writes the same `config/pathweaver.json` and behaves identically. Nothing about
your existing config file changes and no setting is lost.
## New, and off by default: redo distant path searches less often
When a block changes on the route a mob is walking, the game redoes that mob's whole path search. It
will not do it more often than once a second for any one mob, but in a place where terrain keeps
changing, every mob whose route crosses the change pays for it, whether anyone is near enough to see
it or not.
`lodEnabled` widens that limit for mobs beyond 64 blocks from every player: one search every 40 ticks
instead of the game's once a second. Both numbers are settings. A mob picking a new destination is
never affected; this only delays redoing a route the mob already has.
**It ships off, and that is deliberate.** It is the only setting in this mod that keeps a mob walking a
route after the ground under it has changed. (An earlier version of this changelog said everything else
gives a mob the path it would have had anyway. That was too strong: by default a mob whose target moved
by a block or less keeps its current path, `repathToleranceBlocks=1`.) This lets a distant mob keep
walking an out-of-date route for longer after the ground under it changes. That is bounded and remote, but it is a real difference, so it is offered rather than
taken.
Worth turning on for mob farms, penned herds near redstone, or a high simulation distance. It does
nothing at all for mobs whose surroundings are not changing, because the game never redoes their
search in the first place.
## Not in this release
No change to the mod's core numbers. This exact jar was put back through the benchmark against 0.8.0
and against no mod: it is no slower than 0.8.0. Re-measured on 2026-10-13 with the zombies really
chasing a player (the September runs had lost their test player), it saves 4 to 5.5% of tick time at
2500 to 10000 zombies and 8 to 12% at 500 to 1000. This line used to say 5 to 9%.
For LOD there is only a best case. In a test built to favour it, 400 zombies at least 70 blocks from the
player with terrain changing among them all the time, turning it on cut the path searches PathWeaver
started by 13 to 19% and did not measurably change tick time. What it saves on your server depends on
how much terrain changes around mobs nobody is standing near, and in a world where it does not change,
it saves nothing.
beta
0.9.0 - Correctness, Cloth optional, distance LOD (26.1.2)
0.9.0+26.1.214 сент. 2026 г.77Minecraft: 26.1.1, 26.1.2fabric
Что нового
Correctness and honesty, a per-search cost removed from searches that stay on the server thread, and two changes you will notice: Cloth Config is no longer required, and there is a new optional setting for distant mobs.
## Searches PathWeaver leaves on the server thread no longer pay for it
Some path searches stay on the server thread: villagers looking for a bed or a workplace, which use the
answer straight away, and any mob PathWeaver decides not to take. Those searches were slower than with no
PathWeaver at all. Two checks ran once for every node of every search, on every thread, including the
ones they had nothing to say about: a thread-local lookup, and a hook that created a small object on
every call. Both are in 0.8.0 too; only the 0.9.0 build was measured.
Both are gone. In a 317-mod client with a village, villager point-of-interest searches took 24 to 30% of
the server tick in every run with the old build, 20 to 24% with no PathWeaver, and 23 to 26% with this
one. It is a few percent of tick, not a lag spike, but it was a cost on exactly the searches this mod
cannot move off the thread.
**The lag report that led here was not PathWeaver.** In that pack, Enhanced Cats sends every villager
within 10 blocks of a cat towards it, every tick, on the client as well as the server, and the game
lagged with PathWeaver removed too. If your game lags when cats are near villagers, try without
that mod before blaming this one.
## Route sharing survives a settings change
Switching route sharing or the master switch off and on again could leave a stored route in play across changes made while it was off. PathWeaver stops watching for block changes when either switch is off, but stored routes were only discarded when the server stopped, so a route could be handed out after terrain nobody had been watching moved underneath it.
Both switches now discard what was learned under the previous settings, including searches that were already in flight when you changed them. This was reachable from the settings screen in 0.8.0 and 0.8.1 with no restart, and it is the reason to update if you had turned route sharing on.
## Villager paths at the age limit are no longer thrown away
A finished search that arrived at exactly the configured age limit was accepted by one part of the mod and rejected by another, so the work was done and discarded and the mob ran its own search anyway. At `maxResultAgeTicks=1`, which the settings allow, that was every result except the ones that finished within the same tick they were dispatched.
Default settings were affected far less than that, but the wasted searches were real.
## A villager path from the future
If server time moved backwards, on a world reload or a rollback, a finished path already set aside for
a villager could still be handed to it, answering a question asked before the search was dispatched.
The check that refuses a result from the future ran when the result arrived and not when it was
collected, and those are the same rule at two different moments.
## `/pathweaver status` stops overstating route sharing
The line reporting how many searches route sharing skipped was adding together searches that really did not run and cache hits that saved nothing. Hits recorded while the cache was measuring have no stored route to hand out, so they skip nothing. They are now on their own line, and only the first number is a saving.
The cache capacity shown was the one in your settings file rather than the one in use. Capacity is fixed when the server starts, so if you changed it since, the screen now says the change is waiting for a restart.
**If you decided against `SERVE` on the old number, the honest one is smaller.** If you decided for it, look again.
## The route sharing tooltip was too strong
The settings screen said a reused route "is never a stale one". It now says what actually holds: a route is dropped when a block changes along it, and a change away from the route is not noticed, exactly as vanilla does not notice it either. The old wording is in the 0.8.0 and 0.8.1 jars where no page edit could reach it.
## Settings files are checked properly
`resultCacheMode`, `resultCacheMaxAgeTicks` and `resultCacheMaxEntries` were not type-checked when the config was read, so a hand-edited mistake in one of them was quietly coerced instead of reported. Every persisted setting is now checked, and the check is derived from the settings themselves rather than a list that had already fallen behind three times.
## Compatibility checking
The Lithium audit now pins the vanilla pathfinding class it inspects by hash, like the other audits do. It previously inspected whatever was loaded, on the argument that re-deriving the check each time was stronger than pinning it. It is not: that check reads one class and does not follow what that class calls, so on a changed class it would have reported nothing while proving less than it looked like it proved.
No compatibility outcome changes as a result, on any version. Both downloads verify all seven audits on the Minecraft version they are built for; see the project page for what happens if you install the wrong one.
## New: is pathfinding even your problem?
[A ten-minute check](https://github.com/zimdin12/PathWeaver/blob/master/docs/IS-IT-YOUR-BOTTLENECK.md) you can run before installing this mod, using spark. PathWeaver only helps a server whose tick time is going into mob path searches, and plenty of struggling servers are slow for some other reason. It also says how to read the profile without the two mistakes that are easy to make with it.
## Cloth Config is no longer required
PathWeaver needed Fabric API and Cloth Config. Cloth Config draws the settings screen, which a
dedicated server never shows, so every server owner was installing a GUI library to run a server-side
mod.
It now needs Fabric API and nothing else. Install Cloth Config if you want the settings screen; without
it the mod reads and writes the same `config/pathweaver.json` and behaves identically. Nothing about
your existing config file changes and no setting is lost.
## New, and off by default: redo distant path searches less often
When a block changes on the route a mob is walking, the game redoes that mob's whole path search. It
will not do it more often than once a second for any one mob, but in a place where terrain keeps
changing, every mob whose route crosses the change pays for it, whether anyone is near enough to see
it or not.
`lodEnabled` widens that limit for mobs beyond 64 blocks from every player: one search every 40 ticks
instead of the game's once a second. Both numbers are settings. A mob picking a new destination is
never affected; this only delays redoing a route the mob already has.
**It ships off, and that is deliberate.** It is the only setting in this mod that keeps a mob walking a
route after the ground under it has changed. (An earlier version of this changelog said everything else
gives a mob the path it would have had anyway. That was too strong: by default a mob whose target moved
by a block or less keeps its current path, `repathToleranceBlocks=1`.) This lets a distant mob keep
walking an out-of-date route for longer after the ground under it changes. That is bounded and remote, but it is a real difference, so it is offered rather than
taken.
Worth turning on for mob farms, penned herds near redstone, or a high simulation distance. It does
nothing at all for mobs whose surroundings are not changing, because the game never redoes their
search in the first place.
## Not in this release
No change to the mod's core numbers. This exact jar was put back through the benchmark against 0.8.0
and against no mod: it is no slower than 0.8.0. Re-measured on 2026-10-13 with the zombies really
chasing a player (the September runs had lost their test player), it saves 4 to 5.5% of tick time at
2500 to 10000 zombies and 8 to 12% at 500 to 1000. This line used to say 5 to 9%.
For LOD there is only a best case. In a test built to favour it, 400 zombies at least 70 blocks from the
player with terrain changing among them all the time, turning it on cut the path searches PathWeaver
started by 13 to 19% and did not measurably change tick time. What it saves on your server depends on
how much terrain changes around mobs nobody is standing near, and in a world where it does not change,
it saves nothing.
beta
0.8.0 - Villagers off the tick, routes worth reusing (26.2)
0.8.0+26.26 сент. 2026 г.126Minecraft: 26.2fabric
Что нового
Villagers now path off the tick, mobs can reuse each other's routes, and two settings that were switched off by accident are switched on.
## Villagers path off-thread
Villagers, piglins, axolotls, frogs, allays, camels and about twenty other brain-driven mobs never called the method PathWeaver was watching. Every route they walked went through a different one, so the mod could not see them at all. They were not being refused; they were invisible. `brainSinkAsync` covers that route and is on by default.
**It costs one tick.** A brain mob sets off one tick after it otherwise would, because on the tick its search is dispatched its behaviour is told "no path yet". Nothing else differs. That is why it is a setting: `brainSinkAsync=false` turns it off.
Measured on a 231-jar server with 200 mobs, three rounds each way. Server-thread pathfinding went from `4244, 3536, 7328 ms` to `2160, 1984, 2140`, and tick time from `9.05, 6.86, 15.83 ms` to `6.82, 5.68, 6.62`. Every run with it on beat every run without. The spread is the point: without it the arena ran between 6.9 and 15.8 ms per tick, with it between 5.7 and 6.8.
The warden is not covered. Its navigation builds a custom pathfinder, and PathWeaver only dispatches for the stock one.
## Mobs can reuse each other's routes
When two searches agree on every input they produce the same route, so the second one is repetition. A finished route is now kept and an identical later request is answered from it.
Identical is strict. Same starting position, same target, same mob size, same terrain costs, same movement flags. A stored route is dropped the moment a block changes along it. What a mob gets back is what its own search would have returned.
**It ships measuring rather than serving.** How often mobs repeat a search depends on your world, so the default counts what sharing would have saved and hands out nothing. Read `/pathweaver status`, then set `resultCacheMode` to Serve if the number justifies it. No restart. On the benchmark the hit rate was 12 to 16%, and sharing dispatched 11% fewer searches.
Against not having the mod installed at all, sharing gives 46% less server-thread pathfinding and 10% lower tick time, at 6% more total CPU across every thread. Against the cache being switched off rather than absent it bought about 3%, and those run ranges overlapped. The test arena was 200 mobs walking corridors without stopping, which is close to the worst case for it.
## Two settings that were off by accident
**Path reuse was never running.** `repathToleranceBlocks` shipped at 0 and 0 means the reuse never fires. It is 1 now. Upgrading migrates an existing config rather than leaving the fix for new installs, because a saved settings file wins over a default. Any value other than 0 is left alone, and the migration says what it did in the log.
**Automatic worker sizing could produce one worker.** A quarter of your CPU threads is a single worker on a four-thread machine, and one worker serialises every search behind the one in front. The floor is two.
## Compatibility
`compatibilityTier=AUDITED` did nothing at all on 26.2 before this release, because every audit was pinned to 26.1.2 builds. Four are re-derived and five of the seven now verify there.
**Lithium and Diagonal Blocks do not.** On 26.2 they are different builds from the ones the audits were derived from. Lithium alone puts all six movement families back on the server thread, and most performance packs ship Lithium, so treat the checked tier as unusable on 26.2 for now. The shipped default is unaffected, and the world-start report names the mods responsible.
## Also
`/pathweaver status` now reports what route sharing is finding. Startup is quieter on a healthy install: the scan used to warn about movement families it then waived a moment later, which was never a real warning.
beta
0.8.0 - Villagers off the tick, routes worth reusing (26.1.2)
0.8.0+26.1.26 сент. 2026 г.34Minecraft: 26.1.1, 26.1.2fabric
Что нового
Villagers now path off the tick, mobs can reuse each other's routes, and two settings that were switched off by accident are switched on.
## Villagers path off-thread
Villagers, piglins, axolotls, frogs, allays, camels and about twenty other brain-driven mobs never called the method PathWeaver was watching. Every route they walked went through a different one, so the mod could not see them at all. They were not being refused; they were invisible. `brainSinkAsync` covers that route and is on by default.
**It costs one tick.** A brain mob sets off one tick after it otherwise would, because on the tick its search is dispatched its behaviour is told "no path yet". Nothing else differs. That is why it is a setting: `brainSinkAsync=false` turns it off.
Measured on a 231-jar server with 200 mobs, three rounds each way. Server-thread pathfinding went from `4244, 3536, 7328 ms` to `2160, 1984, 2140`, and tick time from `9.05, 6.86, 15.83 ms` to `6.82, 5.68, 6.62`. Every run with it on beat every run without. The spread is the point: without it the arena ran between 6.9 and 15.8 ms per tick, with it between 5.7 and 6.8.
The warden is not covered. Its navigation builds a custom pathfinder, and PathWeaver only dispatches for the stock one.
## Mobs can reuse each other's routes
When two searches agree on every input they produce the same route, so the second one is repetition. A finished route is now kept and an identical later request is answered from it.
Identical is strict. Same starting position, same target, same mob size, same terrain costs, same movement flags. A stored route is dropped the moment a block changes along it. What a mob gets back is what its own search would have returned.
**It ships measuring rather than serving.** How often mobs repeat a search depends on your world, so the default counts what sharing would have saved and hands out nothing. Read `/pathweaver status`, then set `resultCacheMode` to Serve if the number justifies it. No restart. On the benchmark the hit rate was 12 to 16%, and sharing dispatched 11% fewer searches.
Against not having the mod installed at all, sharing gives 46% less server-thread pathfinding and 10% lower tick time, at 6% more total CPU across every thread. Against the cache being switched off rather than absent it bought about 3%, and those run ranges overlapped. The test arena was 200 mobs walking corridors without stopping, which is close to the worst case for it.
## Two settings that were off by accident
**Path reuse was never running.** `repathToleranceBlocks` shipped at 0 and 0 means the reuse never fires. It is 1 now. Upgrading migrates an existing config rather than leaving the fix for new installs, because a saved settings file wins over a default. Any value other than 0 is left alone, and the migration says what it did in the log.
**Automatic worker sizing could produce one worker.** A quarter of your CPU threads is a single worker on a four-thread machine, and one worker serialises every search behind the one in front. The floor is two.
## Compatibility
`compatibilityTier=AUDITED` did nothing at all on 26.2 before this release, because every audit was pinned to 26.1.2 builds. Four are re-derived and five of the seven now verify there.
**Lithium and Diagonal Blocks do not.** On 26.2 they are different builds from the ones the audits were derived from. Lithium alone puts all six movement families back on the server thread, and most performance packs ship Lithium, so treat the checked tier as unusable on 26.2 for now. The shipped default is unaffected, and the world-start report names the mods responsible.
## Also
`/pathweaver status` now reports what route sharing is finding. Startup is quieter on a healthy install: the scan used to warn about movement families it then waived a moment later, which was never a real warning.
beta
0.7.0 - Fewer wrong answers, fewer hiding places (26.2)
0.7.0+26.231 авг. 2026 г.66Minecraft: 26.2fabric
Что нового
Mostly defects. Around twenty of them, found by four parallel read-only hunts over the async, mixin, gate and config packages, then by an adversarial review of the whole diff.
## Player-visible
- **Mobs no longer freeze for up to a second after the world changes under them.** Vanilla nulls a mob's path and asks for a new one. Because the answer arrived a tick later, it recorded a recompute that never produced a path, and both of its retry routes then stayed shut for twenty ticks on a mob standing still. Control goes back to vanilla now.
- **A goal can no longer be told a mob is reachable using a route to somewhere it abandoned.** While a search is in flight, `path` and `targetPos` name different destinations, and vanilla's own path-reuse check treats them as a pair. Direct queries got the stale route.
- **`AUDITED` works on 26.1.1**, not only 26.1.2. The audits now gate on the bytes they pinned rather than on a version label. The pinned vanilla classes are byte-identical on 26.1.1, and different on 26.2, so 26.2 still refuses.
- **Workers skip searches nobody wants any more**, instead of computing them and throwing the result away.
## Six ways it could fail open, all live in 0.6.1
- A negative `workerFailureLimit` landed on the documented "never switch anything off" value. That disabled the family-shutdown safety net while the settings screen showed something legal.
- A config written before the tier setting existed inherited today's permissive default, moving an operator from "scan armed" to "waive everything" with no log line.
- The denial set in `SafetyGate` was public and mutable, so any class on the classpath could clear every scan denial, including the ones a failed scan installs that no tier is allowed to waive.
- A mixin config registered after startup was invisible to the scan, because pathfinding classes are not transformed until a world starts. That was the one place where absent evidence produced ALLOW.
- One third-party jar with unusual capitalisation in its manifest could make the mod permanently inert, through a scan failure no tier can waive.
- Setting `trustedMods` to null made the settings screen unopenable, with no message.
## Reporting
`/pathweaver mobs` called a mob eligible when dispatch would have refused it. The status line said breaker-stopped families were "running anyway", contradicting a line three rows above it. Both reporting sites printed the raw denial set size, showing `1` while five of six families were refused. A trimmed path counted as a successful install and cleared the failure cooldown with no route in place. Requests left over from a previous session were divided into this session's dispatch total.
## Testing
375 unit tests, four game-test harnesses, and roughly thirty mutations compiled and observed to fail. Three of those survived their first defence, including two tests of mine that passed for the wrong reason.
This release is correctness work. No performance change was measured for it, and none is claimed.
beta
0.7.0 - Fewer wrong answers, fewer hiding places (26.1.2)
0.7.0+26.1.231 авг. 2026 г.45Minecraft: 26.1.1, 26.1.2fabric
Что нового
Mostly defects. Around twenty of them, found by four parallel read-only hunts over the async, mixin, gate and config packages, then by an adversarial review of the whole diff.
## Player-visible
- **Mobs no longer freeze for up to a second after the world changes under them.** Vanilla nulls a mob's path and asks for a new one. Because the answer arrived a tick later, it recorded a recompute that never produced a path, and both of its retry routes then stayed shut for twenty ticks on a mob standing still. Control goes back to vanilla now.
- **A goal can no longer be told a mob is reachable using a route to somewhere it abandoned.** While a search is in flight, `path` and `targetPos` name different destinations, and vanilla's own path-reuse check treats them as a pair. Direct queries got the stale route.
- **`AUDITED` works on 26.1.1**, not only 26.1.2. The audits now gate on the bytes they pinned rather than on a version label. The pinned vanilla classes are byte-identical on 26.1.1, and different on 26.2, so 26.2 still refuses.
- **Workers skip searches nobody wants any more**, instead of computing them and throwing the result away.
## Six ways it could fail open, all live in 0.6.1
- A negative `workerFailureLimit` landed on the documented "never switch anything off" value. That disabled the family-shutdown safety net while the settings screen showed something legal.
- A config written before the tier setting existed inherited today's permissive default, moving an operator from "scan armed" to "waive everything" with no log line.
- The denial set in `SafetyGate` was public and mutable, so any class on the classpath could clear every scan denial, including the ones a failed scan installs that no tier is allowed to waive.
- A mixin config registered after startup was invisible to the scan, because pathfinding classes are not transformed until a world starts. That was the one place where absent evidence produced ALLOW.
- One third-party jar with unusual capitalisation in its manifest could make the mod permanently inert, through a scan failure no tier can waive.
- Setting `trustedMods` to null made the settings screen unopenable, with no message.
## Reporting
`/pathweaver mobs` called a mob eligible when dispatch would have refused it. The status line said breaker-stopped families were "running anyway", contradicting a line three rows above it. Both reporting sites printed the raw denial set size, showing `1` while five of six families were refused. A trimmed path counted as a successful install and cleared the failure cooldown with no route in place. Requests left over from a previous session were divided into this session's dispatch total.
## Testing
375 unit tests, four game-test harnesses, and roughly thirty mutations compiled and observed to fail. Three of those survived their first defence, including two tests of mine that passed for the wrong reason.
This release is correctness work. No performance change was measured for it, and none is claimed.
beta
0.6.1 for 26.2
0.6.1+26.219 авг. 2026 г.158Minecraft: 26.2fabric
Что нового
Minecraft **26.2** build of 0.6.1. Same mod, same code — no behaviour differs from the 26.1.2 release.
### Read this if you use the checked tier
`compatibilityTier=AUDITED` **denies every movement family on 26.2**, so the mod does nothing at that
setting. That is the gate working, not a bug: every per-mod exemption is pinned to the exact bytes it
was derived from, and 26.2 changed vanilla — `WalkNodeEvaluator`, `PathNavigation` and
`BlockBehaviour$BlockStateBase` are all different files — so the evidence no longer applies. Re-pinning
the hashes without redoing the bytecode analysis would be a safety claim nobody had checked, so the
audits refuse instead. Re-auditing for 26.2 is on the roadmap.
The shipped default is `UNSAFE`, which performs no such check, so **this affects you only if you
deliberately switched to AUDITED**.
### Verified on 26.2
- `PathWeaver is ACTIVE: all 6 movement families can path off-thread`
- Server game tests at the shipped default: 2/2, dispatched=1 installed=1 discarded=0
- Client harness: real singleplayer world, 3 dispatched / 3 installed / 0 discarded, settings screen
renders
- 357 of 360 unit tests. The 3 failures are the version-pinned audit bundles described above, and
nothing else.
### For the curious: what 26.2 changed
Nothing in the mod. The port is a version bump plus a manifest range. Two vanilla changes did break
the *test* sources: `EntityType` lost about 170 constants (`EntityType.ZOMBIE` is now an
`EntityTypeIds` resource key resolved through the registry, and `ResourceLocation` was renamed to
`Identifier`), and `Minecraft.screen` no longer exists — the current screen moved to `Gui.screen`,
private. Both are worked around in a way that still compiles against 26.1.2, so one source tree
serves both.
If you run ServerCore, make sure it is the 26.2 build; the 26.1.2 one fails at mixin apply on 26.2
regardless of this mod.
beta
0.6.1 — Notice, instead of predicting
0.6.1+26.1.219 авг. 2026 г.55Minecraft: 26.1.1, 26.1.2fabric
Что нового
PathWeaver had two modes: one that did nothing, and one that checked nothing.
The checked tier, `AUDITED`, asks *"did any mod touch this class?"* On a real modpack the answer is
always yes — 20 mods on the reference pack claim a watched pathfinding target — so it has left **0 of
187 mob types eligible since 0.3.0** on that pack with `trustedMods` empty, across five releases, and
the shipped default is `UNSAFE`, which performs no check at all. (On a lean pack the tier admits
everything on its own; that is the configuration this project's headline benchmark runs in. The
problem is not that it never works, it is that it never works on the packs the mod is for.) That tier is now **frozen**: it stays as a conservative escape hatch, and it
is no longer the answer. The reasoning, and the four independent ways the one attempt to fix it was
wrong, are in [ROADMAP.md](ROADMAP.md).
This release replaces prediction with detection.
### Added
- **A worker failure breaker.** A search that throws on a worker is counted against the movement
family whose code ran. Past a windowed threshold that family stops dispatching for the rest of the
session, and every mob in it paths on the server thread exactly as it would without this mod
installed. Falling back to vanilla is the safe direction by construction, so the breaker cannot
destabilise anything it fires on.
- **Failure attribution, which is the half that pays on every install.** The breaker may never fire —
the reference pack ran 753 dispatches with zero search failures. The attribution fires on the
*first* failure, needs no threshold, and turns a single rate-limited `WARN` into a block naming the
family, the exception and, where it can, the mod. The honest limit is stated in the log itself: a
mixin handler is merged into the class it targets, so an `@Overwrite` or an inlined `@Redirect`
leaves nothing to attribute, and the block says so rather than printing an empty list.
- **Two settings**, `workerFailureLimit` (default 3) and `workerFailureWindowTicks` (default 1200,
one minute). `workerFailureLimit=0` keeps dispatching no matter what and still counts and logs.
**No `configVersion` bump**: the serializer throws on any version but 2, 1 or 0 and a load failure
installs fail-closed defaults, so bumping it would have switched the mod off for every existing
install. Both fields default in on an untouched config, verified on the real pack.
- **`/pathweaver status` now shows failures before they trip anything**, because the log block told
operators the running total was there and it was not.
### Why the threshold is windowed
A counter that never decays converges on a certain trip given enough uptime, and this project's own
Lithium audit describes a concurrent-resize exception as an expected, contained event on the most
widely installed performance mod there is. Three of those over a fortnight is not an incompatibility;
three in a minute is. **A false trip is not a free no-op** — being vanilla is the thing the user
installed this mod to stop — so the window is what makes the mechanism affordable. A cumulative
backstop still catches a genuine slow leak.
### What this is not
A breaker sees **throws**. The corruption a user actually fears comes from a silent torn read that
returns the wrong block and never throws, and nothing here catches that. It is a smoke detector: it
does not stop the fire starting, it stops the house burning down and tells you which room it started
in.
### Fixed, found by reviewing the running code
- **A `workerFailureLimit` above 25 was silently capped.** The cumulative backstop was an
unconditional `||` rather than a floor, so a setting that accepts up to 1000 tripped at 25 anyway,
with nothing in the tooltip, the status line or the log admitting it.
- **The trip block named the threshold that had not fired.** A backstop trip printed the *window*
rule, and the cumulative count underneath it, sending an operator to raise a setting that changes
nothing.
- **A `VirtualMachineError` counted as evidence of an unsafe read.** On a 200-mod server an
`OutOfMemoryError` is the likeliest throwable a worker will ever produce; three would have switched
five families off and blamed whichever mods were on the frame.
- **A trip could outlive its server.** `shutdownNow()` does not wait, so a straggler worker past the
threshold check installed its verdict into the *next* world — an inert movement family in a fresh
world with no log line, because the one-shot report had already fired in the world before.
- **A cyclic cause chain spun a worker forever** during attribution.
- The two new config keys skipped the type validation every other integer key gets.
### Also
- `/pathweaver status` and `/pathweaver mobs` were `private static void (CommandSourceStack)` with no
seam, so eight mutations inside them were invisible to every test. They now produce a `List<String>`
the tests assert against.
358 unit tests (zero skipped), three game tests plus a dedicated end-to-end breaker harness, four
server harnesses, the client harness, and verification on the real 221-jar server pack: 184 of 187
eligible, 753 dispatched / 746 installed / 7 discarded, all six evaluator families node-for-node
identical to a synchronous oracle, and **no breaker output at all** — which is the correct result on a
healthy pack and the honest measure of this feature. Benchmarked against published 0.6.0 over six
interleaved runs on this exact jar: mean tick 50.003 ms vs 50.002 ms, p99 147.9 ms vs 144.9 ms. No regression.
Twenty-two mutations were compiled and observed to fail during development. Eight of them survived
their first defence, including both log blocks — the entire user-visible output of this feature was
deletable without a test noticing.
---
**Also runs on Minecraft 26.1.1** (added 15 August 2026). Every pathfinding and navigation class is byte-identical between 26.1.1 and 26.1.2 and the dependencies are the same builds, so this is the same file rather than a separate one. Verified by booting a 26.1.1 server: PathWeaver reports ACTIVE with all six movement families off-thread, and `/pathweaver mobs` reads 88 of 89.
One caveat, the same one as the 26.2 build: `compatibilityTier=AUDITED` refuses on 26.1.1, because every per-mod exemption is pinned to the exact Minecraft version it was derived against. The shipped `UNSAFE` default is unaffected.
beta
0.6.0 — Spiders, and diagnostics that tell the truth
0.6.0+26.1.29 авг. 2026 г.44Minecraft: 26.1.2fabric
Что нового
*The diagnostics work below was briefly numbered 0.5.4 and held back rather than published: on its
own it added no capability, no coverage and no speed, and nobody should update a modpack for a
release that only stops the mod misreporting itself. It ships as part of 0.6 instead.*
### Coverage
- **Spiders path off-thread.** `WallClimberNavigation` overrides `moveTo(Entity, double)` without
calling `super`, so the dispatch marker never ran for it and every spider chasing a player resolved
its path on the server thread — while `/pathweaver mobs` counted spiders as eligible. Third
instance of one mixin mistake; `NavigationOverrideCoverageTest` now derives the overriding
navigation subclasses from Minecraft's own bytecode so a future one cannot silently opt out.
### The default now explains itself
- **The startup log says WHY `UNSAFE` is the shipped default.** It already warned that the denial had
been ignored and that searches run alongside unaudited code. What it never said is the reason, which
is what turns that from "this mod ships recklessly" into a trade an operator can evaluate: the
checked tier denies every family on an ordinary modded pack — measured at **0 of 187 eligible mob
types** on a 221-jar server pack — so shipping it as the default would ship a mod that does nothing. It is
now stated as a trade, explicitly not as a safety claim, and followed by what to actually do: run it
on a copy of your world, keep the setting if nothing looks wrong after a few sessions, switch to
`AUDITED` and report it if something does.
### Diagnostics that agree with the gates
A cumulative review of everything since 0.5.0 and an adversarial concurrency bug hunt. The bug hunt
found **no blocker and no high-severity defect**, and said so explicitly rather than padding — the
epilogue pairing, the install-staleness checks, the evaluator clone, and the pool's generation
isolation were all attacked and held.
### Fixed
- **`/pathweaver mobs` called every land family eligible while dispatch refused all five.** Removing
the command's early return so swim mobs stopped being under-reported had a cost nobody priced: the
table is now printed in the one state where asking `SafetyGate.isAllowed` alone is wrong. Measured,
not argued — `isAllowed(Walk)=true` against `canDispatch(Walk)=false`. The verdict consults the land
registry, the command reads the live latch rather than a constant, and both halves are pinned by
mutations that were compiled and observed to fail.
- **`deniedFamilies` meant two different things in two places.** On the same server in the same second,
the startup log said `deniedFamilies=0` and `/pathweaver status` said `deniedFamilies=6`. Both were
right — the log counts what is *enforced*, status counted what the scan *found* before the tier
waived it — and one label with two meanings is the class of defect this release exists to end. Status
now prints `deniedByScan=` and `enforced=` separately; the log keeps the name the README teaches.
- **A mob held back by its `PathFinder` was blamed on a mod, including when it was vanilla's.** The
line named the class with `getSimpleName()`, which is empty for an anonymous class, so a real pack
produced `navigates with , a mod-supplied PathFinder`. Naming it properly showed what it was:
`Warden$1$1`, a `PathFinder` subclass **vanilla itself** constructs. It now falls back to the full
name and says "a PathFinder subclass" rather than accusing a mod.
- **The command told operators that wall-climber chases stay synchronous** — in the release whose
headline is that they no longer do.
- **The startup banner and `/pathweaver status` reported "ACTIVE, all six families" while five of the
six were being refused every tick.** Dispatch consults Fabric's land path-type registry latch in
addition to `SafetyGate`; the two reporting sites did not. On a pack where that verification fails,
the mod announced itself fully active, `dispatched` rose only from squid and fish, and
`/pathweaver mobs` said the opposite — the mod's own diagnostics contradicting each other on the
first question an operator asks. All three reporting sites now answer through one predicate,
`SafetyGate.canDispatch` — four, in fact: `/pathweaver mobs` was open-coding the same rule a fourth
time.
Precisely what is shared, because an earlier draft of this entry overstated it: dispatch does **not**
call `canDispatch`. It evaluates `isAllowed`, then `requiresEmptyLandRegistry`, then the latch, as
three separate steps. `canDispatch` is a *reconstruction* of that sequence for the reporting sites,
and an unpinned reconstruction is exactly how this bug became re-introducible twice —
`requiresEmptyLandRegistry` could be replaced with `return false` and `canDispatch` reduced to
`isAllowed`, each leaving all 289 tests green. `SafetyGateDispatchParityTest` now asserts the
reconstruction against the sequence over the whole input space rather than against itself, and the
one-argument convenience wrapper that hid the call site is deleted rather than tested beside.
The land-registry half covers all five land-derived families, not just the exact `Walk` class. This
is the third time a diagnostic has been caught disagreeing with what the gates actually do.
- **A setup failure before registration was swallowed entirely — no outcome, no counter, no log.**
Everything from the attribute captures through the evaluator clone runs before the request reaches
the sink, and the catch only recorded an outcome if it had. A deterministic failure there meant the
mod did nothing, forever, while reporting itself as working. It is now counted whether or not
registration happened — as `SETUP_FAILED` when the request had already
been counted as dispatched and `SETUP_FAILED_PRE_DISPATCH` when it had not. The split is at
`markDispatched`, not at registration — those are different events, and choosing on the wrong one
left a single outcome that was simultaneously "wasted dispatched work" and "not part of
dispatched". Logged once per server session. The reachable trigger is a
third-party evaluator whose no-argument constructor throws when invoked outside its own
construction path: `canClone` proves a constructor resolves, never that it runs.
- **The coverage contract treated an omitted `require` as safe.** ASM only visits values that are
present, so `require` arrived as null whenever it was left out — and null was read as fine. What
makes omission safe is `injectors.defaultRequire: 1` in the shipped config, which the test read for
the mixin list and never consulted for this. It now resolves `require` the way Mixin does. (That was
verified by hand-mutating the config both ways during development; it is not pinned by a shipped
test, and saying otherwise here would have been a claim the repo does not support.)
- **That contract's declared side was gated on a literal `Mob` receiver.** Every entity call in all six
evaluators does have owner `Mob` on 26.1.2 — verified — but a version emitting the same call with a
`LivingEntity` static type would have emptied the declared side and left every assertion in the
class passing over a live attribute race.
- **Both worker `ThreadLocal` captures now happen inside the `try`.** Only an `OutOfMemoryError` could
have separated them, but the residue is the exact failure both javadocs warn about: a step height
left published on a pooled thread and inherited by the next mob scheduled onto it.
- **The banner blamed the compatibility tier for refusals it did not cause.** A family failing only
the clone check got the full "you opted into AUDITED" lecture and advice to edit `trustedMods`,
neither of which would have changed anything.
### Documentation that was actively wrong
- `DESIGN.md` §3 still said flying and amphibious evaluators were ineligible. They have been the
default async path since 0.4.0. Anyone auditing the threading story from that file would have
concluded axolotls, turtles, drowned, frogs and every flying mob were synchronous.
- The recompute seam's javadoc claimed vanilla has two outcomes. It has four, and the whole table is
now written out — including the exit where a claim **is** still dropped, which is recorded as
roadmap 2g rather than papered over. That is not a regression (0.5.0 dropped it on all three
branches) and re-applying it there is precisely the 0.5.1 bug, so it needs the request to carry its
origin rather than a widened condition.
- A javadoc describing `rollbackOptimisticTarget` was sitting above `abortFailedInstall`. Two more of
the same: a javadoc in `RequestOutcome` and one in `PWNavigation` each sat directly above *another*
javadoc, documenting nothing, and an `@param dispatchCounted` named a parameter that had been
replaced by `stage`.
- **The README's eligibility numbers were measured with the wrong instrument.** It quoted 187 of 187
at the shipped default, from a harness that never inspects the `PathFinder` a mob actually holds.
`/pathweaver mobs` — the thing a user can run — says **184 of 187**, holding back the two spiders and
the warden. Nothing regressed; the old number was optimistic. Every figure in that section has been
re-measured on 0.6.0 and the claim that 0.4.0 dispatched the first third-party evaluator is
withdrawn: it never dispatched, and direct measurement now says so.
- **The release page claimed path equivalence for "all seven evaluator families".** There are six, and
the seventh row in the harness output is a spider whose third-party `PathFinder` means it never
dispatched — so its "IDENTICAL" compared a synchronous path with itself. The claim also read as a
proof where the README says, correctly, that this is one static scenario per family and that flying
equivalence is not guaranteed by the design at all. Corrected in the README, the changelog and the
Modrinth page. (The underlying result is real and is new: until 0.6.0 only Walk and Swim had an
oracle comparison, and all six now have one.)
- **The `AUDITED` + all-nine-trusted row was quoted without the setting it was measured under.**
`allowModdedMobAsync` defaults to false, and at that tier the origin gate then refuses 98 of the
pack's 187 mob types. The honest pair is **86 of 187** at stock settings and 184 with the bypass on.
The old row said 185, then 184, and never said which.
- `tools/scan_pack.py` counted mixin configs rather than mods in its totals line, and counted
**PathWeaver itself** among the mods claiming a pathfinding target — printing 22, then 21, where the
README says 20. The documented figure was only reproducible on a directory with PathWeaver deleted
from it, which is not a directory anyone has. It now counts distinct third-party mods.
- `PLAN.md` was a 0.2.3 artifact sitting in the repo root, whose "Future boundary" section stated no
engine work remained after 0.2.2 — beside a roadmap describing 0.6 through 1.0. Archived to
`docs/PLAN-0.2-archive.md`. `DESIGN.md`'s product decision still said "hold publication", reversed
at 0.3.0 and four releases ago.
### Added
- **A worker-reachability analysis** (`src/test/java/dev/pathweaver/reach/`), the first step of the
0.6 plan to replace hand-written hazard lists with derivation. **It is a discovery aid, not
evidence.** An earlier draft of this entry cited it as corroborating that no attribute hazard
remains; a review showed it silently truncated in three places that contradicted its own stated
guarantee. Those are fixed — it now resolves interface defaults, records every truncation instead
of swallowing it, and no longer maps a receiver onto a type that does not implement it. The numbers
moved from 1,735 reachable / 0 unresolved / 12 hazards to 2,060 / 168 / 45, which is what an honest
version of the same walk looks like. Details in `docs/ROADMAP-0.6-archive.md` §6. It found no unknown bug. What building it taught is
recorded there too: the naive version is useless rather than imprecise, reporting 1,220 hazards
including the client renderer.
- **`tools/scan_pack.py`**, which measured why `AUDITED` leaves nothing eligible: 20 mods in a real
221-jar server pack claim a watched target, any one of which denies everything, and 14 have no audit.
Nine of those 14 touch only `BlockBehaviour$BlockStateBase` and are not pathfinding mods at all. The
tool over-approximates on purpose — it reads mixin configs, not what the injected code reaches — so
it flags five that PathWeaver's own scanner clears. The scanner names nine blockers on this pack; the
nine that touch only `BlockStateBase` are a *different* nine, which is confusing enough to be worth
saying out loud.
- ASM is now an explicit test dependency instead of arriving through `fabric-loader`.
318 unit tests (zero skipped), three game tests, four server harnesses, the client harness, a
benchmark showing no change against 0.5.3, and verification on a real 221-jar server pack in four
configurations: `AUDITED` with nothing trusted (0 of 187 eligible, nine mods named); `AUDITED` with
those nine trusted at stock settings (86 of 187 — the origin gate refuses 98 mod-added mob classes);
the same with `allowModdedMobAsync=true` (184 of 187, nothing enforced, 732 searches installed); and
the shipped `UNSAFE` default (184 of 187, 755 dispatched / 749 installed / 6 discarded on the
shipping jar, with no PathWeaver exception in any run). With the world held still, all **six** evaluator families produced node-for-node
identical routes to a synchronous oracle — one scenario each, which is evidence and not proof, and
which for flying mobs the design does not guarantee (README, *What is unproven*).
beta
0.5.3 — The branch the fix did not reach
0.5.3+26.1.23 авг. 2026 г.36Minecraft: 26.1.2fabric
Что нового
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
- **`recomputePath` has three exits, and 0.5.2 handled two.** The bytecode is
`canUpdatePath()` → `ifeq` (no recompute) → `getfield targetPos` → **`ifnull` → return** →
`path = null` → `createPath`. 0.5.2 moved the claimed-target re-apply into the wrap on
`createPath`, which is correct for the recomputing branch and unreachable on the `targetPos == null`
early return. When the pre-dispatch target was null — an idle mob handed its first destination
asynchronously — the supersede rolls `targetPos` back 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 on `path == null` — which is not a
heuristic but the precondition of the 0.5.1 bug, negated: vanilla's reuse short-circuit is
`path != 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 default `null`
everywhere, 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 `@Redirect` whose target named the wrong owner (`LivingEntity` for `Mob`) or
the wrong descriptor counted as covering a site it could never bind to — and with `require = 0` that
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 declare
`require >= 1`. Both forgeries are mutation-tested.
- `FlyNodeEvaluator`'s `getRandom()` 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.
beta
0.5.2 — What the guard did not cover
0.5.2+26.1.23 авг. 2026 г.20Minecraft: 26.1.2fabric
Что нового
Review of the 0.5.1 hotfix. It found that the hotfix was incomplete, that one of its fixes was a
regression, and that the test written to prevent recurrence could catch neither failure.
### Fixed
- **A second attribute-backed read-modify-write is still in the A* loop, and it affects all six
families.** `WalkNodeEvaluator.tryFindFirstGroundNodeBelow` — reached from `getNeighbors` via
`findAcceptedNode` — calls `Mob.getMaxFallDistance()`, which for a mob with a target reads
`getMaxHealth()`, which is `getAttributeValue(MAX_HEALTH)` → `AttributeInstance.getValue()`. The
same `if (dirty) { cachedValue = calculateValue(); dirty = false; }` over plain non-volatile fields
that `maxUpStep()` hides. Worse reach than the 0.5.1 blocker: it is declared by `WalkNodeEvaluator`
itself so every admitted family hits it, and it fires exactly when a mob is chasing something. The
corrupted value is the mob's cached max health.
- **0.5.1's own fix was a regression on the branch where vanilla does not recompute.** The re-apply of
the claimed target ran at the `canUpdatePath()` injection point, which is upstream of the branch. On
the false branch — a ground mob mid-jump — vanilla jumps straight to setting
`hasDelayedRecomputation`: it never reads `targetPos` and never nulls `path`. So the re-apply left
`targetPos` naming the claimed destination while `path` still held the route to the old one, and the
next request for that destination hit vanilla's reuse short-circuit and was handed the stale path,
self-sustainingly. That is precisely the pairing `rollbackOptimisticTarget` exists to prevent. The
re-apply now happens inside the wrap that runs only where vanilla actually recomputes.
- **The game-test assertion added in 0.5.1 pinned that regression as correct.** It asserted the
claimed target survived on the airborne branch — where vanilla acts on nothing. It now asserts the
opposite invariant: when vanilla does not recompute, `targetPos` must not be left naming a
destination the installed path does not lead to.
### Changed
- **`LiveMobReadCoverageContractTest` is rewritten to be structural.** 0.5.1's version keyed on class
*names* against a hand-written literal, so it would have stayed green if the new mixin were deleted
from `pathweaver.mixins.json`, and it could not detect a second read in a class already on the list
— which is exactly what `getMaxFallDistance` was. Coverage is now keyed on the
*(declaring class, declaring method, called method)* triple, and the covered side is read out of the
`@Redirect` annotations of the mixins actually listed in the shipped config, via ASM — Mixin's
annotations are `RetentionPolicy.CLASS`, so reflection sees none of them and a reflective version
would have compared a populated set against an empty one. Both failure modes are mutation-tested.
### Known limitation, stated
The list of read *names* considered hazardous is still hand-maintained. The structural version walks
the call graph for the two real sinks — `AttributeInstance.getValue()` and `RandomSource` — instead of
naming their callers, and would have found both of these bugs without being told what to look for.
That is the top item on the 0.6 roadmap, and until it exists this list is the thing most likely to be
incomplete.
270 unit tests, four server harnesses, the client harness.
alpha
PathWeaver 0.5.1 — The half-fixed race
0.5.1+26.1.23 авг. 2026 г.36Minecraft: 26.1.2fabric
Что нового
## 0.5.1 — The half-fixed race
Hotfix for 0.5.0, published the same day. Two independent reviews of the shipped code found a
blocker and a behavioural bug that eight earlier rounds had missed.
### Fixed
- **`Mob.maxUpStep()` was still being called from worker threads by four mob families.** 0.5.0's
`WalkNodeEvaluatorMixin` redirects the two calls inside `WalkNodeEvaluator` and its javadoc declares
the attribute race eliminated. It was eliminated for two of the six admitted families.
`AmphibiousNodeEvaluator` **overrides** `getNeighbors` and makes its own `maxUpStep()` call at
offset 72 of its own bytecode, and a mixin transforms only its target class — so axolotls, turtles,
drowned and frogs kept racing a read-modify-write on non-volatile attribute state from inside the
A* loop. `require = 1` passed on `WalkNodeEvaluator` and said nothing about the subclass.
Fixed by `AmphibiousNodeEvaluatorMixin`, and guarded generally: `LiveMobReadCoverageContractTest`
now scans every allowlisted evaluator for live-mob reads it *declares itself* and fails unless a
mixin exists for that exact class. A seventh evaluator, or Mojang moving a call into a subclass,
now breaks the build instead of going quiet.
- **A recompute discarded a movement request the caller had been told succeeded.** The supersede in
`pathweaver$supersedeBeforeRecomputeGuard` rolls the optimistic `targetPos` back to its pre-dispatch
value — and vanilla reads `targetPos` two bytecodes later to decide where to recompute. So a mob
that had just accepted a move to A re-pathed to the destination it had abandoned, silently. The
claimed destination is now preserved across the supersede, pinned by the routing game test.
- **The startup report printed a false family count.** `"PathWeaver is doing NOTHING on this pack.
All N movement families…"` printed the size of the *denial set*, not the number of families — and
`isDenied` matches with `isAssignableFrom`, so denying `WalkNodeEvaluator` alone blocks five
families while the set size says one. A pack denying only Swim announced that nothing was running
while five families dispatched. It now asks the gate per family and reports partial states.
- The land-registry diagnostic counter is a `LongAdder` rather than an `AtomicLong`. Fabric injects
that lookup once per block position a search examines, so every worker in the pool was contending
on a single cache line thousands of times per search — costing worker throughput, which surfaces as
a worse install ratio.
### Documentation
- **DESIGN.md §9 carried a 0.2.2-era micro-benchmark reporting the mod as a net loss** (2.927 ms OFF
vs 3.012 ms ON). It described the *rejected* engine of §8, was labelled "not a user-real benchmark"
with "noisy pairs", and sat unchanged for three releases — long enough that a senior reviewer read
it as the project's performance evidence and concluded the mod does not pay off. Replaced with
measurements from the shipped jar, including what they do *not* establish. §1–§7 are now marked as a
0.2.x record; they still claimed flying and amphibious were ineligible.
- `EvaluatorCloner`'s no-arg guard was commented as though it refused to rebuild a subclass carrying
its own state. It does not — the fallback reaches the same constructor — and it could not, since
every land evaluator declares scratch fields. The comment now describes what it actually does and
names the real limitation.
- **New §13 records a known gap rather than patching it badly.** A recompute-originated dispatch
leaves the mob pathless for a tick, because vanilla nulls `path` before calling `createPath`.
Returning the pre-null path was implemented, and broke the exact-Swim witness: a non-null
`this.path` re-enables the vanilla reuse short-circuit and Feature B elision on a seam where neither
may fire. The correct fix needs the request to carry its origin, which belongs in a release that can
be soaked.
### Measured
`repathToleranceBlocks` swept at 0/1/4/8, two runs each, order-reversed: **no measurable effect on
tick time.** A first pass appeared to show `1` as clearly worst, which turned out to be a single
outlier run inflating a mean over n=2.
268 unit tests, four server harnesses, the client harness, and an amphibious session run at
`repathToleranceBlocks=1`: 28,648 dispatched, 28,625 installed, **0 cost drift over 288 checks**.
alpha
PathWeaver 0.5.0 — Works on arrival
0.5.0+26.1.23 авг. 2026 г.20Minecraft: 26.1.2fabric
Что нового
## The headline: compatibility checking now ships **off**
`compatibilityTier` now defaults to `Unsafe`. Out of the box PathWeaver runs other mods' uninspected pathfinding code on worker threads. **Back up worlds you care about.**
This is a deliberate risk decision, so here is the reasoning rather than a shrug. `Audited` honours individual bytecode audits and one bounded call sample; any mod outside that evidence denies every movement family. Measured on a 222-mod pack, `Audited` left **0 of 187** mob types eligible — and it has been 0 since 0.3.0, because the limit is other mods touching block state, not anything this mod can fix. Shipping it meant shipping something indistinguishable from broken.
What you are accepting: the most likely failure is quiet — a wrong path or a torn read, which you would probably never report. It is not the only possible one. Nothing has been proven about code that was never inspected, so a crash or a corrupted world is not excluded, only less likely.
Both ways back are one setting away: `compatibilityTier=Audited` for full checking, or `trustedMods` to name individual mods and keep the scan armed for everything else. A blocking warning at world start names every unaudited mod now running on workers.
## Also new
- **All six vanilla evaluators dispatch** — walking, swimming, flying, amphibious, and the frog's and creaking's.
- **A world-start recommendation on small machines.** PathWeaver does not make pathfinding cheaper; it moves it. That only pays when a core is free. At 2 cores or fewer it recommends turning the mod off; at 4 or fewer it warns the benefit will be small. Nothing switches off automatically.
- `/pathweaver status` and `/pathweaver mobs` answer in-game whether it is doing anything, and why not.
## Fixed
Eight rounds of independent review before publication. The ones that mattered:
- **A search could permanently corrupt an amphibious mob's pathfinding costs.** Superseding a request left its epilogue owed, and nothing stopped a second search starting — so two `prepare()` calls ran against one live mob and the restore inverted. Axolotls, turtles, frogs and drowned kept search-time costs for as long as they stayed loaded, silently. Reproduced in a live server on the previous build, then verified fixed over 170,000 dispatched searches.
- **A live data race in the A* loop.** `Mob.maxUpStep()` reads like an accessor and is a read-modify-write on non-volatile attribute state. Present since 0.4.0. The worker is now handed a value instead of a call.
- **A config carrying the retired `overrideCompatibilityScan: false` migrated to `Unsafe`** — an explicit "do not bypass the scan" answered by turning the scan off. The test guarding it compared the code to itself and could never fail.
- **A failed scan is no longer waivable by any tier.** If the scanner cannot tell what is installed, everything stays synchronous regardless of the setting.
- `EvaluatorCloner` no longer guesses between matching constructors, and can no longer throw out of the safety gate.
- A hard server stop no longer abandons epilogues it could safely have run.
## Measured on this jar
1024 zombies in a maze, four paired runs interleaved and order-reversed: **mean tick time −41%, p99 −50%**, effective TPS 10.9 → 18.6.
Profiled with spark on an identical workload, only the master switch differing: server-thread time in `PathFinder.findPath` fell from **52.8% of busy time to 0.58%**, for 24 ms of main-thread cost per 45 seconds.
Verified with 266 unit tests, four in-game server harnesses and a client harness, plus extended real-mob server sessions and a 371-mod pack booting clean.
alpha
PathWeaver 0.3.0 — compatibility tiers
0.3.0+26.1.230 июл. 2026 г.38Minecraft: 26.1.2fabric
Что нового
**This is a large jump from 0.1.2. The headline: PathWeaver now actually runs on most packs, instead of switching itself off.**
## Why it used to do nothing
PathWeaver refuses to run a search off-thread when another mod has modified the code that search executes. That rule is correct, and it is also why the mod was inert on most modpacks — a single popular mod anywhere in your pack switched it off entirely. Fabric API, which PathWeaver itself requires, was enough to do it.
0.3.0 replaces that all-or-nothing behaviour with a setting, and does the work to open the gate honestly rather than by ignoring it.
## Compatibility risk (new setting, default `Audited`)
Replaces the old `overrideCompatibilityScan` checkbox. Existing configs migrate automatically.
- **`Strict`** — structural proofs only. Denies any pack containing Fabric API, so it usually does nothing. Not the default, for that reason.
- **`Audited`** *(default)* — also accepts bounded evidence. Four distinct mechanisms sit behind it and they are not equally strong; the settings screen and the compatibility matrix name each one separately rather than calling them all "proven".
- **`Everything`** — no checks. Runs uninspected mod code on workers. Back up your world.
Newly audited and working: **Lithium** (ships in most performance packs and used to disable this mod on sight), **Diagonal Blocks**, and **Farmer's Delight** — whose stove receives the world and provably never reads it, so its answers are precomputed and frozen. Mods that simply mark a block dangerous are now handled generically, with no per-mod entry and no audit needed.
## Measured, on the configuration you actually get
Six paired runs, interleaved and order-reversed, no harness intervention: mean tick time **78–96 ms → 49–50 ms** (median **41%**, range 36–48%), p99 **726–1096 ms → 338–390 ms**, effective tick rate **10.4–12.7 → 20.0 TPS**, with no overlap between arms. The last pair was re-run on the exact jar published here and landed inside every one of those ranges.
Swimming measured separately: **p99 −65%**, main-thread cost per search **−8×**, mean tick time unchanged — because 1024 fish never saturate the server. That is the mod's real shape: it removes spikes, it does not raise averages.
Also verified at **371-mod** pack scale: 331 mixin configs scanned, zero parse failures.
## Settings
- Compatibility risk is a **dropdown** now, not a cycling button whose long labels scrolled past unreadably.
- Tooltips say what to **do**, not what the setting mechanically is, and name the four settings measured to make no difference so you can leave them alone.
- Two values can silently defeat the mod — a near-zero staleness threshold, and an inflated in-flight limit. Both now **warn loudly at startup and are still honoured exactly as configured**. You are told it is a bad idea; you are not overruled.
- `repathElisionEnabled` is gone. It defaulted to on while the tolerance it depended on defaulted to 0, so it advertised itself as enabled and did nothing. Path reuse is now one control where 0 means off. Behaviour is unchanged.
## Fixes worth calling out
- `Everything` now genuinely means everything: it previously left most of a modded pack's mobs synchronous while reporting that nothing was being checked.
- The compatibility tier is **frozen at startup**. Saving a different tier mid-session used to leave startup denials waived while per-request checks tightened — a session started at `Everything` and saved to `Strict` kept dispatching work `Strict` forbids. It now applies on restart, which is what the setting always claimed.
- Several published performance claims were corrected downward after re-measurement. The earlier "44.8%" rested on a single unusually heavy baseline run.
## Honest status
Still **alpha**. A worker reads live chunk and mob state through a read-only view, not a copy. The [compatibility matrix](https://github.com/zimdin12/PathWeaver/blob/master/COMPATIBILITY.md) states every exemption, exactly what was checked, and where a claim rests on a bounded sample rather than a proof.
This release went through **seven rounds of independent review**, plus one that refused to start because the release tag pointed at the wrong commit. Several findings were changes that looked right, passed all 217 tests, and were wrong anyway — including one that contradicted the document justifying it.
alpha
PathWeaver 0.1.2 — async on by default
0.1.2+26.1.215 июл. 2026 г.102Minecraft: 26.1.2fabric
Что нового
Async is now ON BY DEFAULT (opt-out alpha — disable any time with asyncEnabled=false). Bundles the two biggest v0.2 fixes: (1) query-only createPath calls (reachability checks like canReachPos) now stay SYNCHRONOUS and are no longer force-moved; (2) the compatibility scanner is now FAIL-CLOSED — it keeps async off for any mob whose pathfinding it can't prove safe (so in standard Fabric content-registry packs, Walk/Swim stay on vanilla — safe by default). Exact Walk+Swim only; Fly/Amphibious/custom stay sync. Persisted asyncEnabled=false is preserved on upgrade. Still an experimental alpha — expect bugs, keep backups; no proven net-MSPT-speedup or vanilla-equivalence claim.
alpha
PathWeaver 0.1.1 — honesty and default-off patch
0.1.1+26.1.214 июл. 2026 г.41Minecraft: 26.1.2fabric
Что нового
Honesty & default-off patch. CHANGED: async now defaults OFF (explicit opt-in); repath tolerance default 0; invalid config values clamped; FlyNodeEvaluator no longer async-eligible (its start-node selection consumes live mob RNG off-thread); allowlist is now exact Walk+Swim only (Fly/Amphibious/subclasses stay sync); docs corrected (PathNavigationRegion is a read-only VIEW of live chunks, not an immutable copy). LIMITATIONS: worker still reads live chunk/mob state; general createPath interception can alter query-only reachability; lifecycle/staleness + foreign-mixin discovery are not yet complete safety boundaries — all reworked in v0.2. BENCHMARK (4 paired Spark profiles, 160 zombies): proven server-thread A* offload (WalkNodeEvaluator -90.97% inclusive) but NO universal MSPT speedup (2.927ms OFF vs 3.012ms ON, noisy). Removed the old safe-by-construction / immutable-snapshot / identical-path claims. See the page for Spark URLs + caveats.
alpha
PathWeaver 0.1.0 (alpha)
0.1.0+26.1.210 июл. 2026 г.28Minecraft: 26.1.2fabric
Что нового
0.1.0 — Initial (alpha) release. Async A* pathfinding on a read-only region with an isolated finder + per-thread path-type cache; conservative repath elision; exact-class safety gate + foreign-mixin scanner; clean sync fallback on any guard/failure. See GitHub CHANGELOG for detail.