Skip to content

Elytra in overworld #4698

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 30 commits into
base: 1.19.4
Choose a base branch
from
Open

Conversation

babbaj
Copy link
Collaborator

@babbaj babbaj commented Apr 4, 2025

Started by @underscore-zi
nether-pathfinder changes have been merged in babbaj/nether-pathfinder#20
Closes #4187

@babbaj babbaj changed the title Nether elytra update Elytra in overworld Apr 4, 2025
@babbaj babbaj marked this pull request as ready for review April 4, 2025 07:29
Copy link

@thelampgod thelampgod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow!

@underscore-zi
Copy link

underscore-zi commented Apr 5, 2025

I do have a couple minor commits over on https://github.com/underscore-zi/baritone

First is respecting the allowRoof setting when searching for a landing spot. I had left a TODO in for this but hadn't done so yet.

Second is adding Cobblestone and Obsidian to allowed landing blocks. In vanilla the current list is fine but I was using this around 2b's spawn and it had some issues finding landing spots.

@ZacSharp
Copy link
Collaborator

ZacSharp commented Apr 6, 2025

Can you please wait three days with merging? I'd like to properly read through and test this, but won't be able to do so before April 8.

@babbaj
Copy link
Collaborator Author

babbaj commented Apr 6, 2025

leijurv never merges my PRs anyways

@leijurv
Copy link
Member

leijurv commented Apr 6, 2025

Can you please wait three days with merging?

say no more, i'll check back next month

Copy link
Collaborator

@ZacSharp ZacSharp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, didn't expect quite as much breakage, but this adds at least two ways to crash the game.

  • Disabling elytraUseBaritoneCache unconditionally causes an NPE, crashing the game unless this happens inside a command
  • Disabling elytraAllowAboveRoof while flying above the nether roof and then causing recalculation crashes the game. I didn't even get a crash report, but no segfault either?
  • Enabling elytraPredictTerrain in the overworld leads to endless recalculation and chat spam. Actually not a crash though.

Some less severe points

  • The wall of text printed by #elytra unless elytraTermsAccepted is now outdated. It mentions elytra flight only being for the nether (now wrong) and also recommends elytraAutoJump, which has hardly any chance of working in the overworld, and should also mention that terrain prediction is nether-only.
  • The path is automatically recalculated when elytraNetherSeed changes, elytraAllowThighsSpaces does not have this effect. Not sure whether automatically recalculating is better.

I also really do not like how we are offsetting positions back and forth all across the code. Just look at how many times this went wrong with the existing chunk cache.
Can't we just use exactly one coordinate type (absolute world coordinates) in Baritone and shift to 0 based at the API boundary?
You didn't want to do this in nether-pathfinder itself, but maybe we can wrap the java side of the API to do the shifting?

@@ -39,16 +39,16 @@ public BlockStateOctreeInterface(final NetherPathfinderContext context) {
}

public boolean get0(final int x, final int y, final int z) {
if ((y | (127 - y)) < 0) {
if (y < 0 || y > 383) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This always checks for the maximum chunk height, is that correct? i.e. does nether-pathfinder always allocate full-size chunks?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

Comment on lines 85 to 89
if (this.dimension == Level.NETHER) dim = NetherPathfinder.DIMENSION_NETHER;
else if (this.dimension == Level.END) dim = NetherPathfinder.DIMENSION_END;
else dim = NetherPathfinder.DIMENSION_END;
int height = Math.min(world.dimensionType().height(), 384);
if (!Baritone.settings().elytraAllowAboveRoof.value && dim == NetherPathfinder.DIMENSION_NETHER) height = Math.min(height, 128);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch. Can you please autoformat your code with whatever formatting the rest of Baritone uses?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using properly formatted braces would make it take up more lines for no benefit

boolean isSolid = pair.second() != AIR_BLOCK_STATE;
Octree.setBlock(ptr, pos.getX() & 15, pos.getY(), pos.getZ() & 15, isSolid);
});
// not inserting or deleting from the cache hashmap so we should be fine not being exclusive
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except iirc C++ considers any data race undefined behavior and doing this across an ffi boundary won't make things better.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's undefined behavior if another thread is writing to the data at the same time we are reading it but that is not the case here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are the writing thread here, but since we only have the read lock another thread may do the reading required to trigger undefined behavior.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case you forgot / didn't see it, there's an Octree.setBlock call in this block. The hashmap reading is hopefully fine, as the comment says.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pathfinder racing with this would be inconsequential however multiple calls to this to nearby blocks could cause bad data to be written so i will change it to use a write lock. The read executor is still single threaded so there currently isn't a difference anyways.

writeChunkData(chunk, ptr);
writeLock.lock();
try {
long ptr = NetherPathfinder.allocateAndInsertChunk(this.context, chunk.getPos().x, chunk.getPos().z);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this always returns a completely zeroed chunk?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

@babbaj
Copy link
Collaborator Author

babbaj commented Apr 10, 2025

Disabling elytraUseBaritoneCache unconditionally causes an NPE, crashing the game unless this happens inside a command

fixed

  • Disabling elytraAllowAboveRoof while flying above the nether roof and then causing recalculation crashes the game. I didn't even get a crash report, but no segfault either?

I don't think this description is accurate. If elytraAllowAboveRoof is off and we put ourself above the roof then there is a crash (nether-pathfinder printing "retard" to stderr and calling std::terminate) but changing that setting while flying has no effect except possibly when it finds a landing spot.

I have not yet fixed this but I will probably fix it by pausing pathfinding until the player goes back below the roof.

Enabling elytraPredictTerrain in the overworld leads to endless recalculation and chat spam. Actually not a crash though.

fixed

The path is automatically recalculated when elytraNetherSeed changes, elytraAllowThighsSpaces does not have this effect. Not sure whether automatically recalculating is better.

fixed to behave the same

@ZacSharp
Copy link
Collaborator

You want to fix the out-of-bounds crash before merging this or later?

@babbaj
Copy link
Collaborator Author

babbaj commented Apr 12, 2025

before. i also found another bug last night that's more important.

@underscore-zi
Copy link

underscore-zi commented Apr 12, 2025

I also really do not like how we are offsetting positions back and forth all across the code. Just look at how many times this went wrong with the existing chunk cache.
Can't we just use exactly one coordinate type (absolute world coordinates) in Baritone and shift to 0 based at the API boundary?

I've added a commit on my branch (underscore-zi@d0c3aea) that pulls all those adjustments into the NetherPathfinderContext methods that make the pathfinder calls along with one Octree usage in BlockStateOctreeInterface.

On a related note, is there a better way for me to share commits? Or would you just prefer I left it all over to Babbaj now since its not my PR?

@babbaj
Copy link
Collaborator Author

babbaj commented Apr 13, 2025

Just fixed the rest of the known bugs in 75096e1

I've added a commit on my branch (underscore-zi@d0c3aea)

merged

@ZacSharp
Copy link
Collaborator

Still get a crash by these steps

  1. Stand on the nether roof with some firework rockets and an elytra
  2. Run #settings reset all, #elytraAllowAboveRoof true, #thisway 1000, #elytra
  3. Start flying
  4. Run #elytraAllowAboveRoof false, #elytra reset

@@ -1262,6 +1280,7 @@ private static Vec3 step(final Vec3 motion, final Vec3 lookDirection, final floa
return new Vec3(motionX, motionY, motionZ);
}

// any call to this must be done with the lock held
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you maybe apply this comment to all methods which require synchronization and specify that the readlock is required?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only function run on the main thread that requires synchronization but i added a comment to solveAngles.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell we have

passable called by simulate and pathFindAroundObstacles
simulate called by solvePitch called by the other solvePitch called by solveAngles
solveAngles called by onPostTick with synchronisation and by tick (and tick is public)
tick called by ElytraProcess.onTick with synchronization on the main thread
pathFindAroundObstacles called by PathManager.tick called by onTick0 called by onTick with synchronization on the main thread

At least tick needing synchronization should be documented.

@ZacSharp
Copy link
Collaborator

On a related note, is there a better way for me to share commits? Or would you just prefer I left it all over to Babbaj now since its not my PR?

You could open pull requests against babbaj's pull request branch, but I'm not sure whether that's better than a writing a comment.

@babbaj
Copy link
Collaborator Author

babbaj commented Apr 15, 2025

Still get a crash by these steps

fixed

@ZacSharp
Copy link
Collaborator

ZacSharp commented Apr 15, 2025

Still get a crash by these steps

fixed

Replace #elytra reset with changing elytraNetherSeed/elytraPredictTerrain/elytraAllowTightSpaces and it crashes once again.

@babbaj
Copy link
Collaborator Author

babbaj commented Apr 15, 2025

fixed again

Copy link
Collaborator

@ZacSharp ZacSharp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm out of crashes now. The only thing I managed to find is an "Unhandled exception" error message when you change to an invalid goal mid-flight, but that's not new. (e.g. #goal ~).

@leijurv
Copy link
Member

leijurv commented Apr 22, 2025

I will merge this..... on one condition........

When you #elytra to a goal in the overworld that is at least some distance away (configurable setting, defaults to, let's say 1000 blocks), it should fly upwards (if it cannot fly upwards it'll go towards the goal of course). Once it gets above y=320, it will have a single target point that is simply the goal (ignoring the Y of the goal). I think this will work fine in the code because raytraces in minecraft have a maximum number of blocks they visit so it won't be too laggy? If it is laggy just add partial points at fractions along the way. Then once it is near the goal it dips back down below 320 and does landing or whatever at the goal

I think this would be a compromise that would allow it to fly through interesting overworld terrain like 2b2t spawn, while still going straight any-angle diagonal towards the goal (rather than the straight + 45° thing that I just think is low quality).

@babbaj
Copy link
Collaborator Author

babbaj commented Apr 22, 2025

It is currently not possible to fly above y 320 without increasing the height in nether-pathfinder even more. That should be an easy change.

@kittenvr
Copy link

This is amazing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for auto-flight with Elytras in the overworld and the End.
6 participants