Task 380: .MCMETA File Format

Task 380: .MCMETA File Format

The .MCMETA file format is a text-based JSON format used in Minecraft: Java Edition for metadata in resource packs, data packs, and texture animations. It is not a binary format and has no fixed byte structure or magic number; instead, it relies on valid JSON syntax with specific root keys depending on the file's purpose. There are primarily two variants: pack.mcmeta (for pack metadata) and .png.mcmeta (for animation metadata on textures). The file extension is always .mcmeta, typically encoded in UTF-8, with no inherent MIME type (often treated as application/json). Specifications are sourced from the official Minecraft Wiki.

List of all properties (JSON fields) intrinsic to the format:

  • For pack.mcmeta variant:
  • pack (object): Contains core pack info.
  • description (string, text component, or object): Pack description shown in-game.
  • pack_format (integer): Version compatibility number.
  • supported_formats (integer, array of integers, or object with min_inclusive/max_inclusive): Optional range of supported formats.
  • features (object, optional): Experimental feature selections.
  • filter (object, optional): File filtering rules.
  • block (array of objects): Patterns to block files.
  • namespace (string, optional regex): Namespace filter.
  • path (string, optional regex): Path filter.
  • overlays (object, optional): Sub-pack overlays.
  • entries (array of objects): Overlay definitions.
  • formats (integer, array of integers, or object with min_inclusive/max_inclusive): Format range for overlay.
  • directory (string): Overlay directory name.
  • language (object, optional): Additional languages.
  • <language_code> (object, e.g., "en_us"): Language definition.
  • name (string): Language name.
  • region (string): Region.
  • bidirectional (boolean): Text direction flag.
  • For animation .mcmeta variant:
  • animation (object): Contains animation details.
  • interpolate (boolean, optional, default false): Enable frame interpolation.
  • width (integer, optional): Frame width in pixels.
  • height (integer, optional): Frame height in pixels.
  • frametime (integer, optional, default 1): Default frame duration in ticks.
  • frames (array, optional): Frame order and timings (integers or objects with index (integer) and time (integer)).

Two direct download links for .MCMETA files:

HTML/JavaScript snippet for embedding in a Ghost blog (or similar) to allow drag-and-drop of a .MCMETA file and dump properties to screen:

Drag and drop a .mcmeta file here
  1. Python class:
import json
import os

class McMetaHandler:
    def __init__(self, filepath):
        self.filepath = filepath
        self.data = None

    def read(self):
        if not os.path.exists(self.filepath):
            raise FileNotFoundError(f"File {self.filepath} not found.")
        with open(self.filepath, 'r', encoding='utf-8') as f:
            self.data = json.load(f)

    def print_properties(self):
        if self.data is None:
            print("No data loaded. Call read() first.")
            return
        print(json.dumps(self.data, indent=4))

    def write(self, output_path=None):
        if self.data is None:
            print("No data to write. Load or set data first.")
            return
        path = output_path or self.filepath
        with open(path, 'w', encoding='utf-8') as f:
            json.dump(self.data, f, indent=4)
        print(f"Written to {path}")

# Example usage:
# handler = McMetaHandler('example.mcmeta')
# handler.read()
# handler.print_properties()
# handler.data['pack']['description'] = 'Updated'
# handler.write('updated.mcmeta')
  1. Java class:
import java.io.*;
import org.json.JSONObject;
import org.json.JSONTokener;

public class McMetaHandler {
    private String filepath;
    private JSONObject data;

    public McMetaHandler(String filepath) {
        this.filepath = filepath;
        this.data = null;
    }

    public void read() throws IOException {
        File file = new File(filepath);
        if (!file.exists()) {
            throw new FileNotFoundException("File " + filepath + " not found.");
        }
        try (FileReader reader = new FileReader(file)) {
            this.data = new JSONObject(new JSONTokener(reader));
        }
    }

    public void printProperties() {
        if (data == null) {
            System.out.println("No data loaded. Call read() first.");
            return;
        }
        System.out.println(data.toString(4));
    }

    public void write(String outputPath) throws IOException {
        if (data == null) {
            System.out.println("No data to write. Load or set data first.");
            return;
        }
        String path = (outputPath != null) ? outputPath : filepath;
        try (FileWriter writer = new FileWriter(path)) {
            data.write(writer, 4, 0);
        }
        System.out.println("Written to " + path);
    }

    // Example usage:
    // public static void main(String[] args) throws IOException {
    //     McMetaHandler handler = new McMetaHandler("example.mcmeta");
    //     handler.read();
    //     handler.printProperties();
    //     handler.data.getJSONObject("pack").put("description", "Updated");
    //     handler.write("updated.mcmeta");
    // }
}
  1. JavaScript class (Node.js, using fs module):
const fs = require('fs');

class McMetaHandler {
  constructor(filepath) {
    this.filepath = filepath;
    this.data = null;
  }

  read() {
    if (!fs.existsSync(this.filepath)) {
      throw new Error(`File ${this.filepath} not found.`);
    }
    const content = fs.readFileSync(this.filepath, 'utf-8');
    this.data = JSON.parse(content);
  }

  printProperties() {
    if (this.data === null) {
      console.log('No data loaded. Call read() first.');
      return;
    }
    console.log(JSON.stringify(this.data, null, 4));
  }

  write(outputPath = null) {
    if (this.data === null) {
      console.log('No data to write. Load or set data first.');
      return;
    }
    const path = outputPath || this.filepath;
    fs.writeFileSync(path, JSON.stringify(this.data, null, 4), 'utf-8');
    console.log(`Written to ${path}`);
  }
}

// Example usage:
// const handler = new McMetaHandler('example.mcmeta');
// handler.read();
// handler.printProperties();
// handler.data.pack.description = 'Updated';
// handler.write('updated.mcmeta');
  1. C++ class (using nlohmann/json library for JSON handling; assume included):
#include <iostream>
#include <fstream>
#include <string>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

class McMetaHandler {
private:
    std::string filepath;
    json data;

public:
    McMetaHandler(const std::string& fp) : filepath(fp) {}

    void read() {
        std::ifstream file(filepath);
        if (!file.is_open()) {
            throw std::runtime_error("File " + filepath + " not found.");
        }
        file >> data;
        file.close();
    }

    void printProperties() {
        if (data.is_null()) {
            std::cout << "No data loaded. Call read() first." << std::endl;
            return;
        }
        std::cout << data.dump(4) << std::endl;
    }

    void write(const std::string& outputPath = "") {
        if (data.is_null()) {
            std::cout << "No data to write. Load or set data first." << std::endl;
            return;
        }
        std::string path = outputPath.empty() ? filepath : outputPath;
        std::ofstream file(path);
        file << data.dump(4);
        file.close();
        std::cout << "Written to " << path << std::endl;
    }
};

// Example usage:
// int main() {
//     try {
//         McMetaHandler handler("example.mcmeta");
//         handler.read();
//         handler.printProperties();
//         handler.data["pack"]["description"] = "Updated";
//         handler.write("updated.mcmeta");
//     } catch (const std::exception& e) {
//         std::cerr << e.what() << std::endl;
//     }
//     return 0;
// }