-
Notifications
You must be signed in to change notification settings - Fork 0
3.2 Defining the Blueprint Schema
In this task, you will write the blueprint JSON Schema and prepare example blueprints to constrain the structured output generated by the LLM. After completing this task, you will have a verifiable, constrainable, example-backed blueprint specification, laying the foundation for the subsequent generator modules.
- Completed Task 1: Project initialization and environment setup.
- Virtual environment activated.
-
jsonschemainstalled (already declared inpyproject.toml).
This Schema acts as a "contract" that constrains what the AI generates. It defines the global configuration, the type enum, and the conditional fields required by different types.
Write the following content into modsmith/blueprint/schema.json:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ModSmith Blueprint",
"type": "object",
"required": [
"mod_id",
"package_name",
"minecraft_version",
"fabric_loader_version",
"items"
],
"properties": {
"mod_id": {
"type": "string",
"description": "Unique identifier of the mod. Only lowercase letters, digits, and hyphens, e.g. example-mod",
"pattern": "^[a-z][a-z0-9-]*$"
},
"package_name": {
"type": "string",
"description": "Java package name, e.g. com.example",
"pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$"
},
"minecraft_version": {
"type": "string",
"description": "Target Minecraft version, determined by system configuration"
},
"fabric_loader_version": {
"type": "string",
"description": "Fabric Loader version, determined by system configuration"
},
"items": {
"type": "array",
"description": "List of items to generate",
"items": {
"type": "object",
"required": ["id", "type", "display_name_en"],
"properties": {
"id": {
"type": "string",
"description": "Unique item ID. Only lowercase letters, digits, and underscores, e.g. healing_apple",
"pattern": "^[a-z][a-z0-9_]*$"
},
"type": {
"type": "string",
"enum": ["basic", "food", "fuel", "tool"],
"description": "Item type"
},
"display_name_en": {
"type": "string",
"description": "English display name"
},
"display_name_zh": {
"type": "string",
"description": "Chinese display name"
},
"texture": {
"type": "string",
"description": "Texture path; 'auto' means auto-generate",
"default": "auto"
},
"nutrition": {
"type": "integer",
"minimum": 0,
"description": "Hunger restored by the food (required only when type=food)"
},
"saturation": {
"type": "number",
"minimum": 0,
"description": "Saturation added by the food (required only when type=food)"
},
"always_edible": {
"type": "boolean",
"description": "Whether always edible (effective only when type=food)",
"default": false
},
"effects": {
"type": "array",
"description": "Status effects applied on consumption (effective only when type=food)",
"items": {
"type": "object",
"required": ["effect", "duration_ticks", "amplifier"],
"properties": {
"effect": {
"type": "string",
"description": "Effect ID, e.g. regeneration, speed"
},
"duration_ticks": {
"type": "integer",
"minimum": 1,
"description": "Duration (in ticks; 20 ticks = 1 second)"
},
"amplifier": {
"type": "integer",
"minimum": 0,
"description": "Effect level; 0 means level I, 1 means level II"
}
}
}
},
"burn_time": {
"type": "integer",
"minimum": 1,
"description": "Burn time (in ticks; required only when type=fuel)"
},
"tool_type": {
"type": "string",
"enum": ["sword", "axe", "pickaxe", "shovel", "hoe"],
"description": "Tool type (required only when type=tool)"
},
"durability": {
"type": "integer",
"minimum": 1,
"description": "Durability (required only when type=tool)"
},
"mining_speed": {
"type": "number",
"minimum": 0.1,
"description": "Mining speed (required only when type=tool)"
},
"attack_damage": {
"type": "number",
"minimum": 0,
"description": "Attack damage (required only when type=tool)"
}
},
"allOf": [
{
"if": {
"properties": { "type": { "const": "food" } }
},
"then": {
"required": ["nutrition", "saturation", "always_edible"]
}
},
{
"if": {
"properties": { "type": { "const": "fuel" } }
},
"then": {
"required": ["burn_time"]
}
},
{
"if": {
"properties": { "type": { "const": "tool" } }
},
"then": {
"required": ["tool_type", "durability", "mining_speed", "attack_damage"]
}
}
]
}
}
}
}Notes:
-
patternrestricts the naming format ofmod_idand itemid, preventing the AI from inventing names. -
allOf+if-thenimplements conditional required fields:nutritionand similar fields are only required when the type isfood. -
effectsis an array, supporting multiple status effects on a food item.
_load_examples() automatically reads every .json file under modsmith/blueprint/examples/ and sends them to the AI as few-shot examples. We prepare 3 examples covering different type values.
This is the simplest item example.
{
"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": "Red Ruby",
"texture": "auto"
}
]
}This is a food example with a consumption effect.
{
"mod_id": "example-mod",
"package_name": "com.example",
"minecraft_version": "26.1.2",
"fabric_loader_version": "0.19.5",
"items": [
{
"id": "healing_apple",
"type": "food",
"display_name_en": "Healing Apple",
"display_name_zh": "Healing Apple",
"nutrition": 4,
"saturation": 0.3,
"always_edible": true,
"effects": [
{
"effect": "regeneration",
"duration_ticks": 200,
"amplifier": 0
}
],
"texture": "auto"
}
]
}This is a tool example showing the fields required by the tool type.
{
"mod_id": "example-mod",
"package_name": "com.example",
"minecraft_version": "26.1.2",
"fabric_loader_version": "0.19.5",
"items": [
{
"id": "guidite_sword",
"type": "tool",
"display_name_en": "Guidite Sword",
"display_name_zh": "Guidite Sword",
"tool_type": "sword",
"durability": 455,
"mining_speed": 5.0,
"attack_damage": 1.5,
"texture": "auto"
}
]
}We need to ensure:
- The Schema itself is a valid JSON Schema.
- All examples conform to this Schema.
Write a simple validation script test_schema.py (place it at the project root):
"""Validate that the Schema is legal and that examples conform to it."""
import json
from pathlib import Path
import jsonschema
# Path definitions
SCHEMA_PATH = Path("modsmith/blueprint/schema.json")
EXAMPLES_DIR = Path("modsmith/blueprint/examples")
def main() -> None:
# 1. Load the Schema
with open(SCHEMA_PATH, "r", encoding="utf-8") as f:
schema = json.load(f)
# 2. Validate the Schema itself
try:
jsonschema.Draft7Validator.check_schema(schema)
print("✅ The Schema itself is a valid JSON Schema.")
except jsonschema.SchemaError as e:
print(f"❌ The Schema itself is invalid: {e}")
return
# 3. Validate each example against the Schema
validator = jsonschema.Draft7Validator(schema)
all_passed = True
for example_path in sorted(EXAMPLES_DIR.glob("*.json")):
with open(example_path, "r", encoding="utf-8") as f:
example = json.load(f)
errors = list(validator.iter_errors(example))
if errors:
all_passed = False
print(f"❌ {example_path.name} does not conform to the Schema:")
for error in errors:
print(f" - {error.message}")
else:
print(f"✅ {example_path.name} conforms to the Schema.")
if all_passed:
print("\n🎉 All examples passed validation!")
else:
print("\n⚠️ Some examples did not pass validation. Please check.")
if __name__ == "__main__":
main()Run:
python test_schema.pyExpected output:
✅ The Schema itself is a valid JSON Schema.
✅ 01_basic_item.json conforms to the Schema.
✅ 02_food_item.json conforms to the Schema.
✅ 03_tool_item.json conforms to the Schema.
🎉 All examples passed validation!
After completing the steps above, re-run the previous LLM test script:
python test_llm.pyThis time, the System Prompt sent to the AI contains the complete Schema and the 3 examples. The AI should be able to generate more regular and complete blueprints. For example, if you input "create an apple that restores 4 hunger points when eaten," the JSON it outputs should automatically include effects: [], always_edible: true, and similar fields.
-
schema.jsonincludes global configuration, the item array, and conditional validation (allOf+if-then). - The
examples/directory contains 3 examples coveringbasic,food, andtooltypes. -
test_schema.pyruns successfully and all examples pass validation. - Re-running
test_llm.py, the LLM produces more regular blueprints based on the new Schema and examples.
After completing these steps, ModSmith will have a verifiable, constrainable, example-backed blueprint specification. This is the foundation for the subsequent generator modules (Tasks 6, 7, 8).