Jump to content

  • Curse Sites
Become a Premium Member! Help
Latest News Article

[Creating Mods] Modding tutorials [21/5/11]


  • Please log in to reply
5201 replies to this topic

#41

starbuck4619

Posted 14 December 2010 - 06:04 PM

Could somebody use a decompiler like JD-GUI and give me the code for the basic block?

Register or log in to remove.

#42

Marcus101RR
  • Location: Florida, USA
  • Minecraft: marcus101rr

Posted 14 December 2010 - 10:27 PM

starbuck4619 said:

Could somebody use a decompiler like JD-GUI and give me the code for the basic block?
If you follow the instructions to set up the MCP, you can decompile and recompile MineCraft and get all the java files that you wish to edit or look at.

Posted Image

NOW FOR MINECRAFT


#43

Laughing Man

Posted 14 December 2010 - 10:38 PM

It appears as though you don't have the create a new NPC tutorial on there as well. Would you mind adding it?

#44

simo_415
    simo_415

    Glowstone Miner

  • Members
  • 3046 posts

Posted 15 December 2010 - 01:48 PM

Customising a block class

In this tutorial I will explain how to create custom block behavior rather than the default behavior. It all basically comes down to overwriting methods in Block.class. This can create blocks which when clicked - exhibit some behavior (see example below), having the block be a redstone power source, explode well... basically anything is possible..

Deployable House Example

So below I am going to provide an example of adding to our Example block class a feature that when the block is clicked it will create a basic house - this allows a simple way of creating a deployable house.

This code will need to be added to the BlockExample class.

	public void onBlockClicked(World world, int i, int j, int k, EntityPlayer entityplayer)
	{
		// Basic Building
		int block = Block.wood.blockID;
		int size = 5;
		for (int i1 = 0; i1 < size; i1++)
		{
			for (int j1 = 0; j1 < size; j1++)
			{
				//Walls 
				// i == ++ k == 0
				world.setBlockWithNotify(i+i1,j+j1,k,block);
				// i == ++ k == 4
				world.setBlockWithNotify(i+i1,j+j1,k+(size-1),block);
				// i == 0 k == ++
				world.setBlockWithNotify(i,j+j1,k+i1,block);
				// i == 4 k == ++
				world.setBlockWithNotify(i+(size-1),j+j1,k+i1,block);
				
				//Roof
				world.setBlockWithNotify(i+i1,j+(size-1),k+j1,block);

				//Floor
				world.setBlockWithNotify(i+i1,j,k+j1,block);
			}
		}
		//Door
		world.setBlockWithNotify(i+1,j+2,k,0);
		world.setBlockWithNotify(i+1,j+1,k,0);

		//Windows
		int offset = size % 2 == 0 ? (size / 2) - 1 : (size / 2);
		world.setBlockWithNotify(i,j+offset,k+offset,Block.glass.blockID);
		world.setBlockWithNotify(i+offset,j+offset,k,Block.glass.blockID);
		world.setBlockWithNotify(i+(size-1),j+offset,k+offset,Block.glass.blockID);
		world.setBlockWithNotify(i+offset,j+offset,k+(size-1),Block.glass.blockID);

		//Utilities
		world.setBlockWithNotify(i+1,j+1,k+(size-2),Block.crate.blockID);
		world.setBlockWithNotify(i+(size-2),j+1,k+1,Block.workbench.blockID);
		world.setBlockWithNotify(i+(size-2),j+1,k+(size-2),Block.stoneOvenIdle.blockID);
	}

This will produce a house that looks like follows when clicked.

Posted Image

So like the above example you can create custom block behavior by overwriting methods found in the Block class to create some awesome functionality as seen above in the deployable house example.

#45

simo_415
    simo_415

    Glowstone Miner

  • Members
  • 3046 posts

Posted 15 December 2010 - 01:57 PM

How to create a custom NPC

In this tutorial I will explain how to create your own custom NPC. I must warn anyone who attempts this though - it is substantially more complex than adding a new block to the game. So in this example I am going to create a new NPC that is modelled off a cow - a mad cow, this mob will initially be friendly but I will also show you how to make it agressive.

To begin with you need to create the "logic" class, the logic for extended elements to the game is handled under the Entity classes. You can basically add anything to an entity class to achieve custom game behaviour. So lets create an entity class named EntityExample.java to make a new peaceful NPC.

package net.minecraft.src;

public class EntityExample extends EntityAnimals
{
	public EntityExample(World world)
	{
		super(world);
		texture = "/mob/example.png";
		setSize(0.9F, 1.3F);
	}

	public void writeEntityToNBT(NBTTagCompound nbttagcompound)
	{
		super.writeEntityToNBT(nbttagcompound);
	}

	public void readEntityFromNBT(NBTTagCompound nbttagcompound)
	{
		super.readEntityFromNBT(nbttagcompound);
	}

	protected String getLivingSound()
	{
		return "mob.example";
	}

	protected String getHurtSound()
	{
		return "mob.example";
	}

	protected String getDeathSound()
	{
		return "mob.example";
	}

	protected float getSoundVolume()
	{
		return 0.4F;
	}

	protected int getDropItemId()
	{
		return 0;
	}
}

The above code should be pretty self explanatory as to what it does but I will quickly go over the details.

getSoundVolume() returns a number from 0 - 1 which is the "volume" of the creatures sound. This can be translated into a percent by multiplying by 100.
getLivingSound, getHurtSound, getDeathSound return the location of the "track" to play when each of those things happen. The tracks can be found in the resources directory. For this example I am just going to copy another mobs
sounds rather than create my own.
read and write entity to NBT allows the creature to be saved and loaded from your save.

So the next step would be to make sure you have all the sounds and textures which are specified in your class, using NPC you need to add the sounds to:
/jars/resources/newsound/mob/example.ogg and the texture needs to be added to:
/temp/minecraft/mob/example.png

You can get my MadCow texture below:
Posted Image

The sound is just the cow sound copied and renamed to example.ogg.

This now means that the entity class is finished.

Next you need to create a Model class. A model class basically provides minecraft with the details required to generate the "model" of the entity within minecraft. So these details are dependent upon your example.png texture. Since I am modelling this example off a cow I will be using mostly the same details as the ModelCow
class.

package net.minecraft.src;

public class ModelExample extends ModelQuadraped
{

	public ModelExample()
	{
		super(12, 0.0F);
		head = new ModelRenderer(0, 0);
		head.addBox(-4F, -4F, -6F, 8, 8, 6, 0.0F);
		head.setPosition(0.0F, 4F, -8F);
		horn1 = new ModelRenderer(22, 0);
		horn1.addBox(-4F, -5F, -4F, 1, 3, 1, 0.0F);
		horn1.setPosition(0.0F, 3F, -7F);
		horn2 = new ModelRenderer(22, 0);
		horn2.addBox(4F, -5F, -4F, 1, 3, 1, 0.0F);
		horn2.setPosition(0.0F, 3F, -7F);
		udders = new ModelRenderer(52, 0);
		udders.addBox(-2F, -3F, 0.0F, 4, 6, 2, 0.0F);
		udders.setPosition(0.0F, 14F, 6F);
		udders.rotateAngleX = 1.570796F;
		body = new ModelRenderer(18, 4);
		body.addBox(-6F, -10F, -7F, 12, 18, 10, 0.0F);
		body.setPosition(0.0F, 5F, 2.0F);
		leg1.offsetX--;
		leg2.offsetX++;
		leg1.offsetZ += 0.0F;
		leg2.offsetZ += 0.0F;
		leg3.offsetX--;
		leg4.offsetX++;
		leg3.offsetZ--;
		leg4.offsetZ--;
	}

	public void render(float f, float f1, float f2, float f3, float f4, float f5)
	{
		super.render(f, f1, f2, f3, f4, f5);
		horn1.render(f5);
		horn2.render(f5);
		udders.render(f5);
	}

	public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5)
	{
		super.setRotationAngles(f, f1, f2, f3, f4, f5);
		horn1.rotateAngleY = head.rotateAngleY;
		horn1.rotateAngleX = head.rotateAngleX;
		horn2.rotateAngleY = head.rotateAngleY;
		horn2.rotateAngleX = head.rotateAngleX;
	}

	ModelRenderer udders;
	ModelRenderer horn1;
	ModelRenderer horn2;
}

So as seen above we specify postions and orientation of the new creature. To create a totally new creature with all new dimensions and orientation you would need to play around with these numbers in the constructor a bit.

After creating the Model class we need to create a Render class, the render class provides a way of linking the Model class to the Entity class. Therefore we  will create a new class named RenderExample.java the code is pretty bare boned and all it basically does is overwrite doRender and func_171_a to specify the
specific Entity class.

package net.minecraft.src;

public class RenderExample extends RenderLiving
{
	public RenderExample(ModelBase modelbase, float f)
	{
		super(modelbase, f);
	}

	public void doRenderLiving(EntityLiving entityliving, double d, double d1, double d2, 
			float f, float f1)
	{
		super.doRenderLiving((EntityExample)entityliving, d, d1, d2, f, f1);
	}

	public void doRender(Entity entity, double d, double d1, double d2, 
			float f, float f1)
	{
		doRenderLiving((EntityExample)entity, d, d1, d2, f, f1);
	}
}

Now we have created all the necessary classes for our new NPC so the next step is to let minecraft know about them so that they can be generated. To do this you need to add some code to RenderManager.java within the constructor at the bottom of the list.

entityRenderMap.put(EntityExample.class, new RenderExample(new ModelExample(),0.7F));

And you also need to add them to the necessary biome generator lists, this is done in the MobSpawnerBase class. Within the constructor add the Entity to the biomeCreature array.

EntityExample.class

After this is complete you can now compile and run your new NPC.

If you wish to create an aggressive NPC this is achieved by changing the Entity class slightly so that it extends EntityMobs instead of EntityAnimals. You will also need to change the MobSpawnerBase list if you want it to spawn at night rather than during the day.

Like the block class to achieve customisation of NPCs all that needs to be done is you need to overwrite the methods in the EntityCreature or EntityMobs classes this will allow the mobs to do basically anything.

End Result:
Posted Image

#46

XDMickeYXD
  • Location: The Netherlands
  • Minecraft: MickeyXD

Posted 15 December 2010 - 02:18 PM

simo_415 said:

Could you teach us that? I mean could you teach us to make an entirely new npc,(using spawnlist mod) with a new model, for example a frog (i know how to texture and model, just not how to make the animations work ingame and make it do stuff)
That would be more than awesome because then everyone can make custom npcs =D
If I've helped you, please click this button :-]
Posted Image

#47

Camel1
    Camel1

    Carpenter

  • Members
  • 53 posts

Posted 15 December 2010 - 08:21 PM

Can anyone help me please? Keep getting this when i run "test_game.bat"

*** Minecraft Coder Pack Version 2.5 ***
Exception in thread "main" java.lang.NoClassDefFoundError: Start
Caused by: java.lang.ClassNotFoundException: Start
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: Start.  Program will exit.
Press any key to continue . . .

I keep getting it even with unmodified files, i just decompile (successful), then recompile (seems successful) and i get this when running the game.

Can anyone help? xD


*EDIT*

[loading paulscode\sound\codecs\CodecWav.class(paulscode\sound\codecs:CodecWav.class)]
sources\minecraft\net\minecraft\src\SoundManager.java:96: cannot find symbol
symbol  : class a
location: package paulscode.sound.codecs
                SoundSystemConfig.setCodec("xm", paulscode.sound.codecs.a.class);
                                                                       ^
sources\minecraft\net\minecraft\src\SoundManager.java:97: cannot find symbol
symbol  : class a
location: package paulscode.sound.codecs
                SoundSystemConfig.setCodec("s3m", paulscode.sound.codecs.a.class);
                                                                        ^
sources\minecraft\net\minecraft\src\SoundManager.java:98: cannot find symbol
symbol  : class a
location: package paulscode.sound.codecs
                SoundSystemConfig.setCodec("mod", paulscode.sound.codecs.a.class);
                                                                        ^
[checking net.minecraft.src.MouseHelper]

Maybe this means something to someone? xD

*EDIT2*

Fixed it xD I just reinstalled minecraft to reset the files on there :(

#48

simo_415
    simo_415

    Glowstone Miner

  • Members
  • 3046 posts

Posted 16 December 2010 - 12:31 AM

XDMickeYXD said:

simo_415 said:

Could you teach us that? I mean could you teach us to make an entirely new npc,(using spawnlist mod) with a new model, for example a frog (i know how to texture and model, just not how to make the animations work ingame and make it do stuff)
That would be more than awesome because then everyone can make custom npcs =D

Added.

I am only teaching how to add things using MCP, extra utilities and Modloaders I am not going to give instructions on as this should be covered in their respective threads. Using the instructions given on those threads you should be able to covert any of my tutorials to become compatible with their mods.

#49

simo_415
    simo_415

    Glowstone Miner

  • Members
  • 3046 posts

Posted 16 December 2010 - 12:33 AM

Camel1 said:

Fixed it xD I just reinstalled minecraft to reset the files on there :(

Good to hear =)

That error is usually due to the compiling failing - you have to compile start.java to get start.class

#50

Marcus101RR
  • Location: Florida, USA
  • Minecraft: marcus101rr

Posted 16 December 2010 - 03:04 AM

Nice work simo, love that stuff.

Posted Image

NOW FOR MINECRAFT


#51

alecn1519
  • Minecraft: alecn1519

Posted 16 December 2010 - 04:44 AM

If you don't mind, could you make a simple tutorial on how to make these mods, but using Risugami's modloader?

"We didn't want to go, we didn't want to kill them, but its persistent silence and outstretched arms horrified and comforted us at the same time..."


#52

simo_415
    simo_415

    Glowstone Miner

  • Members
  • 3046 posts

Posted 16 December 2010 - 05:56 AM

alecn1519 said:

If you don't mind, could you make a simple tutorial on how to make these mods, but using Risugami's modloader?

There should be examples of this on risugami's thread.

#53

simo_415
    simo_415

    Glowstone Miner

  • Members
  • 3046 posts

Posted 16 December 2010 - 03:17 PM

How to create custom world generation

In this tutorial I will describe how the map generation works and how to create your own custom map generation. What I mean by map generation is when a new world is created or new chunks are created that terrain that appears is generated terrain - this tutorial will show you how to customise how this happens. I have made quite a few map generation mods now and in my opinion I would have to say they are the most fun. Here are some examples:

Forests
Posted Image

Tall Tree Forests
Posted Image

Ruins
Posted Image

Infinite Track
Posted Image

So as you can see there is a nice variety of map generation available. In this tutorial I will show you how to create a map generator to place random quantities of TNT on the map (a bit of fun =D).

To begin with you will need to create a new WorldGen class, the naming convention is as follows WorldGen[NAME] so for this example I will create a class called WorldGenExample. The bare bones class requires a constructor and generate method. Here it is below:

package net.minecraft.src;

import java.util.Random;

public class WorldGenExample extends WorldGenerator
{

	public WorldGenExample()
	{
	}

	public boolean generate(World world, Random random, int i, int j, int k)
	{
	}
}

Within the generate method we want to put all the logic of the generator. The i, j, k parameters are the block coordinate within minecraft, in general not every block is called and only one block per chunk is called - so keep in mind that each time the generate method is called it is (generally) the only time it will be called for that chunk.

To create the random TNT I am going to add this code to the generate method:

// Gives this a 1 in 10 chance of generating
if (random.nextInt(10) == 0)
{
	// Loops 64 times, this could create up to 64 TNT
	for (int z = 0; z < 64; z++)
	{
		int i1 = i + random.nextInt(8) - random.nextInt(8);
		int j1 = j + random.nextInt(8) - random.nextInt(8);
		int k1 = k + random.nextInt(8) - random.nextInt(8);
		// Checks that there is nothing in the current location and there is grass beneath.
		if(world.getBlockId(i1, j1, k1) == 0 && world.getBlockId(i1, j1 - 1, k1) == Block.grass.blockID && Block.tnt.canPlaceBlockAt(world, i1, j1, k1))
		{
			world.setBlockAndMetadata(i1, j1, k1, Block.tnt.blockID, random.nextInt(4));
		}
	}
}	

After coding the logic of your terrain generation you need to let minecraft know about it so that it can generate the terrain. To do this you need to edit ChunkProviderGenerate, specifically the populate method. This method should be pretty self explanatory - it generates Lakes then Dungeons then Clay, etc etc. You need to add your class to this method - where you put it in this list is very important. If you put it at the top of the method, it is a lot more likely to be generated than having it at the bottom of the method - the choice is yours, I am putting this towards the bottom of the method, specifically below the WorldGenLiquids calls.

(new WorldGenExample()).generate(worldObj, rand, k + rand.nextInt(16), rand.nextInt(112) + 16, l + rand.nextInt(16));

Finally after compiling and generating a new world or exploring new areas in a current world you should be able to find TNT spawns. You may want to configure the randomness and quantity per request to be more to your liking.

Posted Image

#54

Club559
    Club559

    Obsidian Miner

  • Curse Premium
  • Curse Premium
  • 1344 posts
  • Location: A little west of somewhere.
  • Minecraft: Club559

Posted 16 December 2010 - 03:21 PM

simo_415 said:

:D

Now can you make armor tutorial after?
None.

#55

simo_415
    simo_415

    Glowstone Miner

  • Members
  • 3046 posts

Posted 16 December 2010 - 03:24 PM

Club559 said:

simo_415 said:

:D

Now can you make armor tutorial after?

Sure, I will probably do it tomorrow morning.



#56

Club559
    Club559

    Obsidian Miner

  • Curse Premium
  • Curse Premium
  • 1344 posts
  • Location: A little west of somewhere.
  • Minecraft: Club559

Posted 16 December 2010 - 03:34 PM

Making your mod compatible with modloader



Hey guys  :o

Here I will be telling you how to make your mod compatible with modloader. If you are using MCP, you have ran into this bump of sadness. If you have noticed, these tutorials require editing main Minecraft class files. No more doing that with modloader!

EDIT: I have deleted the download for modloader MCP source because Risugami's epicness has finally made it compatible if you just decompile modloader! Just put the modloader files in your minecraft.jar inside of the MCP jars folder, decompile, and you got yourself a working modloader.

It includes every function on the newest modloader, seeing as you're decompiling the current one.

Anyways, this includes some great functions! First of all, you will have to put mod_ at the front of your mod's name, and put this at the top of the code:

public class mod_MyMod extends BaseMod

Now in Beta 1.2_02, there's something you have to do like this:
public String Version()
{
	 return "1.2_02";
}

If you want to register a block from there, use this inside your public class:
public static final Block example;

static
{
	example = (new BlockExample(92, 1)).setHardness(1.5F).setStepSound(Block.soundStoneFootstep);
}

Notice "Block" in front of soundStoneFootstep. This is required as it is being defined in an outside class.

And for the other functions :SSSS:

public void AddRecipes(CraftingManager recipes)
public int AddSmelting(int id)
public int AddFuel(int id)
public void AddEntityID()
public void GenerateNether(World world, Random random, int chunkX, int chunkZ)
public void GenerateSurface(World world, Random random, int chunkX, int chunkZ)

Soon to come: How to use those functions with tutorials explained above!
None.

#57

Club559
    Club559

    Obsidian Miner

  • Curse Premium
  • Curse Premium
  • 1344 posts
  • Location: A little west of somewhere.
  • Minecraft: Club559

Posted 16 December 2010 - 03:38 PM

ModLoader Functions - Part 1 - BaseMod

In BaseMod, you will find a lot of functions to prevent your mod from overwriting the classes that most mods would use if it weren't for modloader. Here is how to use them.

public void AddEntityID()
This tutorial has modloader code for NPC making that includes this function used in it.

public int AddFuel(int id)
Here is an example code I got from an example mod I made. Since there is no fuel tutorial, the number is how long it will take to smelt. Wood is 300, sticks are 100, coal is 1600, and lava buckets are 20000.
	public int AddFuel(int id)
	{
		if(id == Item.flint.shiftedIndex)
		{
			return 2400;
		}
		return 0;
	}

public void AddRecipes(CraftingManager recipes)
Read the crafting tutorial on this. An example code:
public void AddRecipes(CraftingManager recipes)
{
	recipes.addRecipe(new ItemStack(Item.diamond), new Object[] {
		"#", Character.valueOf('#'), Block.dirt
	});
}

public int AddSmelting(int id)
Read up on the smelting tutorial for more information.
public int AddSmelting(int id)
{
	if(id == Block.dirt.blockID)
	{
		return Item.diamond.shiftedIndex;
	}
}



I still have to have explanations for the following:

	public void GenerateNether(World world, Random random, int chunkX, int chunkZ)
	{
	}

	public void GenerateSurface(World world, Random random, int chunkX, int chunkZ)
	{
	}

Until then, have fun with your new modloader mod!



Coming soon:
Part 2 - ModLoader functions
World generation explanations...
None.

#58

simo_415
    simo_415

    Glowstone Miner

  • Members
  • 3046 posts

Posted 16 December 2010 - 04:39 PM

Club559 said:


That's right :iapprove:

sweet, thanks! I will add it to the original post.

#59

NoNamed
    NoNamed

    Coal Miner

  • Members
  • 121 posts

Posted 16 December 2010 - 04:45 PM

I'm trying to create a new recipe. I did what it said here, but it didn't work. I've also tried with an item that isn't custom, and it still didn't work.

#60

simo_415
    simo_415

    Glowstone Miner

  • Members
  • 3046 posts

Posted 16 December 2010 - 04:50 PM

NoNamed said:

I'm trying to create a new recipe. I did what it said here, but it didn't work. I've also tried with an item that isn't custom, and it still didn't work.

The recipe given in this example should never fail if you have the BlockExample class; try this standard recipe:

addRecipe(new ItemStack(Block.stone, 1), new Object[] {"##", "##", Character.valueOf('#'), Block.dirt});

Make sure you recompile and make sure that there are no compile errors, read my original post regarding compiling and debugging.

**edit**
As an afterthought, view the console window while minecraft is open, load a world and press the escape key. The console window should output "100 recipes".