Saturday, 21 November 2015

Redstone


There are a few important concepts to keep in mind with Redstone.

In general, there are two types of redstone blocks:
  • power providers, such as redstone blocks (BlockCompressedPowered), buttons, levers, daylight sensors
  • power consumers, such as redstone lamp (BlockRedstoneLight), BlockDoor, BlockNote
Some blocks are both, such as redstone torch and redstone repeaters.  

Power providers

Power providers can provide power to other blocks in two ways:
  1. “Weak power” – every block adjacent to the power provider is powered.  For example – in the picture below, when the lever is on, all adjacent lamps (south, north, west, east, up, down) will turn on.
  2. “Strong power” – when the power provider is attached to a suitable block, it causes that block to provide weak power to all of its neighbours.  For example – the button provides strong power to the stone block, and the stone block provides weak power to the adjacent lamps.

Weak power - when activated, the lever provides weak power to the adjacent lamps (in this case north, south, east, west)


Strong power - when activated, the button provides strong power to the stone it's attached to.  The stone then provides weak power to the adjacent lamps.

The amount of power provided is from 0 (no power) to 15 (max power), using the following Block methods:
isProvidingWeakPower(IBlockAccess worldIn, BlockPos pos, IBlockState state, EnumFacing side)
in [1.8.9] this is now:
getWeakPower(IBlockAccess worldIn, BlockPos pos, IBlockState state, EnumFacing side)
For the example in the picture below:
BlockCompressedPowered.isProvidingWeakPower(
  world, 
  redstone blockpos, 
  minecraft:redstone_block, 
  EAST)
When this method is called for the redstone, it returns the weak power level (i.e. 15) it is providing to the adjacent lamp.
EAST means that the redstone is to the EAST of the lamp.
pos and state are the position and state of the redstone, not the adjacent lamp.

Redstone block provides weak power to the lamp

isProvidingStrongPower(IBlockAccess worldIn, BlockPos pos, IBlockState state, EnumFacing side)

in [1.8.9] this is now: 

getStrongPower(IBlockAccess worldIn, BlockPos pos, IBlockState state, EnumFacing side)

For the example in the picture below:
BlockButton.isProvidingStrongPower(
  world, 
  button blockpos, 
  minecraft:wooden_button[facing=east,powered=true], 
  EAST)
When this method is called for the button, it returns the strong power level (i.e. 15) it is providing to the adjacent stone block.
EAST means that the button is to the EAST of the stone
pos and state are the position and state of the button, not the adjacent stone.

Button provides strong power to the stone.  This will cause the stone to provide weak power to all of the stone's neighbours.

canProvidePower()
– return true!

Optional methods that can help you tweak your block’s behaviour

canConnectRedstone(side)
- redstone wire will connect to the given side

shouldCheckWeakPower(IBlockAccess world, BlockPos pos, EnumFacing side)
This method is called when Forge wants to know the power level of this block  Actually it is named backwards!  A block which can be strongly powered (eg by an attached lever or button) should return true here.  This lets you override the vanilla assumption that a block can be strongly powered if (and only if) it isNormalCube().

  • If you return true: Forge checks whether this block is being strongly powered by any of its neighbours.  If not, the power level is zero.
  • If you return false: Forge instead checks whether this block itself is providing weak power.

Power consumers

A power consumer is a block which reacts to nearby power providers.   The propagation of power is by “pull”, not push – i.e. The consumer is responsible for requesting information from its neighbouring providers, not the other way around.  It usually does this in one of two ways-

  1. For non-direction blocks such as Redstone Lamp-
    a. World.isBlockPowered()  for an on/off answer; or
    b. World.isBlockIndirectlyGettingPowered() if they need to know the strength [0 – 15]
  2. For directional blocks such as Redstone Torch or redstone repeater-
    a. World.isSidePowered(facing) for an on/off answer; or
    b. World.getRedstonePower(facing) if they need to know the strength [0-15]


The typical sequence is as follows, with example picture below.

  1. An event occurs which means the redstone power needs to be recalculated.  In many cases, this is caused by a change in the power provider – for example the user pushes the BlockLever -> onBlockActivated(), or the user smashes the BlockLever -> breakBlock() or similar.  The block method will typically then call world.notifyNeighborsOfStateChange().
  2. All neighbouring consumers (such as the Redstone Lamp) will then call world.isBlockPowered(BlockPos) with their own blockpos to discover whether they are being powered, either weakly or strongly.  This check usually happens in onBlockAdded, onNeighbourBlockChange, and updateTick
  3. The call to World.isBlockPowered for BlockRedstoneLight will then check its neighbours (in this case- the unattached lever, and the stone):
    a. Check if the neighbour is providing weak power (the unattached lever).
    b. Check if the neighbour can be strongly powered (yes - the stone), and if so, check if the stone has any adjacent blocks which are strongly powering it (the button attached to the stone).
  4. The BlockRedstoneLight will then change its state/ perform some action as appropriate depending on whether it is being powered or not.

The glowstone can be powered by weak power from the lever, or alternatively the strong power from the button can make the stone emit weak power to the glowstone.

Comparators

Comparators function slightly differently from other redstone.  The input to a comparator might be from a block that is two positions away with an isNormalCube() in between – for example the comparator senses the level of water in the cauldron, with a stone block inbetween.

The comparator senses the cauldron water level from two blocks away.

To create your own comparator (BlockRedstoneComparator is the only vanilla example), you should implement
getWeakChanges()
 - return true.  This ensures that your comparator will be informed of a change two blocks away, instead of only for adjacent blocks.


Blocks which can be used as the input for a redstone comparator (eg BlockCauldron) should implement the following methods·

hasComparatorInputOverride() 
return true

getComparatorInputOverride(World worldIn, BlockPos pos)
return the value [0..15] to be used by the comparator


Some notes about server/client and IBlockAccess


  • You may have noticed that the most important redstone methods (eg isProvidingWeakPower() and isProvidingStrongPower()) give you an IBlockAccess instead of a World.  This poses a few restrictions on the methods you can run in there.  Most importantly, it generally means that you must rely on stored power level information rather than trying to calculate it from adjacent block power levels.  Vanilla usually stores the power level in the metadata, for this reason.  The major exception is the comparator, which uses a TileEntity to store the power level (and retrieves this information during the call to isProvidingWeakPower()).  I think this is probably done for a good reason, eg to stop infinite loops from two adjacent blocks calling each other recursively, or perhaps to make sure that the redstone propagates the same way regardless of which order the neighbour blocks update in.
  • Most of the methods relevant to redstone run on the server only - for example updateTick(), onNeighbourBlockChange() - calculation of signal strengths and propagation of power is done on the server only.
  • If your client side needs to know about redstone signal strength for rendering your block correctly, you need to use some way of communicating it to the client.  Vanilla usually does this by storing the power level as metadata (BlockRedstoneWire), or sometimes by changing the block (eg BlockRedstoneLight).  These are automatically synchronised from server to client. 
  • You might think that you could change the block's appearance during render using Block.getActualState() or ISmartBlockModel using getExtendedState() to query the redstone power based on the block's neighbours. Unfortunately this doesn't work.  The reason is that these methods are provided with an IBlockAccess instead of a World; block rendering is multithreaded and is performed on a cached copy of the world, which only stores some of the information.  This cached copy is accessed through IBlockAccess and gives no direct access to weak power methods.  It could be done by storing the redstone power in the block metadata, which would leave no room for any other information (for example- which way the block is facing).  
  • As an alternative, you can attach a TileEntity to the block - the TileEntity is rendered every frame in the client thread - it has a reference to World which you can use to access all the redstone power methods also on the client side.  Although you could use this trick to access World during a call to Block.getActualState() or getExtendedState(), I wouldn't recommend it, because this might lead to the rendering thread accessing the same objects as the client thread without any synchronisation, which is usually a recipe for disaster (i.e. crashes and other weird glitches that are very hard to debug).

Further information

For some more useful background information about redstone devices, see here.  (NB the terminology he uses for "weak" and "strong", "powered", "indirect" doesn't really match the Forge conventions).

Sample Code
Some working examples to illustrate these concepts.







Friday, 24 July 2015

Entity Rotations and Animation

This post is just some notes about Entity Animation and Rotations which I had to learn the hard way and might be of interest.

If you are using an EntityLivingBase, it has a few key variables which determine where it is rendered and which way it is facing.  An EntityLivingBase usually has

  • a body which can rotate left<-->right ("yaw"); and
  • a head which can rotate left<-->right ("yaw") and tilt up<-->down ("pitch")




Minecraft variables used for head orientation.

  • The position of the Entity is given by posX, posY, posZ, which corresponds to the centre of the body, at the entity's feet.  In order to get the entity's eyes you need to add Entity.getEyeHeight() to the Y position.
  • EntityLivingBase uses four variables related to the rotation of the Entity:
  1. rotationYawHead, which indicates which way the head is pointing left<-->right.  0 degrees is south and increases clockwise.
  2. rotationPitch, which indicates where the head is looking tilting up/down.  0 degrees is horizontal, -90 is up, 90 is down.
  3. renderYawOffset, which indicates which way the body is pointing, similar to rotationYawHead.  It is used for rendering.
  4. rotationYaw, which indicates which way the body was pointing when it last moved.  This is similar to renderYawOffset, however it is used in different ways not directly related to the way the entity is rendered.
In most cases, these variables are updated in a couple of key methods & classes
  1. EntityBodyHelper (deobfuscated version here) is used to update the body and head rotations:
    a) if the entity is moving, the body is instantly rotated to the direction of movement (rotationYaw).  The head yaw is rotated if necessary to match the body yaw within +/- 90 degrees (i.e. the head must not be twisted past the shoulders)
    b) if the entity is not moving, after a short delay the body is slowly rotated to the direction that the head is facing (rotationYawHead)
    This code is executed on both client and server.
  2. EntityLookHelper is used by AI on the server side to update the head yaw and pitch:
    a) If the entity is looking at a target (another entity, or an [x,y,z] location) then the method sets the head yaw and pitch appropriately
    b) If the entity is not looking at anything, the method slowly returns the head yaw to match the body yaw.
    If the entity is moving, it will also constrain the head yaw to be within +/- 75 degrees of the body yaw.
  3. EntityMoveHelper is used by AI on the server side to set the rotationYaw.
The variables are synchronised occasionally from the server to the client, using for example
S16PacketEntityLook.

When rendering, the variables are used as follows:

RenderManager::
doRenderEntity(Entity entity, 
               double x, double y, double z, 
               float rotationYaw, float partialTicks, 
               boolean showOutline);


this then calls the Entity Renderer:
RendererLivingEntity::

doRender(Entity entity, 
         double x, double y, double z, 
         float rotationYaw, float partialTicks);

This method 
  1. rotates the rendering frame by renderYawOffset
  2. calculates the 'netHeadYaw' (the angle between the head yaw and the body yaw) and then calls setRotationAngles() for the main model (ModelBase)
  3. calls ModelBase.render().
LimbSwing and LimbSwingAmount are animation parameters/timers used for animating the leg positions properly when the entity is moving.

ModelBase::

setRotationAngles(limbSwing, limbSwingAmount, ageInTicks,
                  netHeadYaw, headPitch, 0.0625F, entity);
// 0.0625F is a scaling factor







ModelBase::
render(limbSwing, limbSwingAmount, ageInTicks,
                  netHeadYaw, headPitch, 0.0625F, entity);
// 0.0625F is a scaling factor


Although rotationYaw is passed to the RenderLivingEntity, it doesn't use it for rendering the model.  It is used when rendering some other Entity types, or (for example) when rendering name labels.


Sunday, 24 May 2015

Symptoms of Block and Item model errors [1.8-11.14.1.1441 and higher]


If you haven't already, read this introduction first.

Texture errors

Missing texture errors have been significantly changed in 1441 and higher.  You now get a summary of any texture errors that looks like this

[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]: +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]: The following texture errors were found.
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]: ==================================================
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]:   DOMAIN missingtextures
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]: --------------------------------------------------
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]:   domain missingtextures is missing 2 textures
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]:     domain missingtextures has 1 location:
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]:       mod missingtextures resources at C:\Users\TGG\Documents\mods\test-1441\mods\missingtextures_build_gradle-1.0_build_gradle.jar
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]: -------------------------
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]:     The missing resources for domain missingtextures are:
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]:       textures/blocks/mt_block_texture_wrong.png
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]:       textures/items/mt_item_texture_wrong.png
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]: -------------------------
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]:     The following other errors were reported for domain missingtextures:
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]: -------------------------
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]:     Problem: broken aspect ratio and not an animation
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]:       textures/blocks/mt_block_texture_malformed.png
[10:07:19] [Client thread/ERROR] [TEXTURE ERRORS]: ==================================================


  1. The domain here should match your modid.  If it doesn't, one of your files has a wrong domain name - MT18 here for blocks, MT69 here for items.  If the domain says "minecraft", you have forgotten the domain name - MT19 here for blocks, MT70 here for items.
  2. The resource location shows where Forge was looking for your mod's resources.  If this is not right, your build environment has a problem or your resources folder structure is not right, or (for older Forge versions) you are using IntelliJ 14 and haven't added
    sourceSets { main { output.resourcesDir = output.classesDir } }
    to the bottom of your build.gradle file.
    In all three cases, see here for more information.
  3. For missing resources each of the filenames is either in the wrong place, or you misspelled the filename in your block model file (see MT17 here) or item model file (see MT68 here).
  4. Make sure your 'resources' tree is marked as a source folder. If it is not, it won't be included in the build when you try to test in the dev environment, and ALL your textures and JSONs will be missing.
  5. A broken aspect ratio message - your texture needs to have the same width and height (aspect ratio = 1).
A useful breakpoint for texture errors is here
TextureMap::
public void loadTextureAtlas(IResourceManager resourceManager)
{
...
catch (IOException ioexception)
catch (RuntimeException runtimeexception)
catch (IOException ioexception1)
}
and for older Forge versions
FMLClientHandler::
public void logMissingTextureErrors()
{
    if (missingTextures.isEmpty() && brokenTextures.isEmpty())
    {
        return;
    }
// breakpoint on the following line
    Logger logger = LogManager.getLogger("TEXTURE ERRORS");
    logger.error(Strings.repeat("+=", 25));
    logger.error("The following texture errors were found.");

Other errors

If missing texture errors aren't the problem, look in the error console for messages which mention your block or item's name, eg messages like this:
 [Client thread/ERROR] [FML]: Exception loading model yourmodid:block/my_block_model with loader instance, skipping

Did you find any?  If so, hunt through the list of error message below until you find the one which best matches your symptom, then check the list of common mistakes for that error.

Otherwise, unfortunately you have made one of the many possible mistakes which produce no error messages in version 1441.  I can only suggest you look through the list of common mistakes one by one to see if you have made any of them.  Failing that, ask your question at the forum...  and when you've solved it, post me a comment to tell me what the problem was...

Console Error Messages


 [Client thread/ERROR] [FML]: Exception loading model missingtextures:block/mt14_block_model with loader instance, skipping.
com.google.gson.JsonParseException: BlockModel requires either elements or parent, found neither

Parent tag in your block or item model is missing, see MT14, MT15 and MT60 here.

[Client thread/ERROR] [FML]: Exception loading model missingtextures:block/mt15_block_model with loader instance, skipping
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 3 column 6

One of your json files, probably the block or item model, has a syntax error in it, at the given line and column.  This site can help you fix it http://jsonlint.com/.

[10:08:53] [Client thread/WARN]: Unable to load definition missingtextures:mt10_blockname#normal
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 3 column 6
One of your json files, probably the blockstates file, has a syntax error in it, at the given line and column.  This site can help you fix it http://jsonlint.com/.

 [Client thread/WARN]: Unable to resolve texture due to upward reference: #all in minecraft:models/block/cube_all
One of your block models, which has cube_all as a parent, didn't define the expected texture #all
see MT13, MT16 here

 [Client thread/ERROR] [FML]: Model definition for location missingtextures:mt61_blockname#normal not found
For blocks:
  a blockstates file problem, see MT02, MT07  here
  or see MT05, MT08 here.
For items:
an item model problem, see MT60, MT61, M62, MT63, MT64, MT65 here

 [Client thread/ERROR] [FML]: Model definition for location missingtextures:mt60_blockname#inventory not found
for blocks a blockstates problem, see MT02  here
for items an itemmodel problem, see MT60, MT64 here




Symptoms of Block and Item Model errors [1.8-11.14.1.1334]


If you haven't already, read this introduction first.

Look in the error console for messages which mention your block or item's name, eg messages like this:
 [Client thread/ERROR] [FML]: Exception loading model yourmodid:block/my_block_model with loader instance, skipping

Did you find any?  If so, hunt through the list of error message below until you find the one which best matches your symptom, then check the list of common mistakes for that error.

Otherwise, unfortunately you have made one of the many possible mistakes which produce no error messages in version 1334.  I can only suggest you look through the list of common mistakes one by one to see if you have made any of them.  Failing that, ask your question at the forum...  and when you've solved it, post me a comment to tell me what the problem was...

Console Error Messages


 [Client thread/ERROR] [FML]: Exception loading model missingtextures:block/mt14_block_model with loader instance, skipping.
com.google.gson.JsonParseException: BlockModel requires either elements or parent, found neither

Parent tag in your block or item model is missing, see MT14, MT15 and MT60 here.

[Client thread/ERROR] [FML]: Exception loading model missingtextures:block/mt15_block_model with loader instance, skipping
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 3 column 6

One of your json files, probably the block or item model, has a syntax error in it, at the given line and column.  This site can help you fix it http://jsonlint.com/.

[10:08:53] [Client thread/WARN]: Unable to load definition missingtextures:mt10_blockname#normal
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 3 column 6
One of your json files, probably the blockstates file, has a syntax error in it, at the given line and column.  This site can help you fix it http://jsonlint.com/.

 [Client thread/ERROR]: Using missing texture, unable to load minecraft:textures/items/mt_item_texture.png
One of your block or item model files has a texture filename or domain which is wrong or in the wrong place.  If the error message contains "minecraft:" then you have probably forgotten to include your modid (MT04, MT63).
For common errors around files see here,
Block texture problems here, MT17, MT18, MT19, MT61, MT62, MT63
Item texture problems here, MT68, MT69, MT70.

[Client thread/ERROR]: Unable to parse metadata from missingtextures:textures/blocks/mt_block_texture_malformed.png
java.lang.RuntimeException: broken aspect ratio and not an animation
Your texture needs to have the same width and height (aspect ratio).

 [Client thread/WARN]: Unable to resolve texture due to upward reference: #all in minecraft:models/block/cube_all
One of your block models, which has cube_all as a parent, didn't define the expected texture #all
see MT13, MT16 here

 [Client thread/ERROR] [FML]: Model definition for location missingtextures:mt61_blockname#normal not found
For blocks:
  a blockstates file problem, see MT02, MT07  here
  or see MT05, MT08 here.
For items:
an item model problem, see MT60, MT61, M62, MT63, MT64, MT65 here

 [Client thread/ERROR] [FML]: Model definition for location missingtextures:mt60_blockname#inventory not found
for blocks a blockstates problem, see MT02  here
for items an itemmodel problem, see MT60, MT64 here





Common mistakes with filenames

Many of the block and item model problems are caused by incorrect filenames, or files being placed in the wrong place.

Some notes about getting filenames and folder structure right:

Your project directory structure should look like the one in this example project here.
i.e. src/main/resources/assets/minecraftbyexample/

When you build your project to debug or run it, the resources in these folders will be copied into the build folder
build/classes/main/assets/minecraftbyexample
which is where forge expects to find them.


View from IntelliJ 14

There are a few reasons things can go wrong, usually one of the following:
  1. You have spelled a folder name incorrectly, check very closely!  Check spaces between words!
  2. You have added .json or .png where it's not required, for example
    {
        "variants": {
            "normal": { "model": "minecraftbyexample:mbe01_block_simple_model.json" }
        }
    }
  3. I'm told that underscores(_) are not permitted in texture names. For example, in a model json, the texture path "MODID:items/TEXTURE", TEXTURE must not contain any underscores. It works ok for me, but hey. 
  4. When specifying a resource location, or in one of your json files, you have added the wrong domain, or forgotten it entirely.  This may be obvious from the error message, for example
    java.io.FileNotFoundException: misspelleddomain:models/block/mbe01_block_simple_model.json
    {
        "variants": {
            "normal": { "model": "misspelleddomain:mbe01_block_simple_model" }
        }
    }
    or missing entirely, in which case it defaults to the minecraft domain.
    java.io.FileNotFoundException: minecraft:models/block/mbe01_block_simple_model.json
    {
        "variants": {
            "normal": { "model": "mbe01_block_simple_model" }
        }
    }
    
    
  5. Upper/Lower case must match!  myModFolder is not the same as mymodfolder!
    Your mod ID, all your package names and folder names should be all lower case.  Your filenames can be mixed case if you are careful to be consistent, but it's probably easier to leave them all lower case too.  Especially since if you use GitHub for your project, it ignores your filename case and will cause you all sorts of grief when you try to fix it without realising what's happening.  (Hint: rename myWROngFile.json to dummyname.json, commit, then rename to mywrongfile.json and commit again).
  6. If you are using IntelliJ 14 instead of Eclipse, you should add this line to the bottom of your build.gradle file, otherwise it won't copy your resources to the right place.
    sourceSets { main { output.resourcesDir = output.classesDir } }
    See here for more information.

Troubleshooting Block and Item Rendering (old version)

This is the old version of the troubleshooter (before 1334).

For the newer version, see here.
---------------------------------------------------
It's pretty certain that the first time you try to create a block or an item, it will probably wind up looking like this:

The dreaded missing texture / missing model.

Unfortunately, there are a lot of things you have to get exactly right before your blocks and items will render properly, and it's often not easy to discover what the problem is.

You can find working examples of a simple block (MBE01) and a simple item (MBE10) here.

Alternatively, this troubleshooting flowchart below might help.
**Note*** - it seems that recent updates to Forge have changed the error messages for some of these errors.  If the guide leads you to a dead end, it might be worth checking each of the possible errors to see if it matches yours.  I'll try to update it soonish.

Before you start

If the problem appears after you have been testing your mod for a while, it is worth taking 2 minutes to start Minecraft, generate a new test world, and see if you still have the problem.  Sometimes the remapping of block and item IDs (that happens when you add and remove blocks or items to your mod) can lead to subtle mismatches and very confusing bugs.

Is it a Block problem, an ItemBlock problem,  or an Item problem?

A Block problem will look wrong when you place it in the world, for example

Block problem
An ItemBlock problem will show up when you are holding the block  in your hand or in the inventory.  (An ItemBlock is the Item that represents your Block when it's not in the world, i.e. in the inventory or in your hand.  It is automatically created when you register a Block.)
ItemBlock problem or Item problem
An Item problem looks the same as an ItemBlock problem except that it doesn't have a Block of course.

If you have a Block problem, go to Blocks Step 1 below.
If you have an Item (ItemBlock) problem, go to Items Step 1.
If you have both, solve the Block problem first.

Blocks - Step 1 - Registration

Does your block appear in the creative tabs?  If not, the problem is probably one of the following:
  1. Your Block registration is not being called (must be called during preInitialisation)
    GameRegistry.registerBlock(blockSimple, "mbe01_block_simple");
  2. You have passed the wrong block to registerBlock.
  3. You haven't set the appropriate creative tab in your Block
public BlockSimple()
{
  super(Material.rock);
  this.setCreativeTab(CreativeTabs.tabBlock);   // the block will appear on the Blocks tab in creative}

Blocks - Step 2

If you place your block in the world, can you see it at all?

Invisible block
If you can see the outline, but no block (with or without the blue square), then your Block.getRenderType() is probably wrong.  Either delete it or override to return 3.
// render using a BakedModel (mbe01_block_simple.json --> mbe01_block_simple_model.json)
// not strictly required because the default (super method) is 3.
@Override
public int getRenderType() {
  return 3;
}

Blocks - Step 3 - Check the console for error messages

If you place your block in the world, does it look like this?
Missing block texture / missing block model.
If not, this troubleshooting guide probably won't help you.

If it does look like this, look in the error console for messages which mention your block's name, eg messages like this:
> [22:14:59] [Client thread/WARN]: Unable to load block model: 'minecraftbyexample:block/mbe01_block_simple.json
> [22:15:00] [Client thread/WARN]: Missing model for: minecraftbyexample:mbe01_block_simple.json
> [22:20:06] [Client thread/WARN]: Unable to load variant: normal from from minecraftbyexample:mbe01_block_simple#normal
> [23:12:54] [Client thread/ERROR]: Using missing texture, unable to load minecraft:textures/blocks/mbe01_block_simple_face1.png
java.io.FileNotFoundException: minecraft:textures/blocks/mbe01_block_simple_face1.png

Did you find any?  If so, continue in Step 4.  Otherwise, skip to Step 7.

Blocks - Step 4 - FileNotFoundException?

Does your console contain a FileNotFoundException for your block?
For example

> [22:06:34] [Client thread/WARN]: Unable to load definition minecraftbyexample:mbe01_block_simple#normal
> java.lang.RuntimeException: Encountered an exception when loading model definition of model minecraftbyexample:blockstates/mbe01_block_simple.json
at net.minecraft.client.resources.model.ModelBakery.getModelBlockDefinition(ModelBakery.java:177) ~[ModelBakery.class:?]
> Caused by: java.io.FileNotFoundException: minecraftbyexample:blockstates/mbe01_block_simple.json

If not, go to step 6.  If so, it means that either
  • one of your filenames is wrong, 
  • your block name is wrong (doesn't match your blockstates filename),  
  • one of the filenames in your json files is wrong, 
  • your resources folder structure is wrong, or
  • your resources folder isn't being copied to the right place.

The extra error information will usually tell you what part of the code was looking for the file.  Fix it by looking through the list of causes below.  If you need more help figuring out which part is the problem, see Step 5.

Some notes about getting filenames and folder structure right:

Your project directory structure should look like the one in this example project here.
i.e. src/main/resources/assets/minecraftbyexample/

When you build your project to debug or run it, the resources in these folders will be copied into the build folder
build/classes/main/assets/minecraftbyexample
which is where forge expects to find them.



There are a few reasons things can go wrong, usually one of the following:
  1. You have spelled a folder name incorrectly, check very closely!
  2. You have added .json or .png where it's not required, for example
    {
        "variants": {
            "normal": { "model": "minecraftbyexample:mbe01_block_simple_model.json" }
        }
    }
  3. I'm told that underscores(_) are not permitted in texture names. For example, in a model json, the texture path "MODID:items/TEXTURE", TEXTURE must not contain any underscores. 
  4. When specifying a resource location, or in one of your json files, you have added the wrong domain, or forgotten it entirely.  This will be obvious from the error message, for example
    java.io.FileNotFoundException: misspelleddomain:models/block/mbe01_block_simple_model.json
    {
        "variants": {
            "normal": { "model": "misspelleddomain:mbe01_block_simple_model" }
        }
    }
    or missing entirely
    java.io.FileNotFoundException: minecraft:models/block/mbe01_block_simple_model.json
    {
        "variants": {
            "normal": { "model": "mbe01_block_simple_model" }
        }
    }
    
    
  5. Upper/Lower case must match!  myModFolder is not the same as mymodfolder!
    Your mod ID, all your package names and folder names should be all lower case.  Your filenames can be mixed case if you are careful to be consistent, but it's probably easier to leave them all lower case too.  Especially since if you use GitHub for your project, it ignores your filename case and will cause you all sorts of grief when you try to fix it without realising what's happening.  (Hint: rename myWROngFile.json to dummyname.json, commit, then rename to mywrongfile.json and commit again).
  6. If you are using IntelliJ 14 instead of Eclipse, you should add this line to the bottom of your build.gradle file, otherwise it won't copy your resources to the right place.
    sourceSets { main { output.resourcesDir = output.classesDir } }
    See here for more information.

Blocks Step 5 - tracking down the source of FileNotFoundException 

If you are getting a FileNotFoundException, the console message will also tell you what part of the code was looking for the file.  These are:

Your blockstates.json file is not being found

> [22:06:34] [Client thread/WARN]: Unable to load definition minecraftbyexample:mbe01_block_simple#normal
> java.lang.RuntimeException: Encountered an exception when loading model definition of model minecraftbyexample:blockstates/mbe01_block_simple.json
at net.minecraft.client.resources.model.ModelBakery.getModelBlockDefinition(ModelBakery.java:177) ~[ModelBakery.class:?]
Caused by: java.io.FileNotFoundException: minecraftbyexample:blockstates/mbe01_block_simple.json

Your blockstates file must exactly match the registered name of the block.  It must be stored in the correct folder (see above).

Model name wrong in blockstates file, or model filename wrong or in wrong folder

> [22:14:59] [Client thread/WARN]: Unable to load block model: 'minecraftbyexample:block/mbe01_block_simple_model' for variant: 'minecraftbyexample:mbe01_block_simple#normal'
> java.io.FileNotFoundException: minecraftbyexample:models/block/mbe01_block_simple_model.json
at
> net.minecraft.client.resources.FallbackResourceManager.getResource( FallbackResourceManager.java:70) ~[FallbackResourceManager.class:?]
> [22:15:00] [Client thread/WARN]: Missing model for: minecraftbyexample:mbe01_block_simple#normal
> [22:15:00] [Client thread/WARN]: No weighted models for: minecraftbyexample:mbe01_block_simple#normal

Either the blockstates.json has the wrong name of the model.json file (remember to include the domain using ":"), or your model.json filename is incorrect or in the wrong folder.

Texture filenames incorrect in block model.json file

> [23:12:54] [Client thread/ERROR]: Using missing texture, unable to load minecraftbyexample:textures/blocks/mbe01_block_simple_face1.png
java.io.FileNotFoundException: minecraftbyexample:textures/blocks/mbe01_block_simple_face1.png
at
> net.minecraft.client.resources.FallbackResourceManager.getResource( FallbackResourceManager.java:70) ~[FallbackResourceManager.class:?]

Your block model file has an incorrect filename, or the texture filename is wrong or in the wrong spot.

{
    "parent": "block/cube_all" 
    "textures":{
        "all": { "minecraftbyexample:blocks/mbe01_block_simple_face1" }
} }

Wrong parent model in your block model.json file

> [23:24:26] [Client thread/WARN]: In parent chain: minecraftbyexample:item/mbe01_block_simple -> minecraftbyexample:block/mbe01_block_simple_model -> minecraft:block/cubeerror; unable to load model: 'minecraft:block/cubeerror'
java.io.FileNotFoundException: minecraft:models/block/cubeerror.json
at
> net.minecraft.client.resources.FallbackResourceManager.getResource(FallbackResourceManager.java:70) ~[FallbackResourceManager.class:?]
at net.minecraft.client.resources.model.ModelBakery.loadModel(ModelBakery.java:260) ~[ModelBakery.class:?]
> [23:24:29] [Client thread/WARN]: Missing model for: minecraftbyexample:mbe01_block_simple#normal
> [23:24:29] [Client thread/WARN]: No weighted models for: minecraftbyexample:mbe01_block_simple#normal

{
    "parent": "block/cubeerror" 
    "textures":{
        "all": { "minecraftbyexample:blocks/mbe01_block_simple_face1" }
} }

Blocks - Step 6 - Console errors other than FileNotFoundException

If your texture is missing but there is no FileNotFoundException, it is usually a block variants mismatch problem.  For example

Incorrect variant names in blockstates files

[22:20:06] [Client thread/WARN]: Unable to load variant: normal from minecraftbyexample:mbe01_block_simple#normal
{
    "variants": {
        "not_normal": { "model": "minecraftbyexample:mbe01_block_simple_model" }
    }
}

Variant listing in blockstates.json doesn't match your code blockstate

[22:26:49] [Client thread/WARN]: Unable to load variant: colour=red,facing=north from minecraftbyexample:mbe03_block_variants#colour=red,facing=north

This might be caused by a mismatch in your blockstates.json file

{
"variants": {
       "colour=red,facing=error": { "model": "minecraftbyexample:mbe03_block_variants_model_red"},
        "colour=red,facing=east": { "model": "minecraftbyexample:mbe03_block_variants_model_red", "y": 90 },
       "colour=red,facing=south": { "model": "minecraftbyexample:mbe03_block_variants_model_red", "y": 180 },
        "colour=red,facing=west": { "model": "minecraftbyexample:mbe03_block_variants_model_red", "y": 270 },
     "colour=green,facing=north": { "model": "minecraftbyexample:mbe03_block_variants_model_green" },
 ... etc...
}

or perhaps your  Block.createBlockState() is wrong...
// necessary to define which properties your blocks use
// will also affect the variants listed in the blockstates model file
@Override
protected BlockState createBlockState()
{
  return new BlockState(this, new IProperty[] {WRONGPROPERTY});
}

note also that for blockstates with multiple properties the order  is important, i.e.
colour=red,facing=north 
won't match
facing=north,colour=red

Incorrect filename or resource location in blockstates.json file

[14:14:22] [Client thread/ERROR] [FML]: Model definition for location
      minecraftpoorexample:mbe01_block_simple_model#normal not found
eg
{
    "variants": {
        "normal": { "model": "minecraftpoorexample:mbe01_block_simple_model" }
    }
}

Blocks Step 7 - no console error message

I have only ever seen this happen in two cases:
a) when one of the texture names is missing from the model file.

For example - the cube_all model needs a texture called #all:
{
    "parent": "block/cube_all",
    "textures": {
        "all_wrong": "minecraftbyexample:blocks/mbe13_block_simple_all_faces",
    }
}
i.e. the parent model cube_all defines #all but we haven't provided it.
{
    "parent": "block/cube",
    "textures": {
        "particle": "#all",
        "down": "#all",
        "up": "#all",
        "north": "#all",
        "east": "#all",
        "south": "#all",
        "west": "#all"    }
}

b) when you have forgotten your mod ID from the blockstates file, eg
blockstates.json
{
    "variants": {
        "normal": { "model": "mbe01_block_simple_model" }
    }
}
instead of
{
    "variants": {
        "normal": { "model": "minecraftbyexample:mbe01_block_simple_model" }
    }
}

Blocks Step 8 - No idea.

Ask your question at the forum...  and when you've solved it, post me a comment to tell me what the problem was.

Items Step 1 - Registration

For ItemBlocks this is not relevant, skip to Step 2.  Otherwise - does your Item appear in the creative tabs?  If not, the problem is probably one of the following:
  1. Your Item registration is not being called (must be called during preInitialisation)
    GameRegistry.registerItem(itemSimple, "mbe10_item_simple");
  2. You have passed the wrong item to registerItem.
  3. You haven't set the appropriate creative tab in your Item
public class ItemSimple extends Item
{
  public ItemSimple()
  {
    this.setCreativeTab(CreativeTabs.tabMisc);   // the item will appear on the Miscellaneous tab in creative  }
}

Items Step 2- ItemCameraTransform problem

Does your model have the right appearance, but is the wrong size, is distorted, or is sitting at the wrong angle in the inventory, your hand, or in third person view?

ItemCameraTransform problem
If so, you have a problem with the ItemCameraTransform information in your item model json.  See here for more information.

Otherwise, contine to step 3...

Items Step 3 - Check the console for error messages

Look in the error console for messages which mention your block or item's name, eg messages like this:
> [23:31:17] [Client thread/WARN]: Unable to load item model: 'minecraftbyexample:item/mbe01_block_simple' for item: 'minecraftbyexample:mbe01_block_simple'
java.io.FileNotFoundException: minecraftbyexample:models/item/mbe01_block_simple.json
at
> net.minecraft.client.resources.FallbackResourceManager.getResource( FallbackResourceManager.java:70) ~[FallbackResourceManager.class:?]
at net.minecraft.client.resources.SimpleReloadableResourceManager.getResource(SimpleReloadableResourceManager.java:67) ~[SimpleReloadableResourceManager.class:?]
at net.minecraft.client.resources.model.ModelBakery.loadModel(ModelBakery.java:260) ~[ModelBakery.class:?]
> [23:31:34] [Client thread/WARN]: Missing model for: minecraftbyexample:item/mbe01_block_simple

Did you find any?  If so, continue to Step 4.  Otherwise, skip to Step 6.

Items Step 4- FileNotFoundException

Does your console contain a FileNotFoundException for your Item?
For example

> [23:31:17] [Client thread/WARN]: Unable to load item model: 'minecraftbyexample:item/mbe01_block_simple' for item: 'minecraftbyexample:mbe01_block_simple'
java.io.FileNotFoundException: minecraftbyexample:models/item/mbe01_block_simple.json
at
> net.minecraft.client.resources.FallbackResourceManager.getResource( FallbackResourceManager.java:70) ~[FallbackResourceManager.class:?]
at
> net.minecraft.client.resources.SimpleReloadableResourceManager.getResource( SimpleReloadableResourceManager.java:67) ~[SimpleReloadableResourceManager.class:?]
at net.minecraft.client.resources.model.ModelBakery.loadModel(ModelBakery.java:260) ~[ModelBakery.class:?]

If not, go to step 4.  If so, it means that either
  • For Items: your item model filename doesn't match the registered item name
  • For ItemBlocks: your item model filename doesn't match the registered block name
  • For Items with subtypes (this.setHasSubtypes(true);), you haven't registered the subtype names properly using ModelBakery.addVariantName (see here for an example.)
  • one of the filenames in your json files is wrong, 
  • your resources folder structure is wrong, or
  • your resources folder isn't being copied to the right place.
For general hints about getting folder structures and filenames right, see Blocks Step 4 above.

item model filename or location wrong

> [23:31:17] [Client thread/WARN]: Unable to load item model: 'minecraftbyexample:item/mbe01_block_simple_model' for item: 'minecraftbyexample:mbe01_block_simple'
java.io.FileNotFoundException: minecraftbyexample:models/item/mbe01_block_simple.json

item model.json file contains incorrect parent model filename

> [17:07:34] [Client thread/WARN]: In parent chain: minecraftbyexample:item/mbe01_block_simple -> minecraftbyexample:block/mbe01_block_simple_model_error; unable to load model: 'minecraftbyexample:block/mbe01_block_simple_model_error'
> java.io.FileNotFoundException: minecraftbyexample:models/block/mbe01_block_simple_model_error.json
at 
> net.minecraft.client.resources.FallbackResourceManager.getResource( FallbackResourceManager.java:70) ~[FallbackResourceManager.class:?]
> [17:07:38] [Client thread/WARN]: Missing model for: minecraftbyexample:item/mbe01_block_simple
{
  "parent": "minecraftbyexample:block/mbe01_block_simple_model_error",
  "display": {
    "thirdperson": {
      "rotation": [ 10, -45, 170 ],
      "translation": [ 0, 1.5, -2.75 ],
      "scale": [ 0.375, 0.375, 0.375 ]
    }
  }
}

Item Step 5 - Console errors other than FileNotFoundException

Never got any of these, so can't help there... Ask your question at the forum...  and when you've solved it, post me a comment to tell me what the problem was...

Item Step 6 - No error messages in the console

This is usually caused when the model renderer goes looking for your item model in the registry, but doesn't find it, so it silently substitutes the missing model instead.  Typically this is because you have messed up the registration with the itemModelMesher.

// required in order for the renderer to know how to render your item. 
ModelResourceLocation itemModelResourceLocation = new ModelResourceLocation("minecraftbyexample:mbe10_item_simple", "inventory");
final int DEFAULT_ITEM_SUBTYPE = 0;
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(StartupCommon.itemSimple, DEFAULT_ITEM_SUBTYPE, itemModelResourceLocation);

Typical causes:
  1. Your model registration with the model mesher is not being executed.  It must be done in the init phase (not preinit), and must be done in the client proxy.
  2. The resource location you have specified is incorrect, missing, or in the wrong location.  See Blocks Step 4 above for advice on making sure that the filenames and locations are correct.  Unfortunately, the model mesher doesn't raise any error messages if you get it wrong.
  3. Your Item has subtypes (this.setHasSubtypes(true);), but you haven't properly registered them with
    ModelBakery.addVariantName("mymodid:subtype1", "mymodid:subtype2", etc)
    and for each subtype metadata value:
    ItemModelMesher().register(StartupCommon.itemSimple, ITEM_SUBTYPE_X_METADATA, itemModelResourceLocationSubTypeX);
    See here for a working example.  The ModelResourceLocation for each subtype must match the strings you provided to ModelBakery.  Don't forget the domain i.e. "mymodid:".
If your item has subtypes but you want the registry to ignore metadata, use the "anonymous class" technique below instead
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(itemVariants, 
  new ItemMeshDefinition()     {
      public ModelResourceLocation getModelLocation(ItemStack stack) {
        return new ModelResourceLocation("spawn_egg", "inventory");
      }
    });


A useful breakpoint to solve registration problems is to set a breakpoint at
ItemModelMesher::
public IBakedModel getItemModel(ItemStack stack)
{
    Item item = stack.getItem();
    IBakedModel ibakedmodel = this.getItemModel(item, this.getMetadata(stack));
}

You can then trace in, to compare 1) the model that your item is looking for, against 2) the contents of the registry.  Where they don't match, you can usually see why immediately.

Item Step 7 - Something else?

Ask your question at the forum...  and when you've solved it, post me a comment to tell me what the problem was...

Common Mistakes with Item Models

The diagram below shows some of the typical files needed to render a simple item (ItemMT01) with an autogenerated model based on a texture.  The most common errors are highlighted. 

For the list of symptoms that these errors produce, see here.

For common mistakes in Blocks, Items which are based on Blocks, or Items with more complicated models, see here.

For Items with subtypes (this.setHasSubtypes(true);), you need to register the subtype names properly using ModelBakery.  If your item has subtypes but you want the registry to ignore metadata, use the "anonymous class" technique below instead
Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(itemVariants, 
  new ItemMeshDefinition()     {
      public ModelResourceLocation getModelLocation(ItemStack stack) {
        return new ModelResourceLocation("spawn_egg", "inventory");
      }
    });

A useful breakpoint to solve registration problems is to set a breakpoint at

ItemModelMesher::
public IBakedModel getItemModel(ItemStack stack)
{
    Item item = stack.getItem();
    IBakedModel ibakedmodel = this.getItemModel(item, this.getMetadata(stack));
}

You can then trace in, to compare 1) the model that your item is looking for, against 2) the contents of the registry.  Where they don't match, you can usually see why immediately.