Closed HoratioGamer closed 3 years ago
I think it would be a good idea to have baritone treat barrier blocks in schematics this way by default. This would simplify communication as no one would need to change their settings for most situations.
I think it would be a good idea to have baritone treat barrier blocks in schematics this way by default. This would simplify communication as no one would need to change their settings for most situations.
That is a good idea, and this way there is no need to add another mode ti it. Well of course some features mentioned by @HoratioGamer will be sacrificed, but will be much cleaner and simpler (and easier to implement).
My first objection to barrier blocks is, they do not behave like regular blocks when building them in creative. When one places them they are visible. Place several and break one, the others become invisible. Unlike the void block, at least they occupy the entire block volume.
My second objection to barrier blocks is they cannot be built in a survival world. There is no way to build the literal schematic (don't set the I-do-not-care block) in a survival world, tinker with it, test it, and then use Lunatrius and Schematica to re-save it as a schematic where one has the option to use an I-do-not-care block set. If what one is building is a machine, there are some things that do not work the same in creative as they do on some survival servers, even different survival servers might behave differently. By making it the barrier block, you remove the choice to use the I-do-not-care feature for a given schematic. Specifically, one is removing the option to build, test, tinker, test, save without having to take it back to creative to place all the flippin barrier blocks all over again.
OK if a command is too complicated:
Make it just a variable, not a command. I am not sure how much work it would be to add another command-line accessible variable to Baritone -- it seems the code already exists for other variables, just the name of the variable changes. If the code is written half-way sensibly, it is a copy and paste and change a variable name.
Then when it comes to the test:
foreach (schematic block in the schematic) {
if {schematic block == minecraft:barrier} continue; /* skip to next schematic block */
set target world block = schematic block
try to place the target block in the world
}
becomes
foreach (schematic block in the schematic) {
if {schematic block == i-do-not-care} continue; /* skip to next schematic block */
set target world block = schematic block
try to place the target block in the world
}
With the as-long-as-it-is logic, it becomes:
foreach (schematic block in the schematic) {
if {schematic block == i-do-not-care} {
if {world block in as-long-as-it-is} continue; /* skip to next schematic block */
set target world block = [ lindex as-long-as-it-is 0 ];
} else {
set target world block = schematic block;
}
try to place the target block in the world
}
Sorry for the mix of C and TCL-ish pseudocode.
The added code to make it an actual variable does not seem onerous if one is going to open this can.
I think this is generally a good idea, but I'd tweak the following few things:
buildIgnoreBlocks
and buildIgnoreExisting
i-do-not-care
should be a list like buildIgnoreBlocks
as-long-as-it-is
or make it a map of valid substitutes like the one planned for litematicaAnd two little notes at the end: Your example of Baritone clearing a path from everything except obsidian wouldn't work because of #1925 Your first objection on barrier blocks is wrong: Barrier blocks are invisible, but as long as you are holding a barrier item, particles indicating their position are spawned (only visible to yourself). What you saw was the particles having different delay when appearing and disappearing, so the block you just placed was longer visible than the others.
After having a quick look at BuilderProcess
I think i-do-not-care
is trivial, as-long-as-it-is
would be trivial and apart from a new command argument datatype a mapping of valid substitutes is trivial as well.
I'll look at implementing at least i-do-not-care
tomorrow. Suggestions for a better name are welcome.
I am flexible on the name, so long as it is descriptive of what is is.
better names in the scheme of buildIgnoreBlocks and buildIgnoreExisting
I would have suggested better names for buildIgnoreBlocks and buildIgnoreExisting so one actually gets a clue they only deal with air blocks.... like:
buildIgnoreBlocks --> treat_these_world_blocks_like_air buildIgnoreExisting --> only_replace_world_air_blocks
I-do-not-care --> schematic-non-buildable-placeholder-block I-do-not-care --> schematic-skip-build-block I-do-not-care --> schematic-unassigned-block I-do-not-care --> schematic-absent-block I-do-not-care --> schematic-dont-change-world-block I-do-not-care --> schematic-null-block I-do-not-care --> schematic-trim-block I-do-not-care --> schematic-empty-block
And my favorite:
I-do-not-care --> schematic-ullage-block
look up ullage, I think you will like it, it is perfectly descriptive of the unused part of a container, the right-prism of the schematic being the container.
You get the idea, something that communicates that it is something in the schematic that changes the interpretation of the schematic, that it is an empty part of the schematic, or one that does not change the world.
(I was not intending any code to parse filenames, that was for the user to read and decide whether to use the recommended i-do-not-care block setting.... always intended that there be user choice, no code there)
And thank you ZacSharp for taking up this change.
I-do-not-care --> schematic-styrofoam-packing-peanuts-block
Your're right, current naming of settings related to block-treatment while building is a mess (could be worse though).
I think I'll take your second suggestion and reorder it to buildSkipBlocks
. I will insist on the "build" at the start, because I want it to show up with other build related settings in alphabetically ordered lists (pretty much anywhere).
Well I am just very happy to see this become part of Baritone. It does not matter what I have to type to make the magic work...
Finally the ability to make schematics that are not right prisms. It is like stepping into a bigger world. There are so many applications for this. Every time something did not quite fit in a box, now it does. One can make non-right-prisms like towers that lean to one side, or that simultaneously lean in both X and Z directions. One can make fancy stairs and ramps that cut through natural rock where the right-prism is long in the horizontal direction and skewing one end up or down in the Y direction to make it slope. Finally, building underground stables is not tedious. One can build things within tall circular and elliptical cylinder voids underground, even perfectly spherical shaped voids. One can recreate something like the great machine of Babylon 5 underground (using redstone of course) carved into native rock. One can recreate fantasy locations like the Mines of Moria, or real natural locations like the Mammoth Cave System, or Carlsbad Caverns, or any real interior void space that has had a 3D scan done of it. One can recreate the interior of one of the great cathedrals underground, or the crypts under Paris, or the London Sewers, or the burial chambers under the Pyramids. That is creative or survival.
In anarchy, where there are hacks to show everything and what is not natural will draw the attention of base hunters, one can make artificial caverns (overworld or nether) and artificial mineshafts that look indistinguishable from naturally generated ones -- because they were created from natural ones by simply snapping a schematic ! One just processes it through creative to get rid of all the mineral and other irrelevant features, and make all buildSkipBlock locations into the same block, not a hard step. That is the dodge of making the artificial (and convenient) look mundane. Really, the buildSkipBlock becomes a way to build air in any shape you want. One can also schematic familiar structures like desert temples or jungle temples, including the underground parts, and stick one anywhere. One can intentionally tweek them to have non-standard traps in them.
The very first use I will put this to is to create baritone schematics that can dig and pave nether highways at any angle we choose, and do so with minimal if any appearance of glitches.
I will just remind you of the hand-in-hand usefulness of the As-long-as-it-is concept:
If one interprets the schematic to take no action, provided certain things appear in the world, that is powerful. Besides all the uses I will put that to in highway building schematics, consider a simple mining schematic that is nothing but a solid block of buildSkipBlocks -- you say useless right? I say no.... imagine the ability to remove everything except the minerals from under a mountain. All you have to do is list all the minerals you want to preserve in the As-long-as-it-is list, with Air as the first element. Set up baritone to AFK clear out all the rock, leaving the minerals hanging in air. It mines out all the stone, granite, gravel, dirt, etc, everything not on the list, leaving all the selected minerals behind. It could be made not to mine silverfish blocks, in case later one wants them for some reason. One can then use a silk or fortune pick selectively on certain minerals, or go in and collect only the iron and gold for use in smelting to turn coal into experience orbs to selectively heal mending enchantment items when the iron or gold is removed from the furnace. Furnaces as bottles of enchantment just got easier.
I do hope you will consider implementing the As-long-as-it-is logic also.
nothing but a solid block of buildSkipBlocks
I'd use #sel fill air
and #buildIgnoreBlocks diamon_ore,coal_ore,iron_ore,emerald_ore,lapis_ore,gold_ore,redstone_ore
And for the highway I'd build the pattern out of wood, select it, make sure there's no unintended wood in my selection, turn on build repeat and use #sel replace wood obsidian
. Because ReplaceSchematic has a cache this would only care about spots where there was wood in your pattern.
So far I haven't found a use for as-long-as-it-is
.
Apart from that, here's the current status:
I managed to make it not place blocks where a block on buildSkipBlocks
belongs, but for whatever reason it still clears the spot and I haven't found the reason yet.
And for the highway I'd build the pattern out of wood, select it, make sure there's no unintended wood in my selection, turn on build repeat and use #sel replace wood obsidian. Because ReplaceSchematic has a cache this would only care about spots where there was wood in your pattern.
One extension to As-long-as-it-is proposed below.
OK, so, I am not understanding this...
I will explain better, and explicitly how I would use it on the highway. There are two processes, to dig the highway and to pave the highway. There are two ways to use as-long-as-it-is. First, I want my schematic to bridge, so, the layer below the obsidian layer, is included in the schematic. Since this is the road bed, so long as there is any competent building block there, I really do not care what it is. So my schematic is made of air and netherrack for the base. I can run this schematic with literal netherrack and it will bridge chasms and it will dig. But really, I do not care what the base it made out of, so long as it is solid. There were a lot of places where cobble or stone or granite or andesite or diorite had been used to make a place to walk, particularly in bridging over chasms. There were other things used that I really don't want in a road bed like dirt, leaf blocks, all sorts of crap blocks. Whatever my standards are, I have a list of acceptable blocks, and a list of unacceptable ones. I make the buildSkipBlocks set to was wood planks, build my road bed schematic out of wood planks and say in as-long-as-it-is the list of all the blocks I would be OK with, starting with netherrack -- if it is not OK, it is replaced by netherrack. Most importantly, if there is obsidian UNDER where the obsidian pavement will eventually go, that is OK, and I really do not want my bot to start uselessly mining obsidian that will be buried later, just to replace it with netherrack that will be buried later. That is one use, the sub-floor of the highway, be more forgiving, break and replace fewer blocks.
The second use in digging is to not mine out obsidian is the layer that will later be obsidian. So my schematic has a netherrack sub-layer, and a layer of buildSkipBlocks on the top in the area the obsidian will eventually go when the paving might happen. I set the as-long-as-it-is variable to Air Obsidian. The schematic will take down taller obsidian builds and leave them flush with the finished paved road bed, but will not mine any obsidian out in the digging stage that will just need to be replaced in the paving stage.
The third use I would use as-long-as-it-is, is in converting scarred terrain into natural terrain around something. I would list natural terrain in the as-long-as-it-is variable, probably with a grass block as the first block, but also include air, and then any block found that is not natural or Air is replaced by the first natural terrain block listed.
The fourth use I would use as-long-as-it-is blocks for is to eliminate caves in areas I do not intend to have air as part of the schematic but leave or make air where I intend for there to be air. I do not care what it is as long as it is a solid block. So the as-long-as-it-is block lists a lot of solid blocks I would be satisfied with.
I hope that at least one of these 4 examples proves the need for as-long-as-it-is.
EXTENSION TO AS-LONG-AS-IT-IS
In short, as-long-as-it-is becomes a build preference, the first element of the list being built if it exists in the hotbar (extended by allowinventory), if not then the next, etc, until we reach Air or the end of the list. If Air is not in the list, and none of the blocks are in the hotbar, then it allows baritone to fail in attempting top place the block in the world. Otherwise it places the first block in the list that it has stock of in the hotbar.
foreach (schematic block in the schematic) {
if {schematic block == buildSkipBlock} {
if {as-long-as-it-is is not set} continue; <<< an error in my previous pseudocode
if {world block in as-long-as-it-is} continue; /* skip to next schematic block */
set index 0;
while {$index<[llength as-long-as-it-is} {
set target world block = [ lindex as-long-as-it-is $index ];
if {target world block==Air} { break; }
if {target world block in hotbar} { break; }
set index [expr $index+1];
}
} else {
set target world block = schematic block;
}
try to place the target block in the world
}
I would use this extension with as-long-as-it-is to make one schematic for both paving and digging. The buildSkipBlock is set to Oak_Planks, and these are placed where the obsidian might be laid in the roadbed. The as-long-as-it-is is set to Obsidian Air -- obsidian first. So long as the player has obsidian, baritone lays it. When the player runs out of obsidian these blocks are still acceptable if there is already obsidian in the world, otherwise it makes the world block into air. It makes the Baritone bot resistant to failing. It paves when it can, and then just digs when it runs out of obsidian. It gets the most of out what the player has.
A railroad-road-bed grader type schematic, to make roads in the overworld would list all the potentially suitable blocks it might encounter in the overworld in the as-long-as-it-is list. As it progresses, it makes tunnels through hills and then reuses blocks to bridge ravine areas, providing a road bed for rails. It would only fail when it no longer has any acceptable blocks, and it has yet to reach the next hill to accumulate more. A superhighway grader schematic might do the same thing.
I didn't new people actually put road beds below their highways. A simple solution would be buildIgnoreExisting, but that wouldn't allow doing everything at once and would allow e.g. saplings in the a road bed. You've found something I can't solve with the current settings, but I think you even mentioned a case where as-long-as-it-is is not enough: If I want it to put anything from a long list of solid blocks I've made in the bottom layer and obsidian or air in the top layer, I need to different sets of acceptable blocks while only having one as-long-as-it-is list. Also for what you want we need more than just making more blocks valid, because even though it accepts more blocks as valid it will still only place the block listed in the schematic. (Everything I did so far only affects where the builder does stuff, not what it does)
I found the culprit for Baritone breaking blocks that should stay: They are defacto correct.
Because I don't have usable schematics lying around on my pc I used Baritones FillSchematic and ReplaceSchematic (which uses a FillSchematic when created via sel replace
). I turns out that FillSchematic has some "smartness" itself and first wants air wherever there is a wrong block and only wants the target block when there's air, essentially replacing it. This causes buildSkipBlocks
to correctly don't do anything (air shouldn't be skipped) until Baritone has broken the block where a skipped block was intended to be. Since Schematics loaded from files don't do this, they should already work.
You are correct, some of those things, if I combined them into one schematic would need separate buildskipBlocks and for each of them a different as-long-as-it-is list of blocks. To solve this problem I was just planning on making more schematics for different purposes. (I make a lot of schematics.) I would make one for rough roads people had cobbled together like within 10k of nether spawn in 2b2t. I would have another that handles the case that someone has dug the tunnel in the wrong geometry and we are not sure what might be under the rails further ahead -- there are a lot of non-standard digs in the ring roads. I would have yet another, the marathon schematic that runs until you run out of obsidian, and then keeps going just digging -- one would use these when far out and carrying a lot of road materials. It might run for hours AFK.
About the road base -- It is simply the blocks under the road, what is not dug out in the tunneling process when passing through void-free netherrack. By including these base blocks in the tunneling schematic, when baritone reaches a chasm, it will automatically take netherrack out of inventory and build the base for the road over the chasm. the chasm is bridged at dig time, it does not need to be bridged later. This way, when and if the pavers ever come through, they have an easy surface to lay obsidian on -- there is no risk of Baritone getting confused and thinking it has to scaffold or something. Also in between the time the road is dug, and it is paved -- which may be months -- if someone comes through on a horse, they have a workable road bed to ride on all the way out. Including the road base in the schematic also fixes little holes in the road and lava pockets in the road bed. If we ever run out of obsidian, the new highways may remain unpaved, so, a contiguous road bed is useful.
Does anyone know why this is in FillSchematic.java?
} else if (current.getBlock() != Blocks.AIR) {
return Blocks.AIR.getDefaultState();
}
It makes it impossible for the builder to ignore specific blocks in the schematic. I also tested it without these lines and didn't find any issues, but maybe there's a non-obvious reason.
Does anyone know why this is in FillSchematic.java
I ask that about a lot of baritone code
That is so that baritone makes sure to remove blocks before it places more in that place I believe, which is needed for obvious reasons.
The reason is not that obvious because BuilderProcess does that itself and Schematics loaded from files don't even have the possibility to dynamically change their content, so either there's another reason or I can remove it.
It is probably legacy code that is no longer needed anymore, so yes, you can probably remove it. If not leijurv will point it out when merging the pull if he ever checks this repo.
Well, another option is to label that section with comments that raise these questions, and then just copy and paste over the buildSkipblocks code to this module, duplicating it. As you said Zac, this code does not even run when people execute schematics from files, so, it is not really going to be a slowdown issue to have duplicate code.
How active is leijurv ?
How active is leijurv ?
lol
How active is leijurv ?
Well...
How active is leijurv ?
Just guess
Since I consider removing useless code as cleaner than duplicating code to places where it doesn't belong I'll just remove those 2 lines for now and if leijurv complains I can still use HoratioGamer's or similar solutions.
Is key'->'value[','key2'->'value2]...
a good mapping syntax? With list-type values this is key'->'value11[','value12]...[','key'->'value21[','value22]...]...
and list-type keys aren't possible because keys can't contain commas.
What is wrong with:
Just a space between block names... there is no key, they are all as long as it is blocks. Someone showed me a split... @Living.... list = string.split(" ") I am guessing .split will do this. Because we just want to know if it is in the list, and preserve the order of the list.
Or are you trying to create multiple buildSkipBlocks, each with their own list of as-long-as-it-is block list? Where it is: SkipBlock_id1->"as-long-as-it-is-list1" SkipBlock_id2->as-long-as-it-is-list2 ?
Like that is way complicated, and highly functional, and I would use it, but I am pretty sure I am the only one who would.
Don't worry about command parsing itself, Baritone's command system is fairly robust for what it does.
It's not about command parsing, it's about datatype parsing. I can't use spaces because Baritone's command system uses them to split arguments and settings only accept one argument (that's why lists like acceptableThrowawayItems use "," and not ", " as a seperator) Yes Horatio, it is a mapping of blocks to their skip blocks and I'm actually using split already.
(Everything I did so far only affects where the builder does stuff, not what it does)
Just found out that my thoughts on this were wrong. When checking block if a block is valid Baritone uses a valid(current,desired) method and I thought that's it and it only places what the schematic requests, but in addition it checks for every invalid block and for every item it is allowed to place if that item would place a valid block in that position, so valid() can indeed change what the builder does.
Is there a reason to suppress that behaviour for a buildValidSubstitutes
setting or does everyone using it want Baritone to place the substitutes anyway? And should the block itself still be valid if it has substitutes specified but they don't contain the block itself (if it is not one can completely swap blocks using something like "stone->netherrack,netherrack->stone)"?
@HoratioGamer is it important that skip blocks aren't considered part of the schematic? With the solution I pushed to my repo (no pull yet, but feel free to use it) it just considers everything in their position as valid and thus penalizes breaking anything there while allowing to place blocks at 0 cost. To treat them like any other block in the world I think I'd have to wrap the schematic with a new subclass of MaskSchematic, which is a lot more to do than the 10 (5 of them are javadoc) lines I already did.
I was holding off responding to your last post because I was uncertain and unknowledgeable.
I am not understanding because buildValidSubstitutes is not documented as far as I can tell. I have tried and it is not a command-line accessible variable as far as I can tell. I do not want to characterize it before I understand it. If you could give me a concrete example of how it gets set, or what values it might have or what influence it might have if I had a particular schematic....
For instance, the first example that springs to mind on if I lay two blocks from my inventory, and what appears in the world is different, is stairs doing the corner stairs with 3 accessible diagonals (outside corner) or 1 accessible diagonal (inside corner). I assume a schematic containing stairs would need to know it is a valid substitute to use regular linear stairs. My attempt at an example screenshot:
I understand the jist of this, there is this list buildValidSubstitutes for some reason I am not clear on. If I assume for a minute that the stairs thing would be covered in BuildValidSubstitutes, I am trying to understand, would this lead to a problem if part of the stairs were outside the schematic, or in the buildSkipBlocks part of the schematic.
I am going to venture a guess, if one were going to implement only buildSkipBlocks, then the most elegant solution be that these blocks are just not part of the schematic at all. This would mean, under no circumstances would baritone consider interacting with them as part of the build. I have observed baritone tunneling through blocks that are outside the schematic to build some part of a schematic, and most times I do not care. Sometimes when it does this tunneling behavior it is ruining the desired end effect -- to not have any holes in the walls.
However, if as-long-as-it-is logic is introduced, then these blocks are conditionally part of the schematic. I do not appreciate all the code problems this would bring.
buildValidSubstitutes sounds like As-long-as-it-s, sort of, and the answer might be to split buildSkipBlocks from as-long-as-it-is, and instead implement as-long-as-it-is as buildUserValidSubstitutes (copy code from buildValidSubstitutes, but use user-defined data) where the data might be a list like (Oak_Planks*, Obsidian, Air) meaning, the valid substitutes for oak planks in the schematic is obsidian or air in the world. The problem is, then there has to be a check if Obsidian is available in the hotbar (inventory) to avoid an error, and instead decide Air is the valid substitute that would be used.
I hate to split the two concepts, but, if it fits the code best, then until I learn JAVA, that is what it has to be....
As for the distinction you ask me to decide between in the latest message, I ask, may I test it ? See if it behaves well ? I have a problem that is kind of basic to Java. If I have multiple forge mods loaded, and more than one contains a copy of baritone, and I want to test your version of baritone in the presence of the balance of the other mods, how do I assure your baritone is the one that is being tested ? How do I make Minecraft/Forge ignore all the other copies of baritone ?
I have found your github, but, git-newbie question, how do I get a baritone.jar of this test code ? I see no downloads or packages that like, wrap it up as a product to download. I would like to avoid the whole download the entire repository and do this, this, and these really gitty things. It is an entire skillset that I would not get right on my first 20 tries.
*
Edit: This will not work because oak_planks is not a valid designation. Only "planks" works, and then Baritone will not distinguish between planks in a schematic.
https://github.com/cabaletta/baritone/issues/2323#issuecomment-774129439
OK, I did a little gitty, and found this....
https://github.com/ZacSharp/baritone/tree/buildSkipBlocks
Can you make this into a bartione_HG.jar for me ? And tell me, would it work with my schematica test configuration in MultiMC and forge making changes to the current mods as :
That is, I will remove baritone standalone and replace it with baritone_HG.jar, and I will remove World Edit and Optifine just to be careful. Would this be a viable test platform ?
If not, can you give me a description of how to install the baritone_HG.jar into Minecraft ?
To get the jar use git clone https://github.com/ZacSharp/baritone.git
, cd baritone
, git checkout buildSkipBlocks
and ./gradlew build
, the output is the dist directory. Before doing the build itself you need to make sure you're using java 8, and if export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
is not the correct way of doing it on your system (I use Linux) I can't help with that.
Your setup would be a viable test platform.
buildValidSubstitutes
only exists in my workspace, not even in a local commit. I sure hope you can't find that.
It is meant as a mapping of blocks to a list of blocks Baritone considers valid in their position, which is as trivial as buildSkipBlocks
if I don't want Baritone to consider the substitutes for placing. But since I want to add a way of changing the block palette of a schematic anyway, I'm wondering if there's any use to buildValidSubstitutes
I found a way to only penalize breaking where a block is skipped, so I can at least easily prevent it from wasting blocks. Would that be good enough? Just not breaking them, but placing like normal?
I found a way to only penalize breaking where a block is skipped, so I can at least easily prevent it from wasting blocks. Would that be good enough? Just not breaking them, but placing like normal?
OK, so, if I include Oak_Planks* in my schematic to mean, don't do anything at this block position, then it means do not do anything. Not breaking blocks saves me time and durability on tools. If the location is occupied by an Oak_Plank block, what exactly could it build there with only the buildSkipBlocks ? Block in the schematic is only a placeholder, I never want it built in the world. Baritone has a problem with building up against the nether ceiling. I want my buildSkipBlocks to go to the nether ceiling, if there is any chance they will be built as anything, it will totally screw up baritone -- it will start tunneling between the bedrock in the ceiling, stuff that would never come up anywhere but against the bedrock ceiling of the nether.
So, I believe the answer is no, there is no chance that just preventing breaking would be good enough, if the block is to be skipped, it cannot be built either.
*
Edit: This will not work because oak_planks is not a valid designation. Only "planks" works, and then Baritone will not distinguish between planks in a schematic.
https://github.com/cabaletta/baritone/issues/2323#issuecomment-774129439
Baritone penalizes breaking valid blocks and makes it free to place valid blocks as part of its path, meaning it could build bridge through a area where the schematic is filled with buildSkipBlocks with the same cost as if the blocks had already been there, essentially wasting blocks and maybe rarely time. It never tries to go there specifically to place buildSkipBlocks, it just favours placing scaffolding where the schematic contains buildSkipBlocks and avoids moving through (breaking) blocks where the schematic contains buildSkipBlocks. I easily can turn the favouring for scaffolding off, but not the break penalty.
The straight line version for that for Ubuntu 18 is:
$ git clone https://github.com/ZacSharp/baritone.git $ cd baritone $ git checkout buildSkipBlocks $ env | grep JAVA
Nothing found so I need to set JAVA_HOME
$ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ $ env | grep JAVA
returns:
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
$ sudo apt install openjdk-8-jdk openjdk-8-jre $ env | grep JRE
Nothing found so I need to set JRE_HOME
$ export JRE_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre
$ sudo update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).
Press
$ java -version openjdk version "1.8.0_275" OpenJDK Runtime Environment (build 1.8.0_275-8u275-b01-0ubuntu1~18.04-b01) OpenJDK 64-Bit Server VM (build 25.275-b01, mixed mode)
finally....
$ ./gradlew build
(many signs of things compiling properly)
$ cd dist baritone/dist$ ls baritone-api-1.2.14.jar baritone-standalone-forge-1.2.14.jar baritone-api-forge-1.2.14.jar baritone-unoptimized-1.2.14.jar baritone-standalone-1.2.14.jar checksums.txt
run java -version
Did you start a new terminal before running java -version
? Because that resets your env.
Same contents as my /usr/lib/jvm/java-8-openjdk-amd64/ directory.
By the way I never did any java installs to compile something, it simply worked when I tried it.
Baritone penalizes breaking valid blocks
So, if I understand correctly, you are asking about other Baritone behaviour surrounding building the schematic, but not actually building the schematic. If a block were outside a prismatic schematic, I have not observed baritone either being careful of placing or breaking blocks. It is indifferent. Where there is a buildSkipBlock, it should be the same, it is simply not a part of the schematic that is built, as though it was not part of the schematic. If for some other reason it wants to build or break a block there, for the buildSkipBlocks without the implementation of the as-long-as-it-is feature, I do not care.
It is sounding more like, the as-long-as-it-is feature should be separate, perhaps buildConditionalBlocks and buildConditionalWhitelist.
I will test buildSkipBlocks soon and report on how it does.
Still don't have the feeling you understood what I meant. What I'm talking about only affects pathing while building. Normally, Baritone slightly penalizes breaking and placing blocks as part of a path; while building breaking valid blocks (in this case including everything masked away by buildSkipBlocks) is even more penalized and placing valid blocks (again everything masked away) doesn't have any cost at all. This does in no way affect what Baritone thinks about a schematics completion or where it needs to place blocks. You know how the pathing works, right?
I assumed it was a weighted A*, smallest metric is the path with the least penalty.
OK, so apart from not intentionally breaking or placing the blocks when considering the buildSkipBlock mapping to a point in the world, I think that Baritone should have the same metrics for non-schematic blocks as buildSkipBuild blocks. If they are in the way of pathing break them with the exact same penalty as blocks that were always outside the schematic. The I-do-not-care block is not a "Well, I would really prefer if were not broken even if it is in your way" block. It is "there is no schematic job to do here" block, anything else other than building schematics, I do not care.
If within the schematic there are weights, I am not seeing a logic to why right off.
No weighting outside the schematic, inside it weights based on whether a block is correct or not (break wrong block: x1, break correct block: xbreakCorrectBlockPenaltyMultiplier, place block where air should be: x2, place wrong block: x3, place correct block: x0). I can easily turn off the weighting for placing, by simply considering newly placed blocks invalid and I can turn off the extra breaking penalty in breakCostMultiplierAt by treating buildSkipBlocks IBlockStates as if they were null (not in schematic). Maybe I should do that in costOfPlacingAt as well.
Pushed a commit excluding them from the schematic. You can get it using git pull
in your clone of my repo.
Next I want to do a setting to replace blocks with other blocks, e.g. for your long highway you could use namePending obsidian->obsidian,air,cobblestone->cobblestone,stone,netherrack,dirt
to make the obsidian optional (it prefers blocks in the order they are listed in) and place some more blocks than just cobble where the schematic wants cobble.
Do you think there would be use for an additional setting that just changes which blocks are valid (the same as the above but without placing)?
(it prefers blocks in the order they are listed in)
OK, at a given block, anything in the list will do. If the block in the world does not match anything in the list, then check to see if we have the first block in the list in inventory, if so, lay that one, otherwise see if we have any of the next block in the list etc.
I think the above will satisfy those needs I currently anticipate.
Do you think there would be use for an additional setting that just changes which blocks are valid (the same as the above but without placing)?
This would be like a baritone checker bot.... when it comes upon a block that is not in the list, it what, stops ? There might be a use for that. Because if it is not going to place, and air is not the last thing in the list so breaking the current block to make air is not acceptable solution, then what else can it do but stop if it will not be placing ? It would be a way to implement a go-until-you-find blacklist by implementing it as a go so long as it is on the whitelist, which is the same as namePending cobblestone->cobblestone,stone,netherrack,dirt (but no place allowed)
Yeah, I just thought of a use.... a grief removing bot that does not break possibly historic signs. Go until it is not air, stop and let the operator decide. The problem is, the acceptable block is air, so, you have to not only not place, but also not break for that to be a use.
Report on Testing:
With the results of my first compile of baritone with buildSkipBlocks, I did ordinary baritone stuff, and there were no problems -- the null test.
As suggested, it git pulled and did a second compile. This is a summary of the results.
This was the very first schematic designed to use buildSkipBlocks:
It is a 2-advance long diagonal schematic. The intention is that the blocks next to the side wall remain in the schematic for one more advance so that in the presence of glitching, if a block next to the side wall glitches, there is an opportunity to correct it. This schematic tested perfectly in a creative world I have made modelling the nether highways of 2b2t at 1/100th scale.
I discovered, there is no functional #set buildSkipBlocks clear functionality:
so I #set buildSkipBlocks Obsidian because there is no obsidian in this schematic. I build the schematic without a functional buildSkipBlocks set, so that the sand was re-produced in my schematic workspace -- that worked correctly.
I then manually extended it to a 5-advance schematic with the buildSkipBlocks of Sand:
I then used this schematic in my model nether highways world
It worked perfectly.
The next test is to get it into 2b2t and test to verify it works there, and also, measure the effect on glitch blocks. So @ZacSharp @l1ving how do I get this to play happy with say this configuration:
Where Impact and KAMI/Blue both contain Baritone? You have not only added lines, you have removed lines, so if I drop baritone-standalone-forge in there, how would it know to use the version of the classes with the buildSkipBlocks in them ? Or do I have to unload all the other mods and go into 2b2t with a naked baritone ?
If your make sure that the name is alphabetically before the other two then it should work fine.
Where Impact and KAMI/Blue both contain Baritone?
Well you'll need to follow Impact's instructions for loading custom Baritone. KAMI Blue will use whichever Baritone is loaded in the classpath first, which means that with impact installed kami blue will use Impact's baritone
Sorry, forgot to add this to sort out impact, https://github.com/cabaletta/baritone/blob/master/SETUP.md#more-info this is some documentation about how to do that.
So it sounds like I can ditch Impact (I can live without Impact for testing, possibly forever), and just drop baritone-standalone in, and KAMI/Blue will automatically accept that baritone.... that was easy once you understand the magic ! Thank you all, and thank you to KAMI/Blue for just being smart about co-existing with others.
You should be able to clear it by resetting it (if I haven't messed up the default). When using a mapping of valid but not placeable substitutes it won't fail when encountering them, as long as it has the block the schematic wants there.
void dealWithBlock(Block currentBlock, Block schematicBlock) {
if (validSubstitutes.get(scheamticBlock).contains(currrentBlock)) {
avoidBreaking();
} else {
normalBlockHandling(); // break if wrong, place schematicBlock if air
}
}
this function doesn't exist ofc
What is the command to reset? Is it #reset buildSkipBlocks ?
yes, alternatively you can type more and use #set reset
(#reset
is an alias)
I think using valid substitutes to prevent it from breaking signs has two major flaws:
I think you shouldn't make air a valid substitute,that would lead to Baritone only placing those blocks in order to walk on them or place blocks against them
the patch of cobble is built by hand to test if Baritone really doesn't touch it ("buildValidSubstitutes obsidian->air,stone->cobblestone,netherrack")
Describe your suggestion
buildIgnoreBlocks and buildIgnoreExisting do the opposite of what I am suggesting. They ignore blocks in the world that do not match what is in the schematic.
I want the opposite, I want to pre-process the blocks in the schematic, interpret the blocks in the schematic. I want to add a new concept, that a particular block in the schematic tells baritone not to change anything in the world. I do not want that to be a fixed block like Air. I want it to be a settable block. When this block is found in the schematic, baritone should take no action, baritone should say, I do not care what is in the world, it is OK as it is, do not try to change the world at that point. I call this the I-do-not-care variable. Usage would be:
I-do-not-care [{block_ID}/clear]
Usage to see what the I-do-not-care block is set to.
I-do-not-care
Usage to set the I-do-not-care block to be sand
I-do-not-care sand
Usage to clear the previous definition of the I-do-not-care block so Baritone returns to interpreting schematics literally.
I-do-not-care clear
When a designer intends a schematic to use an I-do-not-care block they must choose the block at design time, and communicate this choice to users of the schematic. The author of the schematic might save the name of the schematic to signal to the user what to set the I-do-not-care block should be:
My_favorite_schematic_IDC_Sand.schematic
There are so many blocks available in Minecraft that it is possible to choose any buildable block that does not appear in the intended build of the schematic. So say I want sand to be my I-do-not-care block. I can save the schematic, and use the schematic without the I-do-not-care-block set, and I see the oak planks being built -- this allows me to see what is in schematic. Then I set
I-do-not-care sand
and I build the schematic again -- this time not only does it not build the sand, it does not do anything at the locations that there were sand in the schematic.
At run time, the user would know they are using a schematic with an IDC block, and they would have to set the I-do-not-care block variable appropriately before running the schematic.
The use I would put IDC blocks to is, when I want to build a schematic box to enclose a large structure, where part of the structure contains Air, I can fill the portion of the box that I do not really care about with IDC blocks. It means I can create schematics that are effectively not right-prisms. It means I can build triangles or pyramid-shaped schematics, and that part of the shape that is not used in the bounding-prism box is just filled with IDC blocks. This would allow me to make effectively non-prismatic schematics with any current design tool for creating schematics.
For instance, but certainly not limited to this use, when I am building highways in 2b2t, on axis-aligned highways, I make my schematics 6 blocks long in the highway direction. An axis-aligned highway is a right-cylinder. I only need to define its shape in a right-cross-section, which for minecraft, is a one-block-wide slice across the highway. Unfortunately, one experiences glitches where blocks are laid and then disappear. Baritone's behavior is to re-place blocks in the current schematic image that are no longer present, however, if one uses #buildrepeat, when the Baritone advances by the increment, when blocks from the last lay of the schematic, that are not in this lay of the schematic disappear, they stay as a defect after the passage of Baritone. HighwayTools (the KAMI/Blue module) uses 2-block wide schematics, and under some conditions will leave glitches behind. With a 6-block long schematic, every block is in 5 consecutive advances of the schematic... In practice, only the blocks on the leading edge of the schematic are laid in a given cycle. If there are no glitches, there is no need to re-place any blocks. As glitches appear later and later, they may be replaced in one of the 5 previous lays. This is a solved problem -- glitch-free axis-aligned highways -- just make the schematics longer than they have to be.
This does not solve the problem for any highway at any angle where one does not want to determine what appears in certain blocks in the schematic -- if one does not have the use of IDC blocks. Without IDC blocks, there is no way to have an entirely overlapping schematic that advances with buildrepeat 1,0,1 for instance without including a lot of other blocks that either Baritone must place sometimes or must remove sometimes. When the schematic is limited only to blocks that must be determined, the blocks in the wing columns of the schematic only appear in one lay of the schematic as it advances along the other diagonal. With the presence of glitches, there are a lot of blocks not proper in these wing columns after the pass of baritone. The problem can be solved by enlarging the bounding prism to contain multiple appearances of all blocks in every column but then the wings of the prism extend into spaces we really do not care what is there. No strict interpretation of the schematic will solve this problem.
I could set a schematic for a large underground installation, and set only wall skins blocks and the contained Air blocks to be the desired block in the schematic... all the space between rooms and between tiers could be made IDC blocks, and then, if I base my schematic on a save from a world, and try to build it again at a different part of the world, Baritone is not trying to rebuild the random mineral deposits that might have appeared between rooms or between tiers in the original schematic. Anyone who has tried to make a schematic from an existing underground build has encountered this problem. One would be able to make standardized secret entrances (useful in Vanilla minecraft for sure) where all elements needed in some odd geometry are specified, but all unimportant parts of the bounding box are IDC blocks.
Freeing Schematics from the Strictly-Duplicated Right-Prism Prison is what IDC blocks are about.
As a further extension, I propose a second variable, As-long-as-it-is -- the full sentence would be I-do-not-care As-long-as-it-is (one of a list):
Usage:
As-long-as-it-is [{list of block_IDs}/clear]
Usage to list the list of blocks that Baritone will apply IDC filtering to:
As-long-as-it-is
Usage to set the list of blocks that Baritone will apply IDC filtering to:
As-long-as-it-is Air Obsidian
If the IDC block maps to a place in the world that is Air or Obsidian, do nothing.
Usage to clear the list of blocks that Baritone will apply IDC filtering to:
As-long-as-it-is clear
The behaviour would be, if
I-do-not-care sand
As-long-as-it-is Air Obsidian
If the place in the world that sand maps to is Air or Obsidian do nothing. In the case that the location in the world is neither Air nor Obsidian the IDC algorithm does care and makes the block the first element of the #As-long-as-it-is list, in this case Air.
I would use this particular feature for, but not limited to, when I want to dig an area in preparation to laying Obsidian. If there is Obsidian in the schematic, and I do not have any, Baritone will fail. If there is no Obsidian in the schematic and Obsidian is encountered in the world, Baritone will spend a lot of time mining it.
With IDC variable, set to sand, I can just put sand in the schematic where I might eventually want to put Obsidian, and then say #As-long-as-it-is Air Obsidian -- Baritone would clear away any blocks which are not Obsidian. I could use the build schematic, but set the IDC variable to Obsidian and the #As-long-as-it-is Air Obsidian, and get the same effect.
Therefore:
As-long-as-it-is Air Obsidian
is different from:
As-long-as-it-is Obsidian Air
In the first case, the world gets more air for non-matching blocks, in the second more obsidian.
This cannot be done by buildIgnoreBlocks and buildIgnoreExisting because those interpret the schematic literally and then perform judgements on the world, and only with Air either in the schematic or in the world:
To do what I want to do, one has to interpret the schematic with a filter, and apply it to the world, regardless of what is in the world at that location, or only if the world does not contain certain blocks.