Repository navigation
3.1 ModSmith Project Initialization and Environment Setup
This guide walks you through setting up the ModSmith development environment from scratch and configuring Zhipu GLM as the LLM backend. All commands and files can be copied and executed directly.
- Python 3.10+
- Terminal (Terminal on macOS/Linux, PowerShell on Windows)
- Git (optional)
- Zhipu API Key (Get it here)
Check the Python version:
python3 --versioncd ~
mkdir modsmith
cd modsmithYou can use any path you like.
python3 -m venv .venvActivate the virtual environment:
# macOS / Linux
source .venv/bin/activate
# Windows PowerShell
.venv\Scripts\Activate.ps1Verify: (.venv) appears before the terminal prompt.
Create pyproject.toml in the project root:
[build-system]
requires = ["setuptools>=68", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "modsmith"
version = "0.1.0"
description = "Forge Fabric mods from natural language"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"anthropic>=0.40.0",
"jsonschema>=4.23.0",
"jinja2>=3.1.4",
"pillow>=10.4.0",
"typer>=0.15.0",
"rich>=13.9.0",
"python-dotenv>=1.0.0",
]
[project.optional-dependencies]
dev = [
"pytest>=8.3.0",
"pytest-mock>=3.14.0",
]
[project.scripts]
modsmith = "modsmith.cli:app"
[tool.setuptools.packages.find]
where = ["."]
include = ["modsmith*"]mkdir -p modsmith/blueprint/examples
mkdir -p modsmith/llm
mkdir -p modsmith/generator
mkdir -p modsmith/verifier
mkdir -p modsmith/templates/fabric-project
mkdir -p modsmith/templates/java
mkdir -p modsmith/templates/resources
mkdir -p tests"""ModSmith - Forge Fabric mods from natural language."""
__version__ = "0.1.0""""Blueprint definition, schema, and validation.""""""LLM client for generating blueprints from natural language.""""""Deterministic project and file generation.""""""Compile verification via Gradle.""""""ModSmith CLI entry point."""
import typer
from rich.console import Console
app = typer.Typer(
name="modsmith",
help="Forge Fabric mods from natural language.",
no_args_is_help=True,
)
console = Console()
@app.command()
def version() -> None:
"""Show ModSmith version."""
from modsmith import __version__
console.print(f"ModSmith v{__version__}")
@app.command()
def generate(
description: str = typer.Argument(..., help="Natural language description of the mod"),
output: str = typer.Option("./output", "--output", "-o", help="Output directory"),
) -> None:
"""Generate a Fabric mod from a natural language description."""
console.print(f"[yellow]TODO:[/yellow] Generate mod from: {description}")
console.print(f"[yellow]TODO:[/yellow] Output to: {output}")
if __name__ == "__main__":
app()touch tests/__init__.py"""ModSmith global configuration: centralized version numbers and defaults."""
# ============================================================
# Target Minecraft version configuration
# Change only here when upgrading
# ============================================================
MINECRAFT_VERSION = "26.1.2"
FABRIC_LOADER_VERSION = "0.19.5"
LOOM_VERSION = "1.17-SNAPSHOT"
FABRIC_API_VERSION = "0.155.2+26.1.2"
JAVA_VERSION = 25
# ============================================================
# Default mod metadata
# ============================================================
DEFAULT_MOD_VERSION = "0.1.0"
DEFAULT_AUTHOR = "ModSmith User"
DEFAULT_DESCRIPTION = "A ModSmith generated mod"
def default_context() -> dict:
"""Return the default context (version-related fields) for template rendering.
These values are overridden by fields of the same name in the blueprint,
but if the blueprint does not provide them, the defaults here are used.
"""
return {
"minecraft_version": MINECRAFT_VERSION,
"fabric_loader_version": FABRIC_LOADER_VERSION,
"loom_version": LOOM_VERSION,
"fabric_api_version": FABRIC_API_VERSION,
"mod_version": DEFAULT_MOD_VERSION,
"author": DEFAULT_AUTHOR,
"mod_description": DEFAULT_DESCRIPTION,
}Note: To upgrade versions later, just modify these constants here, and all modules will follow automatically.
"""LLM client for generating blueprints from natural language."""
import os
import json
from pathlib import Path
import anthropic
from dotenv import load_dotenv
# Load .env file
load_dotenv()
# Anthropic-compatible endpoint for Zhipu GLM
ZHIPU_BASE_URL = "https://open.bigmodel.cn/api/anthropic"
# Default model (can be overridden in .env)
DEFAULT_MODEL = os.environ.get("GLM_MODEL", "glm-5.3")
# Blueprint schema paths
SCHEMA_PATH = Path(__file__).parent.parent / "blueprint" / "schema.json"
EXAMPLES_DIR = Path(__file__).parent.parent / "blueprint" / "examples"
def _load_schema() -> dict:
"""Load the blueprint JSON Schema."""
with open(SCHEMA_PATH, "r", encoding="utf-8") as f:
return json.load(f)
def _load_examples() -> list[dict]:
"""Load few-shot example blueprints."""
from modsmith.config import default_context
defaults = default_context()
examples = []
if EXAMPLES_DIR.exists():
for path in sorted(EXAMPLES_DIR.glob("*.json")):
with open(path, "r", encoding="utf-8") as f:
example = json.load(f)
# Override version fields in examples with configured versions
example["minecraft_version"] = defaults["minecraft_version"]
example["fabric_loader_version"] = defaults["fabric_loader_version"]
examples.append(example)
return examples
def _build_system_prompt() -> str:
"""Build the system prompt, including the Schema and few-shot examples."""
schema = _load_schema()
examples = _load_examples()
prompt = f"""You are a Minecraft Fabric mod blueprint generator.
Your task is to generate a blueprint that conforms to the following JSON Schema based on the user's natural-language description.
## Schema
```json
{json.dumps(schema, indent=2, ensure_ascii=False)}
```
## Examples
"""
for i, example in enumerate(examples, 1):
prompt += f"### Example {i}\n\n```json\n{json.dumps(example, indent=2, ensure_ascii=False)}\n```\n\n"
prompt += """## Rules
1. Output JSON only. Do not include any explanation, comments, or Markdown code fences.
2. All required fields must be present.
3. The `type` field can only be one of: basic, food, fuel, tool.
4. If the description is ambiguous, use reasonable default values.
5. If the `texture` field cannot be determined, use "auto".
"""
return prompt
def get_client() -> anthropic.Anthropic:
"""Create and return an Anthropic client for Zhipu GLM."""
api_key = os.environ.get("ANTHROPIC_API_KEY")
if not api_key:
raise ValueError(
"ANTHROPIC_API_KEY is not set. Please configure your Zhipu API Key in the .env file."
)
return anthropic.Anthropic(
api_key=api_key,
base_url=ZHIPU_BASE_URL,
)
def generate_blueprint(user_input: str) -> dict:
"""Convert a natural-language description into structured blueprint JSON.
Args:
user_input: The user's natural-language description of the mod.
Returns:
A blueprint dictionary that conforms to the Schema.
Raises:
ValueError: When the API key is not configured.
json.JSONDecodeError: When the content returned by the LLM is not valid JSON.
"""
client = get_client()
system_prompt = _build_system_prompt()
message = client.messages.create(
model=DEFAULT_MODEL,
max_tokens=4096,
system=system_prompt,
messages=[
{"role": "user", "content": user_input},
],
)
# Extract text content
response_text = message.content[0].text.strip()
# Remove possible Markdown code fence markers
if response_text.startswith("```"):
lines = response_text.split("\n")
response_text = "\n".join(lines[1:-1])
# Parse JSON
blueprint = json.loads(response_text)
return blueprintCreate .env in the project root:
# Zhipu GLM API configuration
ANTHROPIC_API_KEY=your_zhipu_api_key
# Optional: specify the model to use (default glm-5.2)
# GLM_MODEL=glm-5.2Get an API Key: Visit Zhipu Open Platform to create one.
.venv/
__pycache__/
*.pyc
*.egg-info/
build/
dist/
output/
.pytest_cache/
.env{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["mod_id", "package_name", "minecraft_version", "fabric_loader_version", "items"],
"properties": {
"mod_id": { "type": "string" },
"package_name": { "type": "string" },
"minecraft_version": { "type": "string" },
"fabric_loader_version": { "type": "string" },
"items": {
"type": "array",
"items": {
"type": "object",
"required": ["id", "type", "display_name_en"],
"properties": {
"id": { "type": "string" },
"type": { "enum": ["basic", "food", "fuel", "tool"] },
"display_name_en": { "type": "string" },
"display_name_zh": { "type": "string" },
"nutrition": { "type": "integer" },
"saturation": { "type": "number" },
"always_edible": { "type": "boolean" },
"effects": {
"type": "array",
"items": {
"type": "object",
"properties": {
"effect": { "type": "string" },
"duration_ticks": { "type": "integer" },
"amplifier": { "type": "integer" }
}
}
},
"texture": { "type": "string" }
}
}
}
}
}{
"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": "治愈苹果",
"nutrition": 4,
"saturation": 0.3,
"always_edible": true,
"effects": [
{ "effect": "regeneration", "duration_ticks": 200, "amplifier": 0 }
],
"texture": "auto"
}
]
}# ModSmith
Forge Fabric mods from natural language.
## Install
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
```
## Usage
```bash
modsmith --help
modsmith version
modsmith generate "create an apple that restores 4 hunger points when eaten"
```Make sure the virtual environment is activated:
pip install -e ".[dev]"For faster installation in China:
pip install -e ".[dev]" -i https://pypi.tuna.tsinghua.edu.cn/simplemodsmith --helpIt should display help information.
modsmith versionIt should output ModSmith v0.1.0.
Create test_llm.py:
"""Test Zhipu GLM connection."""
import json
from modsmith.llm.client import generate_blueprint
result = generate_blueprint("Create an apple that restores 4 hunger points when eaten")
print(json.dumps(result, indent=2, ensure_ascii=False))Run:
python test_llm.pyIf configured correctly, it should output blueprint-like JSON.
git init
git add .
git commit -m "Task 0: project initialization with Zhipu GLM"- Project directory created
- Virtual environment
.venv/created and activated -
pyproject.tomlcreated with all dependencies - Directory structure complete
-
modsmith --helpdisplays help -
modsmith versionoutputsModSmith v0.1.0 -
pip install -e ".[dev]"succeeds -
.envconfigured with Zhipu API Key -
test_llm.pysuccessfully calls Zhipu GLM and returns blueprint JSON - Git repository initialized (optional)
Q1: pip install times out.
Use a China mirror:
pip install -e ".[dev]" -i https://pypi.tuna.tsinghua.edu.cn/simpleQ2: ANTHROPIC_API_KEY is not set.
Confirm that the .env file is in the project root and the key name is correct.
Q3: model_not_found.
Check the GLM_MODEL environment variable and make sure it is a model code supported by Zhipu (for example, glm-5.2).
Q4: The returned content is not valid JSON.
generate_blueprint already performs basic cleanup. If it still fails, strengthen the constraints in the system prompt or add regex extraction.
After completing the above steps, you will have a runnable ModSmith project skeleton and will be able to successfully call Zhipu GLM to generate blueprints. Next, proceed to Task 2: Define Blueprint Schema.