Logo   Home Table of Contents    News  Dev Blogs  Gallery  Timeline  Legend  Tags 
Join us on... 
Banner

Current: Month Day, Year

9.3 Modelling JSON file

The modelling.json file defines the properties, behavior, and UI configuration of individual modelling targets in MakeHuman 2. Each entry in this file corresponds to a morph target or set of targets that can modify the character's appearance through sliders in the modelling interface. This file works in tandem with target_cat.json, which defines the category hierarchy. While target_cat.json organizes targets into categories, modelling.json defines what each target actually does and how it behaves.

File Locations and loading order

Per mesh there might be 3 different target folders, they are scanned in the following order:
User constant targets <UserDataDir>/contarget/<basename>/modelling.json This method is used to replace the read-only system-targets, this is used in case of a complete new base in the user folders (the system-targets are read-only. Especially when a mesh is downloaded as a packet. modelling.json must be manually created.
System targets <SystemDir>/target/<basename>/modelling.json System targets are supplied from MakeHuman team by installation. modelling.json is part of the installation.
Append user targets <UserDataDir>/target/<basename>/modelling.json Additional user targets, which are added to either system-targets or constant targets. modelling.json is auto-generated in this case. Don't add this manually; the auto-generation will overwrite it anyway.

<basename> is the base mesh identifier (e.g., hm08, mh2bot)

To conclude: If contarget/<basename>/modelling.json exists, the system file is ignored. Otherwise, system and user files are scanned. The user entries are always added in the end.

File Format

modelling.json is a standard JSON file with a flat structure where each key represents a unique target identifier:

{ "TargetName1": { /* target properties */ }, "TargetName2": { /* target properties */ }, "TargetName3": { /* target properties */ } }

Target Entry Structure

Each target entry is a JSON object with various properties that define its behavior: "TargetName": { "group": "category|subcategory", "name": "Display Name", "tip": "Tooltip description", "incr": "path/to/increase-target", "decr": "path/to/decrease-target", "default": 0.5, "sym": "SymmetricTargetName", "icon": "icon-filename.png", "measure": "measurement-name", "display": { "slot": 1, "text": "Format: {}", "formula": "python expression" }, "macro": "macro/path", "macro_influence": [0, 1, 2, 3], "barycentric": ["target1", "target2", "target3"], "barycentric_diffuse": [[r, g, b], [r, g, b], [r, g, b]] }

Property Reference

Basic Properties:

group

string, required
"category|subcategory"

Specifies the category and subcategory for this target, separated by a pipe character. The category must match an entry in target_cat.json to appear in the UI. "group": "face|nose size" "group": "main|macro" "group": "torso|stomach"
name

string, optional

Human-readable display name shown in the UI slider label. If omitted: generated from the entry key by:
- Removing the category prefix
- Replacing hyphens with spaces
- Capitalizing appropriately
"Nose Width": { "name": "width", // Displayed as "width" "group": "face|nose size" }
tip

string, optional

Tooltip text displayed when hovering over the slider. Can include HTML tags for formatting. "tip": "Gender, minimum value is female, maximum value is male." "tip": "Age of the human (range from 1 year to 90 years old, with center position 25 years)."
default

number, optional
default: 0.5

Initial slider value when loading a new character. The range is from -1.0 to 1.0 for dual-targets, 0.0 to 1.0 for single targets. Internally stored and used as -100 to 100, so 0.5 becomes 50. "default": 0.0 // Slider starts at minimum "default": 0.5 // Slider starts at center (most common) "default": 1.0 // Slider starts at maximum
incr

string, required

Path to the target file that increases this feature. Format: Relative path from target directory, without .target extension "incr": "armslegs/l-hand-fingers-distance" "incr": "head/head-oval" "incr": "nose/nose-width-incr"
decr

string, optional

Path to the target file that decreases this feature. Used for: Bidirectional/dual targets where a feature can increase or decrease.
Behavior:
If both incr and decr exist: Creates a dual slider with negative and positive ranges
If only incr exists: Creates a unidirectional slider (0 to max)
"Nose Width": { "incr": "nose/nose-width-incr", "decr": "nose/nose-width-decr" }
icon

string, optional

Filename of the icon image to display alongside the slider.
Location: data/target/<basename>/icons/ or user icon directory
Format: PNG image
Auto-detection for user targets: If an icon file matches the pattern <folder>-<targetname>.png, it's automatically linked.
"icon": "head-oval.png" "icon": "breastsize.png" "icon": "nose-nostril-flare.png"
rsym
lsym

string, optional

Name of the symmetric counterpart target for left/right symmetry features. Used for: Features that exist on both sides of the body Behavior: When symmetry mode is enabled in the UI, moving one slider automatically moves its symmetric counterpart. "l-eye-height": { "group": "face|left eye", "rsym": "r-eye-height", "incr": "eyes/l-eye-height-incr", "decr": "eyes/l-eye-height-decr" }, "r-eye-height": { "group": "face|right eye", "lsym": "l-eye-height", "incr": "eyes/r-eye-height-incr", "decr": "eyes/r-eye-height-decr" }
measure

[array of vertices]

When values are given, these vertices are connected with lines in MakeHuman2 to indicate what the measurement stands for. "ME-Torso NapeWaist": { "name": "Nape to Waist", "group": "measure|torso", "decr": "measure/measure-napetowaist-dist-decr", "incr": "measure/measure-napetowaist-dist-incr", "measure": [1491,4181] }
macro

string, optional

Path to the macro definition that controls this target's behavior. The macro system loads a definition from macro.json that specifies which underlying targets to apply and at what intensities based on the slider value and other factors. Format: folder/MacroName (without extension)

Common folders:

  • macro_age/ - Core macro definitions (Gender, Age, etc.)
  • macro_muscle/ - Universal macros (Muscle, Weight)
  • macro_height/ - Height-related macros
  • macro_prop/ - Proportion macros
  • macro_fembreast/ - Breast-related macros
"Gender": { "group": "main|macro", "macro": "macrodetails/Gender", "default": 0.5 }
macro_influence

[array of integers], optional

List of macro component indices that this target influences. The macro influence system allows targets to interact and produce combined effects. When multiple macro targets are changed, their influences on shared components are calculated together to produce the final character shape. The numbers are 0 to 4, each representing a macro component:
  • 0: ethnicity/phenotype
  • 1: age/maturity related
  • 2: proportion related
  • 3: height/scale related
  • 4: gender/sexual characteristics
"Gender": { "macro": "macrodetails/Gender", "macro_influence": [0, 1, 2, 3, 4] // Affects all components } "Height": { "macro": "macrodetails-height/Height", "macro_influence": [3] // Only affects height component } "Muscle": { "macro": "macrodetails-universal/Muscle", "macro_influence": [1, 2, 3, 4] // Affects all except ethnicity }
barycentric

[array of 3 strings], optional

Three target paths defining the corners of a barycentric triangle. Barycentric targets use three-way interpolation between three different states, creating smooth transitions in a triangular coordinate system. UI BehaviorCreates a triangular slider interface where:
  • Each corner represents 100% of one target
  • The center represents 33.33% of each target
  • Any point inside represents a weighted blend of all three targets
"Phenotype": { "group": "main|macro", "barycentric": [ "macrodetails/African", "macrodetails/Asian", "macrodetails/Caucasian" ], "macro_influence": [0] }
barycentric_diffuse

array of 3 arrays, optional

Three color values (RGB) to blend along with the barycentric targets. As the barycentric slider changes, the diffuse color smoothly transitions between the three specified values, providing visual feedback and realistic skin tone variation. "barycentric_diffuse": [ [0.207, 0.113, 0.066], // African skin tone [0.721, 0.568, 0.431], // Asian skin tone [0.843, 0.639, 0.517] // Caucasian skin tone ]

Display Formula

A display formula is an object. It configures a custom text display that shows a calculated value based on the slider position.
slotinteger Display slot number (1-4) for positioning in the UI
textstring Format string with `{}` placeholder for the calculated value
formulastring Python expression to calculate the display value which is available as val and represents the current slider. Usable are python math operations, conditionals, string operations which will be calculated by using 'eval'.

Example 1 - Simple Age Display:

"display": { "slot": 2, "text": "Age: {}", "formula": "round(1 + val / (0.5/24)) if val < 0.5 else round(25 + (val-0.5) / (0.5/65))" } Result: "Age: 1" at 0.0, "Age: 25" at 0.5, "Age: 90" at 1.0

Example 2 - Percentage Display:

"display": { "slot": 3, "text": "Muscle: {}%", "formula": "round(val * 100, 2)" } Result: "Muscle: 0%" at 0.0, "Muscle: 50%" at 0.5, "Muscle: 100%" at 1.0

Example 3 - Conditional Text:

"display": { "slot": 1, "text": "{}", "formula": "'neutral' if 0.49 < val < 0.51 else 'male' if val > 0.99 else 'female' if val < 0.01 else str(round(100.0 - val*100.0)) + '% female, ' + str(round(val*100.0)) + '% male'" } Result: Shows text descriptions like "female", "neutral", "male", or percentages like "30% female, 70% male"

Target Type Examples

Simple Unidirectional Target A basic target that only increases a feature (no decrease).
UI: Single slider from 0 (no effect) to 100 (maximum effect)
"Head Oval": { "name": "Oval Shape", "group": "face|head shape", "icon": "head-oval.png", "incr": "head/head-oval" }
Dual Bidirectional Target A target that can increase or decrease a feature.
UI: Dual slider with: Left side (0-50): Applies decr target
Center (50): Neutral, no effect
"Nose Width": { "group": "face|nose size", "name": "width", "tip": "Makes the nose wider or narrower", "incr": "nose/nose-width-incr", "decr": "nose/nose-width-decr", "default": 0.5, "icon": "nose-width.png" }
Symmetric Target Pair Two related targets that can move together when symmetry is enabled.
UI: Two separate sliders that can be:
- Adjusted independently (normal mode)
- Adjusted together (symmetry mode enabled)
"l-eye-height": { "group": "face|left eye", "name": "eye height", "tip": "Raise or lower the left eye", "incr": "eyes/l-eye-height-incr", "decr": "eyes/l-eye-height-decr", "rsym": "r-eye-height", "default": 0.5, "icon": "eye-height.png" }, "r-eye-height": { "group": "face|right eye", "name": "eye height", "tip": "Raise or lower the right eye", "incr": "eyes/r-eye-height-incr", "decr": "eyes/r-eye-height-decr", "lsym": "l-eye-height", "default": 0.5, "icon": "eye-height.png" }
Macro Target with Display Formula A complex target controlling multiple underlying morphs with custom display.
UI: Slider with text display showing calculated age in years (1 to 90)
"Age": { "group": "main|macro", "tip": "Age of the human (range from 1 year to 90 years, center position is 25 years).", "macro": "macrodetails/Age", "macro_influence": [0, 1, 2, 3, 4], "default": 0.5, "display": { "slot": 2, "text": "Age: {}", "formula": "round(1 + val / (0.5/24)) if val < 0.5 else round(25 + (val-0.5) / (0.5/65))" } }
Measurement Target A target that updates a body measurement.
UI; Slider with live measurement update showing neck height in cm or inches
"ME-Neck Height": { "name": "Neck Height", "group": "measure|neck", "decr": "measure/measure-neck-height-decr", "incr": "measure/measure-neck-height-incr", "measure": [853,854,855,856,857,858,1496,1491] }
Barycentric Target A three-way interpolation target.
UI: Triangular map slider where each corner represents one ethnicity, with smooth blending between all three
"Phenotype": { "group": "main|macro", "tip": "Ethnic characteristics", "barycentric": [ "macrodetails/African", "macrodetails/Asian", "macrodetails/Caucasian" ], "barycentric_diffuse": [ [0.207, 0.113, 0.066], [0.721, 0.568, 0.431], [0.843, 0.639, 0.517] ], "macro_influence": [0] }

Automatic Generation for User Targets

When you add .target files to the user target directory, MakeHuman automatically generates entries in modelling.json:
  1. Scans <UserDataDir>/data/target/<basename> folder for .target files
  2. Detects folder structure (subfolders become subcategories)
  3. Identifies dual target pairs (matching -incr and -decr suffixes)
  4. Links icon files (if they follow naming conventions)
  5. Generates appropriate JSON entries
  6. Writes modelling.json in the user target directory
Dual Target Detection is done by using file naming conventions: features/custom-feature-incr.target features/custom-feature-decr.target which may result in this: "Features Custom Feature": { "user": 1, "name": "custom feature", "group": "user|features", "incr": "features/custom-feature-incr", "decr": "features/custom-feature-decr", "icon": "features-custom-feature.png" } Targets with missing -decr are handled as single targets.

Icons must be placed in <UserDataDir>/target/<basename>/icons folder if they should be automatically linked. they need the following pattern:

<subfolder>-<targetname>.png

Example:

clothes/heels-depth-decr.target clothes/heels-depth-incr.target icons/clothes-heels-depth.png ← Auto-linked Note: Icon should not include -incr or -decr suffix for dual targets. The targets are regenerated in user targets when This ensures the JSON file stays synchronized with actual target files.

Creating Manual Entries to contargets

For Custom Base Meshes edit the file <UserDir>/contarget/<basename>/modelling.json

Typical workflow:

  1. Add target files to appropriate directory
  2. Create icon (optional)
  3. Add entry to modelling.json
  4. Add category to target_cat.json if needed
Example:

{ "CustomHead": { "group": "custom|head", "name": "Custom Head Shape", "tip": "My custom head morph", "incr": "custom-head-incr", "default": 0.5, "icon": "custom-head.png" }, "CustomBody": { "group": "custom|body", "name": "Custom Body Shape", "incr": "custom-body-incr", "decr": "custom-body-decr" } }

Integration with other files

Target Files modelling.json references target files in the same directory structure it is placed.
Format: Binary .npz (compiled) or ASCII .target (source)
See: target for target file format
Category System modelling.json entries must reference categories defined in target_cat.json. group field must match a category identifier
Format: "category|subcategory"
See: target-categories for category system
Macro System Macro targets reference definitions in macro.json. macro field must match path to macro definition and macro_influence field describe which components are affected See: macros for macro system
Base Configuration Some properties interact with base.json, if character measurement is presented, these values will be used with measure field
Start values of targets may be overridden by "modifier-presets" in base.json
See: base.json for base configuration
Character Files Target values are saved in .mhm character files using the format "modifier <target-key> <value>" values are stored as 0.0-1.0. See: mhm for character file format