Skip to content

3.7 Implementing the Resource File Generator

Zhoumy303 edited this page Sep 27, 2026 · 1 revision

The goal of this task is to generate correct resource files for each item in the blueprint, including the client item definition, model JSON, and translation files.
Resource files are the key to how Minecraft identifies an item's appearance and name. In Task 5 we already had a basic version, but it only supported the basic type. This task refines it to support all types including food, fuel, and tool, and to correctly handle the model's parent (item/generated or item/handheld).


Prerequisites

  • Completed Task 5: modsmith/generator/resources.py already has a basic framework.
  • Completed Task 6: The Java code generator is complete, and item IDs and types are finalized.
  • Familiar with resource file path conventions: assets/<mod_id>/items/, models/item/, lang/.

Step 1: Understand the resource file generation rules

File type Path Content
Client item definition assets/<mod_id>/items/<item_id>.json Points to the model file
Model file assets/<mod_id>/models/item/<item_id>.json Defines parent and texture path
English translation assets/<mod_id>/lang/en_us.json Item's English name
Chinese translation assets/<mod_id>/lang/zh_cn.json Item's Chinese name (optional)

Choice of model parent:

  • For tools (tool), use minecraft:item/handheld (handheld model).
  • For other types (basic, food, fuel), use minecraft:item/generated (flat icon).

Step 2: Complete modsmith/generator/resources.py

Replace the file content with the following complete code:

"""Generate item-related resource files (models, translations, client item definitions)."""

import json
from pathlib import Path


def generate_resources(blueprint: dict, project_dir: Path) -> None:
    """Generate resource files for the items in the blueprint.

    Args:
        blueprint: Blueprint dictionary.
        project_dir: Root directory of the generated project.
    """
    mod_id = blueprint["mod_id"]
    assets_dir = project_dir / "src" / "main" / "resources" / "assets" / mod_id

    # Create necessary directories
    (assets_dir / "items").mkdir(parents=True, exist_ok=True)
    (assets_dir / "models" / "item").mkdir(parents=True, exist_ok=True)
    (assets_dir / "textures" / "item").mkdir(parents=True, exist_ok=True)
    (assets_dir / "lang").mkdir(parents=True, exist_ok=True)

    # Collect translation key-value pairs
    en_us = {}
    zh_cn = {}

    for item in blueprint["items"]:
        item_id = item["id"]

        # 1. Client item definition
        client_item = {
            "model": {
                "type": "minecraft:model",
                "model": f"{mod_id}:item/{item_id}"
            }
        }
        (assets_dir / "items" / f"{item_id}.json").write_text(
            json.dumps(client_item, indent=2, ensure_ascii=False), encoding="utf-8"
        )

        # 2. Model file: choose parent based on type
        if item["type"] == "tool":
            parent = "minecraft:item/handheld"
        else:
            parent = "minecraft:item/generated"

        model = {
            "parent": parent,
            "textures": {
                "layer0": f"{mod_id}:item/{item_id}"
            }
        }
        (assets_dir / "models" / "item" / f"{item_id}.json").write_text(
            json.dumps(model, indent=2, ensure_ascii=False), encoding="utf-8"
        )

        # 3. Translation
        translation_key = f"item.{mod_id}.{item_id}"
        en_us[translation_key] = item.get("display_name_en", item_id)
        if "display_name_zh" in item:
            zh_cn[translation_key] = item["display_name_zh"]

    # Write English translations
    (assets_dir / "lang" / "en_us.json").write_text(
        json.dumps(en_us, indent=2, ensure_ascii=False), encoding="utf-8"
    )

    # Write Chinese translations (only when Chinese translations exist)
    if zh_cn:
        (assets_dir / "lang" / "zh_cn.json").write_text(
            json.dumps(zh_cn, indent=2, ensure_ascii=False), encoding="utf-8"
        )

Key improvements:

  • Chooses model parent based on item type: tools use handheld, others use generated.
  • Correctly generates translation keys in the format item.<mod_id>.<item_id>.
  • Creates all necessary directories, including textures/item (although textures are generated in Task 8, the directory is created here in advance).

Step 3: Ensure the project generator calls the resource generator

In modsmith/generator/project.py's generate_project(), generate_resources() is already called. Confirm the code exists:

from modsmith.generator.resources import generate_resources

def generate_project(blueprint: dict, output_dir: Path) -> None:
    render_project(blueprint, output_dir)
    generate_java_items(blueprint, output_dir)
    generate_resources(blueprint, output_dir)
    print(f"✅ Project fully generated at: {output_dir}")

Step 4: Create the test script test_resources.py

Create at the project root:

"""Test resource file generation."""

from pathlib import Path

from modsmith.generator.resources import generate_resources

# Manually construct a blueprint containing multiple types
blueprint = {
    "mod_id": "example-mod",
    "package_name": "com.example",
    "minecraft_version": "26.1.2",
    "fabric_loader_version": "0.19.5",
    "items": [
        {
            "id": "ruby",
            "type": "basic",
            "display_name_en": "Ruby",
            "display_name_zh": "红宝石",
            "texture": "auto"
        },
        {
            "id": "healing_apple",
            "type": "food",
            "display_name_en": "Healing Apple",
            "display_name_zh": "治愈苹果",
            "nutrition": 4,
            "saturation": 0.3,
            "always_edible": True,
            "effects": [],
            "texture": "auto"
        },
        {
            "id": "guidite_sword",
            "type": "tool",
            "display_name_en": "Guidite Sword",
            "display_name_zh": "基迪特剑",
            "tool_type": "sword",
            "durability": 455,
            "mining_speed": 5.0,
            "attack_damage": 1.5,
            "texture": "auto"
        }
    ]
}

# Generate to a temporary directory
output_dir = Path("./test_resources_output")
generate_resources(blueprint, output_dir)
print(f"Resource files generated at: {output_dir}")

Run:

python test_resources.py

Expected result: Under test_resources_output/src/main/resources/assets/example-mod/, the following are generated:

  • items/ruby.json, items/healing_apple.json, items/guidite_sword.json
  • models/item/ruby.json (parent: item/generated)
  • models/item/healing_apple.json (parent: item/generated)
  • models/item/guidite_sword.json (parent: item/handheld)
  • lang/en_us.json and lang/zh_cn.json

Step 5: Verify the generated JSON content

Open a few files manually to confirm:

models/item/guidite_sword.json:

{
  "parent": "minecraft:item/handheld",
  "textures": {
    "layer0": "example-mod:item/guidite_sword"
  }
}

lang/zh_cn.json:

{
  "item.example-mod.ruby": "红宝石",
  "item.example-mod.healing_apple": "治愈苹果",
  "item.example-mod.guidite_sword": "基迪特剑"
}

items/ruby.json:

{
  "model": {
    "type": "minecraft:model",
    "model": "example-mod:item/ruby"
  }
}

Everything is correct.


Step 6: Common issues

Problem Cause Solution
Translation file not generated Blueprint has no display_name_zh Add it manually, or ignore it (English still works)
Wrong model parent Type-checking logic issue Confirm item["type"] == "tool" is evaluated correctly in code
Path case error mod_id contains uppercase letters Ensure mod_id is all lowercase and follows naming conventions
Item not visible in-game after generation Texture missing Task 8 will generate placeholder textures, after which it will display

Step 7: Task 7 Acceptance Criteria

  • resources.py can generate items/*.json and models/item/*.json for all items.
  • Tool types use item/handheld parent; others use item/generated.
  • Generates en_us.json and zh_cn.json (if a Chinese name exists).
  • test_resources.py runs successfully, and the generated JSON content is correct.
  • The resource file paths conform to Fabric conventions and can be loaded by the game.

After completing this task, your ModSmith will be able to generate complete item resource files. Next, Task 8 will implement the texture generator, producing placeholder PNGs for each item so that items are actually visible in-game.

Clone this wiki locally