I have a block, and I want to do some logic when it is added to the world.
I am using the onBlockAdded method to accomplish this.
However, the method is being called twice, and I'm not sure why.
Minmum reproduction using the examplemod from `forge-1.16.4-35.1.0-mdk`
ExampleMod.java
package com.example.examplemod;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.material.Material;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.ObjectHolder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.stream.Collectors;
// The value here should match an entry in the META-INF/mods.toml file
@Mod("examplemod")
public class ExampleMod
{
// Directly reference a log4j logger.
private static final Logger LOGGER = LogManager.getLogger();
public ExampleMod() {
// Register the setup method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
// Register the enqueueIMC method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC);
// Register the processIMC method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC);
// Register the doClientStuff method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff);
// Register ourselves for server and other game events we are interested in
MinecraftForge.EVENT_BUS.register(this);
}
private void setup(final FMLCommonSetupEvent event)
{
// some preinit code
LOGGER.info("HELLO FROM PREINIT");
}
private void doClientStuff(final FMLClientSetupEvent event) {
// do something that can only be done on the client
LOGGER.info("Got game settings {}", event.getMinecraftSupplier().get().gameSettings);
}
private void enqueueIMC(final InterModEnqueueEvent event)
{
// some example code to dispatch IMC to another mod
InterModComms.sendTo("examplemod", "helloworld", () -> { LOGGER.info("Hello world from the MDK"); return "Hello world";});
}
private void processIMC(final InterModProcessEvent event)
{
// some example code to receive and process InterModComms from other mods
LOGGER.info("Got IMC {}", event.getIMCStream().
map(m->m.getMessageSupplier().get()).
collect(Collectors.toList()));
}
// You can use SubscribeEvent and let the Event Bus discover methods to call
@SubscribeEvent
public void onServerStarting(FMLServerStartingEvent event) {
// do something when the server starts
LOGGER.info("HELLO from server starting");
}
@ObjectHolder("examplemod")
public static final class Blocks {
public static final Block EXAMPLEBLOCK = null;
}
// You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD
// Event bus for receiving Registry Events)
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
public static class RegistryEvents {
@SubscribeEvent
public static void onBlocksRegistry(final RegistryEvent.Register<Block> blockRegistryEvent) {
// register a new block here
LOGGER.info("HELLO from Register Block");
blockRegistryEvent.getRegistry().register(
new ExampleBlock(AbstractBlock.Properties.create(Material.IRON)).setRegistryName("examplemod","exampleblock")
);
}
@SubscribeEvent
public static void onRegisterItems(final RegistryEvent.Register<Item> e) {
Item item = new BlockItem(Blocks.EXAMPLEBLOCK, new Item.Properties().group(new ItemGroup(-1, "examplegroup"){
@Override
public ItemStack createIcon() {
return new ItemStack(Blocks.EXAMPLEBLOCK);
}
})).setRegistryName("examplemod","exampleblock");
e.getRegistry().register(item);
}
}
}
ExampleBlock.java
package com.example.examplemod;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class ExampleBlock extends Block {
public ExampleBlock(Properties properties) {
super(properties);
}
@Override
public void onBlockAdded(
BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving
) {
super.onBlockAdded(state, worldIn, pos, oldState, isMoving);
System.out.println("ADDED! " + worldIn.isRemote);
}
}
Right clicking once places the block in the world as expected
However, the method is being called twice.
[02:40:40] [Server thread/INFO] [STDOUT/]: [com.example.examplemod.ExampleBlock:onBlockAdded:19]: ADDED! false
[02:40:40] [Server thread/INFO] [STDOUT/]: [com.example.examplemod.ExampleBlock:onBlockAdded:19]: ADDED! false
Stack from the first call:
onBlockAdded:18, ExampleBlock (com.example.examplemod)
onBlockAdded:702, AbstractBlock$AbstractBlockState (net.minecraft.block)
setBlockState:285, Chunk (net.minecraft.world.chunk)
setBlockState:228, World (net.minecraft.world)
setBlockState:205, World (net.minecraft.world)
placeBlock:152, BlockItem (net.minecraft.item)
tryPlace:57, BlockItem (net.minecraft.item)
onItemUse:42, BlockItem (net.minecraft.item)
onPlaceItemIntoWorld:607, ForgeHooks (net.minecraftforge.common)
onItemUse:191, ItemStack (net.minecraft.item)
func_219441_a:359, PlayerInteractionManager (net.minecraft.server.management)
processTryUseItemOnBlock:986, ServerPlayNetHandler (net.minecraft.network.play)
processPacket:45, CPlayerTryUseItemOnBlockPacket (net.minecraft.network.play.client)
processPacket:12, CPlayerTryUseItemOnBlockPacket (net.minecraft.network.play.client)
lambda$checkThreadAndEnqueue$0:19, PacketThreadUtil (net.minecraft.network)
run:-1, 1364657741 (net.minecraft.network.PacketThreadUtil$$Lambda$5784)
run:20, TickDelayedTask (net.minecraft.util.concurrent)
run:139, ThreadTaskExecutor (net.minecraft.util.concurrent)
run:22, RecursiveEventLoop (net.minecraft.util.concurrent)
run:758, MinecraftServer (net.minecraft.server)
run:159, MinecraftServer (net.minecraft.server)
driveOne:109, ThreadTaskExecutor (net.minecraft.util.concurrent)
driveOneInternal:741, MinecraftServer (net.minecraft.server)
driveOne:735, MinecraftServer (net.minecraft.server)
driveUntil:122, ThreadTaskExecutor (net.minecraft.util.concurrent)
runScheduledTasks:721, MinecraftServer (net.minecraft.server)
func_240802_v_:667, MinecraftServer (net.minecraft.server)
lambda$startServer$0:233, MinecraftServer (net.minecraft.server)
run:-1, 830477086 (net.minecraft.server.MinecraftServer$$Lambda$5086)
run:748, Thread (java.lang)
Stack from the second call:
onBlockAdded:18, ExampleBlock (com.example.examplemod)
onBlockAdded:702, AbstractBlock$AbstractBlockState (net.minecraft.block)
onPlaceItemIntoWorld:666, ForgeHooks (net.minecraftforge.common)
onItemUse:191, ItemStack (net.minecraft.item)
func_219441_a:359, PlayerInteractionManager (net.minecraft.server.management)
processTryUseItemOnBlock:986, ServerPlayNetHandler (net.minecraft.network.play)
processPacket:45, CPlayerTryUseItemOnBlockPacket (net.minecraft.network.play.client)
processPacket:12, CPlayerTryUseItemOnBlockPacket (net.minecraft.network.play.client)
lambda$checkThreadAndEnqueue$0:19, PacketThreadUtil (net.minecraft.network)
run:-1, 1364657741 (net.minecraft.network.PacketThreadUtil$$Lambda$5784)
run:20, TickDelayedTask (net.minecraft.util.concurrent)
run:139, ThreadTaskExecutor (net.minecraft.util.concurrent)
run:22, RecursiveEventLoop (net.minecraft.util.concurrent)
run:758, MinecraftServer (net.minecraft.server)
run:159, MinecraftServer (net.minecraft.server)
driveOne:109, ThreadTaskExecutor (net.minecraft.util.concurrent)
driveOneInternal:741, MinecraftServer (net.minecraft.server)
driveOne:735, MinecraftServer (net.minecraft.server)
driveUntil:122, ThreadTaskExecutor (net.minecraft.util.concurrent)
runScheduledTasks:721, MinecraftServer (net.minecraft.server)
func_240802_v_:667, MinecraftServer (net.minecraft.server)
lambda$startServer$0:233, MinecraftServer (net.minecraft.server)
run:-1, 830477086 (net.minecraft.server.MinecraftServer$$Lambda$5086)
run:748, Thread (java.lang)
Being in survival mode exhibits the same behaviour.
Am I registering something wrong?
Failing to implement some method that has been unnecessary until I wanted to override onBlockAdded?
Is it actually deprecated in favour of a separate method, or is it just "minecraft deprecated"?
I'd appreciate any insights, thank you.
ExampleBlock.java ExampleMod.java