Skip to content

Latest commit

 

History

History
961 lines (744 loc) · 32.4 KB

readme-forge.asciidoc

File metadata and controls

961 lines (744 loc) · 32.4 KB

Minecraft Modding using Forge

Requirements

  • A Windows or Mac computer

  • A Minecraft account is not required

Download and Install

Download

Download the following software

  1. Java Development Kit (JDK): Download and install JDK from https://www.oracle.com/java/technologies/downloads/

  2. Eclipse: Download Eclipse from http://www.eclipse.org/downloads/eclipse-packages/, pick “Eclipse IDE for Java Developers” and unzip.

  3. Forge: Download Forge 1.19 from https://maven.minecraftforge.net/net/minecraftforge/forge/1.19-41.1.0/forge-1.19-41.1.0-mdk.zip

Windows or Mac

Follow the instructions as explained below.

Windows

Make sure all the software listed in Download and Install is downloaded.

  1. Open a Command Prompt as explained at http://windows.microsoft.com/en-us/windows-vista/open-a-command-prompt-window

  2. Change directory to “Desktop” using the command cd Desktop

  3. Make a new directory using mkdir forge

  4. Change to the directory using cd forge

  5. In File Explorer, right-click on the Forge 1.19 zip file downloaded earlier, select “Extract All…​”, and extract the contents into the newly created forge directory.

  6. In Command Prompt, run the command gradlew genEclipseRuns. The output should show BUILD SUCCESSFUL.

Mac

Make sure all the software listed in Download and Install is downloaded.

  1. In Finder, go to “Applications”, then “Utilities”, then double click on “Terminal”.

  2. Change directory to Desktop using the command cd Desktop

  3. Make a new directory using mkdir forge

  4. Change to the directory using cd forge

  5. Unzip the downloaded Forge 1.19 zip file using the command unzip ~/Downloads/forge-1.19-41.1.0-mdk.zip

  6. Run the command ./gradlew genEclipseRuns. The output should show BUILD SUCCESSFUL.

Verify

This is a very important step as this will confirm that you can actually start modding.

  1. Open up Eclipse.

  2. In the “Eclipse IDE Launcher” window, click on “Launch”.

  3. In the Eclipse window, chose menu “File”, “Import…​”.

    1. Click the arrow next to “Gradle”.

    2. Select “Existing Gradle Project” and click “Next >” .

    3. In the box that says “Project root directory”, choose the location of the forge directory.

    4. Click “Finish”.

  4. The Eclipse window should look like the following:

    eclipse startup
  5. Click the “Restore” button at the top left:

    eclipse restore
  6. Now, your window should look like the following:

    eclipse after restore
  7. On the left is the “Package Explorer”, which is where the game’s source code lives. We’ll come back to it later. For now, in the “Gradle Tasks” window on the right side, double click on the forge folder. Then, double click on forgegradle runs and select runClient.

    eclipse runClient
  8. Double click on runClient to start the Minecraft launcher. It should look like the following:

    first run

If you’re able to launch Minecraft in this way, your setup is good to go. Let’s start modding!

Chat Items

Purpose: This mod adds items to player’s inventory when they type a certain word or phrase in chat.

Instructions: Create a new Java class called ChatItems:

  1. Double click on the forge folder in the “Package Explorer” on the left side.

  2. Expand the folder src/main/java.

  3. Right click on the package com.example.examplemod and select New > Class.

  4. In the “Name” box, fill in ChatItems, then click on the Finish Button.

  5. Replace the resulting code with Chat Items code.

Example 1. Chat Items code
package com.example.examplemod;

import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = ExampleMod.MODID)
public class ChatItems {
    @SubscribeEvent
    public static void giveItems(ServerChatEvent event) {
        if (event.getMessage().contains("potato")) {
            event.getPlayer().getInventory().add(new ItemStack(Items.POTATO, 64));
        }
    }
}

At this point, your window should look like the following:

eclipse ChatItems

Once you’ve finished editing the files, it’s time to run the game. Click on the green play button at the top-left to run your modded Minecraft:

eclipse play button

When Eclipse asks you to save the file, click on the “Save” button. This will save the file and start the Minecraft launcher.

Gameplay:

  1. Create a new Creative mode world.

  2. Press T to open the chat window.

  3. Type in any message that contains the word potato.

  4. You should receive one stack (64 items) of potatoes.

Change text/item

This variation produces a different item for a different text message. For example change the text from "potato" to "diamond" and the item produced from Items.POTATO to Items.DIAMOND. To see more possibilities, use Ctrl+Space with your cursor just after Items. to show the list of items.

To see the changes you’ve made, close Minecraft and restart it by clicking on the play button in Eclipse.

Different items

This variation produces different items for different chat text. For example, typing potato will yield potatoes while typing diamond will yield diamonds.

Example 2. Different items
@SubscribeEvent
public static void giveItems(ServerChatEvent event){
    if (event.getMessage().contains("potato")) {
        event.getPlayer().getInventory().add(new ItemStack(Items.POTATO, 64));
    }

    if (event.getMessage().contains("diamond")) {
        event.getPlayer().getInventory().add(new ItemStack(Items.DIAMOND, 64));
    }
}

Multiple items

This variation yields multiple items for a single message. Instead of producing potatoes and diamonds separately, the player gets both items at once from a single trigger word.

Example 3. Multiple items
@SubscribeEvent
public void giveItems(ServerChatEvent event){
    if (event.getMessage().contains("potato")) {
        event.getPlayer().inventory.addItemStackToInventory(new ItemStack(Items.POTATO, 64));
        event.getPlayer().inventory.addItemStackToInventory(new ItemStack(Items.DIAMOND, 64));
    }
}

Ender Dragon Spawner

Purpose: This mod will spawn an ender dragon every time a player places a dragon egg block.

Instructions: In the package com.example.examplemod, make a new class called DragonSpawner and replace its code with the code shown in Ender Dragon Spawner code.

Example 4. Ender Dragon Spawner code
package com.example.examplemod;

import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
import net.minecraft.world.entity.boss.enderdragon.phases.EnderDragonPhase;
import net.minecraft.world.level.block.Blocks;
import net.minecraftforge.event.level.BlockEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = ExampleMod.MODID)
public class DragonSpawner {
    @SubscribeEvent
    public static void spawnDragon(BlockEvent.EntityPlaceEvent event) {
        if (event.getPlacedBlock().getBlock() == Blocks.DRAGON_EGG) {
            event.getLevel().removeBlock(event.getPos(), false); // false = no flags
            EnderDragon dragon = EntityType.ENDER_DRAGON.create(event.getEntity().getLevel());
            dragon.moveTo(event.getPos(), 0, 0);
            dragon.getPhaseManager().setPhase(EnderDragonPhase.TAKEOFF);
            event.getLevel().addFreshEntity(dragon);
        }
    }
}

Gameplay:

  1. Use the command /give Dev minecraft:dragon_egg to give yourself a dragon egg.

  2. Select the hotbar slot containing the dragon egg.

  3. Right click in the world to place down the dragon egg, which will spawn an ender dragon.

Note
When running the /give command, you may get the error You don’t have permissions to perform the command. The reason for this is that you don’t have cheats enabled in your world. When you are creating a world, there will be a box that says you are in “Survival”" mode. Click on the box until it says “Creative” mode, which will automatically enable cheats. Then, create the the world normally. You will need to create a new world for this.

Change block/entity

This variation changes the block that triggers spawning as well as the entity spawned. For example, you can change the block to Blocks.SPONGE and the entity to EntitySquid. Like with Chat Items, use Ctrl+Space to show the list of possible items or entities.

Example 5. Squid spawner
@SubscribeEvent
public static void spawnSquid(BlockEvent.EntityPlaceEvent event) {
    if (event.getPlacedBlock() == Blocks.SPONGE.defaultBlockState()) {
         event.getLevel().removeBlock(event.getPos(), false); // false = no flags
         Squid squid = EntityType.SQUID.create(event.getEntity().level);
         squid.moveTo(event.getPos(), 0, 0);
         event.getLevel().addFreshEntity(squid);
     }
}

After doing this, press Control + Shift + O on a Windows computer or Cmd + Shift + O on a Mac computer to update the imports and fix the error. After launching the game, in the Minecraft game window, give yourself a sponge using the command /give Dev minecraft:sponge, or grab a sponge from the creative inventory. Place the sponge in the world to spawn a squid.

Change spawn position

This variation makes the ender dragon 2 blocks above the location where the dragon egg is placed.

Change the line dragon.moveTo(event.getPos(), 0, 0); to the following:

Example 6. Spawn position offset
dragon.moveTo(event.getPos().above(2), 0, 0);

Creeper Spawn Alert

Purpose: This mod will alert all players when a creeper spawns.

Instructions: Make a new Java class called CreeperSpawnAlert. Replace its contents with Creeper Spawn Alert code.

Example 7. Creeper Spawn Alert code
package com.example.examplemod;

import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.monster.Creeper;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = ExampleMod.MODID)
public class CreeperSpawnAlert {
    @SubscribeEvent
    public static void sendAlert(EntityJoinLevelEvent event) {
        if (event.getEntity() instanceof Creeper && event.getLevel().isClientSide) {
            for (Player player : event.getLevel().players()) {
                player.sendSystemMessage(Component.literal(ChatFormatting.GREEN + "A creeper has spawned!"));
            }
        }
    }
}

Gameplay:

  1. Make sure you are not on peaceful mode.

  2. Set the time to night time using the command /time set night

You should get a bunch of messages saying “A creeper has spawned!”. One of these messages is sent to you every time a creeper spawns.

Change color/format of message

Change color to red

This variation changes the color of the message.

Example 8. Red message
player.sendSystemMessage(Component.literal(ChatFormatting.RED + "A creeper has spawned!"));

Try out different colors by using Ctrl+Space after ChatFormatting.

Change text of message

This variation changes the message printed.

Example 9. Different message text
player.sendSystemMessage(Component.literal(ChatFormatting.RED + "Run away, a creeper has spawned!"));

Print a different message for another mob

This variation prints messages for zombies instead of creepers.

Example 10. Different mob
if (event.getEntity() instanceof Zombie && event.getLevel().isClientSide) {
    for (Player player : event.getLevel().players()) {
    player.sendSystemMessage(Component.literal(ChatFormatting.GREEN + "A zombie has spawned!"));
    }
}

Sharp Snowballs

Purpose: This mod turns all snowballs into arrows so that they can hurt entities.

Instructions: Create a new Java class called SharpSnowballs. Replace its code with Sharp Snowballs code.

Example 11. Sharp Snowballs code
package com.example.examplemod;

import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.projectile.Arrow;
import net.minecraft.world.entity.projectile.Snowball;
import net.minecraft.world.level.Level;
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = ExampleMod.MODID)
public class SharpSnowballs {
    @SubscribeEvent
    public static void replaceSnowballWithArrow(EntityJoinLevelEvent event) {
        Entity snowball = event.getEntity();
        Level level = event.getLevel();

        if (!(snowball instanceof Snowball)) {
            return;
        }

        if (!level.isClientSide) {
            Arrow arrow = EntityType.ARROW.create(level);
            arrow.moveTo(snowball.position());
            arrow.setDeltaMovement(snowball.getDeltaMovement());
            level.addFreshEntity(arrow);
        }

        event.setCanceled(true);
    }
}

Gameplay:

  1. Give yourself a snowball using the command /give Dev minecraft:snowball, or grab a snowball from the creative inventory.

  2. Select the snowball in your hotbar and right click to throw it.

  3. The snowball should turn into an arrow.

You can also spawn snow golems by placing a pumpkin on top of a tower of two snow blocks. The snow golem will act as a turret, shooting out snowballs that turn into arrows at hostile mobs.

Tip: Spawn a zombie or two for the snow golems to shoot.

Explosive snowballs

This variation converts snowballs into lit TNT.

Replace the line Arrow arrow = EntityType.ARROW.create(level); with the code shown in Explosive Snowballs code.

Example 12. Explosive Snowballs code
PrimedTnt arrow = EntityType.TNT.create(level);
arrow.setFuse(80);

Make sure to fix the imports using Ctrl + Shift + O on Windows or Cmd + Shift + O on Mac.

Overpowered Iron Golems

Purpose: This mod adds helpful potion effects to iron golems when they are spawned in the world.

Instructions:

Create a new Java class called OverpoweredIronGolems and replace its contents with Overpowered Iron Golems code.

Example 13. Overpowered Iron Golems code
package com.example.examplemod;

import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.animal.IronGolem;
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = ExampleMod.MODID)
public class OverpoweredIronGolems {
    @SubscribeEvent
    public static void applyPotionEffectsToGolem(EntityJoinLevelEvent event) {
        if (!(event.getEntity() instanceof IronGolem)) {
            return;
        }

        IronGolem golem = (IronGolem) event.getEntity();
        golem.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SPEED, 1000000, 5));
        golem.addEffect(new MobEffectInstance(MobEffects.DAMAGE_BOOST, 1000000, 5));
        golem.addEffect(new MobEffectInstance(MobEffects.REGENERATION, 1000000, 5));
        golem.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, 1000000, 5));
    }
}

Gameplay:

  1. Spawn an iron golem by using the command /summon minecraft:iron_golem

  2. Spawn some hostile mobs (zombies, skeletons, etc.) near the iron golem. For example, use the command /summon minecraft:zombie.

  3. The golem should move towards the hostile mobs to kill them.

Normally, iron golems move slowly, but with the speed effect from the mod, they should move very fast.

Rain Water

Purpose: Normally, rain does not create water on the terrain. This mod places water at the feet of entities when it is raining.

Instructions: Create a new Java class called RainWater and replace its contents with Rain Water code.

Example 14. Rain Water code
package com.example.examplemod;

import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Blocks;
import net.minecraftforge.event.entity.living.LivingEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = ExampleMod.MODID)
public class RainWater {
    @SubscribeEvent
    public static void makeWater(LivingEvent.LivingTickEvent event) {
        Entity entity = event.getEntity();
        Level level = entity.level;
        BlockPos entityPos = entity.blockPosition();

        if (level.isClientSide) {
            return;
        }

        if (!level.isRaining() || level.getBiome(entityPos).get().getPrecipitation() != Biome.Precipitation.RAIN) {
            return;
        }

        for (int i = entityPos.getY(); i < 320; i++) {
            if (level.getBlockState(entityPos.atY(i)).getBlock() != Blocks.AIR) {
                return;
            }
        }

        BlockPos posBelow = entityPos.below(1);
        if (!level.getBlockState(posBelow).isCollisionShapeFullBlock(level, posBelow)) {
            return;
        }

        level.setBlockAndUpdate(entityPos, Blocks.WATER.defaultBlockState());
    }
}

Gameplay:

  1. Go to a biome where it rains, such as plains, forest, swamp, or jungle. Make sure you’re not in a biome where rain doesn’t happen, such as desert, savanna, or taiga.

  2. Use the command /weather rain to start the rain.

  3. Start walking on the ground, and water should be placed at the feet of you and all other entities in the rain.

    1. If water is not spawning, make sure you’re not standing in a transparent block such as tall grass or a flower.

TNT Thunder

This variation spawns TNT during thunderstorms instead of placing water during rain.

Replace the makeWater() method in the RainWater class with the code in TNT Thunder Code.

Example 15. TNT Thunder Code
@SubscribeEvent
public static void spawnTnt(LivingEvent.LivingTickEvent event) {
    Entity entity = event.getEntity();
    Level level = entity.level;
    BlockPos entityPos = entity.blockPosition();

    if (level.isClientSide) {
        return;
    }

    if (!level.isThundering() || level.getBiome(entityPos).get().getPrecipitation() != Biome.Precipitation.RAIN) {
        return;
    }

    for (int i = entityPos.getY(); i < 320; i++) {
        if (level.getBlockState(entityPos.atY(i)).getBlock() != Blocks.AIR) {
            return;
        }
    }

    BlockPos posBelow = entityPos.below(1);
    if (!level.getBlockState(posBelow).isCollisionShapeFullBlock(level, posBelow)) {
        return;
    }

    if (level.random.nextInt(40) != 1) {
        return;
    }

    PrimedTnt tnt = EntityType.TNT.create(level);
    tnt.setFuse(80);
    tnt.moveTo(entityPos, 0, 0);
    level.addFreshEntity(tnt);
}

Don’t forget to fix the imports using Ctrl + Shift + O on Windows or Cmd + Shift + O on Mac.

To test this variation, travel to a rainy biome and use the command /weather thunder to make the weather stormy. Then, watch for TNT to be placed wherever you walk around. The TNT should explode after 4 seconds.

Skeleton War

Purpose: This mod gives armor to all skeletons and makes them attack each other.

Instructions: Create a new Java class called SkeletonWar and replace its contents with Skeleton War code.

Example 16. Skeleton War code
package com.example.examplemod;

import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
import net.minecraft.world.entity.monster.AbstractSkeleton;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import java.util.Arrays;
import java.util.List;

@Mod.EventBusSubscriber(modid = ExampleMod.MODID)
public class SkeletonWar {
    static List<Item> helmets = Arrays.asList(Items.LEATHER_HELMET,
            Items.CHAINMAIL_HELMET, Items.GOLDEN_HELMET, Items.IRON_HELMET,
            Items.DIAMOND_HELMET, Items.NETHERITE_HELMET, Items.TURTLE_HELMET);
    static List<Item> chestplates = Arrays.asList(Items.LEATHER_CHESTPLATE,
            Items.CHAINMAIL_CHESTPLATE, Items.GOLDEN_CHESTPLATE, Items.IRON_CHESTPLATE,
            Items.DIAMOND_CHESTPLATE, Items.NETHERITE_CHESTPLATE);
    static List<Item> leggings = Arrays.asList(Items.LEATHER_LEGGINGS,
            Items.CHAINMAIL_LEGGINGS, Items.GOLDEN_LEGGINGS, Items.IRON_LEGGINGS,
            Items.DIAMOND_LEGGINGS, Items.NETHERITE_LEGGINGS);
    static List<Item> boots = Arrays.asList(Items.LEATHER_BOOTS,
            Items.CHAINMAIL_BOOTS, Items.GOLDEN_BOOTS, Items.IRON_BOOTS,
            Items.DIAMOND_BOOTS, Items.NETHERITE_BOOTS);

    @SubscribeEvent
    public static void makeWarNotPeace(EntityJoinLevelEvent event) {
        if (!(event.getEntity() instanceof AbstractSkeleton skeleton)) {
            return;
        }

        skeleton.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(skeleton, AbstractSkeleton.class, true));

        RandomSource random = skeleton.level.random;
        skeleton.setItemSlot(EquipmentSlot.HEAD, new ItemStack(helmets.get(random.nextInt(6))));
        skeleton.setItemSlot(EquipmentSlot.CHEST, new ItemStack(chestplates.get(random.nextInt(5))));
        skeleton.setItemSlot(EquipmentSlot.LEGS, new ItemStack(leggings.get(random.nextInt(5))));
        skeleton.setItemSlot(EquipmentSlot.FEET, new ItemStack(boots.get(random.nextInt(5))));
    }
}

Gameplay:

  1. Spawn a skeleton by using the command /summon minecraft:skeleton or by using a skeleton spawn egg.

  2. Spawn more skeletons and watch them fight.

You can also create an enclosed arena to spawn skeletons in. Try adding some traps or lava!

Sharing Your Mods

Create your mod .jar file

  1. Open Command Prompt (Windows) or Terminal (Mac).

  2. Go to forge folder using the command cd ~/Desktop/forge

  3. Type the command gradlew build (Windows) or ./gradlew build (Mac).

  4. Your mods will be available in build/libs/modid-1.0.jar

Minecraft Modding Book from O’Reilly

Are you interested in creating a new item, new block, new recipe, new textures, and lots of other fun mods? Then check out Minecraft Modding with Forge from O’Reilly.

minecraft modding book cover

Minecraft Modding Video Tutorial from O’Reilly

Are you interested in following these instructions and learning a bit of Java in the process as well? Then check out Minecraft Modding with Forge Training Video from O’Reilly or scan the QR code from your phone.

minecraft modding oreilly video course