Inter Mod CommunicationInter Mod Communication also referred to as IMC is a feature of the Forge Mod Loader that allows mods to send messages to each other. These messages can contain three types of information, a string, an ItemStack or some NBT data. This can be used to create a light weight API in your mod or tap into existing mods that have an API using this system.
Receiving MessagesTo receive messages the mod must include a new event labeled as FMLInterModComms.IMCEvent. This event can go in the main mod classjust like the PreInit and PostInit events.
package net.darkhax.tutorial.imc; @Mod(modid = "receiver", name = "Inter Mod Communication Tutorial: Receiver", version = "1.0.0") public class CommunicationReceiverMod { @EventHandler public void imcCallback(FMLInterModComms.IMCEvent event) { } } Once an IMCEvent has been established you can set up how your mod will handle receiving messages. The first thing you should do with the IMCEvent is create a loop of all the messages, this way every message sent to the mod will be checked. This can be done by using the getMessages method provided by the event.
package net.darkhax.tutorial.imc; @Mod(modid = "receiver", name = "Inter Mod Communication Tutorial: Receiver", version = "1.0.0") public class CommunicationReceiverMod { @EventHandler public void imcCallback(FMLInterModComms.IMCEvent event) { for (final FMLInterModComms.IMCMessage imcMessage : event.getMessages()) { } } } Now that we have a loop going through all the messages being received we can use imcMessage to grab all the info from the current message in the loop. Depending on what your doing with the IMC event you may be receiving a lot of messages from other mods. To help narrow down the search you can do a check to see if the current message has the right message key. The key for the message should be something relevant to what the message should accomplish, n this example we will be using IMC to accept text based messages and then print them to the client. The specific key for this will be info-message. By checking for this key only messages with the info-message key will be accepted.
package net.darkhax.tutorial.imc; @Mod(modid = "receiver", name = "Inter Mod Communication Tutorial: Receiver", version = "1.0.0") public class CommunicationReceiverMod { @EventHandler public void imcCallback(FMLInterModComms.IMCEvent event) { for (final FMLInterModComms.IMCMessage imcMessage : event.getMessages()) { if (imcMessage.key.equalsIgnoreCase("info-message")) { } } } } Now that only certain messages are being read it is a safe idea to add a check to see if the message contains the right kind of data. Messages can contain strings, item stacks and nbt data so it is possible to send a message containing an ItemStack when the message should contain a string. By adding the check only the correct type of messages will be read further.
package net.darkhax.tutorial.imc; @Mod(modid = "receiver", name = "Inter Mod Communication Tutorial: Receiver", version = "1.0.0") public class CommunicationReceiverMod { @EventHandler public void imcCallback(FMLInterModComms.IMCEvent event) { for (final FMLInterModComms.IMCMessage imcMessage : event.getMessages()) { if (imcMessage.key.equalsIgnoreCase("info-message")) { if (imcMessage.isStringMessage()) { } } } } } Now that we have added in all the needed checks it's safe to actually read the message and use it. For this example I will be grabbing the ID of the mod that sent the message and the content of the message and then sending it to a logger in the mod to be printed to the logs. All of the info on the current message can be obtained by using imcMessage and its methods. imcMessage.getSender() will give me the ID of the sender mod and imcMessage.getStringValue will give me the string contained within the message. For the example we will be using a logger however System.out.println will have the same effect.
package net.darkhax.tutorial.imc; @Mod(modid = "receiver", name = "Inter Mod Communication Tutorial: Receiver", version = "1.0.0") public class CommunicationReceiverMod { public static final Logger logger = LogManager.getLogger("Receiver"); @EventHandler public void imcCallback(FMLInterModComms.IMCEvent event) { for (final FMLInterModComms.IMCMessage imcMessage : event.getMessages()) { if (imcMessage.key.equalsIgnoreCase("info-message")) { if (imcMessage.isStringMessage()) { logger.info("The mod " + imcMessage.getSender() + " has sent the following message: " + imcMessage.getStringValue()); } } } } } That is all there is to receiving and reading IMC Messages. Some things to keep in mind is that you can listen to as many messages as you would like and the messages don't have to be used in the ways shown in this tutorial. You can specify an ItemStack type of message and use it to do things like add recipes to a machine or add modded fuels to a custom furnace in another mod. You can also pass the data in the message on to other methods in other classes to help reduce clutter in the main mod file.
Sending MessagesFortunately there is much less involved in sending a message than receiving one. There is a simple one line method that can be used to send a message. It is worth noting that each mod may have certain rules and exceptions for messages being sent to them and often times the author will have documentation somewhere specifically explaining how messages should be sent. Some important info that you will need about the receiving mod is the modID, message key and the data type. For this example we will sending a message to the mod example made above in the Receiving Messages tutorial.
package net.darkhax.tutorial.imc; @Mod(modid = "sender", name = "Inter Mod Communication Tutorial: Sender", version = "1.0.0") public class CommunicationSenderMod { @EventHandler public void preInit(FMLPreInitializationEvent pre) { FMLInterModComms.sendMessage("receiver", "info-message", "Hello World"); } } The above method has three parameters to it. The first is the modID. The modID of the mod in the receiving example is "receiver". The second parameter is the key for the message, in the other tutorial we are searching for messages with the "info-message" key. The third and final parameter is the actual message being sent. It can be a String, an ItemStack or some NBTData. It is worth noting again that the way the messages are used can differ greatly mod to mod so it is best to check the info for that mod to see what messages it is looking for along with how the messages are used and structured.
|