FIG.01

We have a 3D character - Luntik - fully rigged and animation-ready. He stars in a TV series, and each episode he wears something different: a hat, a coat, a winter jacket. The rigging team builds a separate version of Luntik for each, each living in its own Maya file with the new attire attached to the base rig. One base character, many variants.

Now a bug turns up in the base rig. The rigger fixes it in the main file. What about the ten variants? Replicating the fix by hand across all of them is slow and error-prone. And it gets worse the more characters there are in the show.

Maya references seem like the obvious answer - load Luntik and his accessories as separate references, rig the combination, save the result - but nested reference edits in Maya tend to overlap and lead to crashes. Not a real option.

So: recipes.

The recipe concept

When you need a small variant of a character - Luntik with a hat - you start in an empty scene, load the main rig and the hat as references, do the rigging, and save the result as a recipe: a file that records everything done. References used, new nodes created, attribute changes, connections, the lot. The recipe can then be replayed in any scene to reconstruct the setup. No nested reference edits - every change is applied live in the host scene.

The implementation was built for proprietary use at a company so I can’t share the source, but the structure is worth describing.

A recipe captures:

  • Plugins active when the recipe was created.
  • References loaded, with their namespaces.
  • Nodes created, including meshes. Many deformers generate hidden shape copies of the deformed geometry; those need to be recreated too.
  • Reference edits applied after loading.
  • Animation curves, including driven keys - these have their own creation syntax separate from regular node data.
  • Node connections.

Saving a recipe usually takes under 10 seconds.

Loading order

FIG.02

Loading has to happen in a specific order - most steps depend on earlier ones. You can’t set an attribute on a node that doesn’t exist yet, for example:

  1. Load plugins.
  2. Load references.
  3. Create meshes.
  4. Create nodes.
  5. Parent created nodes.
  6. Add new attributes to non-referenced nodes.
  7. Set attribute values on non-referenced nodes.
  8. Create animation curves.
  9. Apply reference edits.
  10. Apply node connections.
  11. Tag all created nodes with the recipe ID.

Two parts are awkward: reference loading and node creation. The names Maya assigns to newly created nodes and references in the host scene won’t match the names stored in the recipe. So every created node and reference DAG node needs to be mapped back to its recipe-side name before reference edits and connections can be applied - those reference nodes by name, and the names have moved.

Mesh creation also needs per-type handling. Polygons, NURBS curves, NURBS surfaces each need their own code path.

The final step - tagging - is what makes the system manageable. Each created node gets a recipe ID, since a scene can contain multiple recipes or the same recipe applied multiple times. With the ID, you can track which nodes belong to which recipe, and a full removal is just “delete every node carrying this ID.”

Applying a recipe to an already-loaded character

You can apply a recipe to a character that’s already loaded and animated. Say Luntik is in the scene with a few animation passes done, and you want to add the hat recipe. The animation stays, the hat is added, the recipe is applied. The only thing to be careful of: any new references the recipe loads (the hat) need to be transformed to match Luntik’s current pose, not dropped at the scene origin.

Reloading a recipe

Recipes can change after they’ve been loaded into a scene. Suppose the hat design changes and rigging pushes a new version. Luntik is already animated, and the animator has tweaked some attributes themselves. Reloading needs to bring in the new rig without throwing away the animator’s work.

The process:

  1. Preserve the current state of all nodes belonging to the recipe.
  2. Disconnect everything before deletion, so linked animation curves and other nodes survive.
  3. Each recipe stores its initial state on load, encoded as a string attribute on its nodes. Keep this in memory.
  4. Remove the recipe entirely - all its nodes and references.
  5. Load the new recipe.
  6. Reapply the preserved state, filtered.

That last step is the tricky one. You can’t just reapply everything - that would overwrite the new recipe with the old one. So you compare the original recipe to the new one, and for each change in the animator’s work, you check whether the new recipe already touches that same attribute or connection. If it does, the new value wins. If not, the animator’s value is reapplied.

End result: Luntik gets the new hat, the recipe is updated, the animator’s work is preserved.

FIG.03

Limitations

Recipes don’t replace separate character versions for everything. Big structural changes should still live in their own Maya files. Recipes are for small-to-medium variations.

A few rough edges:

  • No notification on recipe updates. Users have to know to reload. Could be solved with a file watcher or a notification on save.
  • Hard reloads are painful. If a recipe changes substantially - references swapped out, large structural shifts - the soft reload above can’t preserve everything cleanly, and you need a hard reload (full removal and reapply). Keeping animation intact through that isn’t fully solved.

Useful for the common case, not a silver bullet.