Skip to content

Command line & CI

The TALODTailor commandlet checks static and skeletal meshes against your targets without opening the editor UI. Use it in build scripts and CI to keep a LOD report up to date and to fail the build when findings reach a given severity. It can also apply LOD presets to the scanned meshes before the report.

UnrealEditor-Cmd.exe Project.uproject -run=TALODTailor [-Paths=/Game/A+/Game/B] [-Report=Saved/LODTailor/Reports] [-Formats=html,csv,json] [-NoReport] [-NoPictures] [-FailOn=Error|Warning|Info|Never] [-Apply -Preset=Standard -SkeletalPreset=Characters -Meshes=Static,Skeletal -Nanite=Skip|Keep|Disable -ReplaceCustomLODs -RemoveUnskinnedBones -NoFolderRules -ReduceDrawCalls -DrawCallsFromLOD=2 -DropSectionsBelow=0.02 -MainMaterialOnly -NoSave]

Example:

Terminal window
UnrealEditor-Cmd.exe "C:\Path\MyGame.uproject" -run=TALODTailor -Paths=/Game/Props+/Game/Environment -Report=Docs/LODReport -FailOn=Warning -unattended -nop4 -nosplash -NullRHI

-unattended, -nop4, -nosplash and -NullRHI are standard Unreal command line options for headless runs. They are not specific to LOD Tailor.

Parameter Default Meaning
-Paths=/Game/A+/Game/B Included Paths from the settings Content folders to scan, including subfolders. Separate several folders with + or ,. Excluded Paths are skipped even when you pass -Paths.
-Report=<folder> Report Directory from the settings (Saved/LODTailor/Reports) Folder for the report. Relative paths start at the project folder.
-Formats=html,csv,json All three Comma-separated list of html, csv and json, case-insensitive. Formats that are not listed are not written.
-NoReport Off Writes no report. The findings are still logged and still decide the exit code.
-NoPictures Off No LOD pictures in the HTML report. Commandlets only render them with -AllowCommandletRendering and without -NullRHI, and then for static meshes; skeletal meshes get pictures in the editor.
-FailOn=<severity> Error Lowest severity that fails the run: Error, Warning, Info or Never (None also works). Case-insensitive.
-Apply Off Applies LOD presets to every scanned mesh before the report. See Applying presets.
-Preset=<name> The first static preset (Standard) The preset -Apply uses for static meshes, by name, case-insensitive. A preset meant for skeletal meshes sets the skeletal recipe instead, and one meant for any mesh sets both. Put names with spaces in quotes: -Preset="Hero / large".
-SkeletalPreset=<name> The first skeletal preset (Characters) The preset -Apply uses for skeletal meshes. The built-in Characters presets can always be named, unless one of your presets has the same name. See Skeletal meshes.
-Meshes=Static,Skeletal Both The meshes -Apply changes: Static, Skeletal or both, case-insensitive.
-Nanite=Skip|Keep|Disable Skip What -Apply does with Nanite meshes: skip them, keep Nanite and add LODs, or turn Nanite off. See Nanite meshes.
-ReplaceCustomLODs Off -Apply also rebuilds meshes with imported (hand-made) LODs.
-RemoveUnskinnedBones Off -Apply removes the bones no vertex is skinned to from LOD 2 on of skeletal meshes. See Unskinned bones.
-NoFolderRules Off -Apply ignores the folder rules.
-ReduceDrawCalls Off -Apply gives the far LODs of static meshes fewer draw calls: sections with the same material are merged. See Fewer draw calls.
-DrawCallsFromLOD=<n> 2 With -ReduceDrawCalls: the first LOD with fewer draw calls, 1 to 7.
-DropSectionsBelow=<share> 0.02 With -ReduceDrawCalls: sections with less than this share of the triangles are dropped, 0 to 0.25. 0 keeps them.
-MainMaterialOnly Off With -ReduceDrawCalls: the far LODs are drawn with the material of their biggest section only.
-NoSave Off -Apply doesn’t save the changed meshes.

All parameters after -Apply in the table only matter together with -Apply. The targets, presets, folder rules and other settings come from Project Settings > Plugins > ta LOD Tailor, or from the settings asset the project uses. See Settings.

  1. Reads -FailOn and the folders to scan.
  2. Waits for the Asset Registry to finish discovering all assets.
  3. Reads and checks every static and skeletal mesh in the folders on every enabled target. To keep memory use down in large projects, it collects garbage after every 200 meshes.
  4. With -Apply: applies the presets to the scanned meshes, then scans them again so the report shows their new state.
  5. Logs one line per finding.
  6. Writes the report, unless -NoReport is given.
  7. Logs a summary line and exits with an exit code.

All lines are logged in the LogTALODTailor category:

LogTALODTailor: Display: Scanning /Game/Props, /Game/Characters
LogTALODTailor: Display: [Warning] Over budget | /Game/Props/SM_Rock_Dense.SM_Rock_Dense | Over the triangle budget: Meta Quest 57,120 / 20,000.
LogTALODTailor: Display: [Warning] No LODs | /Game/Characters/SK_Character_NoLODs.SK_Character_NoLODs | 6,118 triangles and no LODs, so the full mesh is drawn at every distance on Switch 2, Meta Quest.
LogTALODTailor: Display: [Info] Weak reduction | /Game/Props/SM_Bench_Weak.SM_Bench_Weak | LOD 1 keeps 8,572 of the 9,024 triangles of LOD 0.
LogTALODTailor: Display: Report written to C:/Path/MyGame/Docs/LODReport
LogTALODTailor: Display: ta LOD Tailor: 17 mesh(es) in 0.07s. Ready: PC 88%, Steam Deck 65%, Switch 2 47%, Meta Quest 41%. 0 error(s), 12 warning(s), 5 info. 12 finding(s) at or above -FailOn=Warning.
  • Scanning lists the scanned folders, separated by commas.
  • Each finding line has the format [<Severity>] <Rule name> | <Object path> | <Message>. The rule is given by its name, for example Over budget. See Checks.
  • Report written to gives the full report folder. It is not logged with -NoReport.
  • The summary line gives the number of meshes, the scan time, the readiness of every target, the findings per severity and how many findings are at or above -FailOn.

Setup and report errors are logged as errors:

Unknown -FailOn value '<value>'. Use Error, Warning, Info or Never.
Nothing to scan: no -Paths given and no Included Paths in Project Settings.
The ta LOD Tailor subsystem is not available.
Unknown -Preset '<name>'.
Unknown -SkeletalPreset '<name>'.
Unknown -Nanite value '<value>'. Use Skip, Keep or Disable.
Unknown -Meshes value '<value>'. Use Static, Skeletal or Static,Skeletal.
Report failed: <errors>

Report failed also appears when -Formats contains none of html, csv and json: “No format selected.”

Code Meaning
0 Passed: no findings at or above -FailOn. With -FailOn=Never the run always passes unless there is an error below.
1 At least one finding at or above -FailOn.
2 The run itself failed: unknown -FailOn, -Preset, -SkeletalPreset, -Meshes or -Nanite value, nothing to scan (no -Paths and no included folders), the LOD Tailor subsystem is not available, -Apply did not complete (a mesh failed, or the backup could not be written and nothing was changed), or the report could not be written.

Parameters the commandlet doesn’t know are ignored.

With the default -FailOn=Error, the run fails only on Invalid Min LOD, the only rule that reports errors. Use -FailOn=Warning to also fail on meshes over a target’s budget, meshes that need LODs, Nanite meshes without LODs on targets without Nanite, Nanite meshes whose fallback LODs lose material sections, and screen sizes in the wrong order.

With -Apply, the commandlet runs a batch run on every scanned mesh, like Apply on the Batch LODs page with All scanned:

  • the static recipe from -Preset and the skeletal recipe from -SkeletalPreset, as they are in the settings, including the Let Unreal compute screen sizes setting of the static one;
  • the static and skeletal meshes, or only the kinds in -Meshes;
  • the folder rules, unless -NoFolderRules is given;
  • Nanite meshes from -Nanite, with the fallback mesh at 100 %;
  • Replace imported LODs only with -ReplaceCustomLODs, Remove unskinned bones from LOD 2 only with -RemoveUnskinnedBones, fewer draw calls only with -ReduceDrawCalls (from -DrawCallsFromLOD, merging sections with the same material, dropping sections under -DropSectionsBelow, and with -MainMaterialOnly one material), Save the changed meshes unless -NoSave is given;
  • every other option at its default: Build the LOD chain, Screen sizes from the distances, Per-platform screen sizes and Per-platform Min LOD on, Skip meshes under 500 triangles.

A backup is written first, as in the panel. The run logs one line per mesh it changes and a summary:

LogTALODTailor: Display: [Apply] /Game/Props/SM_Rock_Dense.SM_Rock_Dense: 1 -> 4 LODs. 4 LODs from "Standard"
LogTALODTailor: Display: Batch run: 9 changed, 1 skipped, 0 failed in 4.2 s. Backup: LODTailor_20261011-190229-123.json
LogTALODTailor: Display: Applied presets 'Standard' (static) and 'Characters' (skeletal): 9 changed, 1 skipped, 0 failed. Backup: C:/Path/MyGame/Saved/LODTailor/Backups/LODTailor_20261011-190229-123.json

Problems during the run are logged as warnings, the commandlet’s own lines starting with [Apply]. If the backup can’t be written, no mesh is changed and the commandlet stops with exit code 2. If a mesh fails, it also stops with exit code 2 and writes no report. Otherwise it scans the meshes again, and the findings, the report and the exit code reflect the meshes after the run.

This Windows batch step checks the meshes, writes the report, keeps the exit code and passes it on to the build system. It expects to be placed next to MyGame.uproject; adjust the engine path and project name for your setup.

ci_lod_check.bat
@echo off
set UE_CMD="C:\Program Files\Epic Games\UE_5.6\Engine\Binaries\Win64\UnrealEditor-Cmd.exe"
set PROJECT="%~dp0MyGame.uproject"
%UE_CMD% %PROJECT% -run=TALODTailor -Report=Docs/LODReport -FailOn=Warning -unattended -nop4 -nosplash -NullRHI
set RESULT=%ERRORLEVEL%
if %RESULT%==0 echo LOD Tailor: passed
if %RESULT%==1 echo LOD Tailor: findings at or above -FailOn, see Docs\LODReport\lod_report.html
if %RESULT%==2 echo LOD Tailor: setup or report error, check the log
exit /b %RESULT%

Archive the Docs/LODReport folder as a build artifact. lod_report.json in the same folder has every finding for your own checks or dashboards. See Reports. With -NullRHI the report has no LOD pictures; to get them, run with -AllowCommandletRendering on a machine with a graphics device instead. A commandlet pictures static meshes only; skeletal meshes get pictures in the editor.

A common setup is two jobs: a check job on every change that runs the commandlet without -Apply and fails on warnings, and an occasional job or a local run with -Apply -Preset=<name> whose changed meshes you review and commit.

Windows PowerShell 5.1 changes some arguments that start with - before Unreal sees them:

  • An argument with a dot is split in two at the dot, so a report folder such as -Report=Docs/v1.2 or a share such as -DropSectionsBelow=0.02 is cut.
  • An argument with a comma, such as -Formats=html,csv,json, -Meshes=Static,Skeletal or -Paths=/Game/A,/Game/B, makes PowerShell stop with the parse error “Missing argument in parameter list”.

Put such arguments in quotes or in a variable:

Terminal window
$UE = "C:\Program Files\Epic Games\UE_5.6\Engine\Binaries\Win64\UnrealEditor-Cmd.exe"
$Project = "C:\Path\MyGame.uproject"
$Report = "-Report=Docs/LODReport"
$Formats = "-Formats=html,json"
& $UE $Project -run=TALODTailor $Report $Formats -FailOn=Warning -unattended -nop4 -nosplash -NullRHI
exit $LASTEXITCODE

Separating -Paths folders with + instead of , avoids the comma problem.