We are building a game engine that uses USD for all authoring data. Both DCC data to allow for good interop with other tool, as well as all game play properties etc.
Games generally lean much more on prefabs than scene composition / layering.
Games are generally split into multiple completely different scenes. With many prefab instances in it and some bespoke prims fully defined in the scene. Each of these scenes mostly has only one final composition that is used in practice. We can’t just change the scene completely in a different shot in a game Everything has to be one consistent world.
Many games also don’t follow a strict pipeline flow from modeling => texturing => animation => lighting => post processing. Rather it’s a very iterative process. So leaning on layers as overrides is much less commonly used in games.
I can see two purposes for layers:
- You want to avoid version control conflicts and split your scene based on how you work. For most game productions I would probably use an approach of enforcing that you can only segment parts of a scene (Only the layer who introduces a prim can change it’s attributes), as opposed to arbitrarily override prims/attributes in any layer in the composition tool. For the purposes of keeping things simple.
- You have a live game and want to author some events where part of your game changes. By using layers for the event you can easily enable / disable all of those changes. For this the full functionality of layers is very useful.
There are two things that games lean on very heavily to keep content under control. In games we call it prefabs, but it’s basically the same as references.
Overridable Prefabs (references, instanceable = false)
The entire hierarchy shows up in the scene and you can override anything in the scene. It’s very powerful and gives full control.
It quickly leads to a lot of breakages as prefabs get changed and scenes happened to have direct overrides to some part of the scene.
Generally it is something to avoid, since it very quickly leads to breakages when prefabs get refactored and overrides in scenes using it no longer work.
Exposed attribute Prefabs. (references, instanceable = true)
You generally only get to edit the root of the prefab instance. However a common workflow is that technical artists expose specific attributes anywhere in the prefab hierarchy and connect them up to attribute in the prefabs root prim. The exposed attributes are explicitly designed to be tweakable in the composition scene. The composition scene can position the object and change the exposed attributes. Intentionally limiting what you can edit in the scene.
Why?
- This both helps with mental load, given that prefabs can contain a prims / attributes, that a level designer may not fully understand. Being able to quickly see the 10 important tweakable properties on the instance is very useful.
- The ability to guarantee that scenes don’t break when I change my prefab (as long as i keep the same exposed attributes).
- Enforce safe workflows by default where you don’t accidentally do changes in the scene as overrides to a prefab instance that was not meant to for overriding in the scene.
I exposed this in our tooling as usd connections. Where anywhere in the hierarchy of a prefab you can expose a property, which goes into the root of the prefab as exposed:someParameter with the property having a connection to it. This way any instancable = true, references prim can overrides those exposed parameters.
So far I am pretty happy with this approach. We integrated this into our tool & baking workflow. Basically when getting values we always follow the connections to arrive at the final attribute that is actually used.
Unfortunately doing this means we are not creating composition scenes that other tools understand anymore. It is possible to just generate a layer and turn those exposed properties into overrides to allow for interop with other tools that don’t natively understand our use of connections to drive exposed attributes. But of course that’s going to get brittle when other tools start editing those exposed attributes as overrides.
To me exposed properties on instances, seem like quite essential functionality for any safe production workflows.
So my question is, is this useful and worth exploring for the wider USD ecosystem? Have others built similar / same system? Is there something I am missing that exists to solve the problem of safe production workflows for prefab instances.