Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[1.12.2] Entity pathfinder doesn't like going uphill?


Recommended Posts

So, I have an EntityTameable that can be told to search for a block. When it finds that block, it tries to walk as close as it can to that block, using getNavigator().tryMoveToXYZ([block coords + one y level]). Only, if the target coordinates are above the entity, the entity's navigator seems to prioritize a short path that takes the entity below the target over a longer path that will actually reach the target.

Example: In this setup, if I spawn the entity on the ground and tell it to find emerald ore, I expect that it should climb up and around the quartz path to stand on the emerald ore, since that's as close as possible to get to it. Instead, it just moseys over next to the base of the pillar (which is directly underneath the ore) and calls it a day.

BY63Rss.png

It looks like this isn't only an issue with my implementation, either; I made a tamed wolf and a cow follow me, and neither of them would attempt to climb up the path to get to me unless I was within ~5 blocks of the start. This implies to me that the problem might not just be me using the pathfinder incorrectly...

I have tried:

  • As a test: moving the entity partway up the path and starting there; success varied but the entity seemed more likely to jump off and hug the pillar the closer it was to the bottom.
  • As a test: moving the entity to the top platform and having it find one of the ores on the ground; it correctly walks the entire path down to the ground.
  • As a test: moving the entity to the top platform, building extensions that would allow it to stand directly above the ores on the ground, and having it find one of those ores. It still walks the entire path to the ground to stand right on the ores. Downhill does not seem to have this pathing problem.
  • As a test: building a small labyrinth on flat ground and having it find a block at the end; it's a little confused at first and wanders around the outside wall near where the block is, but after a few seconds it figures it out. Seems to work well enough on flat ground.
  • Verifying that the AI is indeed finding the correct block and sending the navigator the correct coordinates.
  • Increasing the entity's follow range to 64, then to 128. I saw that this value was used for something like pathfinding range (?) and guessed that this might encourage the entity to pathfind for greater distances. I verified that the path range changed using GetNavigator().getPathSearchRange(), but it had seemingly no effect on the pathfinding.
  • Going around tryMoveToXYZ() using some of the other PathNavigate and PathNavigateGround methods, which at best gave the same results.
  • Extending EntityAIMoveToBlock and attempting to use it. (EntityAIMoveToBlock apparently does not path vertically at all, worthless!)

TL,DR: my fatass pet is too lazy to climb the damn stairs, wat do?

Link to post
Share on other sites

If this is a vanilla bug, then using vanilla AI tasks is worthless. While writing my mod I also have found several bugs in minecraft pathfinding code. This made me write own implementations of NodeProcessor,  PathNavigateGround and PathFinder. I can't help you with this, though, because their code is really difficult to understand. You'll have to experiment with mentioned classes.

Link to post
Share on other sites

They're usually not "bugs" in the pathfinding but rather performance optimization. If you study pathfinding you see that making a pathfinding that can handle every case can quickly cause performance problems. You can easily create tricky paths (like the one in your picture, or things like large mazes) where the pathfinding will have to give up before it solves it otherwise would cause lag. Think about it -- a path finding algorithm may have to try every possible combination of path within the 3D space and that will grow quickly.

 

It is possible to implement your own pathfinding. For example, one time I was trying an entity that could destroy blocks in its way so I had to figure out some custom pathfinding that allowed it to find paths through those blocks. Pathfinding is extremely well documented in both math and computer science so you can google to find algorithms that help you. But eventually the sheer number of possible paths in a large 3D space will limit your ability to explore them all.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to post
Share on other sites

Well... out of curiosity, I did some more tests in an actual Minecraft world (random terrain and caves and all). The pathfinder seemed to work much smoother under those circumstances, figuring out paths through winding caves at least mostly-reliably? I can't think of why it would work better in a chaotic, randomly-generated environment than in my test world with simple single correct paths to follow, but I guess that means I have a lot of learning to do.

I might take a crack at writing a new pathfinder, but that's getting filed under "maybe in an update" for now.

 

Thank you for your advice.

Link to post
Share on other sites
8 minutes ago, ItsTheKais said:

with simple single correct paths to follow

Because the area outside your test location is flat and unbounded in all directions.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to post
Share on other sites
1 hour ago, ItsTheKais said:

I can't think of why it would work better in a chaotic, randomly-generated environment than in my test world with simple single correct paths to follow, but I guess that means I have a lot of learning to do.

 

It has nothing to do with randomness and more about how specific each step has to be. In most cases in the Minecraft world there are several paths between two points, but in your case there is exactly one correct next step.

 

Then if you think about the general problem of finding the best path when there is only one exact path that works you can see how the problem gets extremely hard. Think about actually trying to code it. What should the first step be? You might think that stepping in the direction of the target is best, but in general case that isn't guaranteed. Maybe you should go sideways a bit, or backwards. Your example only goes upwards but what about a case where you have to go down a bit and then back up? No matter how you code your pathfinding you can always build a case that is bad for that algorithm.

 

In the end the only way to guarantee finding a path is by brute force, meaning try every possible valid move. But that is still hard.  In your example, if you spawned the entity right under the target block the correct block requires about 30 exact steps to get to. So you would need an algorithm that finds every combination of 30 steps to ensure you find the correct one. Sometimes it will be found early and sometimes at the end. With smarter algorithms you can make sure you don't include trying paths that cover ground you've already been on. But it still adds up. If you just do the first level of math, in each step you have 4 directions you can go. So the number of actual paths is 4 raised to the power of 30! That is 1.15x10^18 paths -- or 1.15 million million million! You can cut that down by assuming you don't go back to the space you just came from, but that is still 3^30.

 

Anyway, the number of possible paths is extremely large. The only way to really make it manageable is to limit the number of steps that the pathfinding can look for and hope that getting closer to the target is helpful overall (not always true, but often is).

 

The interesting thing is this shows how good humans are at pathfinding. We can look at a picture and almost instantly understand the path, probably because our brain can take advantage of some massively parallel processing that isn't available on a PC running Minecraft.

 

Again, there is a lot of research into this -- it is important for robotics and gaming and is interesting from a general math and computer science theory. But even the best algorithms are pretty limited.

 

EDIT: If you really want the entity to find the path using vanilla pathfinding I think it should be possible by adding more "waypoints" -- basically intermediate targets within the range of the pathfinding.

Edited by jabelar
  • Like 1

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • I'm currently trying to make a new cauldron-type block, and I'm having difficulty implementing blockstates. Here's the relevant part of the alchemical cauldron's code:   public class AlchemicalCauldronBlock extends Block { public static final IntegerProperty LEVEL = IntegerProperty.create("level", 1, 3); private static final VoxelShape INSIDE = box(2.0D, 4.0D, 2.0D, 14.0D, 16.0D, 14.0D); protected static final VoxelShape SHAPE = VoxelShapes.join(VoxelShapes.block(), VoxelShapes.or(box(0.0D, 0.0D, 4.0D, 16.0D, 3.0D, 12.0D), box(4.0D, 0.0D, 0.0D, 12.0D, 3.0D, 16.0D), box(2.0D, 0.0D, 2.0D, 14.0D, 3.0D, 14.0D), INSIDE), IBooleanFunction.ONLY_FIRST); public AlchemicalCauldronBlock() { super(Properties.of(Material.METAL).sound(SoundType.METAL).harvestLevel(3).strength(2F,2F)); // this.registerDefaultState(this.stateDefinition.any().setValue(LEVEL, 0)); // this.registerDefaultState(this.stateDefinition.any().setValue(LEVEL, Integer.valueOf(0))); } ... When I try to run this with either of the two attempts at registerDefaultState uncommented, I get this error: https://pastebin.com/vPf3UryC. For convenience, I believe this part is most relevant: How can I avoid this? My registry classes look like this, if it helps: public class registry { public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, AlchemyPlus.MODID); public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, AlchemyPlus.MODID); public static void register() { IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); BLOCKS.register(modEventBus); ITEMS.register(modEventBus); registerItems.register(); registerBlocks.register(); } } public class registerBlocks { public static final RegistryObject<Block> ALCHEMICAL_CAULDRON = register("alchemical_cauldron", AlchemicalCauldronBlock::new); static void register() {} private static <T extends Block> RegistryObject<T> registerNoItem(String name, Supplier<T> block) { return registry.BLOCKS.register(name, block); } private static <T extends Block> RegistryObject<T> register(String name, Supplier<T> block) { RegistryObject<T> ret = registerNoItem(name, block); registry.ITEMS.register(name, () -> new BlockItem(ret.get(), new Item.Properties().tab(ItemGroup.TAB_BREWING))); return ret; } } Full GitHub repository available here.   (Other minor problem(?):  I copied the methods getShape and getInteractionShape from net.minecraft.block.CauldronBlock and I'm getting these weird warnings. What's up with that? Do I need to worry about it?)  
    • Personally I use IForgeRegistryEntry#getRegistryName and then ResourceLocation#getNameSpace to get the id of the object.
    • you can get a block form a ResourceLocation, take a look at NBTUtil#readBlockState, do somthing like that
    • I am running forge version 1.16.5 36.1.31 on a server with a lot of mods and when a player refreshes the server list, it sends a long error in the server console. Additionally, the server list displays "Can't connect to server", despite refreshing and actually being able to connect to the server. here's the links to the logs: https://gist.github.com/WaffleTraits/83885b1539d5711fabff73a91924e665 https://gist.github.com/WaffleTraits/5ae78e6eaa330422bbc9f7226faf60ce Here's what's displayed in console when a player refreshes server listing: https://hastebin.com/ativexeyoy.properties server is running on ubuntu 20.04 and is using java 8 for this forge instance.
    • I kept getting this error whenever I tried joining my modded server I want to find a solution to this I checked every mod and it all matched Client : https://mclo.gs/Q39SSu5 server : https://mclo.gs/UO2kbDz
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.