Early docs These pages are very early. Structure and tone are still being worked out, so anything here may change drastically.
Skip to content
Rendered from src/settings/README.md in the repository — edit it there.

Slicing Parameters & Settings ​

Configuration for slicing behavior and printer control. All values stored as JSON.

Quick Reference ​

Slicing Parameters (params.*) ​

ParameterTypeDefaultRangeEffect
layer_heightmm0.20.1–0.4Distance between layers
wall_thicknessmm1.20.8–2.0Perimeter width
infill_density0–10.150.0–1.00=hollow, 1=solid
print_speedmm/s12010–500Fallback speed for any role without its own
nozzle_temp°C210180–250Heat level (material-dependent)
bed_temp°C6020–100Bed heat (material-dependent)
seam_positionenumalignedsee Seam PositionWhere each closed-loop seam sits
min_infill_extrusion_mmmm0.40.0–nozzleDrops sub-threshold solid-surface and sparse-infill segments to cut tiny travels
coasting_distance_mmmm00.0–1.0Length of un-extruded tail at the end of each path
thumbnail_enabledbooltruetrue/falseEmbed a PNG thumbnail comment block in output G-code (Thumbnail group)
thumbnail_size_pxpx32064–1024Square thumbnail resolution (the quality knob)
thumbnail_viewenumisometricisometric/front/rear/left/right/topFixed camera angle the UI renders the thumbnail from
thumbnail_themeenumtransparentlight/dark/transparentFixed thumbnail background (independent of app/OS theme)
thumbnail_color_modeenumfilamentgeneric/filament/customModel colour in the thumbnail: neutral / filament / chosen
thumbnail_custom_colorhex#e0912f#rrggbbModel colour used when thumbnail_color_mode = custom

Infill (params.*) ​

ParameterTypeDefaultEffect
infill_patternenumTpmsDsee below
infill_base_angle°45Sparse fill direction; alternating layers add 90°
infill_anchor_percent%400How far a lone infill line end runs along the wall, as a % of the bead spacing
infill_anchor_max_mmmm20Longest wall stretch that may join two infill lines; 0 = no anchoring
infill_every_layerscount1Print sparse infill once every N layers, at N× the height (1 = off)
infill_combination_max_layer_height_mmmm0Cap on the combined height; 0 = use the nozzle diameter
solid_infill_every_layerscount0Force a solid internal layer every N layers (0 = off)

Infill patterns: Rectilinear, AlignedRectilinear, Grid, Triangles, TriHexagon, Cubic, Honeycomb, Concentric, Gyroid, TpmsD.

Density is measured against the bead spacing (width − h·(1 − π/4)), so a requested density equals the deposited volume at any line width — and every pattern deposits the same amount. See src/infill/README.md.

Surfaces (params.*) ​

ParameterTypeDefaultEffect
surface_infill_angle°45Solid fill direction; alternates 90° per layer
top_surface_patternenumrectilinearFill pattern for the visible top surface
bottom_surface_patternenumrectilinearFill pattern for the bottom surface
internal_solid_infill_patternenummonotonicFill pattern for forced internal solid layers
ironing_enabledboolfalseSweep finished top surfaces with a near-dry smoothing pass
ironing_typeenumtop_surfacestop_surfaces / topmost_only / all_solid
ironing_flow%10Material deposited, as a share of a normal bead
ironing_spacingmm0.1Pitch between ironing passes
ironing_speedmm/s200 = fall back to top_surface_speed
ironing_angle°-1-1 = follow the layer's own fill angle

Surface patterns: rectilinear, aligned-rectilinear, monotonic, monotonic-line, concentric. "Monotonic" draws every line in the same direction, so the nozzle never travels back over a line it just laid.

Ironing carries the Ironing role (;TYPE:Ironing) and its own speed and acceleration. Its width is ironing_spacing × ironing_flow, which keeps the flow reduction out of the G-code generator's flow-ratio parameter — that deliberately reads a non-positive ratio as 1.0, so routing a "wipe only" setting through it would lay a full-width bead at 0.1 mm pitch.

Dimensional compensation (params.*) ​

ParameterTypeDefaultEffect
xy_size_compensationmm0Grow (+) or shrink (−) every contour; also tightens holes
xy_hole_compensationmm0Enlarge (+) or tighten (−) holes only, applied after
elephant_foot_compensation_mmmm0.2Shrink the layers at the bed to undo the first layer's squish
elephant_foot_layersn1How many layers the correction tapers over

Both are applied to the raw contours between slicing and wall generation — the only point at which the rest of the pipeline's measurements stay true. See src/core/compensation.rs.

xy_size_compensation follows the PrusaSlicer/Slic3r meaning (one number, and growing the part necessarily tightens its holes); xy_hole_compensation follows Orca/Bambu's separate hole delta. They are separate fields because collapsing them into one signed value gets imported Orca profiles wrong by 2δ on every hole.

First layer (params.*) ​

ParameterTypeDefaultEffect
first_layer_heightmm0Thickness of the bottom layer; 0 = use layer_height

Affects both geometry and flow: the slicer gives layer 0 its own Z span, and the generator charges it at that height via path_heights. Suppressed when a raft is present, since the raft then owns bed contact.

Bridge & overhang (params.*) ​

ParameterTypeDefaultEffect
bridge_speedmm/s10Print speed for bridge / overhang-perimeter extrusions (slow = smooth)
enable_overhang_speedbooltrueGrade perimeters by unsupported fraction instead of one flat bridge_speed
overhang_1_4_speedRelativeSpeedno overrideDeg1 (0–25% unsupported, to ~27° from vertical); % of perimeter_speed
overhang_2_4_speedRelativeSpeedno override; "50%"/"35%" on the high-speed/maximum presetsDeg2 (25–50%, ~27–45°); % of perimeter_speed
overhang_3_4_speedRelativeSpeedno overrideDeg3 (50–75% unsupported, ~45–56°); % of bridge_speed
overhang_4_4_speedRelativeSpeed"80%"Deg4 (75–100% unsupported, ~56–63°); % of bridge_speed

Each value may also be a literal mm/s. The angles are for 0.2 mm layers on a 0.4 mm nozzle — a degree is layer_height × tan(lean) / nozzle_diameter, so thinner layers push every band steeper. Past 100% the bead has left the layer below altogether and the segment is retagged OverhangPerimeter; below that it stays a wall, graded by degree.

RelativeSpeed (src/settings/relative_speed.rs) is a bare number (absolute mm/s) or a "NN%" string (a fraction of the field named by that property's x-relative-to schema extension) — "no override" means the literal legacy 0 sentinel, which still resolves to the source field's own speed (bridge_speed for Deg3/Deg4, by degree rather than by role). | bridge_flow_ratio | 0–1.5| 1.5 | Flow multiplier for bridge lines (>1 fuses strands into a smooth floor) | | bridge_anchor_mm | mm | 0.4 | Inflate the bridge region outward to anchor strands into solid material | | bridge_min_area_mm2 | mm² | 0.5 | Drop bridge candidates smaller than this; reclassified as BottomSurface | | bridge_noise_filter_mm | mm | 0.05 | Morphological-open radius to wipe sub-pixel slivers before bridge detection | | bridge_fan_speed | 0–1 | 1.0 | Part-cooling duty while printing Bridge segments (per-segment override) | | bridge_angle | ° | 0 | Force one bridging direction; 0 = auto-detect, 180 = horizontal |

Cooling & chamber (params.*) ​

The filament owns the material policy, the printer owns the hardware capability; fan_configs stays the printer-side adaptive layer-time table. Full precedence rules in gcode/README.md.

ParameterTypeDefaultEffect
fan_speed0–11.0Ceiling the adaptive fan_configs curve is clamped to (the high-temp material gate)
first_layer_fan_speed0–10.0Part-cooling duty while pinned by disable_fan_first_layers
disable_fan_first_layersn1Bottom layers where part cooling is pinned; bridge/overhang overrides are suppressed there
min_layer_time_ss4Shortest a layer may take; below it the layer is slowed, then dwelled. Filament profiles set their own
min_print_speedmm/s10Floor the slowdown will not go below
overhang_fan_speed0–11.0Part-cooling duty on overhang segments (needs enable_overhang_speed)
overhang_fan_threshold0–10.5Unsupported fraction above which overhang_fan_speed engages
heated_chamberboolfalsePrinter capability — without it no M141/M191 is ever emitted
chamber_temp°C0Chamber target; bed armed + M141/M191 soak run before the start G-code
chamber_temp_first_layer°C0First-layer soak target (0 = use chamber_temp); restored at layer 2

Retraction (params.*) ​

ParameterTypeDefaultEffect
retract_mmmm1.0Filament pulled back on a retracting travel
retract_speed_mm_minmm/min2400Retract / un-retract feedrate
z_hop_mmmm0.2Nozzle lift during a retracting travel
retract_before_travel_mmmm1.0Minimum travel distance before a retraction is triggered
retract_restart_extra_mmmm0.0Extra prime length added on un-retract to compensate for travel ooze
retract_on_layer_changeboolfalseRetract before every layer-change Z move
use_firmware_retractionboolfalseEmit G10/G11 and sync the firmware (M207/M208 or SET_RETRACTION)
use_relative_e_distancesboolfalseEmit M83 + incremental E (G1 … E<delta>) instead of M82 absolute positions
wipebooltrueRetrace the just-printed path while retracting to smear ooze onto printed material
wipe_distance_mmmm1.0How far to wipe (capped at the previous path's length) when wipe is enabled
retract_before_wipe_percent0–10.0Fraction of the retraction performed before the wipe (the rest is distributed along it)

Machine (params.*) ​

ParameterTypeDefaultEffect
z_offset_mmmm0.0Added to every Z coordinate in the output G-code to compensate a mis-zeroed Z endstop (negative lowers the nozzle). Emitted coordinates and layer markers only — the model, statistics and your start/end G-code are untouched. See gcode/README.md.

Global Settings (top-level) ​

FieldTypeDefaultDescription
gcode_flavorstring"marlin"Firmware dialect ("marlin" or "klipper")
start_print_gcodestring | nullnullCustom start G-code block or file path
end_print_gcodestring | nullnullCustom end G-code block or file path
lifecycle_markersobject{}Per-flavor layer lifecycle marker config (see below)

Config Priority ​

Settings are resolved in this order (highest priority first):

1. CLI arguments          (--layer-height, --gcode-flavor, --start-print-gcode, …)
2. slicer.json            (project config in CWD, or --config FILE)
3. ~/.config/slicer-engine/settings.json  (user config)
4. Built-in defaults

Each layer overrides only the keys it specifies; unset keys fall through to the next layer.

Project Config (slicer.json) ​

Place a slicer.json file in your project directory to set per-project defaults that override the user config without touching it. Only the keys you include are overridden.

json
{
  "params": {
    "layer_height": 0.15,
    "nozzle_temp": 215
  },
  "gcode_flavor": "klipper"
}

The file is auto-discovered when you run any slice command from the same directory. You can also point to it explicitly:

bash
slicer-engine slice --input model.stl --config ./path/to/slicer.json

User Config (settings.json) ​

The persistent user-level config lives at:

PlatformPath
Linux~/.config/slicer-engine/settings.json
macOS~/Library/Application Support/slicer-engine/settings.json
Windows%APPDATA%\slicer-engine\settings.json

Managed via the settings set / settings get subcommands (see below).

JSON Structure ​

Global settings file (settings.json or slicer.json) ​

json
{
  "params": {
    "layer_height": 0.2,
    "wall_thickness": 1.2,
    "infill_density": 0.15,
    "print_speed": 120.0,
    "nozzle_temp": 210.0,
    "bed_temp": 60.0
  },
  "gcode_flavor": "marlin",
  "lifecycle_markers": {
    "klipper": {
      "enabled": true,
      "layer_change": ";LAYER_CHANGE",
      "z_marker": ";Z:{z}",
      "height_marker": ";HEIGHT:{height}",
      "before_layer_change": ";BEFORE_LAYER_CHANGE",
      "after_layer_change": ";AFTER_LAYER_CHANGE",
      "type_annotation": ";TYPE:{type}",
      "width_annotation": ";WIDTH:{width}mm"
    }
  }
}

start_print_gcode and end_print_gcode are omitted from the file when null. lifecycle_markers is omitted entirely when the map is empty (i.e. all defaults are in effect).

Lifecycle Markers ​

Layer lifecycle markers are comments that slicer-aware firmware and post-processing scripts use to track progress, drive LED effects, pause at layers, etc.

How it works ​

Each firmware flavor can have its own LifecycleMarkerConfig entry in the lifecycle_markers map. Flavors not present in the map use the built-in defaults (enabled, standard OrcaSlicer/PrusaSlicer comment format).

When enabled: false, the generator emits a minimal ; layer z=… comment instead of the full lifecycle block.

Per-flavor configuration (LifecycleMarkerConfig) ​

FieldDefault emitted commentSupported placeholders
enabledtrue—
layer_change;LAYER_CHANGE{z}, {height}
z_marker;Z:{z}{z}
height_marker;HEIGHT:{height}{height}
before_layer_change;BEFORE_LAYER_CHANGE{z}
after_layer_change;AFTER_LAYER_CHANGE{z}
type_annotation;TYPE:{type}{type}
width_annotation;WIDTH:{width}mm{width}

All string fields are optional — omit them to keep the built-in default for that marker.

Placeholder reference ​

PlaceholderReplaced withExample
{z}Layer Z coordinate (3 d.p.)0.200
{height}Layer height from params (3 d.p.)0.200
{type}Extrusion role type nameWALL-OUTER, FILL
{width}Extrusion role default width (2 d.p.)0.40

Example: disable markers for Marlin, keep them for Klipper ​

json
{
  "lifecycle_markers": {
    "marlin": { "enabled": false },
    "klipper": { "enabled": true }
  }
}

Example: custom marker strings for a Bambu-style slicer ​

json
{
  "lifecycle_markers": {
    "marlin": {
      "enabled": true,
      "layer_change": ";BAMBULABS_LAYER_CHANGE",
      "z_marker": ";Z_HEIGHT:{z}"
    }
  }
}

CLI overrides ​

The --lifecycle-markers and --no-lifecycle-markers flags on the slice command override the enabled field from settings for the current invocation only:

bash
# Force-enable markers regardless of settings
slicer-engine slice --input model.stl --lifecycle-markers

# Force-disable markers regardless of settings
slicer-engine slice --input model.stl --no-lifecycle-markers

Object settings (per-object override) ​

json
{
  "object_name": "detail_part",
  "overrides": {
    "layer_height": 0.1,
    "print_speed": 40.0
  }
}

When overrides is null, the object inherits all global settings.

CLI Commands ​

Get/Set Individual Values ​

Both flat aliases and full dot-separated paths are accepted:

bash
# These are equivalent
slicer-engine settings get layer_height
slicer-engine settings get params.layer_height

# Set via flat alias
slicer-engine settings set layer_height 0.15

# Set via full path
slicer-engine settings set params.nozzle_temp 215

# Set top-level fields
slicer-engine settings set gcode_flavor klipper
slicer-engine settings set start_print_gcode "START_PRINT BED_TEMP=60 EXTRUDER_TEMP=210"
slicer-engine settings set end_print_gcode "END_PRINT"

# Clear an optional field
slicer-engine settings set start_print_gcode null

# JSON output
slicer-engine settings get layer_height --output-format json

Show All ​

bash
slicer-engine settings show
slicer-engine settings show --output-format json

Validate ​

bash
slicer-engine settings validate \
  --global global.json --object object.json

Checks constraints and ranges. Output: ✓ valid or error messages.

Diff ​

bash
slicer-engine settings diff \
  --global global.json --object object.json

Shows which parameters are overridden:

layer_height    0.2 → 0.1    ✓ Override
print_speed     60  → 40     ✓ Override
nozzle_temp     210 → 210    (no change)

Validation Rules ​

ParameterConstraintNotes
layer_height> 0Typically ≤ nozzle diameter (0.4 mm)
wall_thickness≥ 0.4 mmAt least one nozzle width
infill_density0.0 ≤ x ≤ 1.0Strict bounds
print_speed> 0Higher = faster but lower quality
nozzle_temp180–250°CMaterial-dependent (PLA≈210, PETG≈230)
bed_temp20–120°CMaterial-dependent (PLA≈60, PETG≈100)
gcode_flavor"marlin" | "klipper"Must be a known firmware dialect

Common Profiles ​

PLA ​

json
{
  "params": { "layer_height": 0.2, "nozzle_temp": 210, "bed_temp": 60 },
  "gcode_flavor": "marlin"
}

PETG ​

json
{
  "params": { "layer_height": 0.2, "nozzle_temp": 230, "bed_temp": 85 }
}

High-detail (Klipper) ​

json
{
  "params": { "layer_height": 0.1, "print_speed": 30, "wall_thickness": 1.6 },
  "gcode_flavor": "klipper",
  "start_print_gcode": "START_PRINT BED_TEMP=60 EXTRUDER_TEMP=210",
  "lifecycle_markers": {
    "klipper": { "enabled": true }
  }
}

Seam Position ​

params.seam_position controls where each closed perimeter loop begins and ends — the spot where the printer pauses, retracts, and lifts. That spot leaves a small visible blob ("the seam") on the outer wall.

ValueVertex chosen per loopVisual resultBest for
nearestClosest vertex to the previous path's endScattered seams; minimum travel & print timePrototypes, infill-heavy parts
rearVertex with the largest YSingle seam line at the back of the modelDisplay pieces (Benchy-style)
aligned (default)Vertex with the largest projection onto a fixed direction (+Y)Consistent vertical seam line across all layersParts whose loops shift between layers
sharpest_cornerVertex with the largest convex turn angle (falls back to nearest)Seam hidden in geometry cornersMechanical parts with hard edges
randomHash of the loop's first-vertex bits (deterministic per loop)Seam blobs spread evenly; no visible lineCylinders, organic shapes

Override per-invocation from the CLI:

bash
slicer-engine slice --input model.stl --seam-position rear

Set persistently in slicer.json / settings.json:

json
{ "params": { "seam_position": "sharpest_corner" } }

Hyphens and underscores are both accepted (sharpest-corner ≡ sharpest_corner). See core/README.md for the implementation details and the role-grouped path-ordering pass that consumes this setting.

Integration ​

See Also ​