Baritone AI pathfinder

Baritone AI pathfinder

72.7k Downloads

Cache a list of blocks present in each chunk

typecasto opened this issue · 9 comments

commented

Describe your suggestion

Make a list of every block present in a chunk (overall) and save it alongside the cache data. When the user searches for a block that isn't in any of the loaded chunks, it'll find some cached chunk that has the block, path near enough to the chunk to load it, then path to the actual block, since we now know where it is.
This wouldn't take up that much space, since it won't actually be tracking which blocks are which, just which blocks are present within each chunk, and once it gets near enough to load that chunk, it will re-path to it.

Settings

If applicable, what settings/customizability should be offered to tweak the functionality of your suggestion.
searchCacheForBlocks (Boolean) - Enable or disable the feature overall
cacheBlockBlacklist (List[Block]) - Blocks to avoid caching, since they're so common (grass, dirt, stone, etc.) to reduce size.

Context

If I play on a server for a while, I have a lot of chunks cached, but none of them contain block data. I could have run across a certain block (or, more specifically, loaded it's chunk) dozens of times, but .mine won't be able to find any.
This would improve the .goto and .mine commands, especially for rare blocks like end_portal_frame.

Final checklist

  • I know how to properly use check boxes
  • I have not used any OwO's or UwU's in this issue.

(also, as a complete side note, how does .find work? for me it just echoes the command back and does nothing.)

commented

Sorry, I think that i probably clicked the wrong button.

commented

@scorbett123 Can i ask why this was tagged cringe? I'm trying to get better at contributing to open-source projects, so sorry if I do some things wrong.

commented

Nice, actually like the idea of allowing to #goto to any block over huge distances, but I'm a little concerned about cache size (that's why I didn't say anything), because this would require the full block id of each block + 1 byte separator for each block in a chunk.
I'll see if I can find/gather some more accurate data, but my calculations based on naïve assumptions predict a size increase by 6% to 16% percent, but it is totally possible that I am way off in either direction.

commented

256^2 regions is probably better yeah, worst case baritone has to path to the center of the region before it recieves the live chunks for finding the block. zipping it with the actual chunk data that is already cached for the region to save space might be a good idea, i'd say store the text form of BlockOptionalMetadata and quantity probably doesn't matter

commented

Problem with per-region storage is that a region is 16x16 chunks, so with a render distance below 8 you can't load all of it at once (afaik there are servers with pretty low render distances, that's why leijurv made renderCachedChunks I think)

commented

Normal regions are 512 by 512, this is being reduced to 256 by 256 to help combat this issue. Baritone can also always do abit of exploring to find it. This would mean 4 of these areas per region that could be stored in the region file.

commented

Ok sounds good.
Then:

  1. Full blockstate, BlockOptionalMeta or Block? I think Blockstate might be a bit more than needed and bigger than necessary, but with some form of matcher it would be more useful than BlockOptionalMeta or Block.
  2. With or without amount? What would we need the amount for?
commented

My thoughts on the storage issue is maybe we store the actual block IDs per region, and use that as an list we can index into per chunk, like so:

region data:
minecraft:grass
minecraft:stone
minecraft:iron_ore
minecraft:diamond_ore
...

data for each chunk:
1,2...
1,2,3...
1,2,3...
1,2,3,4...
...

This would cut down on the amount of data that has to be stored and solve the render distance issue, but it would make lookups a bit harder (search for the block name, then find a list of chunks in that region that have that index in their blocks)

Additionally, though it might be more work than it's worth, it could be made into a bytewise tree, where a certain subset of bytes would be reserved for further trees, so grass might be A, but some less common block like emerald ore might end up being 0y, assuming that the numbers are the ones reserved for further trees. This way, the more common blocks (or blocks that we encounter first, with the tiebreaker being frequency in the chunk we encounter them in) like grass get encoded as less costly values, and more uncommon blocks get encoded as more costly values, plus this eliminates the need for any seperators, since we know it's the start of the next block whenever we reach a value that isn't a number (or whatever subset of bytes represents more trees).

This would be more useful if done overall, and we store one tree per world and create it as we go, rather than do it per region. As long as we never update previous blocks and go in the correct order (root tree, 0, 1, 2, ... 9, 00, 01...) the previous chunks would still be valid, and we'd never have to work through every chunk and redo the block ids. We'd only have to store each block ID once, and then we'd have a lookup per chunk that barely takes up any bytes, though this wouldn't allow metadata lookups.

commented

I feel like it should be optional (automatically off) and probably not stored in amount of x blocks per chunk, maybe per 256 by 256 region or something. It can just path there and then search the render distance.