Skip to content
NAMEFRAMECommercial PreviewApply for Pilot
Spawner

Randomness you can describe afterwards.

Scattering objects randomly across a level is easy and almost useless: it produces crates inside walls, people standing on roofs, and a dataset nobody can explain. The spawner’s job is to generate variety inside constraints you authored, and then write down exactly what it did.

Placements in the reference run
3,360
Refused
0
Minimum spacing
1 m
Attempt budget
900 per placement

The problem it solves

A synthetic dataset is only as varied as the scenes behind it, and hand-placing objects does not scale past a few dozen frames. But the naive alternative, uniform random placement, breaks the thing that made synthetic data attractive in the first place: physical plausibility. A detector trained on floating barrels learns floating barrels.

So placement has to be constrained, and the constraints have to be authored in the level rather than guessed at in a config file. You draw the volume; the spawner fills it, respecting spacing, slope, exclusion and ground contact, and reshuffles it for every frame.

Spawner

Build distributions, not just scenes.

Placing a hundred objects by hand gives you one scene. Describing how they should be distributed gives you every scene you were going to need after that.

SURFACEPlan view · diagram

Actors are placed across a region and settle on the surface they land on, so nothing floats and nothing sinks into the ground.

54 placements

What the reference run actually did

The diagrams above show what the spawner can do. This is what it did on the capture the rest of this site uses, which is a narrower and more honest claim.

MeasureValue
Placement rule usedspawn_zone_shuffle
Rule layers across the run120
Placements requested3,360
Placements accepted3,360
Placements refused0
Reshuffled every frameyes
Ground contact tracedyes
Ground clearance allowed2 m

One rule kind, 3,360 placements, nothing refused. That last number is worth reading correctly: it does not mean the constraints did nothing, it means the attempt budget was generous enough that every placement eventually found a legal position within 900 tries. A run with a tighter scene would show refusals here, with reasons.

The constraint that is visible in the output is spacing. Configured at 1 metre, the measured nearest-neighbour distance across all 3,360 placements has a minimum of exactly 1.00 metres, a median of 2.7 and a maximum of 15.01. A constraint you can see from the outside is a constraint that is working.

A rendered airbase frame showing spawned crates, barrels and people among the scene's own vehicles and buildings
Rendered frameMap_Airbase_Demo, frame 000004Unreal Engine 5.8, 1920×10803,360 placements per run

What gets written down

Every frame carries its own manifest. This is what makes a placement decision auditable months later, and it is the difference between a generator and a black box.

{
  "manifest_id": "spawn_manifest_30a7a4a2b05c",
  "frame_id": "plugin_000004",
  "seed": 67,
  "layers": [
    { "kind": "spawn_zone_shuffle", "name": "authored_barrels", "label": "barrel",
      "requested": 24, "accepted": 24, "rejected": 0, "rejection_reasons": {} }
  ],
  "candidates": [
    { "candidate_id": "spawn_candidate_88b61021122d", "label": "barrel",
      "status": "accepted", "instance_id": "StaticMeshActor_778",
      "transform": { "position_m": [-161.099, -73.472, -1.410] } }
  ],
  "summary": { "requested": 84, "accepted": 84, "rejected": 0 },
  "manifest_hash": "f0c3ecffaa0cad2c861b7dd9afaccd403b4b6708d5ce033023e3939e6cd9c267"
}

Abridged from a real manifest in the reference capture. Every accepted placement names the actor it became, so a box in the exported labels can be traced back through the instance id to the decision that put the object there and the seed that drove it.

The manifests are hashed and checked against the run index afterwards. On the reference capture that check reported 40 frame manifests and the index in agreement, 3,360 candidates, 0 rejected with reasons.

Limits

Three things the spawner does not do, stated plainly.

It does not author your scene

Zones, classes and asset pools are yours to draw and assign. The spawner fills volumes; it does not decide that a warehouse should have racking in it.

It does not make placement realistic

Spacing, slope and ground contact keep objects physically plausible. Whether a barrel belongs in that spot at all is a question about your scene, not about the constraint solver.

Attempts are bounded

A placement gets 900 tries to find a legal position. In a scene with almost no legal space, the honest outcome is a refusal with a reason, not an object shoved somewhere illegal.