Skip to content

2. MVP Design

Zhoumy303 edited this page Sep 26, 2026 · 1 revision

MVP Design

This document focuses on the technical design of the ModSmith MVP. Project motivation, industry background, target users, value positioning, and the argument for "why a blueprint layer is needed" are covered in 1. Project Background and are not repeated here.


1. MVP Scope

1.1 Minimum Feature Set

The ModSmith MVP focuses on three item types: basic, food, and tool, to get the pipeline working end to end. The goal:

The user enters "create an apple that restores 4 hunger points when eaten," and the system outputs a compilable Fabric project zip, with the item verifiable in-game.

1.2 Interaction Modes

The MVP implements two modes: Chat and Execute (design rationale in 1. Project Background, Section 5):

Mode Responsibility Output
Chat (concept Q&A) Requirements consultant; multi-turn dialogue to clarify needs Natural language + 【Requirement Summary】
Execute (direct generation) Takes a clear description and triggers the generation pipeline Full project + jar

Chat → Execute handoff: Chat ends by outputting text marked with 【Requirement Summary】; the Web UI's "⚡ Summarize Requirements" button calls /api/chat/summarize to extract the summary, fills it into the Execute description box, and switches tabs automatically.

The Web UI opens the Chat tab by default. Tab order: Concept Q&A → Generate Mod.

Plan mode is a future direction and is out of scope for the MVP (see Section 7).


2. System Architecture

2.1 Four-Layer Architecture

flowchart TB
    subgraph L1["① User Interaction Layer"]
        direction TB
        CLI["CLI<br/>modsmith generate / chat / web"]
        WEB["Web UI<br/>Chat Tab / Execute Tab"]
    end

    subgraph L2["② LLM Parsing Layer"]
        direction TB
        GB["generate_blueprint()<br/>natural language → blueprint JSON"]
        CR["chat_response()<br/>multi-turn dialogue"]
        VB["validate_blueprint()<br/>Schema validation + feedback correction"]
    end

    subgraph L3["③ Deterministic Generation Layer"]
        direction TB
        RP["render_project()<br/>base project skeleton"]
        GJ["generate_java_items()<br/>Java registration code"]
        GR["generate_resources()<br/>models / translations / client items"]
        GT["generate_all_textures()<br/>placeholder textures"]
    end

    subgraph L4["④ Verification & Output Layer"]
        direction TB
        BW["build_with_retry()<br/>compile verification + LLM auto-correction"]
        RW["run_client_with_log()<br/>runtime verification"]
        PO["package_output()<br/>package zip / jar / blueprint / README"]
    end

    L1 --> L2
    L2 --> L3
    L3 --> L4
Loading

2.2 Data Flow

flowchart TD
    A[User description] --> B[Chat mode: multi-turn clarification]
    B --> C[Output 【Requirement Summary】]
    C --> D[Execute mode: clear mod description]
    A --> D

    D --> E[LLM generates blueprint JSON]
    E --> F[Schema validation]
    F --> G{Validation passed?}
    G -- No, up to 3 times --> H[Feed error back to LLM]
    H --> E
    G -- Yes --> I[Blueprint approved]

    I --> J[Jinja2 template rendering<br>generate Java/JSON/PNG files]
    J --> K[./gradlew build]
    K --> L{Compilation succeeded?}
    L -- No, up to 3 times --> M[Feed error back to LLM to fix blueprint]
    M --> E
    L -- Yes --> N[Compilation succeeded]

    N --> O[Package output<br>zip + jar + blueprint + README]
    O --> P[./gradlew runClient]
    P --> Q[Parse logs<br>check mod loading and item registration]
    Q --> R[Return verification result]
Loading

2.3 Version Configuration as a Single Source of Truth

All version numbers are managed centrally in modsmith/config.py:

MINECRAFT_VERSION = "26.2"
FABRIC_LOADER_VERSION = "0.19.5"
LOOM_VERSION = "1.17-SNAPSHOT"
FABRIC_API_VERSION = "0.161.0+26.2"
JAVA_VERSION = 25

Upgrading the Minecraft version requires only changing this one place; template rendering, the System Prompt, and example injection all follow automatically.


3. Key Module Design

3.1 Blueprint Schema

A blueprint is a JSON object describing "what to generate":

{
  "mod_id": "example-mod",
  "package_name": "com.example",
  "minecraft_version": "26.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"
    }
  ]
}

Design points:

  • type is an enum (basic, food, tool), determining which additional fields to generate.
  • Uses allOf + if-then for conditional required fields: nutrition and similar fields are only required when type=food.
  • pattern restricts the naming format of mod_id and item id, preventing the AI from inventing names.
  • Version numbers are injected by config.py; the Schema only enforces format constraints.

3.2 LLM Calling Layer

Module File Responsibility
Blueprint gen llm/client.py generate_blueprint(): natural language → blueprint JSON
Chat dialogue llm/chat.py chat_response(): multi-turn dialogue, requirements clarification
Blueprint check blueprint/validator.py Schema validation + feedback to LLM for correction

System Prompt design:

  • Execute mode: contains the full Schema, few-shot examples, required fields per type, and version requirements. Forces JSON output.
  • Chat mode: acts as a requirements consultant, explicitly stating capability boundaries (only basic/food/tool), limiting clarification dimensions (type/name/effect/value/appearance), refusing to answer technical questions, and ending with a 【Requirement Summary】 marker.

Example injection: example blueprints have their version fields overridden by config.py values at load time, preventing the LLM from learning outdated version numbers from the examples.

3.3 Deterministic Generation Layer

Module File Output
Project skeleton generator/project.py build.gradle, gradle.properties, fabric.mod.json, gradlew
Java code generator/java.py ModItemIds.java, ModItems.java, ModItemsGenerated.java
Resource files generator/resources.py Client item, model JSON, translation files
Textures generator/textures.py 16x16 PNG placeholder textures

Key decisions:

  • Java code is rendered with Jinja2 templates, separating templates from data and guaranteeing syntactic correctness.
  • JSON files use json.dumps() directly, no templates needed.
  • Texture colors are derived from the item ID's MD5 hash, ensuring the same ID produces the same color every time—deterministic and reproducible.
  • Static field declaration order: declare FoodProperties, Consumable, and ToolMaterial before Item, avoiding Java's "illegal forward reference".
  • Fabric template adapted for 26.2+: remove Yarn mappings, use the net.fabricmc.fabric-loom plugin, Java 25, Gradle 9.5.1, implementation instead of modImplementation, remove Mixin and the client entrypoint.

3.4 Verification Layer

Compile verification (verifier/gradle.py):

  • Runs ./gradlew build with a 5-minute timeout.
  • Extracts error lines from stdout/stderr, normalizing them to str.
  • On failure, feeds the error summary back to the LLM to correct the blueprint and retries, up to 3 times.

Runtime verification (verifier/runtime.py):

  • Launches ./gradlew runClient and captures logs line by line.
  • Detects mod loading via Hello Fabric world from.
  • Detects item registration via item.<mod_id>.<item_id> registered.
  • Emits registration logs proactively in ModItemsGenerated.java for the parser.

Division of labor between the two verifications: compile verification ensures the code compiles; runtime verification ensures items are actually registered into the game. They complement each other.

3.5 Packaging Layer

packager/archive.py's package_output() emits four types of files:

File Purpose
<mod_id>-src.zip Full project source, for further development
<mod_id>-1.0.0.jar Mod ready to drop into mods/
<mod_id>-blueprint.json The blueprint from this run, for reproducibility
README.md Installation instructions + full blueprint

The source zip excludes build/, .gradle/, .idea/, and run/ to keep it clean.

3.6 Pipeline Layer

pipeline.py's run_pipeline() integrates the full flow:

def run_pipeline(user_input, project_dir, output_dir, max_retries=3):
    blueprint = generate_validated_blueprint(user_input, max_retries)
    success, final_blueprint = build_with_retry(blueprint, project_dir, max_retries)
    if not success:
        return None
    return package_output(final_blueprint, project_dir, output_dir)

Both CLI and Web UI call it, ensuring consistent behavior.

3.7 Web UI Dual-Mode Routing

Layer File Responsibility
Backend web/app.py FastAPI routes, SSE push, Chat session storage
Frontend web/static/index.html Tab switching, Chat UI, Execute UI

Backend endpoints:

Endpoint Purpose
POST /api/generate Create a generation task
GET /api/stream/{task_id} SSE push of generation logs
POST /api/run_client Launch the game
POST /api/auto_verify Runtime log verification
POST /api/chat Append a Chat message
GET /api/chat/stream/{session_id} SSE push of Chat responses
POST /api/chat/summarize Extract requirement summary from conversation history
POST /api/chat/clear Clear the session

Key design points:

  • CHAT_SESSIONS (Chat sessions) and TASKS (generation tasks) are completely independent in-memory stores.
  • Chat supports SSE streaming output (typewriter effect).
  • Chat history is persisted in localStorage and restored on refresh.
  • /api/chat/summarize first tries to extract the 【Requirement Summary】 marker, falling back to an LLM rewrite.
  • Default tab is Chat. Tab order: Concept Q&A → Generate Mod.
  • No Google Fonts. Uses the system font stack so it loads in mainland China.

4. Technology Choices

Layer Solution Rationale
LLM Zhipu GLM (Anthropic-compatible endpoint) Accessible in China, supports structured output
Blueprint validation JSON Schema + jsonschema Clear definitions, friendly validation errors
Java code generation Jinja2 template engine Separates templates from data; simple and direct
JSON generation Python json module Standard library, no extra dependencies
Texture generation Pillow No external dependencies; deterministic output
Compile verification subprocess calling ./gradlew build Reuses Gradle directly
Runtime verification subprocess log capture + regex matching No GUI dependency; stable
Backend framework FastAPI Lightweight, good SSE support
Frontend Vanilla HTML + JS (no framework) Zero build, easy to distribute

5. Directory Structure

modsmith/
├── modsmith/
│   ├── config.py           # Single source of truth for versions
│   ├── cli.py              # CLI entry point
│   ├── pipeline.py         # End-to-end pipeline
│   ├── blueprint/          # Schema + validation
│   │   ├── schema.json
│   │   ├── validator.py
│   │   └── examples/
│   ├── llm/                # LLM clients
│   │   ├── client.py       # Blueprint generation
│   │   └── chat.py         # Chat dialogue
│   ├── generator/          # Deterministic generation
│   │   ├── project.py      # Project skeleton
│   │   ├── java.py         # Java code
│   │   ├── resources.py    # Resource files
│   │   └── textures.py     # Textures
│   ├── verifier/           # Verification
│   │   ├── gradle.py       # Compile verification
│   │   └── runtime.py      # Runtime verification
│   ├── packager/           # Packaging
│   │   └── archive.py
│   ├── web/                # Web UI
│   │   ├── app.py
│   │   └── static/
│   └── templates/          # Jinja2 templates
│       ├── fabric-project/
│       └── java/
└── tests/

6. Phased Roadmap

Phase Goal Status
Phase 1 CLI tool, basic items only, get compilation working ✅ Done
Phase 2 Extend to basic/food/tool, add LLM auto-correction ✅ Done
Phase 3 Web UI: form, logs, download, preview, launch game ✅ Done
Phase 4 Chat mode + dual-tab routing + runtime log verification ✅ Done
Phase 5 Plan mode + more item types (blocks, armor) 🔜 Future

7. Future Evolution: Plan Mode

Referencing ModCrafting's "three-mode intelligent routing," ModSmith's long-term direction is Chat → Plan → Execute:

  • Chat: clarify requirements
  • Plan: confirm the approach (not yet implemented)
  • Execute: run the generation

The core of Plan mode is having the LLM output a reviewable, editable structured plan before generation, including the files to create, fields, and verification steps. Users can review, edit, confirm, or roll back.

Why Plan is not implemented in the MVP:

  • Chat mode already handles "requirement confirmation"; the 【Requirement Summary】 is a lightweight "plan".
  • With only three simple item types supported, fields are few, and Plan's editing value is diluted.
  • A full Plan implementation requires new backend (plan generation and execution), frontend (third tab, field-level editing), and Schema design—a nontrivial amount of work, unsuitable for the MVP.
  • Plan will truly show its value once blocks, armor, recipes, or multi-item generation are supported.

8. MVP Boundaries

Things explicitly out of scope to prevent scope creep:

Not doing Reason
Blocks, armor, entities Focus on items; get the loop solid first
Crafting recipes Recipes are complex; MVP only generates the item itself
Multi-item batch generation Single item first; multi-item is future work
User accounts MVP is for single-user local use
Cloud deployment Runs locally; no server needed
Plan mode See Section 7; future evolution
Custom renderers Only generates the item; no advanced rendering

9. Acceptance Criteria

The MVP is complete when the following end-to-end flow works:

  1. In the Web UI's Chat tab, the user types "I want to make an apple that heals when eaten."
  2. Chat asks for details; the user replies "call it Healing Apple, heals half a heart."
  3. Chat outputs the 【Requirement Summary】.
  4. The user clicks "⚡ Summarize Requirements"; the Execute tab opens automatically with the summary pre-filled.
  5. The user clicks "⚡ Generate Mod."
  6. The system completes in order: blueprint generation → project generation → compilation → packaging.
  7. The page shows download links, the blueprint JSON, and the README.
  8. The user clicks "🔍 Log Verification."
  9. The system launches the game, parses the logs, and reports "mod loaded, item registered."
  10. The user downloads the jar, drops it into mods/, and sees the Healing Apple in-game.

If any step fails, the system either gives a clear error message or automatically corrects itself.


10. One-Sentence Summary

The ModSmith MVP is a technical implementation that forges mod ideas into compilable, editable Fabric mods through "natural language → structured blueprint → deterministic code generation." It includes dual modes—Chat (requirements clarification) + Execute (direct generation)—along with a dual verification loop: compile verification + runtime verification.

Clone this wiki locally