Let's begin with Chunk Loading.
When creating Command Block systems, we might need to access chunks outside the Players' reach, be it to find entities or use blocks from there.
Sadly Minecraft doesn't give us an official way to remotely load chunks, but there are a few mechanics we can use to solve the problem.
I'm gonna talk about some solutions, each very useful for its own necessity and working based on how Minecraft itself works.
The Arrow Method - Keeping a Chunk loaded
Around a year ago, test137E29 uploaded a video talking about Arrow Chunk Loaders.
Sadly, it relied on using an extending piston and, after piston movements got improved in 1.9, the old system no longer works.
But that doesn't mean we can't still use the concept to our favour and improve it.
test's Chunk Loader worked by simply turning an Arrow's position to NaN (Not a Number) coordinates, which would then make it appear at x = 0, z = 0.
It's possible to set the position of other entities to NaN coords as well, like Myren Eario showed with Shulker Bullets, but Arrows are special as they constantly check the block they are inside of to detect if this is broken or moved. Now, if the block is at unloaded chunks, the Arrow will need to load that area so the detection can be done.
Of course normal Arrows don't act as loaders. When they aren't being processed by the game, the block test will cease.
However, if they are in a loaded area and away from their original position, they will do the block test and remotely load the chunk the block is in. This behaviour allows us to load any area we want.
test137E29 has achieved that by using the NaN position, yet we can actually change the Arrow's position using the /blockdata command.
While the NaN method has the limitation of only working up to 32768 blocks away from 0,0 and needing to keep 0,0 loaded, changing the Pos [tag] doesn't have an area limitation and it can send the Arrow where you want, letting you have the spawn chunks anywhere.
The down sides of this new design is the need to use Command Blocks to make it work and not being able to remove the block the Arrow was in while it's acting as a loader.
Changing the position of an Arrow with commands to send it to 0,0
This loader is used to keep chunks loaded, meaning we need to previously load them before they keep like that.
The main applications are more about accessing entities or blocks inside those chunks.
You can use an entity as a marker and teleport to it whenever you want, being able to do this.
IMPORTANT EDIT
After making the post public, I found out it's not necessary to change the position of an Arrow with /entitydata for this method.
As long as the entity doesn't move, any changes at its position won't interfere at the tile tags, which remember the coordinates of the block it is inside of. In other words, using a teleport will also work.
The only condition for using the /tp command is to have a solid block at the destination. If there's air or something the Arrow can fall through, its Motion tag will change, forgetting where it was previously at.
So, to load a chunk using an Arrow, it's as simple as summoning it at a block, waiting a tick and teleporting to a loaded chunk. It's as perfect as it can get.
Using the System
Firstly we need a block for the Arrow to stay in. Keep in mind that this block cannot be broken while the loader works.
We then summon the Arrow inside the block with a pinpoint tag, just so we know which one we are working with. I also like to give a starting Motion [tag] to make sure it'll be inside the block as fast as possible, though is not necessary.
Afterwards, we'd need to change the Pos [tag], however the Arrow needs a tick to update itself and realise it's inside a block. An easy way to wait this one tick is to set an impulse Command Block to auto:1b using /blockdata and make it power the remaining commands, just reset it right back to auto:0b so it can be reused later.
Having passed a tick, just do an /entitydata to change the Pos [tag] to the coords you wish the Arrow to appear. You can also use the same command to remove the tag used to pinpoint the entity and even add new ones.
Now we'll also need to make sure the Arrow doesn't despawn. Simply put a clock reseting its life [tag] to 0s every so often. It doesn't need to be fast, only trigger before 1 minute.
Edit: You can also set the Arrow's tag to -32768 so it lasts around 27 minutes!
You can find the commands used here.
The Reversed Arrow Method
I've shown you how to load chunks by changing the position of an Arrow whilst it stays inside a block, but the reverse process is also possible.
We can summon an Arrow anywhere and tell it is inside a block somewhere else. For that we use the xTile, yTile and zTile tags, which refer to the block's position.
It's possible to remotely load a chunk by using this reverse process, without the area being previously loaded.
On the other hand, you can only use it at set coordinates and, if you want to keep it loaded, there must be a block there beforehand. If there isn't, the chunk is still going to get loaded, though it'll unload randomly shortly after.
Also, when the Arrow is summoned, it takes one tick for the chunk to get loaded. We can use the 1 tick delay method I talked about to trigger the other commands.
This method is only used for very specific areas, however it is very light to use, as no lag is caused, and really useful for pontual uses of a small area which doesn't need to be previously loaded.
Using the System
To use this system, one command is enough: /summon Arrow x1 y1 z1 {xTile:x2,yTile:y2,zTile:z2}
x1, y1 and z1 are the coordinates where the Arrow is going to appear. You need to keep this area loaded in order for the loader to work.
x2, y2 and z2 are the coordinates you wish to load. There must be a block there beforehand if you intend to keep the area loaded. If the Arrow can't land in a block at these coords, those will be updated to where it was summoned and the chunk will only load for a short moment.
You also need to make sure the Arrow doesn't despawn if you want it to keep loading the area.
Summoning an Arrow to load the 1000 1000 coordinates
The Spreadplayers Method - Loading New Chunks Remotely
The /spreadplayers command is known for being able to load new chunks remotely, although it has a mistaken fame of being unreliable. Nevertheless is possible to use it without problems, just using simple fixes.
The way this command works it similar to how Arrows check for the blocks they are in. When entities are spread, they have to land somewhere where they can stand on, so if there is no block there or water/ lava, they'll try to land somewhere else.
The /spreadplayers will randomly select a block to put the entities and, to know if the location is legit to use, it'll have to be loaded so the block is tested.
Now this is very helpful, we can use any coords we want in the command, even relative to other entities. Not only that, but also load multiple chunks at once and the target location doesn't need to be previously loaded.
It's also instant!
It sounds perfect, however it needs to run every tick, on a 20Hz clock, to make sure the chunk stay loaded. Having lots of these working at once can cause considerable lag because it also needs to do extra calculations every time.
I recommend only using it to access unloaded chunks and, if you need to keep them, use the Arrow method right after.
Remotely Loading a Specific Chunk
If we use set coordinates, loading a chunk is very simple. The main command used is /spreadplayers x z 0 1 false @e[tags], being x and z the destination. We'll need to use an entity for that, any type should work fine. To keep the chunk loaded the command must run in a 20Hz clock; a repeating command block does the job.
There's a little problem, though. If the command stops running, normally because we leave the world, the entity will stay stuck at the destination chunk and we won't be able to load there anymore. The fix is straightfoward, we just need to prevent the entity to stay at unloaded chunks.
The simple solution is to teleport it back to where the command is being executed when /spreadplayers triggers. With that, the loader will manage to keep working after leaving the world and even after more than 7 hours running straight, from what I've tested.
We can also prevent the entity from even leaving its original position, by not letting it land at the set coordinates. Do that by either having only void or water/ lava as the highest blocks there. We cannot always use this solution, but it avoids having to use an extra teleport.
Using the spreadplayers command on a Pig to load the 1000 1000 coordinates
Remotely Loading a non Specific Chunk
There's no need to restrain ourselves to specific destinations. By using relative coordinates, /spreadplayers can be used to load anywhere you desire.
Now, by using relative coords, the entity needs to be first sent to the location and then execute the command on itself. We can achieve that by teleporting the entity there as, when we teleport it to unloaded chunks, some commands can still be run before it unloads, such as teleporting again or using /spreadplayers.
Ok, teleporting also uses specific coordinates, even when using relative ones. But with the help of scoreboards and a little of binary we can go anywhere! Just have one score for each axis (x, y and z) and you're set to go.
To reach the destination, binary comes in play.
To teleport in one direction, we start by checking if the score of that axis is higher than a high 2^n value. If it is, the entity will be teleported by this amount and the same amount will be removed from the score. If it's lower, the current value is ignored.
It then repeats the process with the next value, 2^n-1. The process happens over and over until it reaches 2^0. By the end of it, the entity should arrive at its destination.
Do the calculations using another objective so you don't loose the information.
Also note that the Minecraft world goes from -30 000 000 to 30 000 000 on the x and z axis, so if you want to cover the entire map use 2^n as 2^25.
The coordinate scores can be changed by hand or using command blocks to specifically set those, but we can also transform the entity's position into it, allowing the entity to remember any position it was it.
Wubbi shows us how to do that in his Warp Points video. I recommend watching his video if you want to learn the concept, he explains in details there.
Loading Multiple Chunks at Once
There are two ways of loading a group of chunks.
The first is to have the area you want to load with a water or lava ceiling or without any blocks for the entity to appear when /spreadplayers is used.
The command always try to put the entity somewhere. If it can't, it'll try another location until it works. While it does that, it'll load chunk after chunk to know if it's possible to put the entity there, resulting in all the chunks being loaded in the end of the process.
This method works every time, if you block all the possible landing spots, but it's not clean at all.
The second way is to have multiple entities being spread.
Well, it works but is not optimal at all. That's because, the bigger area you want to load, the more entities will be necessary. The problem, though, is not having lots of entities, but processing all of them at once. Specially if you plan to keep it loaded by using a 20Hz clock. Don't do that.
To be short, I recommend doing this only if you need to execute a clone/ fill at a big unloaded area. Using as a constant loader might make your computer cry. It also might be a better idea to have multiple /spreadplayers, one at each chunk of the area you want to load, rather than just one command spreading through the whole area.
spreadplayers used to load a 50 block radius area around the 900 900 coordinates. 51 entities were used
Other Loaders
There are a few more ways to load chunks in Minecraft. The more useful are the ones which use Arrows or /spreadplayers, but here are four more if you feel you don't have loaders enough.
The End Gateway
In 1.9, the End recieved a lot of implementations. One of them was the End Gateway, which acts as a teleporter. What is fun is that, when an entity enters it, the destination will be loaded, regardless of what goes through the portal.
The destination coordinates are stored in the end gateway block itself as the ExitPortal tag and, using /blockdata, we can change it to go where we want.
To load a chunk, simply summon an entity at the portal. Sadly, though, the area will unload randomly shortly after and it'll only work with specific coordinates.
Using this is about the same as the Reverse Arrow Method, maybe a little more complicated as there's an extra step of needing to have the gateway block. It's also not possible to keep the chunk loaded, like with an Arrow.
Hoppers
A really simple way to load chunks, being also really limited, is to have a hopper with an item inside at a chunk border, pointing at its adjacent one. The hopper will need to know if there's a container in front of it wanting to recieve the item, for that the chunk in front will be loaded.
For it to work the hopper must be loaded, meaning it's not possible to put it anywhere and hope it works. It acts more as an extention of loaded chunks than a proper loader, nonetheless it is pretty good at doing that.
Redstone Dust
Powering a redstone line instantly will load all of the chunks it is in for a short moment. It's very useful when playing survival, but for map making is not recommended, as it takes a huge space, you need to set it all up first and it's quite laggy from all the block updates, specially if you have a really long section.
Nether and End Portals
When an entity goes through a nether or end portal, the other side will be loaded. End portals are not very useful, as they can only lead to the End of the spawn chunks, which are already loaded; however nether ones can be placed anywhere.
This is a very messy method to use, but it can be useful in survival, like the previous one.
It's normally used at Iron Farms to prevent them from breaking. There's no real gain on using it for map making, though.
Well, that's what I had to talk about Chunk Loaders. I hope you've learned something and, if you know about something that isn't here, leave a comment and let me know!
Thank you for reading as always and see you next time!
very very intresting, is the gateway actually random or is it the 45 seocnd unloads? also, i ve never seen nether portals (or end portals) being used for loading apart from keeping the spawn chunks loaded, is there any real reason for that(apart from it not having a very apparent use :D). sadly there doesnt really seem to be any use for all this stuff atm that u added. another thing is that i dont quite get why the shulker bullet doesnt have to check for blocks. it also has to get removed when hitting a block similar to the arrow gtting the on ground tag.
ReplyDeleteThe End Gateway is random like any other loader that doesn't keep the chunks loaded, the destination will unload a moment after an entity goes through it. It can take a few ticks or maybe even up to 45 seconds.
DeleteNether Portals load chunks, but it's not a very good method to do so, as you need to constantly throw items on a dimension to load the other. I mentioned it more because it exists than for being an useful system haha
About the uses for chunk loaders, I put an example of having a Return system, which remembers your position before teleporting and, if you choose the go back, it'll return you there. That's only possible because the chunk where the player was is kept loaded.
You can also use them if you want a destroyable PVP map. Every time a match ends and the arena is in pieces, you can reset it back to its original state by cloning a template. If this area is at unloaded chunks, you'll need to load them first.
And finally, about Shulkers, I believe they only check their own position.
Arrows have separated tags for the block they are inside of, however Shulker Bullets only have their position tag. There's no need for the Shulker Bullet to test for blocks besides its own location, which will be already loaded if it's being processed by the game.
Hi , there is a simple chunk loader for 1.8+ , the creator doesn´t have many subs
ReplyDelete