Skip to content

Resource Loader V2#62

Open
SpaceWalkerRS wants to merge 6 commits intogen2from
resource-loader/v2
Open

Resource Loader V2#62
SpaceWalkerRS wants to merge 6 commits intogen2from
resource-loader/v2

Conversation

@SpaceWalkerRS
Copy link
Copy Markdown
Member

@SpaceWalkerRS SpaceWalkerRS commented May 2, 2026

V2 is a major rewrite of the Resource Loader API, mostly focusing on adding new features. V1 had three main features.

  • Automatically loading bundled mod resources.
  • Allowing mods to register custom bundled resources.
  • Events for listening to resource reloads (1.6+).

The resource management system was otherwise left untouched. The rewrite expands the resource management system with new features and improves the API's integration with Vanilla.

  • Added events for tracking the lifecycles of the resource manager and resource pack repository.
  • Improved API for custom bundled mod resources.
  • Added support for asynchronous resources reloads in 1.13-.
  • Added support for namespaced resources in 1.5-.
  • Added support for finding resources in a given directory in 1.12-.

Several of these were achieved by abstracting the resource management system and replacing a few Vanilla components with wrappers around equivalent OSL components. This way the Vanilla system remains intact and usable, while it is also possible to use the OSL system instead. This allows for more powerful features down the line.

  • Server-side resource loading and data pack support in 1.12-.
  • Client-side resource loading in a1.2.1-.
  • Loading resource packs in 1.5-.
  • Loading texture packs in 1.6+.

Resource Loader V2

I had several goals for V2, but they can be boiled down to: feature parity across Minecraft versions.

On a high level:

  • Implement resource packs in 1.5- and data packs in 1.12-.
  • Implement resource management and texture packs in a1.2.1-.
  • Implement custom pack sources in 1.12-.
  • Add support for asynchronous resource reloading in 1.13-.

On a low level, features from later versions:

  • Retrieving resource stack at a location (as opposed to just the top resource).
  • Listing resources/resource stacks at a location.
  • Lazy resources (separating retrieving/finding resources from opening/reading them).

Supporting Minecraft versions before Alpha 1.2.2 was a big goal. Texture packs were already limited, but before texture packs there was no resource management in the game at all. Back-porting such a system is essential for other APIs to get off the ground.

With this in mind I opted to create one single complete resource management system that is independent from any Vanilla system. This was already necessary for pre-texture pack support, but it makes achieving feature-parity easier as will be interacting with OSL's system, so the Vanilla system need not be augmented.

Events

All events exist for both the client environment and the server environment.

  • INIT_RESOURCE_PACK_REPOSITORY: invoked on start-up, mods should register custom pack sources here.
  • INIT_RESOURCE_MANAGER, invoked on start-up, mods should register custom resource reloaders here.
  • START_RESOURCE_PACKS_RELOAD: invoked before resource packs are reloaded.
  • END_RESOURCE_PACKS_RELOAD: invoked after resource packs are reloaded.
  • START_RESOURCE_RELOAD: invoked before resources are reloaded.
  • END_RESOURCE_RELOAD: invoked after resources are reloaded.

API Overview

Resource Loader automatically adds mod resources to a composite "Mod Resources" pack. While pack sources are the main way of adding custom resource packs, there is a short-cut for bundled resources from sub-directories in your project resources.

interface ResourcePackRepository {
	static registerBundledModResources(
		String: pack id
		String: pack name
		ModContainer: mod that contains the resources
		String: directory in project resources
	)
}

ResourceManager provides static access to the client-side and server-side resource managers, and functions as the access point for resources in the game.

interface ResourceManager {
	static ReloadableResourceManager client()
	static ReloadableResourceManager server()

	// access resources using String paths
	InputStream getResource(
		String: path to resource
	)

	// access resources using namespaced locations
	Optional<Resource> getResource(
		NamespacedIdentifier: location of resource
	)
}
interface ReloadableResourceManager {
	// add resource reloader
	addReloader(
		ResourceReloader: resource reloader or reload listener
	)

	// initiate a resource reload
	ResourceReload startReload(
		List<ResourcePack>: resource packs to use for resource reload
		Executor: background thread executor
		Executor: main thread executor
		CompletableFuture<?>: initial task that is run before the reload
	)
}

ResourcePackRepository provides static access to the client-side and server-side pack repositories, and functions as the access point for available and selected resource packs.

interface ResourcePackRepository {
	// add pack source
	addSource(
		Source: pack source
	)

	// access summaries of available and selected packs
	Collection<ResourcePackSummary> getAvailablePacks()
	Collection<ResourcePackSummary getSelectedPacks()
}

Updating From V1

Events

The following events were removed:

  • ADD_DEFAULT_TEXTURE_PACKS (1.5-).
  • ADD_DEFAULT_RESOURCE_PACKS (1.6+).
  • ADD_DEFAULT_DATA_PACKS (1.13+).

There are two possible update paths

Registering Custom Bundled Mod Resources

The ResourcePackRepository class has a method for registering bundled mod resources from a sub-directory in your project resources.

package com.example;

import net.ornithemc.osl.entrypoints.api.client.ClientModInitializer;
import net.ornithemc.osl.resource.loader.api.resource.repository.ResourcePackRepository;

public class ExampleInitializer implements ClientModInitializer {

	private static final ModContainer MOD = FabricLoader.getInstance().getModContainer("example").get()

	@Override
	public void initClient() {
		ResourcePackRepository.registerBundledModResources(
			"cookie-assets",  // pack id
			"Cookie Assets"   // pack name
			MOD,              // mod container
			"client/cookies/" // directory in project resources
		);
	}
}

Registering Custom Resource Pack Repository Source

If you want to register custom resource packs from elsewhere, you can register a custom ResourcePackRepository.Source, which gives complete freedom of what kind of resource packs you load in.

package com.example;

import net.ornithemc.osl.entrypoints.api.client.ClientModInitializer;
import net.ornithemc.osl.resource.loader.api.resource.repository.ResourcePackRepository;

public class ExampleInitializer implements ClientModInitializer {

	@Override
	public void initClient() {
		ClientResourceLoaderEvents.INIT_PACK_REPOSITORY.register(packRepository -> {
			packRepository.addSource(new ExamplePackSource());
		});
	}
}
package com.example;

import java.util.function.Consumer;

import net.ornithemc.osl.resource.loader.api.resource.pack.ResourcePack;
import net.ornithemc.osl.resource.loader.api.resource.repository.ResourcePackRepository;

public class ExamplePackSource implements ResourcePackRepository.Source {

	@Override
	public void loadResourcePacks(Consumer<ResourcePack> consumer) {
		// load your custom resource packs here
	}
}

API classes

The following pack-related API classes were removed.

  • ModTexturePack (1.5-).
  • ModResourcePack (1.6-1.12).
  • ModPack (1.13+).
  • ResourceUtils (1.6+).

There is no equivalent for the pack-related classes in the rewrite, but the update path for their main use (default texture/resource packs) was covered in the previous section. net.ornithemc.osl.resource.loader.api.resource.pack.ResourcePack is the base class for all resource packs. AbstractResourcePack in the same package is an implementation that manages namespaces and resource metadata.

ResourceUtils was also removed without a replacement. If you have suggestions for a solution or have a use-case for this that now goes un-met, please leave a comment.

Localization

All localization-related code has been removed to be made into a separate API (see #58).

Notes on Compatibility

Given the nature of the rewrite, almost all OSL internals have been changed in some way. If your mod relied on any internals, chances are high it will need updating.

The rewrite also changes how Vanilla-integration is done. In particular, the resourceManager and packRepository in Minecraft/MinecraftServer have been replaced with wrappers around OSL's own resource managers and pack repositories. This means any Mixins into SimpleReloadableResourceManager, FallbackResourceManager, and PackRepository are likely to have no effect whatsoever. If you have reason to modify these classes, please leave a comment, as there may be a way to add the desired change/functionality to OSL in this rewrite.

@SpaceWalkerRS SpaceWalkerRS added the enhancement New feature or request label May 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant