Hey what’s going on guys turtle here and welcome back to another forge modding tutorial for minecraft 1.17 in this tutorial we are going to be covering much uh requested and highly anticipated block entities so block entities may sound a bit strange and that is because they are essentially what we call Tile entities now so they’ve changed from tile entities and they’re now called block entities so that’s might be a little bit confusing of a change at first but you do get used to it it took me a little while but yeah so if are not aware of what a block Entity is it is basically a normal um it’s basically something you apply to a block which allows you to save special data and do stuff every tick there’s a bunch of stuff you can do with them they’re extremely useful something like the furnace the chest the beacon all those different things they are Block entities because they store stuff and they do special functions so what i’m going to be doing in this tutorial is quite stupid i’m going to be making a toilet um and this is a suggestion by uh brammy15 he is in my discord server so a special Thanks to him uh for his great suggestion um and essentially this toilet will simply store um it’ll basically store the amount of times you have you have gone on the toilet basically um and in a future tutorial i’ll also be saving um well i will have a keybind for uh Using the toilet and it will store that instead but for now let’s just go ahead and get started so i’ve already created the block and i’ve already initialized it down here and i’ve also created the item i’m pretty sure yep i have and for this tutorial i have also gone ahead And created an entity and this is just so that the toilet toilet is suitable so here’s my system entity um obviously all of this code will be on my github you don’t need this for a block entity of course this just so that i can sit on The block it’s the best way to do it with an entity since you can just make it a rideable entity that is invisible so this is an invisible entity obviously it does have a renderer so here’s the renderer it doesn’t do anything special it just extends the normal entity renderer has no texture And yeah nothing really is happening here so let’s let’s get started shall we so the first thing we want to go ahead and do is create a new init class and we can call this block entity init now block entities are very similar to normal entities in the way that they Have entity types and you can register the type and then you create the entity from the entity type so as usual this will just be a final class with a private constructor and obviously you can throw in that constructor if you wish um and then we’ll just create a public Static final deferred register of type block entity type and we’ll leave that wild card and we’ll just block entities that is equal to deferred register dot create board registries dot block entities and then our mod id so that is tutorial mod dot mod id just format that and import everything Okay then we just need to create the registry object as usual so public static final registry object objects i’m not sure why it’s not appearing there we go and this will just be of type and this will this will be a type um block entity type But then this will take in the class of our block entity so i’m going to call the i’m going to be calling the class just toilet block entity you could also just do toilet b e if it’s too long of a name but i prefer to have just toilet and then block entity That’s just sticking with vanilla to be honest uh to the rest that i can do and i’m just going to be naming this toilet is equal to block entities register toilets and then a supplier and very similar to entities here we are doing block entity type dot builder dot off Now this is a block entity supplier so that is basically just a supplier of your block entities constructor so a method reference is how we’d like to do this and that is just going to be toilet block entity or whatever your block entity class is colon colon new And then we need to supply the valid blocks so this is basically the blocks that our block entity will work on so you only want to supply the blocks that you want this block entity to work for so for me that will just be block init dot toilet And obviously that won’t work until we do dot get okay obviously we have an error that is because we don’t have such thing as a toilet block entity okay let’s uh go into our block class since we need to go ahead and do a few things The first thing we need to go ahead and do is implement entity block and essentially what this does is it allows our block to contain an end block entity so if we just go ahead and add the unimplemented methods here we go and that adds the new block Entity we also want to actually go ahead and add get ticker okay let’s just rename these so obviously block pause is pos and block state is the state the level is the level or the world you could say uh block state the states and then the tick uh the type is just Uh i guess just the type i mean yeah and we’re not gonna run over return the super i’ll leave that blank for a mo so as you can see i have already created this class it’s just got the voxel shapes uh as the horizontal block tutorial does it’s got All this different stuff i’ve also created this boolean property for whether it’s used or not this currently is going to be unused i’m not going to be using this in this tutorial specifically but i will be using this in a later tutorial so i’m just going to leave it there So the first um method we want to be covering here is new block entity and this is called essentially when you place down the block and the block entity is created so this function is what creates the block entity itself in here you just want to be returning block entity init dot toilet Dot get dot create and that just takes in the pause and the state obviously that will give us an error because the actual class that this is referencing does not exist that’s perfectly fine okay and the next method is get ticker so this is basically this is for Your tick function so if you don’t want your block entity to tick and you just want it to save data and not tick then you can just uh you don’t need to override this method but since i want my block entity to tick i want it to be able to Do some updates every tick and just to demonstrate taking we are going to need to return something in here and we need to go ahead and return level uh return level dot is client side now if it is client-side we just want to return null we don’t want it to tick side Uh and then we can go ahead and say or and here’s where we need a supplier for the actual uh ticker so we we need this functional interface right here if you go into here you can just see it’s a functional interface with this tick method so it Expects a level a pause a state and the block entity itself so we need to actually go and specify these and obviously you could make instead a static method and just call uh like class quote-unquote on static method with your actually clark with your actual class and obviously That method would instead just take in those parameters but i prefer to do it this way that means i don’t have to make a static method and i don’t have to have any arguments instead i’m going to have um dollar sign zero and i’ll explain while i’m doing well i’ll explain Why i’m doing this in a second and then we have dollar sign one and then we’ll have dollar sign two and then we have block entity and then we’ll just have a supplier and we will cast our toilet block entity which obviously doesn’t exist right now we’ll cast that to block entity Let’s just uh double brackets this so that we can call dot tick okay so let’s explain what i’m doing right here so the reason we have dollar sign 0 1 and 2 is because this is the level the block pause and the block state now We don’t need these so as you can see here we already have the level we already have the state and i mean sure it gives us the pause so if you wanted to you could put pause here but we’re not using this pause as you can see so there’s not really any points I mean i guess we could like we we could say um level zero and state zero you could do that if you want in fact i will do that for the just the purpose of uh showing you um but you can just do dollar sign and then number that’s what I like to do that just sort of shows that it’s unused it’s not needed uh you used to be able to do underscore i believe um but you can’t do that anymore so if i hover over this you’ll say you’ll see that it says uh is a keyword from source level 9 Onwards so yeah you you can’t do that anymore you used to be able to but not anymore so yeah obviously we still have these errors so let’s just go ahead and create our block entity class i’ve just created a new package in our block package for entity And i’ll call this toilet block entity okay and this is simply just going to extend block entity there we go and let’s add the constructor now we’re actually just going to want to change this constructor so we’re going to want to get rid of this block entity type right there Let’s rename these to pause And state and then in here we just want to super off our block entity type so that is block nc init dot toilet and then obviously dot get to actually get the type let’s just go back into our init and make sure we import this class so that we can Get rid of some errors um it doesn’t like that did i do something wrong here possibly let’s go into our block class and make sure we import it here all right this tick method doesn’t exist yet that’s fine but why is this giving me um an issue So supplier of blocking c type dot builder dot of and then toilet block entity click on new right of course so we are actually just creating a builder here we need to build the builder to actually give us the block entity type now you can see this takes in a type and That is basically for the data fixer now data fixes is basically what mojang uses to allow things to persist between versions so when you update version it can stay you don’t have to you know create a new world it will basically fix the data for the new version and make it work now We can’t really implement this um just because forged i believe doesn’t really work that way and data fixes are a pain to work with there’s like a massive essay on how they work and everyone’s too lazy to look through them so instead we can just pass in null in here And there’ll just be a null data fixer that’s that’s perfectly fine it does expect no that’s okay now this tick method doesn’t exist but we can close that class for now uh actually yeah we’ll close that class for now and we can close our block entity in it Oh while i remember let’s make sure we call our block entity in it here so let’s go block entity in it dot block ends tease dot register and bus just before we forget about that okay first thing let’s do in our block entity class is create this tick method So let’s have a public void tip this is obviously as i say only if you have a tick method you can also if you wanted to you could do implements block entity ticker and toilet block entity And then you could add the unimplemented methods and then you have the tick method in here you could do that and obviously just return that inside of here so you could just return uh block entity you could do that if you want or that doesn’t work but um Yeah something like this i’m not exactly sure why this isn’t working i think i’m just being stupid oh right yeah so you need to do But yeah anyways basically that um but i’m not gonna do that because i don’t see the point in having these parameters here we already have access to all these things in the class itself so we don’t need these that’s just you you there’s many ways you can implement the ticker this is Just how i like to do it it makes more sense having a tick method no parameters because we don’t need parameters we have all of the stuff already from block entity so yeah it’s a little weird how that whole system works but that’s just how it is Okay the next thing we’re going to want to do let’s add the reading and writing so obviously the main thing with block entities is being able to read and write some nbt mbt is just basically data that you can save into this specific object so loading is obviously uh reading it From the mbt and saving it is just writing it to the mbt um yeah so these are called any time these need to happen which is actually more often than you may think um so obviously we just fill these out with any mbt data we want to save Now i’m going to go ahead and actually implement this uh seat block seat entity into this block entity so that i can just save that data so i’m going to go ahead and do that real quickly okay so i’ve gone ahead and done that All now um and here it is so i’ve also gone ahead and saved everything to the mbt as well so i’m just using a list tag for this since there’s no way to save a map um and here i’m just using get list but this takes an integer which is for the Type that is saved to the list so i’m using tag compound but you can also see there’s a bunch of different options here so yeah fairly simple uh i’m just saving that’s the map in here and i’m just adding it to the list here and then Putting it back into the mbt which will save it um yeah all of that is done now the final thing we need to go ahead and do is we need to well we don’t need to do that this is actually it this would work perfectly fine however if we Wanted any of this data on the client side say that we were using a gui which i will be doing soon then we need to go ahead and make sure we sync this data to the client side and the reason being if we check our block class We can go ahead and see Right here now if it’s client-side we just return null for the ticker and in this used method we only run this if it’s not client-side of its server-side so all of this basically here is aside and if we wanted any of this client side we currently won’t be able to do that it Would all be server side and on the client side it will just all be the default stuff so if you need it on the client side you need to go and sync it now i don’t need any of this on the client side however i’m going to do it just for demonstration purposes So let’s get started now syncing to the client is very very very simple it is way way way simpler than it sounds so there are three ways let’s just say there’s two ways to sync to the client and that is syncing on the chunk load so whenever the chunk loads And there is syncing every time there’s a block update Now there isn’t a third way and that is syncing with a custom packet so when something happens on the client you might want to or when something happens on the server you might want to then update the client or vice versa but we’ll just cover the first two ways And we can do the packet in a future tutorial on say capabilities so let’s do first on the chunk loading and there’s two methods for this and let’s let’s actually override all these methods so this handle update tag and there’s get update tag now get update tag will happen When the uh chunk loads essentially and this will just create a compound tag that is sent to clients and that is received in handle update tag so yeah so it’s gotten from here and it’s received from here now all we need to do in these methods Is this one we need to save the mbt and this one we just need to load the enmity back so it’s as simple as it sounds to be honest in here we just want to save of a new compound mbt or compound tag isn’t it yep and then in handle update tag Simply just load tag as simple as it can be then if you want to synchronize on block update which you most likely do want to do there are two more methods that is get update packets and on data packets so this happens when there is a block Update for example uh if you set block um with the update flag then this will these methods will be called so obviously it’s the same as uh on chunk load essentially however you’re handling with the packets directly so for get update packet you just want to return a new Client bound block entity data packets and this takes in the position first so this got world position then it takes in an id now this is just a vanilla thing you don’t really need to worry about it you just need to make sure it doesn’t conflict with a vanilla id And the way to do that is just to set it to negative one you could also set it to zero but negative one is safer so that’s how i like to do it and then we just want to do save and that will be a new compound empty now let’s say In fact for both of these let’s say there was only specific data you wanted to sync which ideally you would do you would only save specific data and the way you could do that is just simply creating this um tag up here so let’s say um Bar tag is equal a new compound tag and then you would just write your data to this tag so put int um beans ticks for example so say you only wanted to save ticks let that go let that go there it is so say you only want to do That and then you can just put in tag here ideally you would do that you would only save or you would only sync what you need to sync but i’m just going to call save it makes this whole demonstration a lot easier and where’d that go It keeps moving around okay there we go so that is get update packet that happens when the block update happens and then on data packets is when that same packet has been received and here obviously you would just load it so you would load your specific data But since we’re just using save we just can call load and that would just be packet.get tag very very simple um yeah yeah that’s it actually so you need to make sure you’ve done the lang the block model the block state the item model etc etc uh textures Of course if you have any um and yeah let’s go ahead let’s run the game and let’s see if it works here we are we are in the game let’s place down our beloved toilet absolutely fantastic model i know i spent a very long time on this model I actually didn’t spend very long on it but that’s not the point uh we should be able to sit on it it’s not perfect i mean you can see you can kind of turn around a little bit it’s a little bit glitchy but it does work Uh the aim was just to make sure the head stays in the right place uh that is fine now i can get off it by pressing shift and if i click on it again it does that now you should be able to see if i shift right click It says i have shifted two times and if i do it again now it’s three times fantastic now if i save and quit okay and as you can see if i shift right click you can say you can see it still says three times and obviously if i Reload the game that will stay there as well i can also spam click on it nothing really happens as of yet fantastic but yeah i intend to do a tutorial very soon on key binds so i’ll be able to press uh f or s because s it doesn’t do anything right now uh Yeah no keys actually do anything other than shift or and slash of course um but yeah i’ll be doing a tutorial on keybinds soon and we should be able to change some stuff with the toilet when that happens so that will be very exciting so yeah i hope you guys did find this Tutorial useful if you did please do be sure to smash your face into that like button and subscribe if you really enjoyed please do be sure to share it and uh yeah i will see you guys in the next tutorial good bye [Applause] [Applause] You Video Information
This video, titled ‘1.17/1.18 Minecraft Forge Modding Tutorial – Block Entities’, was uploaded by TurtyWurty on 2021-11-20 17:30:23. It has garnered 4166 views and 98 likes. The duration of the video is 00:29:39 or 1779 seconds.
In this video, I cover how to make a block entity (more often referred to as “tile entity”) and save some data, as well as how to sync the data to the client.
Join my Discord Server, to receive support with your modding related questions: https://discord.gg/jCTnnhxc7J My CurseForge where you can find my released mods: https://www.curseforge.com/members/realturtywurty Github Repository: https://github.com/DaRealTurtyWurty/1.17-Tutorial-Mod