Skip to content
Open

26.3 #17

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
9cb3a68
fix chunk packing writing solid sections as air
dekrom Aug 25, 2026
abcb47d
set daemon on baritone threadpool
dekrom Aug 25, 2026
07373e7
add release workflow
dekrom Aug 25, 2026
9713291
pin proguard toolchain to the CI JDK
dekrom Aug 25, 2026
7f253b4
use zulu jdk in CI (image temurin 25 package lacks jmods)
dekrom Aug 25, 2026
d8e5a09
fix fall cost charging a phantom tick of gravity
dekrom Aug 30, 2026
8adc0bb
fix descend cost when landing on top of a block
dekrom Aug 30, 2026
a5327d5
fix GoalRunAway building its bounding box from the wrong corner
dekrom Aug 30, 2026
e6b66d3
fix diagonal magma check reading the wrong block
dekrom Aug 30, 2026
ae63b29
fix pathfinder height limit ignoring world min y
dekrom Aug 30, 2026
169c5de
fix waterlogged blocks being treated as passable
dekrom Aug 30, 2026
8219f85
don't jump through blocks that can't be walked through
dekrom Aug 30, 2026
84eb670
give GoalGetToBlock a heuristic
dekrom Aug 30, 2026
26b60fc
keep backtrackCostFavoringCoefficient positive
dekrom Aug 30, 2026
8d95c8c
snapshot player state for the pathing thread
dekrom Aug 30, 2026
1d410c5
make cancelRequested volatile
dekrom Aug 30, 2026
764ef96
stop rebuilding throwaway state every tick
dekrom Aug 30, 2026
b9af2b5
recalculate the elytra segment when a path node is inside a block
dekrom Aug 30, 2026
9113ee8
match vanilla elytra physics in the flight simulation
dekrom Aug 30, 2026
7052503
fly to survive when no pitch reaches the path
dekrom Aug 30, 2026
3fe6912
add elytraPathLookahead
dekrom Aug 30, 2026
892c80c
take off from flat ground when there is no ledge to walk off
dekrom Aug 30, 2026
e1c56e4
document the fork and version the release jars
dekrom Aug 30, 2026
5d63ef9
readme: the version specific fixes are not on every branch
dekrom Aug 30, 2026
f3a51d4
Revert client registry access for loot table resolution
Todarac Aug 31, 2026
b60a3e5
Merge branch '1.21.1' into 1.21.5
Todarac Aug 31, 2026
b4599b4
Merge branch '1.21.5' into 1.21.8
Todarac Aug 31, 2026
5bf4542
Merge branch '1.21.8' into 1.21.10
Todarac Aug 31, 2026
2372389
Merge branch '1.21.10' into 1.21.11
Todarac Aug 31, 2026
016cc21
Merge branch '1.21.11' into 26.1
Todarac Aug 31, 2026
c85c9ee
Merge branch '26.1' into 26.2
Todarac Aug 31, 2026
9fadf7c
Bump 26.2 to 1.19.0
Todarac Aug 31, 2026
d4fe4d5
save cached regions atomically
dekrom Sep 1, 2026
c76ae7b
fix two arithmetic bugs in the above build limit pathfinder
dekrom Sep 1, 2026
c2a52eb
never call into a freed pathfinder context
dekrom Sep 1, 2026
f4fb89e
stop cancelling elytra from freezing the game
dekrom Sep 1, 2026
f55f995
readme: the elytra teardown and chunk cache fixes
dekrom Sep 1, 2026
0a61ecf
never run a path calculation under the read lock
dekrom Sep 5, 2026
3310b7f
bound the pathfinder context teardown
dekrom Sep 5, 2026
677db2e
don't stitch the old path onto an unfinished segment
dekrom Sep 5, 2026
fa36a05
repack the chunks around the player when the cache is wrong
dekrom Sep 5, 2026
d2b111c
take off through the first clear cube overhead
dekrom Sep 5, 2026
5611a7b
light the takeoff rocket the tick after the elytra opens
dekrom Sep 5, 2026
54b3c12
climb out of lava on the takeoff rocket
dekrom Sep 5, 2026
b1dad68
readme: the takeoff, lava and cache fixes
dekrom Sep 5, 2026
30176ed
26.3
rfresh2 Jan 19, 2026
e9e84d7
forge
rfresh2 Sep 19, 2026
3c2030f
move player update post event inject target
rfresh2 Sep 19, 2026
aa9bd45
fix mouse button ids
rfresh2 Sep 19, 2026
4b96a99
remove indent diff
rfresh2 Sep 19, 2026
9338452
local work snapshot 2026-09-22
dekrom Sep 22, 2026
9c35132
Revert client registry access for loot table resolution
Todarac Aug 31, 2026
319fc9e
Merge remote-tracking branch 'rfresh2/26.3' into 26.3
dekrom Oct 7, 2026
2713d88
readme: the cache budget, packing, goal and folder name fixes, and 26.3
dekrom Nov 4, 2026
3f7d049
evict regions nothing can save
dekrom Nov 4, 2026
41edbe5
repack on unload when this load's pack never ran
dekrom Nov 4, 2026
521b1a1
Fix Litematica detection
ZacSharp Jun 14, 2026
2745cb1
Compare block state property values with equals, not reference identity
pirateben820 Sep 16, 2026
a98221d
Write cache and waypoint files atomically
kekkykekkek Sep 17, 2026
ac5625e
readme: the waypoint, litematica and builder fixes, and when a dirty …
dekrom Nov 8, 2026
843427f
drop the review notes and scripts that are not part of baritone
dekrom Nov 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Build and Release

on:
push:
tags:
- 'v*'
workflow_dispatch:

permissions:
contents: write

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Read build config
id: cfg
run: |
mc=$(grep '^minecraft_version=' gradle.properties | cut -d= -f2)
version=${GITHUB_REF_NAME#v}
{
echo "java=$(grep '^java_version=' gradle.properties | cut -d= -f2)"
echo "mc=$mc"
echo "version=$version"
echo "modver=${version%-$mc}"
} >> "$GITHUB_OUTPUT"

- name: Set up JDK ${{ steps.cfg.outputs.java }}
uses: actions/setup-java@v4
with:
java-version: ${{ steps.cfg.outputs.java }}
distribution: 'zulu'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Build with Gradle
run: >
./gradlew build
-Pmod_version=${{ steps.cfg.outputs.version }}
-Porg.gradle.java.installations.auto-detect=false
"-Porg.gradle.java.installations.paths=$JAVA_HOME"

- name: Release
if: startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@v2
with:
name: Baritone ${{ steps.cfg.outputs.modver }} for Minecraft ${{ steps.cfg.outputs.mc }}
files: dist/*
fail_on_unmatched_files: true
381 changes: 260 additions & 121 deletions README.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions fabric/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"mixins.baritone-meteor.json"
],
"depends": {
"fabricloader": ">=0.19.3",
"minecraft": ["26.2"]
"fabricloader": ">=0.19.5",
"minecraft": "~26.3"
},
"custom": {
"modmenu": {
Expand Down
2 changes: 1 addition & 1 deletion forge/src/main/resources/META-INF/mods.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ A Minecraft pathfinder bot.
modId="minecraft"
mandatory=true
# This version range declares a minimum of the current minecraft version up to but not including the next major version
versionRange="[26.2]"
versionRange="[26.3, 26.4)"
ordering="NONE"
side="BOTH"
10 changes: 5 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ org.gradle.jvmargs=-Xmx4G

available_loaders=fabric

mod_version=26.2-SNAPSHOT
mod_version=26.3-SNAPSHOT
maven_group=baritone
archives_base_name=baritone

java_version=25

minecraft_version=26.2
minecraft_version=26.3

forge_version=65.0.3
forge_version=66.0.2

neoforge_version=11-beta
neoforge_version=6-beta

fabric_version=0.19.3
fabric_version=0.19.5

nether_pathfinder_version=1.6

Expand Down
2 changes: 1 addition & 1 deletion neoforge/src/main/resources/META-INF/neoforge.mods.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ A Minecraft pathfinder bot.
modId="minecraft"
type="required"
# This version range declares a minimum of the current minecraft version up to but not including the next major version
versionRange="[26.2]"
versionRange="[26.3, 26.4)"
ordering="NONE"
side="BOTH"

Expand Down
13 changes: 13 additions & 0 deletions scripts/proguard.pro
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@
@baritone.KeepName *;
}

# XaeroPlus (BaritonePathSync) reflects the elytra path through these members by name;
# Meteor's obfuscated builds rename them and lose the map overlay
-keepclassmembers class baritone.process.ElytraProcess {
baritone.process.elytra.ElytraBehavior behavior;
}
-keepclassmembers class baritone.process.elytra.ElytraBehavior {
baritone.process.elytra.ElytraBehavior$PathManager pathManager;
}
-keepclassmembers class baritone.process.elytra.ElytraBehavior$PathManager {
baritone.process.elytra.NetherPath path;
public baritone.process.elytra.NetherPath getPath();
}

# setting names are reflected from field names, so keep field names
-keepclassmembers class baritone.api.Settings {
public <fields>;
Expand Down
57 changes: 51 additions & 6 deletions src/api/java/baritone/api/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -646,16 +646,48 @@ public final class Settings {
public final Setting<Boolean> chunkCaching = new Setting<>(true);

/**
* On save, delete from RAM any cached regions that are more than 1024 blocks away from the player
* Evict cached regions from RAM. The cache maintenance thread drops a region once it has been idle (not read
* by pathing or scanning, not written by the packer) for longer than {@link #cachedRegionsIdleSeconds}, and
* drops the least recently used regions whenever the resident cache exceeds {@link #cachedRegionsRamBudgetMB}.
* Regions with unsaved changes are written to disk first and are never evicted before that write succeeded,
* unless {@link #chunkCaching} is off and nothing will ever write them.
* <p>
* Temporarily disabled
* <p>
* Temporarily reenabled
*
* @see <a href="https://github.com/cabaletta/baritone/issues/248">Issue #248</a>
* false keeps every region touched in this session in RAM.
*/
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true);

/**
* Upper bound for the cached regions kept in RAM, in MiB. A fully cached region costs about 27 MiB
* (1024 chunks of 24 KiB block data). The bound is soft by one maintenance tick.
*/
public final Setting<Integer> cachedRegionsRamBudgetMB = new Setting<>(192);

/**
* A cached region that nothing has read or written for this many seconds is evicted from RAM (after being
* saved if it changed). Regions come back from disk on demand.
*/
public final Setting<Integer> cachedRegionsIdleSeconds = new Setting<>(180);

/**
* How often changed regions are written to disk. The elytra nether pathfinder reads the region files, so this
* is also how long newly seen terrain takes to become visible to it.
*/
public final Setting<Integer> cachedRegionsSaveIntervalSeconds = new Setting<>(30);

/**
* When pathing asks for a region that is not in RAM, load it from disk in the background so the next path
* calculation sees terrain explored in earlier sessions. Without this only the packer (chunks around the
* player) and explicit scans (#find, explore) ever bring regions into RAM.
*/
public final Setting<Boolean> cachedRegionsLoadOnDemand = new Setting<>(true);

/**
* Pack a chunk again when it unloads even if no block changed since it was packed on load. Off by default:
* the unload pack doubled the packer's work for an identical result. A chunk that changed while loaded, or
* whose load-time pack was dropped or has not run yet, is still packed on unload.
*/
public final Setting<Boolean> repackUnchangedChunksOnUnload = new Setting<>(false);

/**
* The chunk packer queue can never grow to larger than this, if it does, the oldest chunks are discarded
* <p>
Expand Down Expand Up @@ -1445,6 +1477,13 @@ public final class Settings {
*/
public final Setting<Integer> elytraPitchRange = new Setting<>(25);

/**
* The number of path nodes ahead of the player that are considered as flight targets. Higher values let the bot
* commit to a further-away node and cut corners, which is smoother at firework speed, but are computationally
* more expensive.
*/
public final Setting<Integer> elytraPathLookahead = new Setting<>(20);

/**
* The minimum speed that the player can drop to (in blocks/tick) before a firework is automatically deployed.
*/
Expand Down Expand Up @@ -1490,6 +1529,12 @@ public final class Settings {
*/
public final Setting<Boolean> elytraAutoJump = new Setting<>(false);

/**
* When {@link #elytraAutoJump} can't find a ledge to walk off of, jump on the spot and light a firework the
* moment the elytra opens instead of giving up. Costs one firework per attempt.
*/
public final Setting<Boolean> elytraStandingTakeoff = new Setting<>(true);

/**
* The seed used to generate chunks for long distance elytra path-finding in the nether.
* Defaults to 2b2t's nether seed.
Expand Down
7 changes: 7 additions & 0 deletions src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ public double heuristic(int x, int y, int z) {
return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff);
}

@Override
public double heuristic() {
// the largest heuristic value that is still guaranteed to be inside the goal: the six positions
// adjacent to the block, of which the one directly above is the most expensive
return Math.max(GoalXZ.calculate(1, 0), Math.max(GoalYLevel.calculate(0, 1), GoalYLevel.calculate(0, -1)));
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand Down
12 changes: 6 additions & 6 deletions src/api/java/baritone/api/pathing/goals/GoalNear.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@ public class GoalNear implements Goal, IGoalRenderPos {
private final int x;
private final int y;
private final int z;
private final int rangeSq;
private final long rangeSq;

public GoalNear(BlockPos pos, int range) {
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
this.rangeSq = range * range;
this.rangeSq = (long) range * range;
}

@Override
public boolean isInGoal(int x, int y, int z) {
int xDiff = x - this.x;
int yDiff = y - this.y;
int zDiff = z - this.z;
long xDiff = (long) x - this.x;
long yDiff = (long) y - this.y;
long zDiff = (long) z - this.z;
return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff <= rangeSq;
}

Expand Down Expand Up @@ -105,7 +105,7 @@ public boolean equals(Object o) {

@Override
public int hashCode() {
return (int) BetterBlockPos.longHash(x, y, z) + rangeSq;
return (int) BetterBlockPos.longHash(x, y, z) + Long.hashCode(rangeSq);
}

@Override
Expand Down
20 changes: 10 additions & 10 deletions src/api/java/baritone/api/pathing/goals/GoalRunAway.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class GoalRunAway implements Goal {

private final BlockPos[] from;

private final int distanceSq;
private final double distanceSq;

private final Integer maintainY;

Expand All @@ -47,7 +47,7 @@ public GoalRunAway(double distance, Integer maintainY, BlockPos... from) {
throw new IllegalArgumentException("Positions to run away from must not be empty");
}
this.from = from;
this.distanceSq = (int) (distance * distance);
this.distanceSq = distance * distance;
this.maintainY = maintainY;
}

Expand All @@ -57,9 +57,9 @@ public boolean isInGoal(int x, int y, int z) {
return false;
}
for (BlockPos p : from) {
int diffX = x - p.getX();
int diffZ = z - p.getZ();
int distSq = diffX * diffX + diffZ * diffZ;
double diffX = (double) x - p.getX();
double diffZ = (double) z - p.getZ();
double distSq = diffX * diffX + diffZ * diffZ;
if (distSq < distanceSq) {
return false;
}
Expand Down Expand Up @@ -96,9 +96,9 @@ public double heuristic() {// TODO less hacky solution
minX = Math.min(minX, p.getX() - distance);
minY = Math.min(minY, p.getY() - distance);
minZ = Math.min(minZ, p.getZ() - distance);
maxX = Math.max(minX, p.getX() + distance);
maxY = Math.max(minY, p.getY() + distance);
maxZ = Math.max(minZ, p.getZ() + distance);
maxX = Math.max(maxX, p.getX() + distance);
maxY = Math.max(maxY, p.getY() + distance);
maxZ = Math.max(maxZ, p.getZ() + distance);
}
DoubleOpenHashSet maybeAlwaysInside = new DoubleOpenHashSet(); // see pull request #1978
double minOutside = Double.POSITIVE_INFINITY;
Expand Down Expand Up @@ -143,8 +143,8 @@ public boolean equals(Object o) {
@Override
public int hashCode() {
int hash = Arrays.hashCode(from);
hash = hash * 1196803141 + distanceSq;
hash = hash * -2053788840 + maintainY;
hash = hash * 1196803141 + Double.hashCode(distanceSq);
hash = hash * -2053788840 + Objects.hashCode(maintainY);
return hash;
}

Expand Down
4 changes: 3 additions & 1 deletion src/api/java/baritone/api/pathing/movement/ActionCosts.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ static double distanceToTicks(double distance) {
double tmpDistance = distance;
int tickCount = 0;
while (true) {
double fallDistance = velocity(tickCount);
// you have already been falling for one tick by the time you have moved at all; velocity(0) is 0,
// so indexing from tickCount would charge a phantom tick against every fall
double fallDistance = velocity(tickCount + 1);
if (tmpDistance <= fallDistance) {
return tickCount + tmpDistance / fallDistance;
}
Expand Down
16 changes: 8 additions & 8 deletions src/api/java/baritone/api/utils/BlockOptionalMeta.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
import sun.misc.Unsafe;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
Expand Down Expand Up @@ -281,9 +280,10 @@ public static ServerLevelStub fastCreate() {

@Override
public RegistryAccess registryAccess() {
if (client.level != null) {
return client.level.registryAccess();
}
// Loot tables are populated only by the reloaded server registries built
// in load(). A client RegistryAccess never receives them, so sourcing the
// holder from client.level made every block resolve to zero drops, which
// silently broke #mine item pickup (regression from PR #5058).
return registryAccess.join();
}

Expand All @@ -305,22 +305,22 @@ public static CompletableFuture<RegistryAccess> load() {
// Simplified from {@link net.minecraft.server.WorldLoader#load()}
CloseableResourceManager closeableResourceManager = new MultiPackResourceManager(
PackType.SERVER_DATA,
List.of(ServerPacksSource.createVanillaPackSource())
List.of(ServerPacksSource.createVanillaPackSource().fullResources())
);
LayeredRegistryAccess<RegistryLayer> baseLayeredRegistry = RegistryLayer.createRegistryAccess();
List<Registry.PendingTags<?>> pendingTags = TagLoader.loadTagsForExistingRegistries(
closeableResourceManager, baseLayeredRegistry.getLayer(RegistryLayer.STATIC)
);
List<HolderLookup.RegistryLookup<?>> worldGenRegistryLookupList = TagLoader.buildUpdatedLookups(
baseLayeredRegistry.getAccessForLoading(RegistryLayer.WORLDGEN),
baseLayeredRegistry.getAccessForLoading(RegistryLayer.WORLD),
pendingTags
);
LayeredRegistryAccess<RegistryLayer> layeredRegistryAccess = baseLayeredRegistry.replaceFrom(
RegistryLayer.WORLDGEN,
RegistryLayer.WORLD,
RegistryDataLoader.load(
closeableResourceManager,
worldGenRegistryLookupList,
RegistryDataLoader.WORLDGEN_REGISTRIES,
RegistryDataLoader.WORLD_REGISTRIES,
ForkJoinPool.commonPool()
).join()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ private void postHandleChunkData(ClientboundLevelChunkWithLightPacket packetIn,
new ChunkEvent(
EventState.POST,
!packetIn.isSkippable() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
packetIn.getX(),
packetIn.getZ()
packetIn.x(),
packetIn.z()
)
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/launch/java/baritone/launch/mixins/MixinMinecraft.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private void postRunTick(CallbackInfo ci) {
method = "tick",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/multiplayer/ClientLevel.tickEntities()V",
target = "Lnet/minecraft/client/player/LocalPlayer;sendChanges()V",
shift = At.Shift.AFTER
)
)
Expand Down
Loading