Difference between revisions of "Stages of Modloading"

From Forge Community Wiki
(Inital Import from doku wiki)
 
(Update to 1.17)
Line 1: Line 1:
 
The FML mod loading process is broken into several stages, with each stage having associated events fired alongside with it on the mod-specific event bus. These events are known as the <code>mod lifecycle events</code>, as they are fired during the different phases of a mod's life.
 
The FML mod loading process is broken into several stages, with each stage having associated events fired alongside with it on the mod-specific event bus. These events are known as the <code>mod lifecycle events</code>, as they are fired during the different phases of a mod's life.
  
The different mod loading stages are represented each by a value in the enum class <code><nowiki>net.minecraftforge.fml.ModLoadingStage</nowiki></code>. Most of the mod lifecycle events are stored in the <code><nowiki>net.minecraftforge.fml.event.lifecycle</nowiki></code> package.
+
The different mod loading stages are represented each by a value in the enum class <code><nowiki>net.minecraftforge.fml.ModLoadingStage</nowiki></code>. Their states are split between the <code><nowiki>net.minecraftforge.fml.core.ModStateProvider</nowiki></code> for mod states (construct, common setup, etc.) and <code><nowiki>net.minecraftforge.fmllegacy.ForgeStatesProvider</nowiki></code> for forge injected states (creating registries, injecting capabilities, etc.) Most of the mod lifecycle events are stored in the <code><nowiki>net.minecraftforge.fml.event.lifecycle</nowiki></code> package.
  
 
== Parallelism ==
 
== Parallelism ==
Line 7: Line 7:
 
The mod loading system is parallelized to some extent. While all of the stages are changed at the same time across all mods, most of the events are fired in parallel to each mod. That is, all mods will concurrently receive the event, then FML will wait until all mods have processed the event before moving to the next stage and firing the next event. These concurrently dispatched events are distinguished by them extending <code><nowiki>ParallelDispatchEvent</nowiki></code>.
 
The mod loading system is parallelized to some extent. While all of the stages are changed at the same time across all mods, most of the events are fired in parallel to each mod. That is, all mods will concurrently receive the event, then FML will wait until all mods have processed the event before moving to the next stage and firing the next event. These concurrently dispatched events are distinguished by them extending <code><nowiki>ParallelDispatchEvent</nowiki></code>.
  
This does means that in these parallel mod lifecycle events, care must be taken to be thread-safe, like when calling external methods which are backed by non-thread-safe collections. Most of the systems in Forge are protected for this; however, vanilla systems and external mods' APIs may not be thread-safe. FML provides a way for mods to defer tasks/work until the event is finished dispatching, where it will be run sequentially along with other events on the main thread. This is done the <code><nowiki>enqueueWork</nowiki></code> method, which is a member of all events which extend <code><nowiki>ParallelDispatchEvent</nowiki></code>.
+
This does means that in these parallel mod lifecycle events, care must be taken to be thread-safe, like when calling external methods which are backed by non-thread-safe collections. Most of the systems in Forge are protected for this; however, vanilla systems and external mods' APIs may not be thread-safe. FML provides a way for mods to defer tasks/work until the event is finished dispatching, where it will be run sequentially along with other events on the main thread. This is done with the <code><nowiki>#enqueueWork</nowiki></code> method, which is a member of all events which extend <code><nowiki>ParallelDispatchEvent</nowiki></code>.
  
== Stages and Events ==
+
== Common Transition Stages and Events ==
  
 
{| class="wikitable sortable" border=1
 
{| class="wikitable sortable" border=1
 
!  Name  !!  Enum Constant  !!  Lifecycle Event  !!  Parallel?  !! Description  
 
!  Name  !!  Enum Constant  !!  Lifecycle Event  !!  Parallel?  !! Description  
 
|-
 
|-
|  Construction  ||  <code><nowiki>CONSTRUCT</nowiki></code>  ||  <code><nowiki>FMLConstructModEvent</nowiki></code>  ||  Yes  ||  Fired when the mod's constructor has been called. Can be used to initialize listeners outside of the constructor. <inline tip> There is usually no reason to use this event, as any code should be placed in the mod constructor instead. </inline>
+
|  Construction  ||  <code><nowiki>CONSTRUCT</nowiki></code>  ||  <code><nowiki>FMLConstructModEvent</nowiki></code>  ||  Yes  ||  Fired when the mod's constructor has been called. Can be used to initialize listeners outside of the constructor. There is usually no reason to use this event, as any code should be placed in the mod constructor instead.
 
|-
 
|-
 
|  Registry Creation  ||  <code><nowiki>CREATE_REGISTRIES</nowiki></code>  ||  <code><nowiki>RegistryEvent.NewRegistry</nowiki></code>  ||  No  ||  Fired for mods to create and initialize their custom registries.  
 
|  Registry Creation  ||  <code><nowiki>CREATE_REGISTRIES</nowiki></code>  ||  <code><nowiki>RegistryEvent.NewRegistry</nowiki></code>  ||  No  ||  Fired for mods to create and initialize their custom registries.  
Line 28: Line 28:
 
|  IMC Processing  ||  <code><nowiki>PROCESS_IMC</nowiki></code>  ||  <code><nowiki>InterModProcessEvent</nowiki></code>  ||  Yes  ||  Fired for mods to process messages from other mods sent using the <code><nowiki>InterModComms</nowiki></code> system in the previous stage.  
 
|  IMC Processing  ||  <code><nowiki>PROCESS_IMC</nowiki></code>  ||  <code><nowiki>InterModProcessEvent</nowiki></code>  ||  Yes  ||  Fired for mods to process messages from other mods sent using the <code><nowiki>InterModComms</nowiki></code> system in the previous stage.  
 
|-
 
|-
|  Loading Complete  ||  <code><nowiki>COMPLETE</nowiki></code>  ||  <code><nowiki>FMLLoadCompleteEvent</nowiki></code>  ||  Yes  ||  Fired when mod loading is complete, before handing control back to the main game. <inline tip> There is usually no reason to use this event, as most actions can be done during the Common or Sided Setup stages. </inline>
+
|  Loading Complete  ||  <code><nowiki>COMPLETE</nowiki></code>  ||  <code><nowiki>FMLLoadCompleteEvent</nowiki></code>  ||  Yes  ||  Fired when mod loading is complete, before handing control back to the main game. There is usually no reason to use this event, as most actions can be done during the Common or Sided Setup stages.
 
|-
 
|-
 
|}
 
|}

Revision as of 01:08, 30 July 2021

The FML mod loading process is broken into several stages, with each stage having associated events fired alongside with it on the mod-specific event bus. These events are known as the mod lifecycle events, as they are fired during the different phases of a mod's life.

The different mod loading stages are represented each by a value in the enum class net.minecraftforge.fml.ModLoadingStage. Their states are split between the net.minecraftforge.fml.core.ModStateProvider for mod states (construct, common setup, etc.) and net.minecraftforge.fmllegacy.ForgeStatesProvider for forge injected states (creating registries, injecting capabilities, etc.) Most of the mod lifecycle events are stored in the net.minecraftforge.fml.event.lifecycle package.

Parallelism

The mod loading system is parallelized to some extent. While all of the stages are changed at the same time across all mods, most of the events are fired in parallel to each mod. That is, all mods will concurrently receive the event, then FML will wait until all mods have processed the event before moving to the next stage and firing the next event. These concurrently dispatched events are distinguished by them extending ParallelDispatchEvent.

This does means that in these parallel mod lifecycle events, care must be taken to be thread-safe, like when calling external methods which are backed by non-thread-safe collections. Most of the systems in Forge are protected for this; however, vanilla systems and external mods' APIs may not be thread-safe. FML provides a way for mods to defer tasks/work until the event is finished dispatching, where it will be run sequentially along with other events on the main thread. This is done with the #enqueueWork method, which is a member of all events which extend ParallelDispatchEvent.

Common Transition Stages and Events

Name Enum Constant Lifecycle Event Parallel? Description
Construction CONSTRUCT FMLConstructModEvent Yes Fired when the mod's constructor has been called. Can be used to initialize listeners outside of the constructor. There is usually no reason to use this event, as any code should be placed in the mod constructor instead.
Registry Creation CREATE_REGISTRIES RegistryEvent.NewRegistry No Fired for mods to create and initialize their custom registries.
Registry Population LOAD_REGISTRIES RegistryEvent.Register No Fired when a registry is open to registrations for any registrable objects, such as blocks, items, etc.
Common Setup COMMON_SETUP FMLCommonSetupEvent Yes Used for doing any work or action that should be run on both physical sides.
Sided Setup SIDED_SETUP FMLClientSetupEvent for physical client, FMLDedicatedServerSetupEvent for physical server Yes Used for doing any physical side-specific initialization work.
IMC Enqueue ENQUEUE_IMC InterModEnqueueEvent Yes Fired for mods to enqueue messages for other mods using the InterModComms system.
IMC Processing PROCESS_IMC InterModProcessEvent Yes Fired for mods to process messages from other mods sent using the InterModComms system in the previous stage.
Loading Complete COMPLETE FMLLoadCompleteEvent Yes Fired when mod loading is complete, before handing control back to the main game. There is usually no reason to use this event, as most actions can be done during the Common or Sided Setup stages.