User Tools

Site Tools


documentation:entrypoint

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
documentation:entrypoint [2020/02/21 23:12] – created jamieswhiteshirtdocumentation:entrypoint [2023/12/27 13:07] (current) – ↷ Links adapted because of a move operation 34.220.124.230
Line 26: Line 26:
 </code> </code>
  
-**Caution:** It is recommended to use separate classes for main, client and server entrypoints to avoid class loading issues. Consider the case where the same class is used for both a main and a client entrypoint. When launched on a dedicated server, even if the "client" entrypoint is never loaded, the class that contains the client initialization logic will. Even if the client logic will never be executed, the act of only loading the code may trigger class loading issues.+**Caution:** It is recommended to use separate classes for main, client and server entrypoints to avoid class loading issues. Consider the case where the same class is used for both a main and a client entrypoint. When launched on a dedicated server, even if the "client" entrypoint is never loaded, the class that contains the client initialization logic will be. Even if the client logic will never be executed, the act of merely loading the code may trigger class loading issues.
  
 ==== Built-in entrypoint prototypes ==== ==== Built-in entrypoint prototypes ====
  
-Fabric Loader provides four built-in entrypoint prototypes for mod initialization, some of which are designed to deal with initialization with respect to physical sides (see [[tutorial:side]]). The main, client and server entrypoints are loaded and called about early during the game's initialization, at a point where **most but not all** game systems are ready for modification. These entrypoints are typically used to bootstrap mods by registering registry objects, event listeners and other callbacks for doing things later.+Fabric Loader provides four built-in entrypoint prototypes for mod initialization, some of which are designed to deal with initialization with respect to physical sides (see [[tutorial:side]]). The main, client and server entrypoints are loaded and called early during the game's initialization, at a point where **most but not all** game systems are ready for modification. These entrypoints are typically used to bootstrap mods by registering registry objects, event listeners and other callbacks for doing things later.
  
   * **main**: The first normal initialization entrypoint to run. Uses the type ''ModInitializer'' and will call ''onInitialize''.   * **main**: The first normal initialization entrypoint to run. Uses the type ''ModInitializer'' and will call ''onInitialize''.
Line 41: Line 41:
 ==== Code reference types ==== ==== Code reference types ====
  
-An entrypoint's code reference is turned into an instance of the entrypoint prototype's type. The most common way to make an entrypoint is to refer to a class which implements the expected type, but these code references can be made in multiple ways. Internally, a language adapter is responsible for interpreting the references. The default language adapter is designed for Java code, and thus supports the following types of references:+An entrypoint's code reference is turned into an instance of the entrypoint prototype's type. The most common way to make an entrypoint is to refer to a class which implements the expected type, but these code references can be made in multiple ways. Internally, a language adapter is responsible for interpreting the references and turning them into instances. The default language adapter is designed for Java code, and thus supports the following types of references:
  
   * **Class reference**: ex. ''net.fabricmc.example.ExampleMod'' refers to the non-abstract class by this name. The class must have a public constructor with no arguments. The class must implement or extend the expected type. The resulting object is a new instance of the class.   * **Class reference**: ex. ''net.fabricmc.example.ExampleMod'' refers to the non-abstract class by this name. The class must have a public constructor with no arguments. The class must implement or extend the expected type. The resulting object is a new instance of the class.
Line 55: Line 55:
 Mods can call each others' entrypoints for integration purposes. An entrypoint is loaded lazily when entrypoints for a specific entrypoint prototype are requested, which makes an entrypoint an excellent tool for optional mod integrations. A mod may become an entrypoint prototype provider by declaring that other mods should provide entrypoints based on an entrypoint prototype, often using a class or interface that the mod provides in its API. Mods can safely use this class or interface even if the provider is not installed (rendering the class or interface inaccessible) because entrypoints are loaded only on request. When the provider is not present, the entrypoint will simply be ignored. Mods can call each others' entrypoints for integration purposes. An entrypoint is loaded lazily when entrypoints for a specific entrypoint prototype are requested, which makes an entrypoint an excellent tool for optional mod integrations. A mod may become an entrypoint prototype provider by declaring that other mods should provide entrypoints based on an entrypoint prototype, often using a class or interface that the mod provides in its API. Mods can safely use this class or interface even if the provider is not installed (rendering the class or interface inaccessible) because entrypoints are loaded only on request. When the provider is not present, the entrypoint will simply be ignored.
  
-Entrypoints can be accessed by using ''FabricLoader#getEntrypoints(name, type)''.+Entrypoint instances can be accessed by calling ''FabricLoader#getEntrypointContainers(name, type)''. This returns a list of entrypoint containers. These containers contain the entrypoint instance and the mod container of the mod which provided the instance. This can be used by a mod to determine which mods have registered an entrypoint.
  
-==== A note about load order (or lack thereof) ====+Entrypoint instances are memoized by their name and also their type. Using the same code reference for multiple entrypoints will result in multiple instances. Though highly absurd in practice, if ''getEntrypoints'' is called multiple times with the same name but different types, instances are constructed and memoized per type.
  
-Fabric Loader does not have a concept of a load order. Initializer entrypoints are the mechanism with which most mod loading is usually done, but whether or not an initializer has been called does not determine whether or not a mod can be considered to be "loaded". Thus, it is unreasonable to expect that mod has completed its modifications to the game after its initializers have been called.+==== A note about load order and phases (or a lack thereof) ====
  
-A common example is the expectation that a mod has finished populating a registry with objects so that +Fabric Loader does not have a concept of a load order or loading phases. Initializer entrypoints are the mechanism with which most mod loading is usually done, but whether or not an initializer has been called does not determine whether or not a mod can be considered to be "loaded". Thus, it is unreasonable to expect that a mod has completed its modifications to the game after its initializers have been called. Additionally, the order in which entrypoints are called is mostly undefined and cannot be altered. The only guarantee is that a list of initializers in a fabric.mod.json file are called in the order in which they are declared. Fabric Loader does not provide multiple phases of initializers to work around the lack of order, either. 
 + 
 +A common example is the expectation that mod A should be able to load after mod B because mod A will replace an object registered by mod B. Alternatively, mod C wants to be loaded before mod D because mod D will do something in response to registration performed by mod C. This is cannot be done for two reasons: 
 + 
 +  - Mod initializers are not required to represent transition in a "mod loading lifecycle" so that after the initializer is called, all its registry objects are registered. 
 +  - The order in which mod initializers are called is undefined, and cannot be influenced so that mod A's initializers are called after mod B's initializers, or so that mod C's initializers are called before mod D's initializers. 
 + 
 +Leaving aside the missing guarantee of registration of all objects in initializers, one might argue that there should therefore be other entrypoints to perform "pre-initialization" and "post-initialization" so that there is a sense of order. This creates a multi-phase loading scheme, which in practice creates issues with the establishment of conventions for which operations are to be performed in which phase, uncertainty and lack of adherence to these conventions and outliers which do not fit.
documentation/entrypoint.1582326735.txt.gz · Last modified: 2020/02/21 23:12 by jamieswhiteshirt