Jump to content

[1.7.2] general questions about log blocks/blocks with meta


pryingtuna85649

Recommended Posts

I'm sorry if these are really stupid questions, but it's something I've been wondering about and unable to find an answer to.

 

So I created custom logs for custom trees. My code works, but the issue I ran into was that I had 5 logs I wanted to create. This doesn't seem like it should be an issue, given that logs are created in an array that are then cycled through in the getSubBlocks method. But when I tried this with 5 blocks (and also rewrote the code in getSubBlocks to account for 5 blocks), it didn't work. What happened was that my 5th log in the array was the texture of the first log. After looking at the vanilla code, I realized there was a BlockOldLog class, which has a string of 4 logs, and BlockNewLog class, which has a string of 2 logs. When I separated my code up similarly (ie, one class with an array of 4 logs, the other with an array of 1, since I had 5 custom log blocks I wanted to create), the textures worked. The only thing that I know isn't right about it is for some reason (despite being a separate class), my 5th log's name (before registering it in my lang file) shows up as the first log from the class with 4 logs.

 

That might be confusing...sorry. But for anyone who followed the description, have you ever heard of this? What's going on with this? My leaf class is doing the same, except it will only take an array of 2, but my sapling class doesn't have this problem. I also created dirt and grass without needing multiple classes.

 

Another question...and I really hate asking this because I think I already know the answer (but I'm of course going to ask anyway)...I'm creating biomes that I want to have my custom grass as the top block and custom dirt as the filler block. I've created my grass and dirt by cycling through a string, as I said above. When I'm setting my this.topBlock and this.fillerBlock in my biome classes, however, it (as I expected) didn't cycle through the array, but created each biome with the first grass/dirt blocks in the arrays as the top/filler blocks for each biome. Obviously I can't set the this.topBlock equal to the array name and location of the specific block I want it to be...that's an error because this.topBlock requires a block, and the array is a string. But is there some other way to do this? I was trying to think of a for loop or an if loop, but that still leads to the problem of blocks vs strings. The one thing I haven't tried is having my biomes all be in one class as a string to cycle through at the top...but I kinda think that will cause an error since it's biomes and then all my biomes would be the same land layout, but with different colors. Which ultimately, I don't want.

 

Anyway, sorry for the stupid (if even comprehended) questions. And thanks in advance.

Link to comment
Share on other sites

The reason of why you can't have 5 logs is because block metadata is 0-15 (4 bits).

 

Two bits are used for rotation, which leaves two bits for other metadata. 2 bits = 4 combinations.

BEFORE ASKING FOR HELP READ THE EAQ!

 

I'll help if I can. Apologies if I do something obviously stupid. :D

 

If you don't know basic Java yet, go and follow these tutorials.

Link to comment
Share on other sites

OK, sorry for continued stupid questions. I have actually read that about metadata before (and again just now), but metadata has been hard for me to fully understand.

 

While what you say makes sense, I still don't fully understand due to other blocks that use metadata. Leaves are also metadata (unless I'm farther off in understanding than I thought), but I can only have 2 separate leaves per class. The leaves don't have rotation like logs do, so I don't understand why those classes only work with 2 blocks per class. Meanwhile, my grass and dirt blocks allow for all 5 blocks in one class.

 

Do you have a good resource for how metadata works? I've looked through this several times: http://www.minecraftforge.net/wiki/Metadata_Based_Subblocks, but I can't apply what is explained there to what you have said. The pieces just aren't coming together yet. Or something is missing.

 

Also, I've looked at code from other mods to get an idea at how other people have done things (not to copy...I WILL NOT plagiarize code...but it does help me put the pieces together and understand concepts better from seeing how others have done things...as well as exposes me to new concepts sometimes), and I've seen others who have registered more than 4 logs in one class. Which is also why I'm confused.

 

Thanks for the help. I really appreciate it.

Link to comment
Share on other sites

Okay, I'll try explain block metadata as best as I can.

 

Block metadata is exactly 4 bits. That is, from 0000 to 1111. Once you have four logs registered, since they all have 3 rotation values, then you'd have something like this:

 

Two of the bits would be used to determine the log type (00, 01, 10, 11), and the other two for rotation (00, 01, 10). This leaves you with exactly one more possible combination (1111), and that can't store enough information about a log.

 

Leaves use metadata for their type (again assuming 4, that's 2 bits). I believe they also use a bit for whether they were naturally placed or not, to know whether or not they SHOULD decay, and maybe another bit to flag that decay needs to happen.

 

If someone registered more than 4 logs to a single block, then they are either using a tileentity, or ignoring rotation.

BEFORE ASKING FOR HELP READ THE EAQ!

 

I'll help if I can. Apologies if I do something obviously stupid. :D

 

If you don't know basic Java yet, go and follow these tutorials.

Link to comment
Share on other sites

Cool, thanks for the explanation! That does make a bit more sense now. So when this (for lack of better words) translates to code, does this mean that each method takes up a bit? Because the decay and placement of leaves are determined by methods, it sounds like those are parts of the bits (and thus become the metadata?).

 

This is all really abstract, which is something I've always struggled with, so again I apologize for having to clarify so much. *crosses eyes*

 

Link to comment
Share on other sites

Not really.

 

Metadata is stored. It's stored weirdly as an Integer, although it's values are never going to be outside the bounds of 0 and 15.

 

You use bitwise AND, OR and XOR operations to determine things.

 

So say you used the two bits on the right for rotation, and you wanted to see what type of log it was (the right two bits).

 

You'd take the metadata and use a bitwise AND to do checks.

 

Say you had the last type of log (11**) and the highest rotation value (**10). It's metadata would've been 1110. That translates to 8 + 4 + 2 = 14.

So you would do metadata & 12 (1100), which would give you back 12 (1100). You'd then know for certain it's the last type of log. Take a look at the maths in the vanilla log classes.

BEFORE ASKING FOR HELP READ THE EAQ!

 

I'll help if I can. Apologies if I do something obviously stupid. :D

 

If you don't know basic Java yet, go and follow these tutorials.

Link to comment
Share on other sites

Metadata might seem mysterious if you don't understand why they did it and if you aren't familiar with bit representations of data.

 

The makers of Minecraft had a bit of a problem -- the number of blocks in the world is very large.  Think about just a 10 x 10 x 10 block of dirt blocks -- it has 1000 blocks in it.  In a Minecraft world there are actually over a quadrillion blocks (if you include air blocks which you should because Minecraft has to process air too).  So if you had a Java instance for every block, performance and memory space would be big problems.  To solve this, they did several things, such as dividing the world into chunks that only appear when needed and they also used a single instance of each block class and instead just recorded the placement of each block in a giant "array".  That wasn't enough though because to make Minecraft interesting some blocks needed to be able to have a bit of change -- a door needs to open, torches need to attach to a wall, etc.  So they wanted some unique data for some blocks; however it couldn't be too much so they decided to use only four bits of data for each block.  That is what they call "metadata".  With that metadata, the coder for a block is free to do what they want -- they can use it for different types of wood, or they can use it for the rotation of a ladder, or use it to show whether a door is open or closed.  To see the list of metadata uses in Minecraft see this wiki: http://minecraft.gamepedia.com/Data_values#Data

 

One problem though is that the metadata was used inconsistently by the programmers of Minecraft.  Especially irritating (if you're trying to code algorithmically like making structures) is rotation.  For example, a piston uses 2 for north, 3 for south, 4 for west, 5 for east, while a door uses 0 for west 1 for north, 2 for east, and 3 for south.

 

Anyway, you should read the link of data values as it gives you a good idea on all the uses for meta data.

 

Next you need to understand binary bit representations of numbers.  If you want to represent something that has two states (like door open or door closed) you can use one bit.  But that bit can be in different locations (place values) in the data.  So the bit being 1 could actually mean a value of 1, 2, 4, or 8.  For doors it turns out that it uses the thrid place value so door open is value of 4.  What gets tricky then is the combination of bit values.  You can't just test if the metadata == 4 because the other bits might be different values for other reasons (in case of door the other bits are rotation).  So an open door might actually have a metadata value of 4, 5, 6, or 7 -- those are all open doors!  What you need to do then is to "mask" the bits before you test them.  This requires "bit-wise" operators.  To learn about these you really need to read up and study it, but as an example to test if the door is open it is easiest if you make sure all the other bits are 0 by doing a bit-wise AND operation on the value before you test it.  So you would do: if ((metadata & 4) == 4).  The bit-wise & function only has a bit high in same position as the door open bit so it forces all the other bits to zero and then you can just test against the door value.  Hopefully you already know all this, but if not it takes some study to get comfortable.

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

Link to comment
Share on other sites

You could conceivably store up to 5 block types in meta data along with rotations considering that logs only allow for 3 axes (X, Y, and Z orientation) Y means log is vertical, X and Z point log along that axis.

 

So, given metadata range of 0-15, you could encode 3 orientations by 5 subtypes in a block. You would have to do the math or use a array though to get and set metadata and subtypes.

Link to comment
Share on other sites

@ShieldBug1 - Thanks for the response. Combined with jabelar's response, that helped a lot. I've looked several times at the vanilla log class, but the math never made sense because I never understood what was going on with the metadata (despite googling it multiple times). I couldn't find any explanations that cleared the fuzz for me.

 

@jabelar - Your explanation is gold! That kind of breakdown is what I needed. Thanks A TON! I've seen that list of metadata uses before but I've just never understood it. I've also googled bitwise before, but couldn't make the connection to metadata. I think that's probably because the explanations are typically very abstract and don't give concrete examples (I actually don't like referring to oracle java docs for this reason...it's just not conducive to how I learn, I guess). I will dig into learning about bitwise and binary bit representations more. What you described with the door reminds me of the way a circuit works. Going off of that, I have a quick question. You said an open door might have a metadata value of 4, 5, 6, or 7, but to mask the bits before testing them. So if you are testing a door with metadata value of 5, for example, does that mean it would look like this: if ((metadata & 5) == 4)? I'm about to read more about bitwise right now and concentrate on getting a handle on it more before digging into Minecraft code again, so maybe that's a really stupid question that I'll realize after learning more about bitwise, but right now that's how I'm comprehending it.

 

@sequituri - Thanks for the response. Given what jabelar said, I need a better understanding of bitwise before I can do (and understand) what you are saying. Hopefully it will all be clear soon, though.

 

Thanks again, everyone. This has REALLY helped a ton!

 

 

Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.