Thursday, 26 December 2013

Forge concepts - Events

Forge provides a large number of events that you can subscribe to. When a particular part of the vanilla code is reached, it fires an “event” and calls any EventHandler code that you have subscribed to that particular event. An example is the PlayerSleepInBed event, which gets triggered whenever a player sleeps in a bed.
There are currently three main ways that you subscribe to events.
  1. The first is the Event Bus.  There are a lot of Event Bus events and it looks like this will be the preferred method for new events added in the future.
  2. The second is through the TickRegistry (for TickHandlers).
  3.  The third is through the @Mod and @NetworkMod annotations used at startup of your mod. 
In addition, there are a few miscellaneous others such as GameRegistry.registerPickupHandler and GameRegistry.registerPlayerTracker, EntityMinecart.registerCollisionHandler().

Event Bus

You subscribe your handler to the event bus using the following basic steps:
  1. Create a MyEventHandler class and register it using the .register method of the appropriate event bus – these are
    * MinecraftForge.EVENT_BUS (this is nearly always the one you need)
    * MinecraftForge.TERRAIN_GEN_BUS
    * MinecraftForge-ORE_GEN_BUS
  2.  Use @ForgeSubscribe to annotate each method in your MyEventHandler which handles an event, eg
public void interceptMouseInput(MouseEvent event)

Whenever the event occurs, your method will be called, with relevant information passed in using the event variable.
Some events can be canceled, by setting event.setCanceled(true) before returning.  This is typically useful where you want to replace the vanilla behaviour with something different - for example if the LivingDropsEvent (called when a mob dies and drops treasure) is canceled, it skips the vanilla code to spawn dropped items.  Cancelable Events have the annotation @Cancelable immediately before the Event class declaration.
public class LivingDropsEvent extends LivingEvent

Some events have a "result" - "DEFAULT, ALLOW, DENY".  This is sometimes just used as an alternative to setCanceled, in other cases (eg LivingSpawnEvent) it is used to choose between "yes", "no", or "let vanilla decide".  @HasResult is used to annotate these events.

The events are all nicely organised into a package (minecraftforge/event) so it is worth a browse to see what flavours are available.


The TickRegistry appears to be an older method of handler, it is used for frequent regular occurrences such as the game loop “tick” that is triggered 20 times per second.
The important steps are
  1. Create your class MyTickHandler implements ITickHandler
  2. Give it a ticks() method which returns a Set of the type of ticks that MyTickHandler is interested in.
  3. Override the tickStart() and/or tickEnd() method with the code that should be executed every time this event triggers.
  4. Register the MyTickHandler using TickRegistry.registerTickHandler.

Some general notes

  • ITickHandler is used when you want the handler to be called every single tick.
  • IScheduledHandler is useful if you only want the handler to be called occasionally, for example every 400 ticks. It is registered using registerScheduledTickHandler.
  • The various types of Tick that you have available are listed in TickType; the most useful are
    CLIENT – the client tick loop
    SERVER – the server tick loop
    PLAYER – whenever an EntityPlayer’s onUpdate is called
    WORLD – each time a WorldServer is ticked
    WORLDLOAD – on the server, when a world is loaded

 @Mod and @NetworkMod for code startup 

The @Mod annotation is used to control startup of your code. See here.
The @NetworkMod annotation is used to register your custom packet handlers (IPacketHandler).


The miscellaneous other handlers are all registered by calling a method specific for that handler, for example
  • GameRegistry.registerPickupHandler – when player picks up an item, superceded by EntityItemPickupEvent.
  • GameRegistry.registerPlayerTracker for tracking players – login, logout, respawn, dimension change.
  • EntityMinecart.registerCollisionHandler for minecart collisions
  • GameRegistry.registerCraftingHandler (ICraftingHandler) for when an item is crafted or smelted.
  • NetworkRegistry.registerChatListener(using IChatListener) for intercepting chat messages including commands
  • NetworkRegistry.registerConnectionHandler(IConnectionHandler) which gives control over clients and players connecting to the server.

~Overview of Forge (and what it can do for you)
    Forge concepts
           Some general notes
           How Forge starts up your code (@Mod, @SidedProxy, etc)  
           Registering your classes
           Extra methods for vanilla base classes
     Forge summary - grouped by task
           World generation, loading, saving
           Miscellaneous - player input, rendering, GUI, chat, sounds

No comments:

Post a Comment