> For the complete documentation index, see [llms.txt](https://docs.bestway.com.ua/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bestway.com.ua/gem-rts-tools/gem-importer.md).

# GEM Importer

Quick Guide

**GEM Importer** converts input **FBX**, **OBJ**, **glTF**/**GLB**, and **MDL** files into a set of **GEM/MDL** output files.

**The program can be launched in two ways:**

1. Double-click `gem_import.exe`.\
   The program runs according to the settings in the `gem_import.json` configuration file.
2. [From the command line](#user-content-fn-1)[^1].\
   This method allows you to pass parameters for a specific run without modifying the `gem_import.json` configuration file.

## First run

{% hint style="info" %}
The **first run** means that the `gem_import.json` configuration file is **not present** in the folder containing `gem_import.exe`.
{% endhint %}

On the first run, **GEM Importer** creates a basic `gem_import.json` configuration file in the folder containing `gem_import.exe` and then exits.

To perform the first run, either double-click `gem_import.exe` or run the program from the **command line** without any parameters \[`gem_import`].

{% hint style="warning" %}
No files are imported during the first run.
{% endhint %}

## Configuration source precedence

The final import parameter values are determined from three sources. Each subsequent source has higher priority and overrides the corresponding values from the previous source:

1. Built-in default values;
2. Sections in `gem_import.json`;
3. Explicit CLI overrides.

{% hint style="info" %}
Command-line parameters apply only to the current run and do not modify the contents of `gem_import.json`.
{% endhint %}

## Configuring `gem_import.json`

The `gem_import.json` file is the primary way to configure GEM Importer. After the first run, open the generated file in a text editor and specify the import parameters. On subsequent launches by double-clicking, the program uses the settings from this file.

<details>

<summary>Example <code>gem_import.json</code></summary>

```json
{
  "app": {
    "version": 2,
    "importer": "gem_import 1.0.0.110",
    "description": "Configuration for importing and exporting GEM/MDL assets",
    "author": "gem_import",
    "debug": {
      "outLog": "./out_log",
      "verbose": 1,
      "htmlFormat": false,
      "dryRun": false
    }
  },
  "import": {
    "general": {
      "inputDir": "./in",
      "outDir": "./out",
      "format": "MDL3",
      "importUniformScale": 1.0
    },
    "content": {
      "volumes": true
    },
    "overwriteExisting": {
      "mesh": true,
      "texture": true,
      "animation": true,
      "material": true,
      "cmesh": true,
      "def": true,
      "mdl": true
    },
    "textures": {
      "searchPaths": [],
      "textureOutputSubdir": "",
      "useTexturesFromModel": true,
      "fileNameConvention": {
        "diffuse": ["basecolor", "base_color", "albedo", "diffuse"],
        "bump": ["normal", "normalmap", "normal_pbr", "bump", "nm"],
        "ao": ["ao", "ambientocclusion", "cavity"],
        "lightmap": ["lm", "lightmap", "lightingmap"],
        "roughness": ["roughness", "rough", "rg"],
        "metallic": ["metallic", "metalness", "metal", "met", "mt"],
        "specular": ["specular", "spec", "sp"],
        "glossiness": ["gloss", "glossiness"],
        "emissive": ["emissive", "emission", "emit"],
        "fuzz": ["fuzz"]
      }
    },
    "materials": {
      "classSimple": "pbr/simple",
      "classStandard": "pbr/standard",
      "classStandardLightmap": "pbr/standard_lightmap",
      "classStandardEmissive": "pbr/standard_emissive",
      "defaultNormal": "$/pbr/0_nm",
      "defaultAo": "$/pbr/0_ao",
      "defaultRoughness": "$/pbr/0_rg",
      "defaultMetallic": "$/pbr/0_met"
    }
  }
}
```

</details>

### `gem_import.json` key reference

<table><thead><tr><th width="236.0703125">Section</th><th width="208.8046875">Key</th><th>Description</th></tr></thead><tbody><tr><td><code>app.debug</code></td><td><code>outLog</code></td><td>Path to the log folder</td></tr><tr><td><code>app.debug</code></td><td><code>verbose</code></td><td>File log verbosity level [0..2]</td></tr><tr><td><code>app.debug</code></td><td><code>htmlFormat</code></td><td>Write the import log in HTML format instead of TXT</td></tr><tr><td><code>app.debug</code></td><td><code>dryRun</code></td><td>Enables read and validation mode without writing the regular output</td></tr><tr><td><code>import.general</code></td><td><code>inputDir</code></td><td>Path to the source folder containing files to import.<br>Input folders used by <code>--run-config</code></td></tr><tr><td><code>import.general</code></td><td><code>outDir</code></td><td>Path to the root import output folder</td></tr><tr><td><code>import.general</code></td><td><code>format</code></td><td>Specifies the target MDL format for the imported model.<br>Available values:<br>• <code>MDL1</code> — for <strong>GEM1</strong>.<br>• <code>MDL2</code> — for <strong>GEM2</strong>.<br>• <code>MDL3</code> — for <strong>GEM RTS</strong>.</td></tr><tr><td><code>import.general</code></td><td><code>importUniformScale</code></td><td>Scale applied to imported models</td></tr><tr><td><code>import.content</code></td><td><code>volumes</code></td><td>When enabled, the importer preserves and exports detected volume/collision content to MDL and <code>.cmesh</code></td></tr><tr><td><code>import.overwriteExisting</code></td><td><p><code>mesh</code>,</p><p><code>texture</code>,</p><p><code>animation</code>,</p><p><code>material</code>,</p><p><code>cmesh</code>,</p><p><code>def</code>,</p><p><code>mdl</code></p></td><td>Allows existing output files of the specified types to be overwritten</td></tr><tr><td><code>import.textures</code></td><td><code>searchPaths</code></td><td>Additional folders in which to search for source textures</td></tr><tr><td><code>import.textures</code></td><td><code>textureOutputSubdir</code></td><td>Relative subfolder inside <code>outDir</code> for exported textures. If the value is empty, textures are written next to the model</td></tr><tr><td><code>import.textures</code></td><td><code>useTexturesFromModel</code></td><td><ul><li><code>true</code> — use texture references from the source material;</li><li><code>false</code> — collect material textures from folders named after the materials</li></ul></td></tr><tr><td><code>import.textures</code></td><td><code>fileNameConvention</code></td><td>Maps filename suffixes to <code>.material</code> fields when <code>useTexturesFromModel=false</code></td></tr><tr><td><code>import.materials</code></td><td><code>classSimple</code>, <code>classStandard</code>, <br><code>classStandardLightmap</code><br><code>classStandardEmissive</code></td><td>Classes of the generated MDL materials</td></tr><tr><td><code>import.materials</code></td><td><code>defaultNormal</code>, <code>defaultAo</code>, <code>defaultRoughness</code>, <code>defaultMetallic</code></td><td>Fallback textures for generated materials</td></tr></tbody></table>

### Geometry processing

The importer automatically accounts for the coordinate systems used by the input formats and performs the transformations required for GEM/MDL output. For FBX and OBJ files, normals are generated only if they are missing from the source model.

Polygon sidedness cannot be configured through JSON.

* For GLB/GLTF, the source material's `doubleSided` value is preserved.
* For FBX, the importer uses the material's two-sided setting and any `CullingOff/CullingOn` value explicitly assigned to the node.
* A submesh with no assigned material is forced to use `twoSided=true`.

Setting `content.volumes=true` does not generate **volumes** when none are present. This flag allows the importer to preserve and write volumes detected in the source model.

* When set to `false`, volume resources and `.cmesh` elements are removed before the output is written.
* Overwriting an existing `.cmesh` is controlled independently by `overwriteExisting.cmesh`.

### The `overwriteExisting` flag

The `overwriteExisting` flags do not disable the export of new files. They protect only files that already exist. The following rules apply:

* if the file does not exist, it is written;
* if the file already exists, it is written only when\
  &#x20;`overwriteExisting.<type> = true`.

This parameter prevents existing, configured `.def` and `.mdl` files from being overwritten when the model is imported again.

<details>

<summary>Example settings for the <code>overwriteExisting</code> section</summary>

```json
"overwriteExisting": 
    { 
    "mesh": true, 
    "texture": true, 
    "animation": true, 
    "material": true, 
    "cmesh": true, 
    "def": false, 
    "mdl": false
    }
```

</details>

### Texture processing

The `searchPaths` parameter specifies where the importer searches for source textures. It is also used to locate external images referenced by `.gltf` files.

The `textureOutputSubdir` parameter specifies the output subfolder for exported textures inside `outDir`.

The model is then written to `<outDir>/<model_stem>/`,\
and its textures are written to `<outDir>/textures/<model_stem>/`.

If `textureOutputSubdir` is empty, the textures are written next to the model.

<details>

<summary>Example settings for the <code>textures</code> section</summary>

```json
"textures": 
    { 
    "searchPaths": ["D:/SourceTextures/Rock"], 
    "textureOutputSubdir": "textures", 
    "useTexturesFromModel": true, 
    "fileNameConvention": 
        { 
        "diffuse": ["basecolor", "base_color", "albedo", "diffuse"], 
        "lightmap": ["lm", "lightmap", "lightingmap"],
        "bump": ["normal", "normalmap", "normal_pbr", "bump", "nm"], 
        "ao": ["ao", "ambientocclusion", "cavity"], 
        "roughness": ["roughness", "rough", "rg"], 
        "metallic": ["metallic", "metalness", "metal", "met", "mt"], 
        "specular": ["specular", "spec", "sp"], 
        "glossiness": ["gloss", "glossiness"], 
        "emissive": ["emissive", "emission", "emit"], 
        "fuzz": ["fuzz"] 
        }
    }
```

</details>

### The `useTexturesFromModel` parameter

1. Standard mode (default setting):

```json
"useTexturesFromModel": true
```

The importer uses texture references from the source material: FBX material slots, OBJ `.mtl`, or glTF/GLB materials.

2. Alternative mode:

```json
"useTexturesFromModel": false
```

The importer ignores texture references embedded in the model and searches for material folders next to the source model and directly inside each folder listed in `searchPaths`.

Without `searchPaths`:

```
model_folder/
    model.fbx
    <materialName>/
        <anything>_<textureType>.<ext>
```

To add an extra `textures` level, specify it explicitly relative to the model folder:

```json
"searchPaths": ["textures"]
```

```
model_folder/
    model.fbx
    textures/
        <materialName>/
            <anything>_<textureType>.<ext>
```

The same structure is used for an absolute `searchPaths` value:

```
<materialName>/
    <anything>_<textureType>.<ext>
```

Example for the `matid_1` material:

```
matid_1/
    rock_basecolor.jpg
    rock_normal.jpg
    rock_ao.jpg
    rock_roughness.jpg
```

Texture type suffixes are configured in `import.textures.fileNameConvention`:

```json
"fileNameConvention": 
    { 
    "diffuse": ["basecolor", "base_color", "albedo", "diffuse"],
    "lightmap": ["lm", "lightmap", "lightingmap"], 
    "bump": ["normal", "normalmap", "normal_pbr", "bump", "nm"],
    "ao": ["ao", "ambientocclusion", "cavity"],
    "roughness": ["roughness", "rough", "rg"],
    "metallic": ["metallic", "metalness", "metal", "met", "mt"],
    "specular": ["specular", "spec", "sp"],
    "glossiness": ["gloss", "glossiness"], 
    "emissive": ["emissive", "emission", "emit"],
    "fuzz": ["fuzz"]
    }
```

The key is a field or slot in the generated `.material`.\
The key value is a list of accepted suffixes that follow the final underscore \[ `_` ] in the filename.\
The name of the immediate parent folder must match the material name. Files in folders belonging to other materials are ignored.

{% hint style="info" %}
The importer compares only the part of the filename after the final underscore \[ `_` ]. Therefore, compound values containing underscores, such as `base_color` and `normal_pbr`, are not recognized. Use single-part values such as `basecolor`, `normal`, or `normalmap`.
{% endhint %}

{% hint style="info" %}
When `useTexturesFromModel=false`, the names of exported `.dds` files and their references in `.material` are written in lowercase. This ensures exact path matching on case-sensitive file systems, including Linux.
{% endhint %}

<details>

<summary>Example of an incorrect parameter configuration</summary>

If the configuration file contains\
`"bump": ["normal","normalmap","normal_pbr","bump","nm"]`,

the following files

`matid_1/rock_normal.png`

and

`matid_1/rock_normalmap.png`

will both be assigned to the `bump` field during import.

</details>

## Command-line parameters

Command-line parameters allow you to change settings for a specific GEM Importer run. The supplied values take precedence over the corresponding values in **gem\_import.json** but do not modify the configuration file.

<table><thead><tr><th width="233.48046875">Parameter</th><th>Description</th></tr></thead><tbody><tr><td>No parameters</td><td>Create the <code>gem_import.json</code> configuration file with the basic import settings and exit on the first run.<br>If <code>gem_import.json</code> already exists, import files according to the settings in the configuration file</td></tr><tr><td><code>-i, --input &#x3C;file></code></td><td>One input file.<br>Supported formats: <code>.fbx</code>, <code>.obj</code>, <code>.gltf</code>, <code>.glb</code>, <code>.mdl</code></td></tr><tr><td><code>--input-dir &#x3C;dirs></code></td><td>One or more input folders. Separate paths with a semicolon [ <code>;</code> ]</td></tr><tr><td><code>--run-config</code></td><td>Import from <code>import.general.inputDir</code></td></tr><tr><td><code>-s, --settings &#x3C;file></code></td><td>Use the specified <code>gem_import.json</code></td></tr><tr><td><code>-o, --out-dir &#x3C;dir></code></td><td>Root output folder. Overrides <code>import.general.outDir</code></td></tr><tr><td><code>--verbose [0 | 1 | 2 ]</code></td><td>Set the log file verbosity level</td></tr><tr><td><code>--html</code><br><code>--no-html</code></td><td>Write an HTML log<br>Write a TXT log</td></tr><tr><td><code>--dry-run</code></td><td>Read and validate only, without writing the regular output</td></tr><tr><td><code>--write-help</code></td><td>Write <code>gem_import.md</code> next to the executable</td></tr><tr><td><code>--version</code></td><td>Display the <code>gem_import</code> version and exit</td></tr><tr><td><code>-h, --help</code></td><td>Display command-line help</td></tr></tbody></table>

### Running with a BAT file

For regular **GEM Importer** runs with the same parameters, you can create a BAT file. This eliminates the need to enter the command manually each time.

Create a text file in the folder containing `gem_import.exe`, add the launch command, and save the file with the `.bat` extension, for example, `import_models.bat`:

```bat
@echo off
gem_import --input-dir "D:\Models\fbx;D:\Models\gltf" --out-dir "D:\Out" --verbose 1
pause
```

Double-click the BAT file to run the command. The `pause` command keeps the Command Prompt window open after the import is complete so that you can review the program messages.

<details>

<summary>Command-line examples</summary>

{% hint style="info" %}
Enter all commands shown below in Windows Command Prompt.
{% endhint %}

1. Importing a single file:

```bash
gem_import --input "D:\Models\vehicle.fbx" --out-dir "D:\Out" --verbose 2 --html
```

The command imports `vehicle.fbx`, writes the output to `D:\Out`, and generates a detailed HTML log.

2. Importing files from multiple folders:

```bash
gem_import --input-dir "D:\Models\fbx;D:\Models\gltf" --out-dir "D:\Out" --verbose 1
```

The command imports supported files from `D:\Models\fbx` and `D:\Models\gltf`. Folder paths are separated with a semicolon. The output is written to `D:\Out`, and the file log uses verbosity level 1.

3. Importing with a specified configuration file:

```bash
gem_import --run-config --settings "D:\Work\gem_import.json"
```

The command uses `D:\Work\gem_import.json` and imports files from the folders specified in `import.general.inputDir`.

</details>

## Import output files

A typical import produces the following set of files:

```
<outDir>/
    <model_name>/
        <model_name>.def
        <model_name>.mdl
        .mesh
        .cmesh
        .material
        .animation
        *.dds
```

{% hint style="info" %}
The output file set depends on the source model and the data it contains.
{% endhint %}

[^1]: To open Command Prompt in Windows:

    1. Open File Explorer.
    2. Place the cursor in the File Explorer address bar.
    3. Enter `cmd` and press Enter.
