Resource Pack Stacking
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
Resource Pack Stacking is a core system in HoloPrint designed to mimic Minecraft Bedrock Edition's asset override behavior. It allows the application to resolve resource requests by searching through a stack of user-provided "local" resource packs before falling back to vanilla game assets. This system is essential for generating holograms that accurately represent custom textures, block shapes, and UI elements defined in external addons or community resource packs.
The system facilitates the extraction of textures for the Texture Atlas and ensures that block definitions and translation files are correctly merged or prioritized based on the user's configuration.
Sources: src/ResourcePackStack.js:1-5, src/index.js:525-527, README.md:94-96
Architecture and Components
The system is centered around the ResourcePackStack class, which manages a collection of LocalResourcePack instances.
ResourcePackStack Class
This class maintains the state of the resource hierarchy. It stores an array of local packs where the first item in the array represents the highest priority (the "top" of the stack).
| Property | Type | Description |
|---|---|---|
hasResourcePacks | boolean | Indicates if any custom packs are attached. |
localResourcePacks | LocalResourcePack[] | Array of packs provided by the user via the UI. |
Sources: src/ResourcePackStack.js:11-20
Resource Resolution Logic
The resolution logic distinguishes between standard assets (like images) and specific configuration JSON files that require merging rather than simple replacement.
The diagram shows the decision path taken by the fetchResource method when an asset is requested.
Sources: src/ResourcePackStack.js:33-55
Data Flow and Merging
Mergeable JSON Files
Certain files are not simply overridden but are merged to combine definitions from multiple sources. This is handled using the deepmerge library. The system identifies these files via the static #JSON_FILES_TO_MERGE array:
blocks.jsontextures/terrain_texture.jsontextures/flipbook_textures.json
Sources: src/ResourcePackStack.js:12-12
Fetching Process
When fetchResource(resourcePath) is called:
- JSON Merging: If the path is in the merge list, the system fetches the vanilla version and all available local versions. It reverses the local pack array so that lower-priority packs are processed first, allowing higher-priority packs to overwrite values during the merge.
- Standard Overrides: For other files (e.g.,
.pngtextures,.langfiles), the system iterates throughlocalResourcePacks. The first pack containing the file returns it immediately. - Vanilla Fallback: If no local pack contains the file, it defaults to the
fetchers.vanillaDatautility.
Sources: src/ResourcePackStack.js:33-55
UI Integration
The user interacts with the stacking system through the "Resource packs" tab in the web interface.
Input Handling
In index.html, a file input with the webkitdirectory attribute allows users to upload entire local resource pack folders.
<fieldset>
<legend data-translate="resource_packs.heading">Resource packs</legend>
<label><span data-translate="resource_packs.upload_local">Upload a local resource pack:</span><br/>
<input type="file" webkitdirectory name="localResourcePack"/></label>
<button type="button" id="clearResourcePackCacheButton">Clear resource pack cache</button>
</fieldset>
Sources: src/index.html:183-188
Initialization in Generation
During the pack generation process in index.js, the form data is parsed, and a new ResourcePackStack is instantiated with the uploaded directories.
let localResourcePackFiles = cast(generatePackForm.elements.namedItem("localResourcePack"), HTMLInputElement).files;
if(localResourcePackFiles.length) {
resourcePacks.push(await LocalResourcePack.new(localResourcePackFiles));
}
let resourcePackStack = new ResourcePackStack(resourcePacks);
Sources: src/index.js:523-531
Integration with Pack Generation
The ResourcePackStack is passed as a dependency to the main makePack function. It is primarily utilized by the TextureAtlas and BlockGeoMaker to resolve textures and geometry definitions.
The sequence diagram illustrates how the ResourcePackStack provides assets to the TextureAtlas during the generation of the hologram's texture sheet.
Sources: src/HoloPrint.js:133-138, src/HoloPrint.js:189-195
Verification and Testing
The project includes tests to ensure translation coverage and resource availability. Specifically, tests/checkBlockTranslationCoverage/index.js utilizes ResourcePackStack to fetch en_US.lang to verify that all block names are properly mapped to translatable strings.
Sources: tests/checkBlockTranslationCoverage/index.js:17-25
Summary
Resource Pack Stacking provides a flexible layer between the core generation logic and the asset source. By prioritizing local directories and performing deep merges on critical configuration files, HoloPrint ensures that generated resource packs are compatible with custom user environments and specialized block data.