Procedurally create a map in C++

I am trying to write a commandlet that creates an empty map, spawns a list of Static Mesh Actors into it and saves it.
I would also like to access the map from the editor for debug purposes.

I have tried multiple approaches, both by taking inspiration from the C++ APIs and from other projects (e.g. CARLA sim), however due to the lack of documentation on this specific feature it’s been very hard.

The two approaches I tried to follow are:

  • Use the function UEditorLoadingAndSavingUtils::NewBlankMap(bool); and then UEditorLoadingAndSavingUtils::SaveMap( UWorld * World, const FString & AssetPath), which either generates crashes during the procedure or does not generate a map file at all
  • Create an empty map in the contents folder (let’s call it BaseMap), use that as a base, then use UPackage and FAssetRegistryModule to create a new instance in another folder, then save it using UPackage::SavePackage. This creates a new map (let’s call this FinalMap), but it’s as if this new map was a “link” to BaseMap (if I modify BaseMap, save it and then open FinalMap, the latter will have the changes of BaseMap).

This is the code that I used for the second approach:

TArray<AStaticMeshActor*> UExportAssetsForPackagingCommandlet::GenerateNewMap(
    const TArray<FString>& AssetsPaths, const FString& MapPath)
{
    UWorld* ExporterWorld = CastChecked<UWorld>(ExporterMapData.GetAsset()); 
    UPackage* ExporterPackage = ExporterMapData.GetPackage();
    FString OutputFolder(TEXT("/Game/Exporter/Output"));
    ExporterPackage->SetFolderName(*OutputFolder);
    ExporterPackage->FullyLoad();
    ExporterPackage->MarkPackageDirty();

    FAssetRegistryModule::AssetCreated(ExporterWorld);

    ExporterWorld->Rename(TEXT("Assets_To_Export"), ExporterWorld->GetOuter());
    FString PackagePath = OutputFolder + TEXT("/AssetsExporter");
    FAssetRegistryModule::AssetRenamed(ExporterPackage, *PackagePath);
    ExporterPackage->MarkPackageDirty();

    FString PackageFileName = FPackageName::LongPackageNameToFilename(PackagePath, FPackageName::GetMapPackageExtension());

    UPackage::SavePackage(ExporterPackage, ExporterWorld, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *PackageFileName,
        GError, nullptr, true, true, SAVE_NoError);

    return {};    // SpawnedMeshes;
}

Is there a correct way of doing this? Where can I find the documentation for procedurally create a map file from scratch in C++?

If it was possible I would also like to understand what’s the concept of packages and how it relates to assets because the official documentation only talks about packages when talking about “Packaging a game”, but it seems to be a different concept when talking about assets handling.

Very interested in this topic, for all that I saw unreal its just not prepared at all for procedural like this. Hope see if theres any way to make it possible