-
Notifications
You must be signed in to change notification settings - Fork 0
Initialization Layer
The Initialization Layer is the first and most critical layer in the Temporal Engine lifecycle; it discovers mod classes, creates the mod context, and builds the dependency injection environment used by all subsequent layers.
The Initialization Layer exists to:
- identify and describe the running mod
- discover all relevant classes belonging to the mod and the API
- create a per-mod dependency injection container
- populate that container with core services and external objects
- prepare a fully initialized runtime context for later layers
Without this layer, no other engine layer can function correctly.
At runtime, the Initialization Layer performs the following steps in strict order:
- Creates a
NeoModinstance - Discovers mod and API classes
- Registers the active mod in
ModContext - Creates an
InjectionPool - Runs object pool initializers (static and dynamic)
All of this happens inside:
InitializationLayer.processAllTasks()NeoMod mod = NeoMod.create(this.modClass, this.classScanners);This step:
- validates the presence of
@Mod - extracts the
modId - runs all configured
ModClassScanners - collects all discovered classes into a single set
The result is a complete runtime description of the mod.
ModContext.NEO_MOD = mod;This establishes:
- the currently active mod
- the global execution context for Temporal API
All future dependency resolution depends on this value.
Set<Class<?>> initializationClasses = Stream.of(classes, apiClasses)
.flatMap(Set::stream)
.collect(Collectors.toSet());The Initialization Layer combines:
- mod-specific classes
- Temporal API internal classes
This ensures that:
- both user code and framework code participate in dependency injection
- annotations and processors work uniformly
ObjectPool objectPool = ModContext.getInstance().createPool(modId);This creates:
- a single InjectionPool per mod
- the core container for all injected objects, factories, handlers, and processors
This pool becomes globally accessible via:
InjectionPool.getInstance()The Initialization Layer runs two categories of initializers.
objectPoolInitializers.forEach(initializer -> initializer.initialize(...));Default initializers include:
TemporalRegisterPoolInitializerFactoryPoolInitializerEventBusPoolInitializerModContainerPoolInitializerInjectedObjectPoolInitializerStrategyPoolInitializerHandlerPoolInitializerProcessorPoolInitializer
These define the baseline engine capabilities.
objectPool.getAll(ObjectPoolInitializer.class)This allows:
- user-defined initializers
- dynamically injected initializers
- plugin-like extensibility
Dynamic initializers are resolved from the InjectionPool itself.
Class scanners define how classes are discovered during initialization.
ClasspathModClassScannerThis scanner:
- loads all classes found in the mod file
- does not filter by annotation
- guarantees full visibility of mod code
This is the safest and most complete scanner.
AnnotatedModClassScannerThis scanner:
- discovers only classes annotated with:
@Injected@Strategy@Handler
- relies on NeoForge scan metadata
- improves performance for annotation-driven systems
The InitializationLayerBuilder configures and executes the Initialization Layer.
By default, it uses:
ClasspathModClassScanner- a full set of engine-provided initializers
- externally supplied objects (EventBus, ModContainer)
This configuration is sufficient for most mods.
You can override behavior using the builder:
configureInitializationLayer()
.modClass(MyMod.class)
.classScanners(customScanners)
.initializers(customInitializers)
.externalSource(List.of(eventBus, modContainer))
.and();Calling .and():
- finalizes the configuration
- executes the layer immediately
- returns control to the EngineBuilder
Customization is useful when:
- you want custom class discovery rules
- you introduce new dependency injection mechanisms
- you need to inject external systems early
- you are extending the Temporal API itself
Most mod developers do not need to customize it.
After the Initialization Layer finishes:
-
ModContext.NEO_MODis set -
InjectionPoolexists and is populated - class metadata is fully available
- dependency injection is operational
Every other layer depends on these guarantees.
🚀 Getting Started
🧩 Core Concepts
⚙️ Data Generation
- ⚙️ Advancement
- ⚙️ Damage Type
- ⚙️ Chest Loot Modifier
- ⚙️ Recipe
- ⚙️ Sound
- ⚙️ Jukebox Song
- ⚙️ Enchantment
- ⚙️ Trim Material
- ⚙️ Trim Pattern
- ⚙️ Banner Pattern
- ⚙️ Painting Variant
- ⚙️ Particle Sprite Set
- ⚙️ Wolf Variant
- ⚙️ Item Model
- ⚙️ Block Model
- ⚙️ Block Loot Table
- ⚙️ Tag
- ⚙️ Language Translation
- ⚙️ World Feature
- ⚙️ Custom Properties
🚨 Events
🛠 Engine Layers
🧪 Resources
- 🧪 Examples