A few questions from someone who is learning to mod

  • The FTB Forum is now read-only, and is here as an archive. To participate in our community discussions, please join our Discord! https://ftb.team/discord

Kyle98750

Active Member
Sep 16, 2013
90
32
43
So recently I have decided that I would like to start modding Minecraft and I decided I would start where it seemed logical; Pahimar's Let's Mod Reboot series. This was going fantastic until it well...ended (not really, Pahimar just isn't prioritizing it for very good reasons.) Anyway, Those tutorials were fantastic and I got everything that he was teaching but In my desire to progress further I have come across some questions.
*Be gentle, I'm new at this.
--------------------------------------------------------------------------------------------------------------------------------------------------------------
As far as I know a TileEntity is a type of block that can store more than 4 Bits of data such as a chest or furnace. Yet how do I work with TileEntities? Or better yet, create and do stuff with them.

For example, I looked at the EE3 code to see how the alchemical chest was created, I noticed in the block class this "createTileEntity" method it takes class a world object and a integer for metadata. Does this mean that TileEntities need to be instantiated from a block? If so, why register TileEntities?

I also noticed that all of the items in the chest are written to NBT and read from NBT, do all chests (from other mods/vanilla) do this? If not, what are the advantages of this?

I looked for how to create a item as a fuel. I found a tutorial on the Minecraft Forge wiki but it must be outdated as it asks to initialize a item as a "ItemFuel" and I can't seem to do that. The only thing I can find related to fuel is this "IFuelHandler" interface which just takes burn time. I added it to the item class and It (as I expected, didn't work) So how does one go about doing this?

If I wanted to go about creating a GUI, where would I start, I looked at the "BlockChest" class and noticed this "onBlockActivated" method, I decided to use it in my created block, I successfully made the block, on right click to create a vaniila chest GUI. I traced this "displayGUIChest" method back to EntityPlayer, but it was just an empty method but I found this "openGUI" method, but it was rather confusing, might anyone be able to explain this a bit?

If I wanted to alter the world generation, say play with the way tree's generate, where would I start? Or implement my own generation.

I know that a packet is a piece of data that is sent from the client to the server telling it something. How can I utilize these? What are their uses in vanilla items or maybe in some mod items? How do I handle these, and when do I have to use them?
---------------------------------------------------------------------------------------------------------------------------------------------------------
If I may, I also have a few java related questions / smaller questions about modding. I know java, just as clarification for something I may have not learned.

For this: *EE3 Code
for (int currentIndex = 0; currentIndex < inventory.length; ++currentIndex)
{
if (inventory[currentIndex] != null)
{
NBTTagCompound tagCompound = new NBTTagCompound();
tagCompound.setByte("Slot", (byte) currentIndex);
inventory[currentIndex].writeToNBT(tagCompound);
tagList.appendTag(tagCompound);
}
}
nbtTagCompound.setTag(Names.NBT.ITEMS, tagList);
If I am interpreting this right, this is simply cycling through the inventory of a the chest, checking if a slot is null, if it isn't it is writing the item to NBT in the following format: "Slot 1 *Insert the item here"
Only thing I am not quite sure of is the "(byte) currentIndex" I assume this is converting the inventory slot integer to a byte but why in this format? To convert to any other format, say Int -> Float it would be Float.parseFloat(Integer.toString(*Integer)). My point being why isn't it a method call? Like Byte.parseByte()?

I am planning on creating an addon mod for Thaumcraft, how does one go about doing this? Is there an up to date guide about this? *Created a addon mod for anther mod that is

Why are all the variables in forge something like "p_152446_1_"? The code is still very readable, just curious for this one. It's like going "Hello, Meet my friend p_152446_1_!", it's still a legible sentence, just has me going "lol wut?".
----------------------------------------------------------------------------------------------------------------------------------------------------------
I might add more to this as I get more questions to ask but these are mainly what I am curios of at the moment.

Any answer / help is greatly appreciated. Thanks in advance!

If anyone has a YouTube series (I am a very visual person) that focus's on 1.7.10 modding and explains everything in depth I would very much like watch it. Everything I could find was either outdated or more outdated.
 
Last edited:

Lomeli12

New Member
Jul 29, 2019
25
0
1
Alright, there's a lot to cover here, some of which I don't even know, so I'll just cover the ones I do know.
Yet how do I work with TileEntities? Or better yet, create and do stuff with them.
You'll need a block that either extends BlockContainer instead of Block or implements ITileEntityProvider and a TileEntity class (which is just a class that extends TileEntity).
For example, I looked at the EE3 code to see how the alchemical chest was created, I noticed in the block class this "createTileEntity" method it takes class a world object and a integer for metadata. Does this mean that TileEntities need to be instantiated from a block? If so, why register TileEntities?
When a chunk is being loaded and it goes to create the entities for that chunk. It'll try to make a new instance of a class based on an id string stored in the chunk's NBT data. You need to register your tile entities so that when it creates that instance, it uses YOUR tileentity class for YOUR tileentities (it's a bit more complicated than that, but that's the short version of it). The createTileEntity method just gives you a way to have multiple tile entities for a single block class (so like Thermal Expansion has multiple machines that are the same block but with different metadata, each metadata value will give an instance of a different tileentity class corresponding to that machine).
I also noticed that all of the items in the chest are written to NBT and read from NBT, do all chests (from other mods/vanilla) do this? If not, what are the advantages of this?
Every bit of data you want to store in a TileEntity is stored as NBT data.
I looked for how to create a item as a fuel. I found a tutorial on the Minecraft Forge wiki but it must be outdated as it asks to initialize a item as a "ItemFuel" and I can't seem to do that. The only thing I can find related to fuel is this "IFuelHandler" interface which just takes burn time. I added it to the item class and It (as I expected, didn't work) So how does one go about doing this?
Make a FuelHandler class that implements IFuelHandler and register an instance of it in the GameRegistry (EE3 example: https://github.com/pahimar/Equivale...java/com/pahimar/ee3/handler/FuelHandler.java)
If I wanted to go about creating a GUI, where would I start, I looked at the "BlockChest" class and noticed this "onBlockActivated" method, I decided to use it in my created block, I successfully made the block, on right click to create a vaniila chest GUI. I traced this "displayGUIChest" method back to EntityPlayer, but it was just an empty method but I found this "openGUI" method, but it was rather confusing, might anyone be able to explain this a bit
This one is a bit more complicated as it requires multiple things depending on what you do. In short all you really need is a GuiHandler (Example: https://github.com/Lomeli12/Augment...t/lomeli/augment/core/handler/GuiHandler.java), and instance of your mod (just use @Mod.Instance(MOD_ID) in you main class and have a public static uninitialized instance of your mod), and of course a Gui (extend GuiScreen). If you're Gui is gonna display an inventory of any form, you'll need your Gui to extend GuiContainer and have a Container (Example: https://github.com/Lomeli12/Augment...eli/augment/inventory/ContainerRingForge.java). Then you just register your GuiHandler in the NetworkRegistry. To open your Gui, you'll have to use player.openGui(), which takes your mod instance, an id for the gui, and the self explanatory world and x,y,z positions. In the case of blocks, you usually use the onBlockActivated method as that is called when the player right clicks.
If I am interpreting this right, this is simply cycling through the inventory of a the chest, checking if a slot is null, if it isn't it is writing the item to NBT in the following format: "Slot 1 *Insert the item here"
Only thing I am not quite sure of is the "(byte) currentIndex" I assume this is converting the inventory slot integer to a byte but why in this format? To convert to any other format, say Int -> Float it would be Float.parseFloat(Integer.toString(*Integer)). My point being why isn't it a method call? Like Byte.parseByte()?
He's just copy/pasting the way the vanilla chest writes items to NBT. You could store the slot number as a string and parse it if you wanted to. Why you would want to do that is beyond me.
Why are all the variables in forge something like "p_152446_1_"? The code is still very readable, just curious for this one. It's like going "Hello, Meet my friend p_152446_1_!", it's still a legible sentence, just has me going "lol wut?".
Either they haven't come up with a name for it during the mapping process (which is MCP's side, not forge) or the javadoc for the method or item already says what it does (which isn't great either but better than nothing)
 
Last edited:

Kyle98750

Active Member
Sep 16, 2013
90
32
43
Thanks for the reply!
I have successfully created two fuels that share the same ID with metadata =D. Yet I am bit confused with creating a gui, I have created the classes you specified, and that all went well. I am just confused with the actual construction of the gui. How is it done? After some Google searching, it seems there might be a bit of OpenGl involved with the gui process aswell.

I made this: https://github.com/WaffleMan0310/ThaumcraftAddon
 

Kyle98750

Active Member
Sep 16, 2013
90
32
43
I think I get the idea now, at least I think, but I keep getting this crash whenever I right click on the block in game:
java.lang.NullPointerException: Ticking memory connection
at net.minecraft.inventory.Slot.getStack(Slot.java:88)
at net.minecraft.inventory.Container.getInventory(Container.java:67)
at net.minecraft.inventory.Container.addCraftingToCrafters(Container.java:53)
at cpw.mods.fml.common.network.internal.FMLNetworkHandler.openGui(FMLNetworkHandler.java:88)
at net.minecraft.entity.player.EntityPlayer.openGui(EntityPlayer.java:2501)
at com.WaffleMan0310.ThaumcraftAddon.Blocks.BlockArcaneChest.onBlockActivated(BlockArcaneChest.java:33)
at net.minecraft.server.management.ItemInWorldManager.activateBlockOrUseItem(ItemInWorldManager.java:409)
at net.minecraft.network.NetHandlerPlayServer.processPlayerBlockPlacement(NetHandlerPlayServer.java:593)
at net.minecraft.network.play.client.C08PacketPlayerBlockPlacement.processPacket(C08PacketPlayerBlockPlacement.java:74)
at net.minecraft.network.play.client.C08PacketPlayerBlockPlacement.processPacket(C08PacketPlayerBlockPlacement.java:122)
at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:241)
at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:182)
at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:726)
at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:614)
at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:485)
at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:752)
I go to the openGui call in the block class and I can't see anything wrong with it, only thing I can derive here is that it is having trouble getting a stack from a slot.
I updated the GitHub so the code is on there.
To confirm my current understanding of what I am doing with Guis, are container classes the things that actually create a inventory in the game while the Gui class is just a way of drawing the actual texture for the chest onto the screen?

On a side note, have you messed with world generation at all?
I added a question about packets to the main post.
 
Last edited:

Kyle98750

Active Member
Sep 16, 2013
90
32
43
I have been working on making particles emit from the block, it was going fine until I tried to change the particles based off of the metadata of the block in the world.
This is the code: http://pastebin.com/zGTnC6Ph
The case it picks is always the first one, which is a metadata of 0. On another note, what is a good example to look at of a block emitting particles from the center of the block? (what I currently have is just copied from the "BlockRedstoneOre" code)

EDIT: My stupid a** didn't know about the ItemBlockWithMeta class, only the ItemBlock. Everything is fine now.
 
Last edited:

ljfa

New Member
Jul 29, 2019
2,761
-46
0
float automatically gets converted to double on assignment. Likewise, if you add int and float the int is converted into float as well.
You can get rid of all those casts. Also it would make sense to use nextDouble there rather than nextFloat.

Edit: Oh I see, that comes from BlockRedstoneOre
 
Last edited:

Kyle98750

Active Member
Sep 16, 2013
90
32
43
I never really got around to loading textures for added stuff into the game and I decided I would do that, so I just made copies of the coal texture and put it in the correct place in the resources directory as placeholder. Yet I keep getting this:

java.io.FileNotFoundException: thaumcraftaddon:textures/items/magicalFuel.arcaneFuel.png

When the path of the image is: C:\Blah\Blah\ThaumcraftAddon\src\main\resources\assets\thaumcraftaddon\textures\items\magicalFuel.arcaneFuel.png ... and so on with other items.

Code:
@SideOnly(Side.CLIENT)
@Overridepublic void registerIcons(IIconRegister iconRegister){
fuelIcons = new IIcon[Names.Items.FUEL_TYPES.length];
for (int iconIndex = 0; iconIndex < Names.Items.FUEL_TYPES.length; iconIndex++) {
fuelIcons[iconIndex] = iconRegister.registerIcon(Textures.RESOURCE_PREFIX + Names.Items.MAGICAL_FUEL + "." + Names.Items.FUEL_TYPES[iconIndex]);}
}
 

Kyle98750

Active Member
Sep 16, 2013
90
32
43
So I have been playing around with custom block rendering and have been trying to create a render that creates the texture for a block based off of vanilla textures. I created some fuel items and blocks to correspond with them, and have created the custom render fine. The only thing I am having a problem with is exactly how renders tell that tessellator what texture to use. I've been trying to tell it to use a specific texture but can't seem to find out how to tell it that. I tried using bindTexture in the Minecraft render engine but it doesn't seem to be acknowledging my bind. I am using a ISBRH. My code thus far:

http://pastebin.com/szQhyWDE

I have disabled the standard block render in pass 0 just for testing purposes, it works fine.

I was playing with the U and V values for the item render and changing them all to say " + 0.25F" would result in the nether wart texture rendering on the given block face. This would leave me to believe that the Tessellator is using the vanilla texture map...
Anyone ever done something like this before, or knows what I am doing wrong?

Picture of the texture that keeps coming up:
1e89rt3.png

The coal texture is purposefully done by me, the blue tint with that thing in the corner is the result of the overlay that is supposed to be the texture of the item the block represents.

As it turns out, it if I register the texture in the block class to the item I want to overlay, it works fine, I guess the renderer does not like projecting item icons onto blocks?
 
Last edited:

FyberOptic

New Member
Jul 29, 2019
524
0
0
You can't typically change the bound OpenGL texture during chunk rendering. Tessellator calls insert vertices into a buffer, which is rendered as a vertex array during Tessellator.draw(). That's not called until an entire chunk segment (16x16x16) is rendered out, meaning every block has to use the same OpenGL texture. Changing it changes all blocks in that segment.

This might sound like a nuisance, but it's actually a huge benefit to performance because texture swaps are expensive, and we don't want every mod switching to its own textures anymore. Minecraft deals with this by stitching each individual block texture file into one large atlas at startup (or a resource pack refresh with F3 + T), and then selects the texture it wants via UV coordinates. The same happens for items, in their own atlas. If you want custom textures to be stitched into the atlas, you need to register them via Block.registerBlockIcons. You'll get a handle back to an IIcon, which will provide you the functionality you need to obtain the UV coords to use during rendering.

You can get the IIcon that vanilla (or any) blocks use in your ISimpleBlockRenderingHandler class via various RenderBlocks.getBlockIcon kinds of methods, since you get a RenderBlocks object as a parameter. RenderBlocks also lets you render out individual block faces and stuff without having to deal with UV coordinates directly, though perhaps you're just playing with direct tessellator use intentionally to learn how it all works, in which case never mind!

It's worth mentioning that Forge has removed all of this in 1.8. No tessellator access, nothing. Not even a post chunk render hook. You can't do custom block rendering at all. Best you can do is spit out pieces of models. So you might want to remember that in case you decide to move on to 1.8 any time soon, unless you're good with adding your own ASM hooks.
 

Kyle98750

Active Member
Sep 16, 2013
90
32
43
I've been reading that 1.8 isn't even worth moving to, that there is a lot of JSON fidangling and other things that make it harder than modding 1.7 or prior.
 

Lomeli12

New Member
Jul 29, 2019
25
0
1
I've been reading that 1.8 isn't even worth moving to, that there is a lot of JSON fidangling and other things that make it harder than modding 1.7 or prior.
It's not too bad. The fiddliness really comes from not being able to control item/non-tileentity block rendering and blockstates, but if you're clever you can get around some things. *shameless plug* Like me rending models without dealing with JSON using 1.8's layer system.
B_HbY1GU0AA4-Xe.png:large
 

Kyle98750

Active Member
Sep 16, 2013
90
32
43
Does that mean that you cannot use techne models or obj models for blocks or mutliblocks? Could you provide an example of something that would not be possible in 1.8, ex. something in 1.7 due to the changes?
 

ljfa

New Member
Jul 29, 2019
2,761
-46
0
Does that mean that you cannot use techne models or obj models for blocks or mutliblocks? Could you provide an example of something that would not be possible in 1.8, ex. something in 1.7 due to the changes?
It is not easily possible to render things programmatically. As it is now, every possible look of a block has to be set in stone rather than dynamically generated.
Think blocks with connected textures. Each face of such a block has at least 16 possible different textures, so you end up with 16^6 = over 16 million block states for all six faces. And you can construct even more ridiculuos examples.
Having one JSON file with for each possible render state would be insane.
 

Kyle98750

Active Member
Sep 16, 2013
90
32
43
Why not just generate the JSON files programmatically? Sure 16 million files is a lot, but storage is becoming increasingly larger so why not? XD
 

PhoenixSmith

New Member
Jul 29, 2019
649
-8
1
Why not just generate the JSON files programmatically? Sure 16 million files is a lot, but storage is becoming increasingly larger so why not? XD
Some mods like Buildcraft would take upwards amoutnt of N-bytes just for pipes... So untill a fix is found we are going to be waiting for the a larger mods to update to 1.8. Talking from my recent endeavors in 1.8, the jsons are not that bad. Maybe 5+ minutes of fiddling per block and less for items. (Blocks need 3 jsons [blockstate, block model, item block model] items only 1)
 

FyberOptic

New Member
Jul 29, 2019
524
0
0
You can still generate blocks dynamically in 1.8, but you have to do it in the form of model components, like baked quads and crap, through a system which can result in multi-threading issues if you don't use it right, doesn't provide you easy access to the tile entity or anything unless you understand how to get it into your custom model renderer, and takes more CPU and RAM to work with than if you could just make direct tessellator calls like 1.7.10.

Rendering isn't the only thing Forge is doing wrong for 1.8, but it's a big one. Just stick to 1.7.10 for now until they start listening.
 

Kyle98750

Active Member
Sep 16, 2013
90
32
43
That sucks although the improvement in Minecraft's rendering engine as a whole is one is a very good one, there seems to be many problems interacting with it, I guess. Anyways back on topic ... I was getting the custom render working and all but then I came across a problem with textures for certain sides. The top, north and west sides show the texture, but the rest don't, I took away the block texture itself and the textures for those sides are only rendered when you are looking through the block from a side that does render, heres a picture:
dUNMp7c.png

And the class: http://pastebin.com/KmHW9yEz

Another issue I was having was with creating inventories. It seems that the container class is just adding duplicates of 1 slot, over and over again. Maybe it has something to do with the method that I created to do it for me? *shrug
Class: http://pastebin.com/u6eRwBej

Also, #BringBackTessellatorCalls , I don't usually make those things, did I do it right? ;)
 

ljfa

New Member
Jul 29, 2019
2,761
-46
0
As far as I can tell you are not initializing the ARCANE_STORAGE_ARRAY. All the entries are zero there, that's why all the slots refer to position zero.