How to correctly create a new MaterialInstanceConstant in the editor from code

I’m trying to post-process imported FBX files, replacing the ton of Material references that each FBX brings in with MaterialInstances (the materials in question are all highly self-similar, varying only in texture assignments). Doing this by hand for a single model is trivial but I have several hundred models.

Here’s what I’m doing, in pseudocode:

  1. import the fbx
  2. load an existing MaterialInstanceConstant off disk that’s correctly set up
  3. create new package with a path and the editorworld as it’s outer
  4. duplicate the MaterialInstanceConstant from (2) with the package as it’s outer, naming it appropriately
  5. create a StaticMeshActor, setting its StaticMeshComponet.StaticMesh to the model I loaded in (1)
  6. set the Actor’s Override material(s) to reflect the stuff I synthesized in (2)

This actually creates the data formatted the way I want; my StaticMeshActor has the right mesh and the mesh’s material slots point at the MaterialInstanceConstants. However the MaterialInstanceConstants don’t get saved to disk, even if I manually trigger a ‘save all…’

What step could I be missing to make the new package/MaterialInstanceConstant register itself with the editor propertly?

Using the UnrealJS plugin, this more or less does what I need. However the MaterialInstanceConstants are not saved to disk independently: they appear to be serialized into the map file… ? They do save and persist between sessions. What would it take to save them as independent assets?

// this does the basics but we need to figure out how to 
// make the material istancer have it's own identity
// but 
function reassign_mesh(mesh_nanme, template){
"use strict";
let world = Root.GetEngine().GetEditorWorld();
var static_mesh_actor;
var ctr;
var actor_list = world.GetAllActorsOfClass(StaticMeshActor).OutActors;
for (ctr in actor_list)
{
	let each_actor = actor_list[ctr];
	if (each_actor != undefined)
	{
		console.info("? " + each_actor.GetDisplayName());
		if (each_actor && each_actor.GetDisplayName() == mesh_nanme)
		{
			static_mesh_actor = each_actor;
			console.info("found " + static_mesh_actor.GetDisplayName())
		};
	};
};
let model = static_mesh_actor.StaticMeshComponent.StaticMesh;
if (model == undefined)
{
	return "Can't find it";
}

var f;
var arr = [];
for (f in model.Materials)
{
	var mtl = model.Materials[f];
	var mtl_name = "proxy_" + f;
	if (mtl != undefined){
		mtl_name = mtl.GetDisplayName();
	
	};
	var filename = '/Game/p_' + mtl_name;
	let m2 = MaterialInstanceConstant.Load( template);
	let pkg = new Package(world, filename); 
	var dup = m2.Duplicate(pkg, 'p_' + mtl_name);
	arr.push(dup);
	
};
console.info(arr);
static_mesh_actor.StaticMeshComponent.OverrideMaterials = arr;

}