Architecture
NameFrame is built around one boundary. Understanding where it sits explains most of the rest of this documentation, including why some things can be redone cheaply and others require rendering again.
The durable boundary#
ScenarioConfig
│
▼
Canonical compiler
│
▼
CaptureJob
│
▼
Unreal runtime ← the world, and the raw truth
│
▼
RAW DUMP ← the boundary
│
├── Verify
├── Label
├── Report
├── Dataset
├── Metadata
└── Analytics
Above the dump, Unreal owns everything: what exists, where it stands, what the camera sees, which pixel belongs to which object. Below it, Python owns everything: boxes, masks, verification, reports, exports, metadata.
Why the boundary is where it is#
The raw dump is not a temporary file to delete once a dataset exists. It is the durable record, and keeping it is what makes the following cheap:
- a different annotation format;
- a different train/validation split;
- a new report or validation rule;
- a derivation that did not exist when the capture ran.
All of those are re-derivations over an existing dump. None of them require opening the editor.
A rerender is required when render-time truth changes: the world, the camera, the lighting, the population, or which modalities are captured. If the pixels have to be different, the pixels have to be made again.
Public intent and the runtime job#
ScenarioConfig is the configuration contract a person writes. It is not what
the engine executes.
The canonical compiler combines the scenario with the scene manifest, the runtime's
declared capabilities and its own context, and produces a CaptureJob: the
low-level plan the runtime actually runs. The result carries hashes and diagnostics, so the
exact plan that ran is inspectable afterwards rather than reconstructed from memory.
One compiler exists so that Studio, the API and automation cannot each interpret the same scenario slightly differently. A field that is registered as public but is not consumed during compilation is treated as a failure rather than ignored.
What a completed frame contains#
frames/plugin_000004/
├── rgb.png the rendered frame
├── seg.png the per-instance identity buffer
├── depth.npy float32 metres per pixel, when depth is enabled
├── frame.json camera, every actor, environment, validation, timings
└── spawn_manifest.json what was requested, placed and refused, hashed
seg.png is an identity buffer, not a semantic segmentation preview. Each
object has its own flat colour. That distinction is what makes instance masks and
occlusion-aware boxes possible, and it is worth internalising early because several later
pages depend on it.
See outputs and formats for the full layout of a run, and determinism for what makes a dump reproducible.