Создание модов с помощью ModLoader

Материал из Playzone Minecraft Wiki
Версия от 18:42, 1 февраля 2013; Softer (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск
Статья еще в разработке!
Вы уже можете создавать свои моды, но в дальнейшем будут добавляться новые разделы, совершенствоваться уже написанный код и т.д
Внимание Обновления!
Код разделов, неважно, готов ли он, будет иногда меняться. Будут добавляться новые параметры и т.д. Так что проглядывайте пройденный материал!

В этой статье будет рассказано о том, как создать мод используя ModLoader. Уроки очень просты, рассчитаны на новичка, который никогда не создавал моды для Minecraft.

Настоятельно рекомендую проходить учебник последовательно, так как по много раз повторять одинаковые объяснения просто глупо!

Статус разделов

Название раздела Статус
Начало Работы Готов
Блок Готов
Предмет Готов
Еда Код пишется (http://www.youtube.com/watch?v=24fT1uhAEXI)
Инструмент Готов

Начало работы

Подготовка

Нужно Для последней версии MineCraft
MineCraft (чистый) Скачать
ModLoader Скачать
MineCraft Coder Pack Скачать
NotePad++ (или Eclipse) Скачать NotePad,Скачать Eclipse

Ролик по моддингу - Подготовка

  • Создаём в любом удобном для вас месте пустую папку. Туда распаковываем MineCraft Coder Pack (дальше MCP)
  • Кладём папки bin и resources и файл minecraft_server.jar в папку jars, которая находится вместе с распакованным ранее MCP
  • Открываем папку bin и с помощью архиватора открываем файл minecraft.jar. Удаляем папку META-INF
  • Кладём в minecraft.jar все файлы скачанного ModLoader'а
  • Запускаем decompile.bat и ждем, пока консоль не предложит нажать любую клавишу для выхода
  • Все файлы игры будут лежать в появившейся после декомпиляции папке src по пути: \src\minecraft\net\minecraft\src


Если вы используете NotePad++ то откройте его, по умолчанию у вас будет открыт файл new 1. Выбираете Файл>Сохранить как... и сохраняете по уже известному пути \src\minecraft\net\minecraft\src (там, где все файлы лежат). В имя файла вписываем mod_***.java.

mod_ - обязательная приставка. *** - любое название (выберите что попроще и лучше без пробелов (пример: mod_block)). И нажимаем сохранить. Пишем в файл:

package net.minecraft.src;

import java.util.Random;
                        
public class mod_*** extends BaseMod
{                       
         public void load()     
         {                      
                        
         }
        
         public String getVersion()
         {                      
return "1.4.7";
         }
        
}

Это базовый шаблон для любого мода.

package net.minecraft.src;

Эта строчка должна присутствовать в каждом файле в самом верху. Это указание директории вашего мода(если вы используете ModLoader, то все моды должны находиться в этой директории).

import java.util.Random;

Эта строчка нужна, когда вы используете расширенные возможности моддинга, о них позже.

public class mod_*** extends BaseMod

Это объявление класса mod_*** (везде меняйте *** на имя вашего мода).

{                       
         public void load()     
         {                      
                        
         }
        
         public String getVersion()
         {                      
return "1.4.7";
         }
        
}

Здесь, в public void load() пишутся текстуры для блоков, рецепты, и ещё много чего.

return "1.4.7"; - Версию в кавычках можно менять на любую другую. Обычно используют для обозначения версии Minecraft'а.

Компиляция и создание готового мода

Чтобы проверить код на наличие ошибок необходимо запустить файл recompile.bat. Он заново компилирует игру. Если ошибок нет, то консоль закроется.

После запускаем startclient.bat, после чего запускается игра, где можно опробовать мод прямо в игре.

Если вы создали готовый мод, и хотите получить готовые рабочие файлы, то

Запускаем reobfuscate.bat, и после успешного создания мода в папке reobf появляются .class файлы. Теперь в любой MineCraft с установленным ModLoader вы копируете в minecraft.jar эти файлы и мод устанавливается.

Если у вас ошибка при рекомпиляции

Очень часто бывает, что при рекомпиляции возникают ошибки. В таком случае надо:

  • Перепроверить все файлы и сравнить их с кодов учебника
  • Проверить везде ли и правильно ли вставлены КОДОВЫЕ имена объектов (об этом узнаете ниже)
  • Проверить побуквенно всю строчку, на которую ссылается рекомпилятор
  • Если не помогает, то копируете код вашего мода и строку на которую ссылается компилятор и вставляете в обсуждение

Блок

Добавление блока

Ролик по моддингу - Блок

Сразу хочу сказать, что мы будем создавать блок New Block (так он будет в игре называться). Так будет проще я думаю чем бесконечно ставить ***.

Для начала после package net.minecraft.src;, сразу после import java.util.Random;, прямо под ней, пишем следующий код

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

Эти строчки могут предотвратить некоторые проблемы при создании блоков.

Далее между public class mod_*** extends BaseMod { и void load мы вставляем строчку, которая создает блок (вещь, предмет)

public static final Block NewBlock = new BlockNewBlock(160, 0).setStepSound(Block.soundStoneFootstep).setBlockName("NewBlock").setHardness(4.5F).setResistance(5F).setLightValue(0.375F);

Разберем данную на первый взгляд непонятную строчку.

public static final Block - Эта строчка собственно и создает блок.

NewBlock - это имя нашего блока, но не в игре! NewBlock мы используем в коде. И использовать это имя нам придется часто.

BlockNewBlock - в процессе создания блока, нам надо будет создать файл специально для этого блока. В данном случае имя этого файла будет BlockNewBlock.java (если вы порылись в src, то наверняка видели файлы Block.dirt, Block.sand и так далее).

(160, 0) - 160 - это ID блока. При создании каждого нового блока (вещи, материала и т.д.) обязательно нужно меня ID. То есть если у нас есть три блока, то ID будут соответственно 160, 161, 162. 0 просто оставьте без изменений.

.setStepSound(Block.soundStoneFootstep) - звук, воспроизводимый при ходьбе по какому-нибудь блоку. Меня нужно soundStoneFootstep на нужные значения. Их можно посмотреть в Block.java (Файл>Открыть>Block.java). Для простоты приведу таблицы всех звуков.

Код Звук
soundWoodFootstep Звук при ходьбе по дереву
soundGravelFootstep Звук при ходьбе по гравию
soundGrassFootstep Звук при ходьбе по траве
soundStoneFootstep Звук при ходьбе по камню
soundMetalFootstep Звук при ходьбе по драгоценным блокам
soundGlassFootstep Звук при ходьбе по стеклу
soundClothFootstep Звук при ходьбе по шерсти
soundSandFootstep Звук при ходьбе по песку
soundSnowFootstep Звук при ходьбе по снегу
soundLadderFootstep Звук при движении на лестнице
soundAnvilFootstep Звук при движении по наковальне

.setBlockName("NewBlock") - тоже самое что и в строчке public static final Block NewBlock. Просто копируем наше кодовое название и вставляем в кавычки.

.setHardness(4.5F) - это время, которое требуется долбить блок, чтобы его добыть. Ориентируетесь на то, что устойчивость земли равна 0.5F.

.setResistance(5F) - это взрывоустойчивость блока. Например у обсидиана (не разрушается TNT) взрывоустойчивость равна 6000F.

.setLightValue(0.375F) - можно убрать этот параметр. Определяет светимость блока. 1F - свет как от светокамня.

В итоге должно получиться так

package net.minecraft.src;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class mod_NewBlock extends BaseMod
{
public static final Block NewBlock = new BlockNew(160, 0).setStepSound(Block.soundMetalFootstep).setBlockName("NewBlock").setHardness(0.5F).setResistance(6000F);
public void load()
{

}
public String getVersion()
{
return "1.4.7";
}
}

Имя, текстура, крафт блока

Теперь приступаем к самому главному. К строчке

public void load()     
         {                      
                        
         }

Внутри этих скобок мы и запишем путь к текстуре, присвоим имя блоку уже в игре, добавим ему крафт.

Итак для начала создадим нашему блоку имя в игре

ModLoader.addName(NewBlock, "New Block");

Обратите внимание, что в (NewBlock, "New Block") NewBlock - этот как раз наше кодовое имя блока. А в кавычках у нас имя блока в игре. В кавычках действуют знаки форматирования кода. Это означает, что если вы напишите "§6NewBlock", то цвет имени вашего блока будет золотым. В таблице указаны свойства, которые мы можем применить к нашему блоку(исключительно визуальные).

Sample Code Common Name Foreground Color Background Color
R G B HEX R G B HEX
§0 Черный 0 0 0 #000000 0 0 0 #000000
§1 Темно-Синий 0 0 170 #0000AA 0 0 42 #00002A
§2 Темно-Зеленый 0 170 0 #00AA00 0 42 0 #002A00
§3 Темная Вода 0 170 170 #00AAAA 0 42 42 #002A2A
§4 Темно-Красный 170 0 0 #AA0000 42 0 0 #2A0000
§5 Пурпурный 170 0 170 #AA00AA 42 0 42 #2A002A
§6 Золотой 255 170 0 #FFAA00 42 42 0 #2A2A00
§7 Серый 170 170 170 #AAAAAA 42 42 42 #2A2A2A
§8 Темно-Серый 85 85 85 #555555 21 21 21 #151515
§9 Цвет Индиго 85 85 255 #5555FF 21 21 63 #15153F
§a Ярко-Зеленый 85 255 85 #55FF55 21 63 21 #153F15
§b Водяной 85 255 255 #55FFFF 21 63 63 #153F3F
§c Красный 255 85 85 #FF5555 63 21 21 #3F1515
§d Розовый 255 85 255 #FF55FF 63 21 63 #3F153F
§e Желтый 255 255 85 #FFFF55 63 63 21 #3F3F15
§f Белый 255 255 255 #FFFFFF 63 63 63 #3F3F3F
Код Описание
§l Выделение
§m Зачеркнутое
§n Подчеркнутое
§o Наклонный

Далее зададим путь к текстуре

NewBlock.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/textures/New Block.png");

Итак "/textures/New Block.png". /textures это папка в minecraft.jar, которая, как вы помните находится в jars. Можно изменить на любое. /New Block.png это картинка 16x16, положенная в эту папку. Имя и формат должны В ТОЧНОСТИ совпадать с указанными в коде.

Тоесть написав эту строчку идем в jars, bin, открываем minecraft.jar WinRar и создаем там папку textures (или то, что вы указали). И туда кидаем нашу картинку .png.

Регистрируем блок

ModLoader.registerBlock(NewBlock);

И наконец наше любимое - рецепт

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

{"###", "###", "###", Character.valueOf('#'), Block.dirt

Короче объясню эту непонятную сетку. Первые три ### это первые три клетки верстака верхние, слева на право. И так далее.

То есть первый ряд - первые три ###, второй, вторые три ###.

Далее Character.valueOf('#'), Block.dirt

Это выражение определяет # как блок земли. То есть чтобы сделать наш блок нам надо заполнить весь верстак землей.

Но ведь глупо создавать предметы только из одного материала.

Поэтому рассмотрим такой крафт

ModLoader.AddRecipe(new ItemStack(NewBlock, 1), new Object[]{ "#&", Character.valueOf('#'), Block.Glass,  Character.valueOf('$'), Item.Coal});

Тут у нас инвентарь игрока 2x2. # - это как мы видим стекло, & - это уголь. Значит чтобы получить наш блок нам надо в первых двух верхних ячейках разместить стекло - уголь.

Получится что-то наподобие этого

package net.minecraft.src;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class mod_NewBlock extends BaseMod
{
public static final Block NewBlock = new BlockNew(160, 0).setStepSound(Block.soundMetalFootstep).setBlockName("NewBlock").setHardness(0.5F).setResistance(6000F);
public void load()
{
NewBlock.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/textures/New Block.png");
ModLoader.registerBlock(NewBlock);
ModLoader.addName(NewBlock, "New Block");
ModLoader.addRecipe(new ItemStack(NewBlock, 1), new Object [] {"#@#", "#@#", "#@#", Character.valueOf('#'), Block.dirt, Character.valueOf('@'), Block.glass});
}
public String getVersion()
{
return "1.4.7";
}
}


Надеюсь объяснил понятно)

Создание файла блока

Создаем новый файл BlockNewBlock.java в уже известной нам директории src\minecraft\net\minecraft\src. Пишем в него:

package net.minecraft.src;

import java.util.Random;

public class BlockNewBlock extends Block
{
public BlockNewBlock(int par1, int par2)
{
         super(par1, par2, Material.rock);
         this.setCreativeTab(CreativeTabs.tabBlock);
}

public int quantityDropped(int par1)
{
         return (1);
}
}

return mod_***.NewBlock.shiftedIndex - Что будет выпадать из блока при разрушении.

return 1 - Количество выпадающего блока или предмета.

Обращаю ваше внимание на строчку (CreativeTabs.tabBlock);

Эта сточка помещает наш блок в меню творческого режима в игре. Как вы помните, там несколько вкладок - Материалы, Блоки и т.д. Так вот .tabBlock добавляет наш блок в закладку Блоки. Вот таблица значений, которые можно использовать вместо .tabBlock

Код Вкладка Creative
tabBlock Добавляет объект во вкладку "Блок"
tabDecorations Добавляет объект во вкладку "Декоративные"
tabRedstone Добавляет объект во вкладку "Механизмы"
tabTransport Добавляет объект во вкладку "Транспортировка"
tabMisc Добавляет объект во вкладку "Разное"
tabFood Добавляет объект во вкладку "Еда"
tabTools Добавляет объект во вкладку "Инструменты"
tabCombat Добавляет объект во вкладку "Оружие"
tabBrewing Добавляет объект во вкладку "Зельеварение"
tabMaterials Добавляет объект во вкладку "Материалы"

Генерация блока

Этот раздел нужен для тех, кто хочет, чтобы их блок генерировался в мире (или в аду). Например при создании руды.

Генерация в обычном мире.

Итак сразу под строчкой

public class mod_NewBlock extends BaseMod
{

пишем

public void generateSurface(World world, Random random, int i, int j)
{
for(int k = 0; k < 5; k++)
{
         int randPosX = i + random.nextInt(16);
         int randPosY = random.nextInt(128);
         int randPosZ = j + random.nextInt(16);
         (new WorldGenMinable(yourOreBlockName.blockID, 17)).generate(world, random, randPosX, randPosY, randPosZ);
}
}

Разбираем:

for(int k = 0; k < 5; k++) - k < 5 чем больше цифра после <, тем более часто генерируется блок.

int randPosY = random.nextInt(128); - 128 высота блока. У алмазной руды 16. То есть алмазная руда генерируется на 16 блоков от админиума.

(yourOreBlockName.blockID, 17)) - yourOreBlockName.blockID имя вашего блока (BlockNew.blockID).

Рекомпилируем и ищем наш блок.

Генерация в аду.

Заменяем код, написанный выше на

public void generateNether(World world, Random rand, int i, int j)
{
         for(int m = 0; m < 7; m++)
         {
                 int randPosX = i + rand.nextInt(16);
                 int randPosY = rand.nextInt(128);
                 int randPosZ = j + rand.nextInt(16);
                 (new NetherGenMinable(yourNetherOre.blockID, 15)).generate(world, rand, randPosX, randPosY, randPosZ);
         }
}

Все параметры одинаковы как и с генерацией в обычном мире.

Создаем файл NetherGenMinable.java и вписываем в него (без изменений, код уже готов)

package net.minecraft.src;
import java.util.Random;
public class NetherGenMinable extends WorldGenerator
{
/** The block ID of the ore to be placed using this generator. */
private int minableBlockId;
/** The number of blocks to generate. */
private int numberOfBlocks;
public NetherGenMinable(int par1, int par2)
{
         this.minableBlockId = par1;
         this.numberOfBlocks = par2;
}
public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5)
{
         float var6 = par2Random.nextFloat() * (float)Math.PI;
         double var7 = (double)((float)(par3 + 8) + MathHelper.sin(var6) * (float)this.numberOfBlocks / 8.0F);
         double var9 = (double)((float)(par3 + 8) - MathHelper.sin(var6) * (float)this.numberOfBlocks / 8.0F);
         double var11 = (double)((float)(par5 + 8) + MathHelper.cos(var6) * (float)this.numberOfBlocks / 8.0F);
         double var13 = (double)((float)(par5 + 8) - MathHelper.cos(var6) * (float)this.numberOfBlocks / 8.0F);
         double var15 = (double)(par4 + par2Random.nextInt(3) - 2);
         double var17 = (double)(par4 + par2Random.nextInt(3) - 2);
         for (int var19 = 0; var19 <= this.numberOfBlocks; ++var19)
         {
                 double var20 = var7 + (var9 - var7) * (double)var19 / (double)this.numberOfBlocks;
                 double var22 = var15 + (var17 - var15) * (double)var19 / (double)this.numberOfBlocks;
                 double var24 = var11 + (var13 - var11) * (double)var19 / (double)this.numberOfBlocks;
                 double var26 = par2Random.nextDouble() * (double)this.numberOfBlocks / 16.0D;
                 double var28 = (double)(MathHelper.sin((float)var19 * (float)Math.PI / (float)this.numberOfBlocks) + 1.0F) * var26 + 1.0D;
                 double var30 = (double)(MathHelper.sin((float)var19 * (float)Math.PI / (float)this.numberOfBlocks) + 1.0F) * var26 + 1.0D;
                 int var32 = MathHelper.floor_double(var20 - var28 / 2.0D);
                 int var33 = MathHelper.floor_double(var22 - var30 / 2.0D);
                 int var34 = MathHelper.floor_double(var24 - var28 / 2.0D);
                 int var35 = MathHelper.floor_double(var20 + var28 / 2.0D);
                 int var36 = MathHelper.floor_double(var22 + var30 / 2.0D);
                 int var37 = MathHelper.floor_double(var24 + var28 / 2.0D);
                 for (int var38 = var32; var38 <= var35; ++var38)
                 {
                         double var39 = ((double)var38 + 0.5D - var20) / (var28 / 2.0D);
                         if (var39 * var39 < 1.0D)
                         {
                                 for (int var41 = var33; var41 <= var36; ++var41)
                                 {
                                         double var42 = ((double)var41 + 0.5D - var22) / (var30 / 2.0D);
                                         if (var39 * var39 + var42 * var42 < 1.0D)
                                         {
                                                 for (int var44 = var34; var44 <= var37; ++var44)
                                                 {
                                                         double var45 = ((double)var44 + 0.5D - var24) / (var28 / 2.0D);
                                                         if (var39 * var39 + var42 * var42 + var45 * var45 < 1.0D && par1World.getBlockId(var38, var41, var44) == Block.netherrack.blockID)
                                                         {
                                                                 par1World.setBlock(var38, var41, var44, this.minableBlockId);
                                                         }
                                                 }
                                         }
                                 }
                         }
                 }
         }
         return true;
}
}

Все готово, можете искать вашу руду в аду.

Мульти-текстура

Чтобы у нашего блока были разные текстуры с разных сторон, надо немного изменить код.

package net.minecraft.src;

public class mod_Block extends BaseMod
{
        public static final Block Multi= new BlockMulti(160, 0).setBlockName("Multi").setHardness(3F).setResistance(4F).setLightValue(1F);
        
        public static int MultiHereBottom = ModLoader.addOverride("/terrain.png", "/textures/blockbottom.png");
        public static int MultiHereTop = ModLoader.addOverride("/terrain.png", "/textures/blocktop.png");
        public static int MultiHereSides = ModLoader.addOverride("/terrain.png", "/textures/blocksides.png");
        
        public void load()
        {
                Multi.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/textures/image.png");
                ModLoader.registerBlock(Multi);
                ModLoader.addName(Multi, "Multi Block");
                ModLoader.addRecipe(new ItemStack(Multi, 1), new Object [] {"#", Character.valueOf('#'), Block.dirt});
        }

        public String getVersion()
        {
                return "1.4.7";
        }
}

public static final Block Multi= new BlockMulti(160, 0).setBlockName("Multi").setHardness(3F).setResistance(4F).setLightValue(1F); - все также как и с обычным блоком.

public static int MultiHereBottom = ModLoader.addOverride("/terrain.png", "/textures/blockbottom.png"); - тут текстура на нижнюю сторону блока

public static int MultiHereTop = ModLoader.addOverride("/terrain.png", "/textures/blocktop.png"); - на верхнюю

public static int MultiHereSides = ModLoader.addOverride("/terrain.png", "/textures/blocksides.png"); - и боковые стороны

Далее все как и с обычным блоком. Загружаем картинки, рекомпилируем и радуемся мульти-текстурным блоком.

Падающий блок

В mod_*** все также, а в BlockNewBlock.java вставляем

package net.minecraft.src;

import java.util.Random;

public class BlockTest extends BlockSand
{
        public static boolean fallInstantly = false;

        public BlockTest(int par1)
        {
                super(par1, Block.stone.blockIndexInTexture, Material.rock);
                this.setCreativeTab(CreativeTabs.tabBlock);
        }
}

extends BlockSand - этот параметр и заставляет наш блок падать, так как копирует гравитационные свойства у песка.

Блок готов. Можно рекомпилировать и проверять в игре (см. 1.1 Компиляция и создание готового мода).

Предмет

Добавление предмета

Ролик по моддингу - Предмет

Как и в разделе "Блок" для удобства мы будем создавать предмет NewItem.

Долго разбираться в коде не будем. Чтобы лучше понять смотрите раздел блок - они практически одинаковы.

Итак, как и с блоком, между public class mod_*** extends BaseMod { и void load мы вставляем строчку, которая создает блок (вещь, предмет)

public static final Item NewItem = new ItemNewItem(5000).setItemName("NewItem");

Тут все параметры абсолютно совпадают с параметрами создания блока

public static final Block NewBlock = new BlockNewBlock(160, 0).setStepSound(Block.soundStoneFootstep).setBlockName("NewBlock").setHardness(4.5F).setResistance(5F).setLightValue(0.375F);

final Item - создание предмета final Block - создания блока

NewItem = new ItemNewItem(5000) и NewBlock = new BlockNewBlock(160, 0) - тут все также. ID у предмета 5000. Не забываем с каждым предметом увеличивать ID.

Далее у блока идут функции и сходство только в .setItemName("NewItem").

Как видите код создания блока и предмета почти одинаковы.

Вот как должен выглядеть код

package net.minecraft.src;

import java.util.Random;

public class mod_NewItem extends BaseMod
{
public static final Item NewItem = new ItemNewItem(5000).setItemName("NewItem");
public void load()
{

}

public String getVersion()
{
return "1.4.7";
}
}

Имя, текстура, крафт предмета

Тут смотрите подраздел "Имя, текстура, крафт блока" в разделе "Блок". Все также. Только NewBlock заменяем на NewItem.

Вот так в конечном итоге выглядит код

package net.minecraft.src;

import java.util.Random;

public class mod_NewItem extends BaseMod
{
public static final Item NewItem = new ItemNewItem(5000).setItemName("NewItem");
public void load()
{
NewItem.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/NewItem.png");
ModLoader.addName(NewItem, "New Item");
ModLoader.addRecipe(new ItemStack(NewItem, 1), new Object [] {"###", "###", "###", Character.valueOf('#'), Block.dirt});
}

public String getVersion()
{
return "1.4.7";
}
}

Единственное, не добавляем ModLoader.registerBlock(NewBlock); - тут эта сточка не нужна.

Создание файла предмета

Создаем новый файл ItemNewItem.java. Вспомните new ItemNewItem(5000) в строке добавления мода - ItemNewItem и определяет название нашего нового файла.

package net.minecraft.src; 

import java.util.Random; 

public class ItemNewItem extends Item 
{ 

        public ItemNewItem (int i) 
        { 
                super(i); 
                maxStackSize = 64;
		this.setCreativeTab(CreativeTabs.tabMaterials);				
        } 
} 

maxStackSize = 64 - Количество предметов в одном слоте.

this.setCreativeTab(CreativeTabs.tabMaterials); - добавление во вкладку в креативе. Смотрите "Создание файла блока".

Предмет готов. Запускаем recompile, затем startclient и проверяем. Если есть ошибки, то еще раз читаем статью.

Инструмент

Создание инструмента

Ролик по моддингу - Инструмент

Туда же, куда мы вписывали код для создания блока и предмета вписываем

public static final Item NewSword = (new ItemSword(203, EnumToolMaterial.EMERALD)).setItemName("NewSword");

yourSword - кодовое имя.

(new ItemSword - созданием меча.

203, EnumToolMaterial.EMERALD - тут ID и очень важная вещица, о которой позже.

.setItemName("yourSword") - снова кодовое имя.

Теперь подробнее о EnumToolMaterial.***. *** - это материал нашего инструмента. Переходим в EnumToolMaterial.java и видим различные материалы нашего инструмента. Приведу табличку материалов.

Код Материал
WOOD Дерево
STONE Камень
IRON Железо
EMERALD Алмаз
GOLD Золото

Но это не конец, вы можете создать собственный материал, просто под имеющимися пишем большими буквами имя, например, NEW.

Теперь разберем эти странные цифры: 3, 1561, 8.0F, 3, 10 (в пример я взял EMERALD). 3 - уровень разрушения блоков, насколько серьезные блоки можно добыть. 1561 - количество использований. 8.0F - скорость разрушения блоков. 3 - урон мобам. 10 - оставьте без изменения.

В этом примере мы создали меч. Следующие строки создают мотыгу, лопату, кирку, топор соответственно.

public static final Item NewHoe = new ItemHoe(204, EnumToolMaterial.MATERIALNAME).setItemName("NewHoe");
public static final Item NewShovel = new ItemSpade(202, EnumToolMaterial.MATERIALNAME.setItemName("NewShovel");
public static final Item NewPickaxe = new ItemPickaxe(200, EnumToolMaterial.MATERIALNAME).setItemName("NewPickaxe");
public static final Item NewAxe = new ItemAxe(201, EnumToolMaterial.MATERIALNAME).setItemName("NewAxe");

MATERIALNAME заменяете на нужный или созданный вами.

Имя, текстура, крафт инструмента

Вот код для всего tool сета. Пишем в public void {

public void load()
{
NewPickaxe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/NewPickaxe.png");
NewAxe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/NewAxe.png");
NewShovel.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/NewShovel.png");
NewSword.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/NewSword.png");
NewHoe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/NewHoe.png");

ModLoader.addRecipe(new ItemStack(NewPickaxe, 1), new Object [] {"###", " X ", " X ", Character.valueOf('#'), Block.dirt, Character.valueOf('X'), Item.stick});
ModLoader.addRecipe(new ItemStack(NewShovel, 1), new Object [] {"#", "X", "X", Character.valueOf('#'), Block.dirt, Character.valueOf('X'), Item.stick});
ModLoader.addRecipe(new ItemStack(NewSword, 1), new Object [] {"#", "#", "X", Character.valueOf('#'), Block.dirt, Character.valueOf('X'), Item.stick});
ModLoader.addRecipe(new ItemStack(NewAxe, 1), new Object [] {"##", "#X ", " X", Character.valueOf('#'), Block.dirt, Character.valueOf('X'), Item.stick});
ModLoader.addRecipe(new ItemStack(NewHoe, 1), new Object [] {"##", " X", " X", Character.valueOf('#'), Block.dirt, Character.valueOf('X'), Item.stick});

ModLoader.addName(NewPickaxe, "Pickaxe Name");
ModLoader.addName(NewAxe, "Axe Pickaxe Name");
ModLoader.addName(NewShovel, "Shovel Pickaxe Name");
ModLoader.addName(NewSword, "Sword Pickaxe Name");
ModLoader.addName(NewHoe, "Hoe Pickaxe Name");
}

public String getVersion()
{
return "1.4.7";
}
}

Вот собственно и все. Кидаем текстурки предметов в textures.

Я дал коды целого tool сета потому что чаще всего создают не отдельный инструмент, а сразу комплект.

Вот так будет выглядеть полностью код

package net.minecraft.src;
public class mod_NewMod extends BaseMod
{
public static final Item NewPickaxe = (new ItemPickaxe(200, EnumToolMaterial.MATERIALNAME)).setItemName("NewPickaxe");
public static final Item NewAxe = (new ItemAxe(201, EnumToolMaterial.MATERIALNAME)).setItemName("NewAxe");
public static final Item NewShovel = (new ItemSpade(202, EnumToolMaterial.MATERIALNAME)).setItemName("NewShovel");
public static final Item NewSword = (new ItemSword(203, EnumToolMaterial.MATERIALNAME)).setItemName("NewSword");
public static final Item NewHoe = (new ItemHoe(204, EnumToolMaterial.MATERIALNAME)).setItemName("NewHoe");

public void load()
{
NewPickaxe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/NewPickaxe.png");
NewAxe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/NewAxe.png");
NewShovel.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/NewShovel.png");
NewSword.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/NewSword.png");
NewHoe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/NewHoe.png");

ModLoader.addRecipe(new ItemStack(NewPickaxe, 1), new Object [] {"###", " X ", " X ", Character.valueOf('#'), Block.dirt, Character.valueOf('X'), Item.stick});
ModLoader.addRecipe(new ItemStack(NewShovel, 1), new Object [] {"#", "X", "X", Character.valueOf('#'), Block.dirt, Character.valueOf('X'), Item.stick});
ModLoader.addRecipe(new ItemStack(NewSword, 1), new Object [] {"#", "#", "X", Character.valueOf('#'), Block.dirt, Character.valueOf('X'), Item.stick});
ModLoader.addRecipe(new ItemStack(NewAxe, 1), new Object [] {"##", "#X ", " X", Character.valueOf('#'), Block.dirt, Character.valueOf('X'), Item.stick});
ModLoader.addRecipe(new ItemStack(NewHoe, 1), new Object [] {"##", " X", " X", Character.valueOf('#'), Block.dirt, Character.valueOf('X'), Item.stick});

ModLoader.addName(NewPickaxe, "Pickaxe Name");
ModLoader.addName(NewAxe, "Axe Pickaxe Name");
ModLoader.addName(NewShovel, "Shovel Pickaxe Name");
ModLoader.addName(NewSword, "Sword Pickaxe Name");
ModLoader.addName(NewHoe, "Hoe Pickaxe Name");
}

public String getVersion()
{
return "1.4.7";
}
}

Генерация объектов

Ролик по моддингу - Генерация объектов