Construct render export

Image and video export from the Construct editor

Overview

Construct's render export feature renders the active scene to disk as still images, image sequences, or videos. Rendering happens in the background on a dedicated worker thread; the editor stays fully interactive while jobs run.

The whole UI lives under the Rendering dialog, opened from the toolbar's "Rendering" button. The dialog has two tabs:

Tab Purpose
Options Visual quality controls (raymarch, exposure, shading mode, environment, debug view, tone mapping, AA, projection) plus a render-preset bar at the top for saving / loading named bundles of these.
Export Output side: filename template, output format, resolution, frame range, fps, preset selector, existing-file policy, Queue Export button.

Render presets

A render preset is a named bundle of every Options-tab control's value. Once saved, the same preset can be applied to any scene and rendered at any resolution.

  • Storage: JSON files at config/presets/construct/<name>.json on the sentient path, resolved by the libfs file-engine handler to the active sentient's hive. With no sentient mounted, the same path under the app data folder is used. Each file is a level file of the construct schema (schema, level, values), and the fields that are not settings ride under render. RenderPresetStore is a caller of config::ui::PresetStore, so these are also the presets of the settings page and of config.preset.*. Draft, Standard and Final are built-in presets of the construct schema.
  • Per-job overrides: resolution, fps, frame range, output format, and filename template are not part of a preset — they belong to the Export tab and travel with the job, not with the preset.

Filename template DSL

The Export tab's filename field accepts a small token language so each frame in a sequence can have a unique path. Tokens:

Token Expands to
%f, %4f, %6f frame number (zero-padded; default 4 digits)
%Y %M %D year (4), month (2), day (2)
%h %m %s %z hour, minute, second, millisecond
%e the extension of the output format (png, mp4, mov), as %{format}
%{<expression>} any expression evaluated per frame
%% literal percent

Variables visible to %{...}: time (auto-set to frame / fps), frame, firstFrame, lastFrame, fps, width, height, format.

The datetime tokens are captured once at queue press, so every frame in a sequence shares the same folder timestamp.

Per-format filename memory: three separate template slots persist across sessions —

  • singleImage — when format is PNG / JPG / EXR / TIFF and from == to
  • imageSequence — same formats but from != to
  • singleVideo — when format is MP4 / MOV / WebM / MKV

Switching format or frame range automatically swaps to the right slot.

Output formats

The format combo is built dynamically at dialog construction from two probes against Qt's actual encoding capability:

  • ImageFormatProbe::availableFormats() — filters QImageWriter::supportedImageFormats() down to {PNG, JPG, EXR, TIFF}.
  • MediaFormatProbe::availableContainers() — enumerates QMediaFormat::supportedFileFormats(Encode) × supportedVideoCodecs(...).

Formats the running build can't actually encode never appear in the combo. If a plugin disappears between dialog construction and job execution, the worker still fails cleanly via the libbatch error mechanism.

Background execution

Pressing Queue Export snapshots the scene plus the selected preset into a ConstructSnapshot, stashes it under a fresh UUID in RenderSnapshotStore, and submits a construct/render_export BatchJob. The user can edit, save, or close the scene immediately — the render worker reads only the frozen snapshot.

The worker writes one image per frame (or feeds frames into QMediaRecorder for video) and reports progress through the queue. Output paths, libbatch error messages, and per-frame logs all surface in the Jobs panel (BatchActivity in the node window).

Existing-file policy

  • Overwrite (default) — replaces any pre-existing file.
  • Skip — for single files, the job no-ops; for sequences, only missing frames are rendered. Useful for resuming a canceled run.

Disk-space pre-flight

The estimate label under the Frames group shows expected output size and a coarse wall-clock estimate. When the size exceeds 95 % of free space on the target volume the label turns red and the Queue button surfaces the same warning inline.

Limitations

  • Audio: not supported in this phase — video output is silent.
  • Path-traced sample budget: PT presets render with their live accumulation behaviour; a dedicated samples-per-frame / time-per-frame UI is future work.
  • Keyframe animation: there is no keyframe timeline yet. Drive animation by binding an expression to a parameter and referencing time (or frame) — both advance per frame during a sequence render.
  • Distributed rendering: out of scope; everything runs in one BatchQueueService on the local node.

Files

The files are in three folders below libconstruct/construct/:

  • ui/: the UI dialog, the export tab and the preset bar.
  • batch/rendering/: the worker, the snapshot, the filename engine, the two encoders and the probes.
  • batch/: the generic store.
Layer File
UI dialog RenderingOptionsWidget.{hpp,cpp}
Export tab RenderExportTab.{hpp,cpp}
Preset bar RenderPresetBar.{hpp,cpp}
Worker ConstructRenderWorker.{hpp,cpp}
Snapshot ConstructSnapshot.{hpp,cpp}
Filename engine FilenameTemplate.{hpp,cpp}
Image encoder ConstructImageEncoder.{hpp,cpp}
Video encoder ConstructVideoEncoder.{hpp,cpp}
Probes {Image,Media}FormatProbe.{hpp,cpp}
Generic store BatchContextStore.hpp
Topics
reference construct render export video