Data Driving Minecraft

Loading the JSON Data

Minecraft uses JsonReloadListener to load all JSON files in a specific folder. We could use the same class, but this leads to some messy code and doesn’t feel clean. As we did with the ModResourceManager we can create a stripped down version of it specifically for mods:

public class ModJsonLoader {
    private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().disableHtmlEscaping().create();
    private static final String JSON_EXTENSION = ".json";
    private static final int JSON_EXTENSION_LENGTH = JSON_EXTENSION.length();
    private static final Logger LOGGER = LogManager.getLogger();

    public Map<ResourceLocation, JsonObject> loadJsonResources(IResourceManager resourceManager, String folder) {
        Map<ResourceLocation, JsonObject> result = Maps.newHashMap();
        int folderNameLength = folder.length();

        for (ResourceLocation resourceLocation : resourceManager.getAllResourceLocations(folder, (x) -> {
            return  x.endsWith(".json");
        })) {
            String path = resourceLocation.getPath();
            String namespace = resourceLocation.getNamespace();
            String resourceName = path.substring(folderNameLength, path.length() - JSON_EXTENSION_LENGTH);
            ResourceLocation registryName = new ResourceLocation(namespace, resourceName);

            try (
                    IResource resource = resourceManager.getResource(resourceLocation);
                    InputStream inputStream = resource.getInputStream();
                    Reader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            ) {
                JsonObject jsonObject = JSONUtils.fromJson(GSON, reader, JsonObject.class);
                if (jsonObject != null) {
                    JsonObject entry = result.put(registryName, jsonObject);
                    if (entry != null) {
                        throw new IllegalStateException("Duplicate data file ignored with ID " + registryName);
                    }
                } else {
                    LOGGER.error("Couldn't load file {} from {} as it's null or empty.", registryName, resourceLocation);
                }
            } catch (IllegalArgumentException | IOException | JsonParseException exception) {
                LOGGER.error("Couldn't parse data file {} from {}", registryName, resourceLocation, exception);
            }
        }

        return  result;
    }
}

This is pretty much a copy of the code in JsonReloadListener. We have moved the Gson object into this class since this is the only place it is used, and we have changed the method declaration so it only takes a ResourceManager and the folder to load from. Now we have a simple class that can load all JSON files from any subfolder in assets or data.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.