Browse Source

Script only game runtime (#16903)

* Script-only-mode continuation

* A generic launcher is built when building without targets
* The generic launcher is used as the launcher in script only mode
* Script Only projects now include a package.sh / package.bat
* Script only projects now include an example seed and "start" level
* Script only projects auto start the "start" level.
* When building an installer, we generate 3rd party cmake files that
  can be used to copy the missing dependencies from the installer
  into script-only projects.  These scripts are only used in
  script-only projects.

Signed-off-by: Nicholas Lawson <[email protected]>

* Fixes for the launcher due to conflicts

Signed-off-by: Nicholas Lawson <[email protected]>

* Fixes for the script-only mode feature (Due to PR)

* Fixes comments from the PR
* Adds the exported project folder to AP ignores so that generating
  a project using the package script doesn't cause the next run
  of the engine to add those generated package files into the cache.
* Adds a check for using 'o3de' as a project name

Signed-off-by: Nicholas Lawson <[email protected]>

* Fix the fatal error message

Signed-off-by: Nicholas Lawson <[email protected]>

* Update for PR code comments

Signed-off-by: Nicholas Lawson <[email protected]>

* PR Comments addressed.

Signed-off-by: Nicholas Lawson <[email protected]>

* Updates to make it work with the new development branch

I had to resolve conflicts, and found that there is no longer a
need for a separate export script compared to a source build project.

Signed-off-by: Nicholas Lawson <[email protected]>

* Fix a problem that only happens when building engine-centric
with a project specified.

Signed-off-by: Nicholas Lawson <[email protected]>

* Fix for AR failure

Signed-off-by: Nicholas Lawson <[email protected]>

* What a spelling mistake!

Signed-off-by: Nicholas Lawson <[email protected]>

---------

Signed-off-by: Nicholas Lawson <[email protected]>
Nicholas Lawson 1 year ago
parent
commit
5aea1a28f7

+ 21 - 2
Code/LauncherUnified/Launcher.cpp

@@ -411,7 +411,26 @@ namespace O3DELauncher
             // Settings registry must be available at this point in order to continue
             // Settings registry must be available at this point in order to continue
             return ReturnCode::ErrValidation;
             return ReturnCode::ErrValidation;
         }
         }
-        const AZStd::string_view buildTargetName = GetBuildTargetName();
+
+        // Save the build target name (usually myprojectname_gamelauncher, or myprojectname_serverlauncher, etc)
+        // into the specialization list, so that the regset files for xxxxx.myprojectname_gamelauncher are included in the loaded set.
+        // in generic mode, this needs to be updated to a name based on the project name, so it is not a string view, here.
+        AZ::SettingsRegistryInterface::FixedValueString buildTargetName(GetBuildTargetName());
+
+        // retrieve the project name as specified by the actual project.json (or updated from command line)
+        AZ::SettingsRegistryInterface::FixedValueString updatedProjectName = AZ::Utils::GetProjectName();
+        if (IsGenericLauncher())
+        {
+            constexpr AZStd::string_view O3DEPrefix = "O3DE_";
+            // this will always be the value O3DE_xxxxx where xxxxx is the type of target ("GameLauncher/ServerLauncher/UnifiedLauncher/etc")
+            // and O3DE is a placeholder for the project name.  Replace the "O3DE_" part with "{ProjectName}_" (keeping the underscore).
+            if (buildTargetName.starts_with(O3DEPrefix))
+            {
+                auto replacementName = AZ::SettingsRegistryInterface::FixedValueString::format(
+                    "%.*s_", aznumeric_cast<int>(updatedProjectName.size()), updatedProjectName.data());
+                buildTargetName.replace(0, O3DEPrefix.size(), replacementName);
+            }
+        }
         AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization(*settingsRegistry, buildTargetName);
         AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization(*settingsRegistry, buildTargetName);
 
 
         //Store the launcher type to the Settings Registry
         //Store the launcher type to the Settings Registry
@@ -432,7 +451,7 @@ namespace O3DELauncher
         AZ_TracePrintf("Launcher", R"(Running project "%.*s")" "\n"
         AZ_TracePrintf("Launcher", R"(Running project "%.*s")" "\n"
             R"(The project name has been successfully set in the Settings Registry at key "%s/project_name")"
             R"(The project name has been successfully set in the Settings Registry at key "%s/project_name")"
             R"( for Launcher target "%.*s")" "\n",
             R"( for Launcher target "%.*s")" "\n",
-            aznumeric_cast<int>(launcherProjectName.size()), launcherProjectName.data(),
+            aznumeric_cast<int>(updatedProjectName.size()), updatedProjectName.data(),
             AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey,
             AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey,
             aznumeric_cast<int>(buildTargetName.size()), buildTargetName.data());
             aznumeric_cast<int>(buildTargetName.size()), buildTargetName.data());
 
 

+ 3 - 0
Code/LauncherUnified/Launcher.h

@@ -91,6 +91,9 @@ namespace O3DELauncher
     //! This function returns the build system target name
     //! This function returns the build system target name
     AZStd::string_view GetBuildTargetName();
     AZStd::string_view GetBuildTargetName();
 
 
+    //! This function returns whether its the Generic launcher or not (for Script-Only mode)
+    bool IsGenericLauncher();
+
     //////////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////////
     // The following functions are defined per launcher type (e.g. Client/Server/Unified)
     // The following functions are defined per launcher type (e.g. Client/Server/Unified)
     //////////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////////

+ 15 - 0
Code/LauncherUnified/LauncherProject.cpp

@@ -6,6 +6,12 @@
  *
  *
  */
  */
 
 
+// note that this is the only file pulled into a launcher target that has the
+// defines set such as LY_CMAKE_TARGET, and LY_PROJECT_NAME, other files come from a static library
+// which do not provide those defines.
+// note that the tests use a mock implementation of this file, see Tests/Test.cpp
+// If you modify this file or the interface launcher.h, make sure to update the mock implementation as well.
+
 #include <AzCore/std/string/string_view.h>
 #include <AzCore/std/string/string_view.h>
 
 
 #if defined(AZ_MONOLITHIC_BUILD)
 #if defined(AZ_MONOLITHIC_BUILD)
@@ -32,4 +38,13 @@ namespace O3DELauncher
 #endif
 #endif
         return { LY_PROJECT_NAME };
         return { LY_PROJECT_NAME };
     }
     }
+
+    bool IsGenericLauncher()
+    {
+#if defined(O3DE_IS_GENERIC_LAUNCHER)
+        return true;
+#else
+        return false;
+#endif
+    }
 }
 }

+ 9 - 0
Code/LauncherUnified/Tests/Test.cpp

@@ -8,6 +8,10 @@
 
 
 #include <AzCore/std/string/string_view.h>
 #include <AzCore/std/string/string_view.h>
 
 
+// this is a mock O3DE Launcher implementation for unit tests and is used
+// instead of LauncherProject.cpp.  If you modify LauncherProject.cpp or the interface launcher.h, make sure
+// to update this file as well.
+
 namespace O3DELauncher
 namespace O3DELauncher
 {
 {
     bool WaitForAssetProcessorConnect()
     bool WaitForAssetProcessorConnect()
@@ -47,4 +51,9 @@ namespace O3DELauncher
     {
     {
         return { "Tests" };
         return { "Tests" };
     }
     }
+
+    bool IsGenericLauncher()
+    {
+        return false;
+    }
 }
 }

+ 72 - 34
Code/LauncherUnified/launcher_generator.cmake

@@ -27,46 +27,62 @@ set(SERVER_VARIANT_HeadlessServerLauncher HeadlessServers)
 # and allow them to be overridden to "INTERFACE" in script-only mode.
 # and allow them to be overridden to "INTERFACE" in script-only mode.
 set(LAUNCHER_TARGET_PROPERTY_TYPE "PRIVATE")
 set(LAUNCHER_TARGET_PROPERTY_TYPE "PRIVATE")
 
 
-# in script_only_mode, generate interface targets.  If a real 'generic launcher' is added, this would
-# also be an opportunity to add imported exectables.
-if (O3DE_SCRIPT_ONLY)
-    set(PAL_TRAIT_LAUNCHERUNIFIED_LAUNCHER_TYPE INTERFACE)
-    set(SERVER_LAUNCHERTYPE_ServerLauncher INTERFACE)
-    set(SERVER_LAUNCHERTYPE_HeadlessServerLauncher INTERFACE)
-    set(LAUNCHER_TARGET_PROPERTY_TYPE INTERFACE) # you can only set interface properties on interfaces.
-endif()
-
 # Launcher targets for a project need to be generated when configuring a project.
 # Launcher targets for a project need to be generated when configuring a project.
 # When building the engine source, this file will be included by LauncherUnified's CMakeLists.txt
 # When building the engine source, this file will be included by LauncherUnified's CMakeLists.txt
 # When using an installed engine, this file will be included by the FindLauncherGenerator.cmake script
 # When using an installed engine, this file will be included by the FindLauncherGenerator.cmake script
 get_property(SERVER_LAUNCHER_TYPES GLOBAL PROPERTY SERVER_LAUNCHER_TYPES)
 get_property(SERVER_LAUNCHER_TYPES GLOBAL PROPERTY SERVER_LAUNCHER_TYPES)
 get_property(O3DE_PROJECTS_NAME GLOBAL PROPERTY O3DE_PROJECTS_NAME)
 get_property(O3DE_PROJECTS_NAME GLOBAL PROPERTY O3DE_PROJECTS_NAME)
-foreach(project_name project_path IN ZIP_LISTS O3DE_PROJECTS_NAME LY_PROJECTS)
 
 
-    # Computes the realpath to the project
-    # If the project_path is relative, it is evaluated relative to the ${LY_ROOT_FOLDER}
-    # Otherwise the the absolute project_path is returned with symlinks resolved
-    file(REAL_PATH ${project_path} project_real_path BASE_DIRECTORY ${LY_ROOT_FOLDER})
+# when NO project is specified, for example, when creating a pre-built version of the engine,
+# create a generic launcher that can be shipped with the engine
+
+set(launcher_generator_LY_PROJECTS ${LY_PROJECTS})
+
+# the following generates "generic" launchers when no project is specified
+# this cannot happen in script only mode, since scripts-only mode requires a prebuilt installer
+# and the prebuilt installer always operates on a project, so will generally only happen
+# when building an installer from the o3de source code, or just compiling O3DE itself with no
+# project specified.
+if (NOT launcher_generator_LY_PROJECTS)
+    set(launcher_generator_LY_PROJECTS ":PROJECT_PATH_ONLY_FOR_GENERIC_LAUNCHER")
+    set(O3DE_PROJECTS_NAME "O3DE")
+    set(launcher_generator_BUILD_GENERIC TRUE) # used to skip the asset processing step
+    
+    # set a compile definition on the launchers themselves to let them know they are generic launchers
+    # they can use this in their code and logic to avoid doing things like loading the burned-in
+    # registry keys.
+    set(GENERIC_LAUNCHER_COMPILE_DEFINITION "O3DE_IS_GENERIC_LAUNCHER")
+endif()
 
 
-    ################################################################################
-    # Assets
-    ################################################################################
-    if(PAL_TRAIT_BUILD_HOST_TOOLS)
-        add_custom_target(${project_name}.Assets
-            COMMENT "Processing ${project_name} assets..."
-            COMMAND "${CMAKE_COMMAND}"
-                -DLY_LOCK_FILE=$<GENEX_EVAL:$<TARGET_FILE_DIR:AZ::AssetProcessorBatch>>/project_assets.lock
-                -P ${LY_ROOT_FOLDER}/cmake/CommandExecution.cmake
-                    EXEC_COMMAND $<GENEX_EVAL:$<TARGET_FILE:AZ::AssetProcessorBatch>>
-                        --zeroAnalysisMode
-                        --project-path=${project_real_path}
-                        --platforms=${LY_ASSET_DEPLOY_ASSET_TYPE}
-        )
-        set_target_properties(${project_name}.Assets
-            PROPERTIES
-                EXCLUDE_FROM_ALL TRUE
-                FOLDER ${project_name}
-        )
+
+foreach(project_name project_path IN ZIP_LISTS O3DE_PROJECTS_NAME launcher_generator_LY_PROJECTS)
+
+    if (NOT launcher_generator_BUILD_GENERIC) # generic launcher does not build assets.
+        # Computes the realpath to the project.  Only used in building assets.
+        # If the project_path is relative, it is evaluated relative to the ${LY_ROOT_FOLDER}
+        # Otherwise the the absolute project_path is returned with symlinks resolved
+        file(REAL_PATH ${project_path} project_real_path BASE_DIRECTORY ${LY_ROOT_FOLDER})
+
+        ################################################################################
+        # Assets
+        ################################################################################
+        if(PAL_TRAIT_BUILD_HOST_TOOLS)
+            add_custom_target(${project_name}.Assets
+                COMMENT "Processing ${project_name} assets..."
+                COMMAND "${CMAKE_COMMAND}"
+                    -DLY_LOCK_FILE=$<GENEX_EVAL:$<TARGET_FILE_DIR:AZ::AssetProcessorBatch>>/project_assets.lock
+                    -P ${LY_ROOT_FOLDER}/cmake/CommandExecution.cmake
+                        EXEC_COMMAND $<GENEX_EVAL:$<TARGET_FILE:AZ::AssetProcessorBatch>>
+                            --zeroAnalysisMode
+                            --project-path=${project_real_path}
+                            --platforms=${LY_ASSET_DEPLOY_ASSET_TYPE}
+            )
+            set_target_properties(${project_name}.Assets
+                PROPERTIES
+                    EXCLUDE_FROM_ALL TRUE
+                    FOLDER ${project_name}
+            )
+        endif()
     endif()
     endif()
 
 
     ################################################################################
     ################################################################################
@@ -109,16 +125,35 @@ foreach(project_name project_path IN ZIP_LISTS O3DE_PROJECTS_NAME LY_PROJECTS)
             Legacy::CrySystem
             Legacy::CrySystem
         )
         )
 
 
+        # in script only mode, which can only happen when building a project
+        # that is using a prebuilt installer, add the generic gamelauncher as a run time dependency
+        # of the project launcher.  The project launcher is "fake" and will not get actually compiled,
+        # but this will cause the generic game launcher and its dependencies to get deployed into the bin folder
+        # since they are all dependencies of this fake target.
+        
+        if (O3DE_SCRIPT_ONLY)
+            set(game_runtime_dependencies ${game_runtime_dependencies} O3DE.GameLauncher)
+        endif()
+
         if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
         if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
             set(server_runtime_dependencies
             set(server_runtime_dependencies
                 Legacy::CrySystem
                 Legacy::CrySystem
             )
             )
+
+            if (O3DE_SCRIPT_ONLY)
+                foreach(server_launcher_type ${SERVER_LAUNCHER_TYPES})
+                    set(SERVER_RUNTIME_DEPENDENCIES_${server_launcher_type} "${SERVER_RUNTIME_DEPENDENCIES_${server_launcher_type}}" O3DE.${server_launcher_type})
+                endforeach()
+            endif()
         endif()
         endif()
 
 
         if(PAL_TRAIT_BUILD_UNIFIED_SUPPORTED)
         if(PAL_TRAIT_BUILD_UNIFIED_SUPPORTED)
             set(unified_runtime_dependencies
             set(unified_runtime_dependencies
                 Legacy::CrySystem
                 Legacy::CrySystem
             )
             )
+            if (O3DE_SCRIPT_ONLY)
+                set(unified_runtime_dependencies ${unified_runtime_dependencies} O3DE.UnifiedLauncher)
+            endif()
         endif()
         endif()
 
 
     endif()
     endif()
@@ -141,6 +176,7 @@ foreach(project_name project_path IN ZIP_LISTS O3DE_PROJECTS_NAME LY_PROJECTS)
                 # when loading .setreg file specializations
                 # when loading .setreg file specializations
                 # This is needed so that only gems for the project game launcher are loaded
                 # This is needed so that only gems for the project game launcher are loaded
                 LY_CMAKE_TARGET="${project_name}_GameLauncher"
                 LY_CMAKE_TARGET="${project_name}_GameLauncher"
+                "${GENERIC_LAUNCHER_COMPILE_DEFINITION}" # this is empty if its not a generic launcher
         INCLUDE_DIRECTORIES
         INCLUDE_DIRECTORIES
             ${LAUNCHER_TARGET_PROPERTY_TYPE}
             ${LAUNCHER_TARGET_PROPERTY_TYPE}
                 .
                 .
@@ -201,6 +237,7 @@ foreach(project_name project_path IN ZIP_LISTS O3DE_PROJECTS_NAME LY_PROJECTS)
                         # when loading .setreg file specializations
                         # when loading .setreg file specializations
                         # This is needed so that only gems for the project server launcher are loaded
                         # This is needed so that only gems for the project server launcher are loaded
                         LY_CMAKE_TARGET="${project_name}_${server_launcher_type}"
                         LY_CMAKE_TARGET="${project_name}_${server_launcher_type}"
+                        "${GENERIC_LAUNCHER_COMPILE_DEFINITION}" # this is empty if its not a generic launcher
 
 
                 INCLUDE_DIRECTORIES
                 INCLUDE_DIRECTORIES
                     ${LAUNCHER_TARGET_PROPERTY_TYPE}
                     ${LAUNCHER_TARGET_PROPERTY_TYPE}
@@ -210,7 +247,7 @@ foreach(project_name project_path IN ZIP_LISTS O3DE_PROJECTS_NAME LY_PROJECTS)
                     ${LAUNCHER_TARGET_PROPERTY_TYPE}
                     ${LAUNCHER_TARGET_PROPERTY_TYPE}
                         ${SERVER_BUILD_DEPENDENCIES_${server_launcher_type}}
                         ${SERVER_BUILD_DEPENDENCIES_${server_launcher_type}}
                 RUNTIME_DEPENDENCIES
                 RUNTIME_DEPENDENCIES
-                    ${server_runtime_dependencies}
+                    ${SERVER_RUNTIME_DEPENDENCIES_${server_launcher_type}}
             )
             )
             # Needs to be set manually after ly_add_target to prevent the default location overriding it
             # Needs to be set manually after ly_add_target to prevent the default location overriding it
             set_target_properties(${project_name}.${server_launcher_type}
             set_target_properties(${project_name}.${server_launcher_type}
@@ -265,6 +302,7 @@ foreach(project_name project_path IN ZIP_LISTS O3DE_PROJECTS_NAME LY_PROJECTS)
                     # when loading .setreg file specializations
                     # when loading .setreg file specializations
                     # This is needed so that only gems for the project unified launcher are loaded
                     # This is needed so that only gems for the project unified launcher are loaded
                     LY_CMAKE_TARGET="${project_name}_UnifiedLauncher"
                     LY_CMAKE_TARGET="${project_name}_UnifiedLauncher"
+                    "${GENERIC_LAUNCHER_COMPILE_DEFINITION}" # this is empty if its not a generic launcher
             INCLUDE_DIRECTORIES
             INCLUDE_DIRECTORIES
                 ${LAUNCHER_TARGET_PROPERTY_TYPE}
                 ${LAUNCHER_TARGET_PROPERTY_TYPE}
                     .
                     .

+ 3 - 0
Registry/AssetProcessorPlatformConfig.setreg

@@ -206,6 +206,9 @@
                 "Exclude Install": {
                 "Exclude Install": {
                     "glob": "install/*"
                     "glob": "install/*"
                 },
                 },
+                "Exclude ProjectPackages": {
+                    "glob": "ProjectPackages/*"
+                },
                 // Exclude Gems inside Projects, their Assets folders will still be included
                 // Exclude Gems inside Projects, their Assets folders will still be included
                 "Exclude Gems": {
                 "Exclude Gems": {
                     "glob": "Gems/*"
                     "glob": "Gems/*"

+ 15 - 0
Templates/ScriptOnlyProject/Template/AssetBundling/SeedLists/Example.seed

@@ -0,0 +1,15 @@
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "AZStd::vector<SeedInfo, allocator>",
+    "ClassData": [
+        {
+            "assetId": {
+                "guid": "{B3C48432-037D-5AA5-BB1B-6D7AE19E89DF}",
+                "subId": 204440690
+            },
+            "platformFlags": 2,
+            "pathHint": "levels/start/start.spawnable"
+        }
+    ]
+}

+ 557 - 0
Templates/ScriptOnlyProject/Template/Levels/start/start.prefab

@@ -0,0 +1,557 @@
+{
+    "ContainerEntity": {
+        "Id": "Entity_[1146574390643]",
+        "Name": "Level",
+        "Components": {
+            "Component_[10641544592923449938]": {
+                "$type": "EditorInspectorComponent",
+                "Id": 10641544592923449938
+            },
+            "Component_[12039882709170782873]": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 12039882709170782873
+            },
+            "Component_[12265484671603697631]": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 12265484671603697631
+            },
+            "Component_[14126657869720434043]": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 14126657869720434043,
+                "Child Entity Order": [
+                    "Entity_[1176639161715]"
+                ]
+            },
+            "Component_[15230859088967841193]": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 15230859088967841193,
+                "Parent Entity": ""
+            },
+            "Component_[16239496886950819870]": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 16239496886950819870
+            },
+            "Component_[5688118765544765547]": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 5688118765544765547
+            },
+            "Component_[7247035804068349658]": {
+                "$type": "EditorPrefabComponent",
+                "Id": 7247035804068349658
+            },
+            "Component_[9307224322037797205]": {
+                "$type": "EditorLockComponent",
+                "Id": 9307224322037797205
+            },
+            "Component_[9562516168917670048]": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 9562516168917670048
+            },
+            "LocalViewBookmarkComponent": {
+                "$type": "LocalViewBookmarkComponent",
+                "Id": 1290452037346922644,
+                "LocalBookmarkFileName": "start_1697236353301802388.setreg"
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[1155164325235]": {
+            "Id": "Entity_[1155164325235]",
+            "Name": "Sun",
+            "Components": {
+                "Component_[13620450453324765907]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 13620450453324765907
+                },
+                "Component_[2134313378593666258]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 2134313378593666258
+                },
+                "Component_[234010807770404186]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 234010807770404186
+                },
+                "Component_[2970359110423865725]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 2970359110423865725
+                },
+                "Component_[3722854130373041803]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 3722854130373041803
+                },
+                "Component_[5992533738676323195]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5992533738676323195
+                },
+                "Component_[7378860763541895402]": {
+                    "$type": "AZ::Render::EditorDirectionalLightComponent",
+                    "Id": 7378860763541895402,
+                    "Controller": {
+                        "Configuration": {
+                            "Intensity": 1.0,
+                            "CameraEntityId": "",
+                            "ShadowFilterMethod": 1
+                        }
+                    }
+                },
+                "Component_[7892834440890947578]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 7892834440890947578,
+                    "Parent Entity": "Entity_[1176639161715]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            0.0,
+                            13.487043380737305
+                        ],
+                        "Rotate": [
+                            -76.13099670410156,
+                            -0.847000002861023,
+                            -15.8100004196167
+                        ]
+                    }
+                },
+                "Component_[8599729549570828259]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 8599729549570828259
+                },
+                "Component_[952797371922080273]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 952797371922080273
+                }
+            }
+        },
+        "Entity_[1159459292531]": {
+            "Id": "Entity_[1159459292531]",
+            "Name": "Ground",
+            "Components": {
+                "Component_[12260880513256986252]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 12260880513256986252
+                },
+                "Component_[13711420870643673468]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 13711420870643673468
+                },
+                "Component_[138002849734991713]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 138002849734991713
+                },
+                "Component_[16578565737331764849]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 16578565737331764849,
+                    "Parent Entity": "Entity_[1176639161715]"
+                },
+                "Component_[16919232076966545697]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 16919232076966545697
+                },
+                "Component_[4228479570410194639]": {
+                    "$type": "EditorStaticRigidBodyComponent",
+                    "Id": 4228479570410194639
+                },
+                "Component_[5182430712893438093]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 5182430712893438093
+                },
+                "Component_[5245524694917323904]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 5245524694917323904,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            0.0,
+                            -0.5
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 1,
+                        "Box": {
+                            "Configuration": [
+                                512.0,
+                                512.0,
+                                1.0
+                            ]
+                        }
+                    },
+                    "DebugDrawSettings": {
+                        "LocallyEnabled": false
+                    }
+                },
+                "Component_[5675108321710651991]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 5675108321710651991,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}",
+                                    "subId": 277889906
+                                },
+                                "assetHint": "objects/groudplane/groundplane_512x512m.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[5681893399601237518]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 5681893399601237518
+                },
+                "Component_[592692962543397545]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 592692962543397545
+                },
+                "Component_[7090012899106946164]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 7090012899106946164
+                },
+                "Component_[9410832619875640998]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 9410832619875640998
+                }
+            }
+        },
+        "Entity_[1163754259827]": {
+            "Id": "Entity_[1163754259827]",
+            "Name": "Camera",
+            "Components": {
+                "Component_[11895140916889160460]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11895140916889160460
+                },
+                "Component_[16880285896855930892]": {
+                    "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
+                    "Id": 16880285896855930892,
+                    "Controller": {
+                        "Configuration": {
+                            "Field of View": 55.0
+                        }
+                    }
+                },
+                "Component_[17187464423780271193]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 17187464423780271193
+                },
+                "Component_[17495696818315413311]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 17495696818315413311
+                },
+                "Component_[18086214374043522055]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 18086214374043522055,
+                    "Parent Entity": "Entity_[1176639161715]",
+                    "Transform Data": {
+                        "Translate": [
+                            -2.3000001907348633,
+                            -3.9368600845336914,
+                            1.0
+                        ],
+                        "Rotate": [
+                            -2.050307512283325,
+                            1.9552897214889526,
+                            -43.623355865478516
+                        ]
+                    }
+                },
+                "Component_[2654521436129313160]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 2654521436129313160
+                },
+                "Component_[5265045084611556958]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5265045084611556958
+                },
+                "Component_[7169798125182238623]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 7169798125182238623
+                },
+                "Component_[7255796294953281766]": {
+                    "$type": "GenericComponentWrapper",
+                    "Id": 7255796294953281766,
+                    "m_template": {
+                        "$type": "FlyCameraInputComponent"
+                    }
+                },
+                "Component_[8866210352157164042]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 8866210352157164042
+                },
+                "Component_[9129253381063760879]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 9129253381063760879
+                }
+            }
+        },
+        "Entity_[1168049227123]": {
+            "Id": "Entity_[1168049227123]",
+            "Name": "Grid",
+            "Components": {
+                "Component_[11443347433215807130]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11443347433215807130
+                },
+                "Component_[14249419413039427459]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14249419413039427459
+                },
+                "Component_[15448581635946161318]": {
+                    "$type": "AZ::Render::EditorGridComponent",
+                    "Id": 15448581635946161318,
+                    "Controller": {
+                        "Configuration": {
+                            "primarySpacing": 4.0,
+                            "primaryColor": [
+                                0.501960813999176,
+                                0.501960813999176,
+                                0.501960813999176
+                            ],
+                            "secondarySpacing": 0.5,
+                            "secondaryColor": [
+                                0.250980406999588,
+                                0.250980406999588,
+                                0.250980406999588
+                            ]
+                        }
+                    }
+                },
+                "Component_[1843303322527297409]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 1843303322527297409
+                },
+                "Component_[380249072065273654]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 380249072065273654,
+                    "Parent Entity": "Entity_[1176639161715]"
+                },
+                "Component_[7476660583684339787]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 7476660583684339787
+                },
+                "Component_[7557626501215118375]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 7557626501215118375
+                },
+                "Component_[7984048488947365511]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 7984048488947365511
+                },
+                "Component_[8118181039276487398]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 8118181039276487398
+                },
+                "Component_[9189909764215270515]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 9189909764215270515
+                }
+            }
+        },
+        "Entity_[1172344194419]": {
+            "Id": "Entity_[1172344194419]",
+            "Name": "Shader Ball",
+            "Components": {
+                "Component_[10789351944715265527]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 10789351944715265527
+                },
+                "Component_[12037033284781049225]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 12037033284781049225
+                },
+                "Component_[13759153306105970079]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 13759153306105970079
+                },
+                "Component_[14135560884830586279]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14135560884830586279
+                },
+                "Component_[16247165675903986673]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 16247165675903986673
+                },
+                "Component_[18082433625958885247]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 18082433625958885247
+                },
+                "Component_[6472623349872972660]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 6472623349872972660,
+                    "Parent Entity": "Entity_[1176639161715]",
+                    "Transform Data": {
+                        "Rotate": [
+                            0.0,
+                            0.10000000149011612,
+                            180.0
+                        ]
+                    }
+                },
+                "Component_[6495255223970673916]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 6495255223970673916,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{FD340C30-755C-5911-92A3-19A3F7A77931}",
+                                    "subId": 281415304
+                                },
+                                "assetHint": "objects/shaderball/shaderball_default_1m.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[8550141614185782969]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 8550141614185782969
+                },
+                "Component_[9439770997198325425]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 9439770997198325425
+                }
+            }
+        },
+        "Entity_[1176639161715]": {
+            "Id": "Entity_[1176639161715]",
+            "Name": "Atom Default Environment",
+            "Components": {
+                "Component_[10757302973393310045]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 10757302973393310045,
+                    "Parent Entity": "Entity_[1146574390643]"
+                },
+                "Component_[14505817420424255464]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14505817420424255464,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 10757302973393310045
+                        }
+                    ]
+                },
+                "Component_[14988041764659020032]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 14988041764659020032
+                },
+                "Component_[15900837685796817138]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 15900837685796817138
+                },
+                "Component_[3298767348226484884]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 3298767348226484884
+                },
+                "Component_[4076975109609220594]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 4076975109609220594
+                },
+                "Component_[5679760548946028854]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5679760548946028854
+                },
+                "Component_[5855590796136709437]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 5855590796136709437,
+                    "Child Entity Order": [
+                        "Entity_[1155164325235]",
+                        "Entity_[1180934129011]",
+                        "Entity_[1172344194419]",
+                        "Entity_[1168049227123]",
+                        "Entity_[1163754259827]",
+                        "Entity_[1159459292531]"
+                    ]
+                },
+                "Component_[9277695270015777859]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 9277695270015777859
+                }
+            }
+        },
+        "Entity_[1180934129011]": {
+            "Id": "Entity_[1180934129011]",
+            "Name": "Global Sky",
+            "Components": {
+                "Component_[11231930600558681245]": {
+                    "$type": "AZ::Render::EditorHDRiSkyboxComponent",
+                    "Id": 11231930600558681245,
+                    "Controller": {
+                        "Configuration": {
+                            "CubemapAsset": {
+                                "assetId": {
+                                    "guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}",
+                                    "subId": 1000
+                                },
+                                "assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage"
+                            }
+                        }
+                    }
+                },
+                "Component_[1428633914413949476]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 1428633914413949476
+                },
+                "Component_[14936200426671614999]": {
+                    "$type": "AZ::Render::EditorImageBasedLightComponent",
+                    "Id": 14936200426671614999,
+                    "Controller": {
+                        "Configuration": {
+                            "diffuseImageAsset": {
+                                "assetId": {
+                                    "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+                                    "subId": 3000
+                                },
+                                "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
+                            },
+                            "specularImageAsset": {
+                                "assetId": {
+                                    "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+                                    "subId": 2000
+                                },
+                                "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
+                            }
+                        }
+                    }
+                },
+                "Component_[14994774102579326069]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 14994774102579326069
+                },
+                "Component_[15417479889044493340]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 15417479889044493340
+                },
+                "Component_[15826613364991382688]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 15826613364991382688
+                },
+                "Component_[1665003113283562343]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 1665003113283562343
+                },
+                "Component_[3704934735944502280]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 3704934735944502280
+                },
+                "Component_[5698542331457326479]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 5698542331457326479
+                },
+                "Component_[6644513399057217122]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 6644513399057217122,
+                    "Parent Entity": "Entity_[1176639161715]"
+                },
+                "Component_[931091830724002070]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 931091830724002070
+                }
+            }
+        }
+    }
+}

+ 14 - 0
Templates/ScriptOnlyProject/Template/autoexec.cfg

@@ -0,0 +1,14 @@
+; edit this file to make it load whatever level you want on startup automatically
+; You can also add additional commands in here that you want it to exec on startup.
+loadlevel start
+
+; uncomment the following line in any game packages that have all the
+; assets precompiled, so that it doesn't try to launch the Asset Processor in
+; actual shipping builds.
+
+; bg_ConnectToAssetProcessor 0
+
+; uncomment the following line to hide any debug display info from the top
+; right corner of the screen.
+
+; r_DisplayInfo 0

+ 27 - 0
Templates/ScriptOnlyProject/Template/package.bat

@@ -0,0 +1,27 @@
+REM --------------------------------------------------------------------------------------------------
+REM 
+REM Copyright (c) Contributors to the Open 3D Engine Project.
+REM For complete copyright and license terms please see the LICENSE at the root of this distribution.
+REM 
+REM SPDX-License-Identifier: Apache-2.0 OR MIT
+REM 
+REM --------------------------------------------------------------------------------------------------
+
+
+REM This script is meant to export the project into a standalone shippable project that others can run.
+REM However, the project developer is expected to modify it to add steps or change it to their needs.
+REM
+REM To get more information about the possible tweakable parameters, run 
+REM (engine folder)\scripts\o3de.bat export-project -es ExportScripts/export_source_built_project.py --script-help
+
+set O3DE_PATH=${EnginePath}
+set O3DE_PROJECT_PATH=${ProjectPath}
+set O3DE_PROJECT_SEEDLIST=%O3DE_PROJECT_PATH%\AssetBundling\SeedLists\Example.seed
+set OUTPUT_PATH=%O3DE_PROJECT_PATH%\ProjectPackages
+
+REM change this to release or debug if you want it to make a release or debug package
+REM (Only works if the installer you have actually includes release and debug binaries)
+set OUTPUT_CONFIGURATION=profile
+
+%O3DE_PATH%\scripts\o3de.bat export-project -es ExportScripts\export_source_built_project.py --project-path %O3DE_PROJECT_PATH% --no-monolithic-build --log-level INFO -assets --config %OUTPUT_CONFIGURATION% --archive-output zip --seedlist %O3DE_PROJECT_SEEDLIST% -out %OUTPUT_PATH%
+

+ 24 - 0
Templates/ScriptOnlyProject/Template/package.sh

@@ -0,0 +1,24 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+# This script is meant to export the project into a standalone shippable project that others can run.
+# However, the project developer is expected to modify it to add steps or change it to their needs.
+
+# To get more information about the possible tweakable parameters, run 
+# (engine folder)/scripts/o3de.sh export-project -es ExportScripts/export_source_built_project.py --script-help
+
+O3DE_PATH=${EnginePath}
+O3DE_PROJECT_PATH=${ProjectPath}
+O3DE_PROJECT_SEEDLIST=${O3DE_PROJECT_PATH}/AssetBundling/SeedLists/Example.seed
+OUTPUT_PATH=${O3DE_PROJECT_PATH}/ProjectPackages
+
+# change this to release or debug if you want it to make a release or debug package
+# (Only works if the installer you have actually includes release and debug binaries)
+OUTPUT_CONFIGURATION=profile
+
+${O3DE_PATH}/scripts/o3de.sh export-project -es ExportScripts/export_source_built_project.py --project-path ${O3DE_PROJECT_PATH} --no-monolithic-build  --log-level INFO -assets --config ${OUTPUT_CONFIGURATION} --archive-output gztar --seedlist ${O3DE_PROJECT_SEEDLIST} -out ${OUTPUT_PATH}

+ 28 - 0
Templates/ScriptOnlyProject/template.json

@@ -42,6 +42,10 @@
             "file": "Config/shader_global_build_options.json",
             "file": "Config/shader_global_build_options.json",
             "isTemplated": false
             "isTemplated": false
         },
         },
+        {
+            "file": "Levels/start/start.prefab",
+            "isTemplated": false
+        },
         {
         {
             "file": "Platform/Android/android_project.cmake",
             "file": "Platform/Android/android_project.cmake",
             "isTemplated": false
             "isTemplated": false
@@ -258,6 +262,18 @@
             "file": "autoexec.cfg",
             "file": "autoexec.cfg",
             "isTemplated": false
             "isTemplated": false
         },
         },
+        {
+            "file": "package.bat",
+            "isTemplated": true
+        },
+        {
+            "file": "package.sh",
+            "isTemplated": true
+        },
+        {
+            "file": "AssetBundling/SeedLists/Example.seed",
+            "isTemplated": false
+        },
         {
         {
             "file": "game.cfg",
             "file": "game.cfg",
             "isTemplated": false
             "isTemplated": false
@@ -275,12 +291,24 @@
         {
         {
             "dir": "Assets"
             "dir": "Assets"
         },
         },
+        {
+            "dir": "AssetBundling"
+        },
+        {
+            "dir": "AssetBundling/SeedLists"
+        },
         {
         {
             "dir": "cmake"
             "dir": "cmake"
         },
         },
         {
         {
             "dir": "Config"
             "dir": "Config"
         },
         },
+        {
+            "dir": "Levels"
+        },
+        {
+            "dir": "Levels/start"
+        },
         {
         {
             "dir": "Platform"
             "dir": "Platform"
         },
         },

+ 112 - 0
cmake/3rdParty/script-only-mode/PostProcessScriptOnlyMappings.cmake

@@ -0,0 +1,112 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+# this file is used during generation of the installer layout.
+# note that ARGV0 is the cmake command itself, and ARGV1 is the -P command line option, so we skip them
+# ARGV2 is the name of this script.
+# ARGV3 is the output folder name
+# ARGV4 and onwards are the names of input files, generated during the engine configure/generate
+# containing information about the 3p libraries available.
+
+#[[ there is 1 input file for each 3p library, and each input file contains a set of "set" commands in this format:
+    set(target_name ${TARGET_NAME})
+    set(copy_dependencies_source_file_path ${copy_dependencies_source_file_path})
+    set(copy_dependencies_target_rel_path ${copy_dependencies_target_rel_path})
+
+    The goal of this file is to generate one output_filename/target_name.cmake for each input file such 
+    that it contains the ability to register the given 3p library target
+    libraries as fake ones (which have the appropriate dependencies so that files get copied).
+]]#
+
+if (${CMAKE_ARGC} LESS 5)
+    message(FATAL_ERROR "This command was invoked incorrectly.\nUsage:\n"
+                             "cmake -P (SCRIPT_NAME) (OUTPUT_DIR) (INPUT FILE) (INPUT FILE) ...")
+    return()
+endif()
+
+set(output_directory ${CMAKE_ARGV3})
+
+if (NOT output_directory)
+    message(FATAL_ERROR "Expected the first argument to be an output directory")
+endif()
+
+foreach(index RANGE 4 ${CMAKE_ARGC})
+    if (CMAKE_ARGV${index})
+        list(APPEND file_list ${CMAKE_ARGV${index}})
+    endif()
+endforeach()
+
+
+set(copyright_and_preamble [[#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+# Generated as part of the install command, this file contains calls to register 3p libraries
+# for script-only mode, to ensure that their dependent files are copied to the final location
+# during game deploy.  It should ONLY be used in script-only mode.
+]])
+
+foreach(data_file IN LISTS file_list)
+    unset(target_name)
+    unset(copy_dependencies_source_file_path)
+    unset(copy_dependencies_target_rel_path)
+    unset(trimmed_source_paths)
+    set(final_data ${copyright_and_preamble})
+
+    include(${data_file})
+
+    if (NOT target_name)
+        message(FATAL_ERROR "Error parsing data file ${data_file} - consider cleaning it out and rebuilding.")
+    endif()
+
+    foreach(abs_filepath IN LISTS copy_dependencies_source_file_path)
+        cmake_path(GET abs_filepath FILENAME filename_only)
+        list(APPEND trimmed_source_paths ${filename_only})
+    endforeach()
+
+    # sanity check
+    if (trimmed_source_paths OR copy_dependencies_target_rel_path)
+        list(LENGTH trimmed_source_paths source_list_length)
+        list(LENGTH copy_dependencies_target_rel_path relpath_list_lenth)
+        if (NOT source_list_length EQUAL relpath_list_lenth)
+            message(FATAL_ERROR "Programmer error - for target ${target_name}, lists are supposed to be same length, but\n\
+                                ${source_list_length} source and ${relpath_list_lenth} relpath\n\
+                                source:'${trimmed_source_paths}'\n\
+                                relpath: '${copy_dependencies_target_rel_path}'")
+        endif()
+    endif()
+
+    string(APPEND final_data "add_library(${target_name} INTERFACE IMPORTED GLOBAL)\n")
+
+    # binary_folder can be a genex but will always be the Default folder since monolithic
+    # cannot be combined with script-only
+    set(installer_binaries [[${LY_ROOT_FOLDER}/bin/${PAL_PLATFORM_NAME}/$<CONFIG>/Default]])
+    if (trimmed_source_paths)
+        foreach(file_name relative_path IN ZIP_LISTS trimmed_source_paths copy_dependencies_target_rel_path)
+            if (relative_path)
+                set(file_name "${installer_binaries}/${relative_path}/${file_name}")
+            else()
+                set(relative_path "")
+                set(file_name "${installer_binaries}/${file_name}")
+            endif()
+            string(APPEND final_data 
+                    "ly_add_target_files(TARGETS ${target_name}\n\
+                        FILES\n\
+                            \"${file_name}\"\n\
+                        OUTPUT_SUBDIRECTORY \"${relative_path}\")\n\n")
+        endforeach()        
+    endif()
+
+    string(REPLACE "::" "__" CLEAN_TARGET_NAME "${target_name}")  
+    file(WRITE "${output_directory}/${CLEAN_TARGET_NAME}.cmake" "${final_data}")
+
+endforeach()

+ 20 - 1
cmake/LYWrappers.cmake

@@ -573,14 +573,23 @@ function(ly_parse_third_party_dependencies ly_THIRD_PARTY_LIBRARIES)
 
 
     # Interface dependencies may require to find_packages. So far, we are just using packages for 3rdParty, so we will
     # Interface dependencies may require to find_packages. So far, we are just using packages for 3rdParty, so we will
     # search for those and automatically bring those packages. The naming convention used is 3rdParty::PackageName::OptionalInterface
     # search for those and automatically bring those packages. The naming convention used is 3rdParty::PackageName::OptionalInterface
+    unset(all_thirdparty_dependencies_found)
+
     foreach(dependency ${ly_THIRD_PARTY_LIBRARIES})
     foreach(dependency ${ly_THIRD_PARTY_LIBRARIES})
         string(REPLACE "::" ";" dependency_list ${dependency})
         string(REPLACE "::" ";" dependency_list ${dependency})
         list(GET dependency_list 0 dependency_namespace)
         list(GET dependency_list 0 dependency_namespace)
         if(${dependency_namespace} STREQUAL "3rdParty")
         if(${dependency_namespace} STREQUAL "3rdParty")
+            list(APPEND all_thirdparty_dependencies_found ${dependency})
             if (NOT TARGET ${dependency})
             if (NOT TARGET ${dependency})
                 if (O3DE_SCRIPT_ONLY)
                 if (O3DE_SCRIPT_ONLY)
                     # we don't actually need 3p deps to try to download the package or call find_package.
                     # we don't actually need 3p deps to try to download the package or call find_package.
-                    add_library(${dependency} IMPORTED INTERFACE GLOBAL)
+                    # instead we use pre-created part-of-the-installer 3p targets baked in from the above list
+                    # which will have been made at install time.
+                    # instead, we execute a pregenerated file that was created as part of install to 
+                    # create this target:
+                    string(REPLACE "::" "__" CLEAN_TARGET_NAME "${dependency}")  
+                    # not all 3ps actually exist as real targets, so this is an OPTIONAL include.
+                    include(${LY_ROOT_FOLDER}/cmake/3rdParty/Platform/${PAL_PLATFORM_NAME}/Default/${CLEAN_TARGET_NAME}.cmake OPTIONAL)
                 else()
                 else()
                     list(GET dependency_list 1 dependency_package)
                     list(GET dependency_list 1 dependency_package)
                     list(LENGTH dependency_list dependency_list_length)
                     list(LENGTH dependency_list dependency_list_length)
@@ -602,6 +611,16 @@ function(ly_parse_third_party_dependencies ly_THIRD_PARTY_LIBRARIES)
     foreach(dependency IN LISTS packages_with_components)
     foreach(dependency IN LISTS packages_with_components)
         find_package(${dependency} REQUIRED MODULE COMPONENTS ${${dependency}_components})
         find_package(${dependency} REQUIRED MODULE COMPONENTS ${${dependency}_components})
     endforeach()
     endforeach()
+    
+    foreach(dependency ${all_thirdparty_dependencies_found})
+        if (TARGET ${dependency})
+            # keep track of all the 3p dependencies we actually depended on.
+            get_property(o3de_all_3rdparty_targets GLOBAL PROPERTY O3DE_ALL_3RDPARTY_TARGETS)
+            if(NOT ${dependency} IN_LIST o3de_all_3rdparty_targets)
+                set_property(GLOBAL APPEND PROPERTY O3DE_ALL_3RDPARTY_TARGETS "${dependency}")
+            endif()
+        endif()
+    endforeach()
 endfunction()
 endfunction()
 
 
 #! ly_configure_target_platform_properties: Configures any platform specific properties on target
 #! ly_configure_target_platform_properties: Configures any platform specific properties on target

+ 136 - 1
cmake/Platform/Common/Install_common.cmake

@@ -349,6 +349,140 @@ function(ly_setup_subdirectories)
     endforeach()
     endforeach()
 endfunction()
 endfunction()
 
 
+#! ly_setup_3p_target: Export enough data such that the script-only mode knows about the runtime dependencies
+#! for the given target.  This function returns a string which is a setup function that can be called
+#! in script only mode to create a fake target for the 3p library that just includes its copy dependencies.
+function(ly_setup_3p_target OUTVAR_GENERATED_DATA_FILENAME OUTVAR_FILE_NAME_TO_GENERATE ALIAS_TARGET_NAME)
+    ly_de_alias_target(${ALIAS_TARGET_NAME} TARGET_NAME)
+    o3de_get_dependencies_for_target(
+            TARGET "${TARGET_NAME}"
+            COPY_DEPENDENCIES_VAR target_copy_dependencies
+            TARGET_DEPENDENCIES_VAR target_target_dependencies
+        )
+
+    # note that we want to actually create and register the aliased target name
+    # but get the data from the de-aliased target.  So except for the call above
+    # we use the aliased target name.
+    string(REPLACE "::" "__" CLEAN_TARGET_NAME "${ALIAS_TARGET_NAME}")  
+
+    unset(copy_dependencies_target_rel_path)
+    unset(copy_dependencies_source_file_path)
+    foreach(conf IN LISTS CMAKE_CONFIGURATION_TYPES)
+        unset(copy_dependencies_${conf})
+    endforeach()
+
+    foreach(dependency_for_target IN LISTS target_target_dependencies)
+        if (NOT TARGET ${dependency_for_target})
+            # Sometimes, things set actual shared libraries as a target dependency instead of a copy dependency.
+            list(APPEND target_copy_dependencies "${dependency_for_target}\n")
+        endif()
+    endforeach()     
+    
+    # note that the copy dependencies are actually in pairs newline delimited, so
+    # file_to_copy_a\nwhere_to_copy_a;file_to_copy_b\nwhere_to_copy_b;...
+    foreach(copy_dependency IN LISTS target_copy_dependencies)
+        string(REPLACE "\n" ";" copy_dep_pair "${copy_dependency}")
+        list(POP_FRONT copy_dep_pair source_filepath destination_relpath)
+        list(APPEND copy_dependencies_source_file_path "${source_filepath}")
+        # a quirk of list append is that if you give it an empty element, it does nothing.
+        # use dummy element (0) to indicate its an empty path
+        if (NOT destination_relpath)
+            set(destination_relpath "0")
+        endif()
+
+        list(APPEND copy_dependencies_target_rel_path "${destination_relpath}")
+    endforeach()
+
+    # sanity check
+    if (copy_dependencies_source_file_path OR copy_dependencies_target_rel_path)
+        list(LENGTH copy_dependencies_source_file_path source_list_length)
+        list(LENGTH copy_dependencies_target_rel_path  relpath_list_lenth)
+        if (NOT source_list_length EQUAL relpath_list_lenth)
+            message(FATAL_ERROR "Programmer error - for target ${ALIAS_TARGET_NAME}, lists are supposed to be same length, but\n\
+                                ${source_list_length} source and ${relpath_list_lenth} relpath\n\
+                                source:'${copy_dependencies_source_file_path}'\n\
+                                relpath: '${copy_dependencies_target_rel_path}'")
+        endif()
+    endif()
+
+    unset(${OUTVAR_GENERATED_DATA_FILENAME} PARENT_SCOPE)
+
+    # the absolute source paths of files to copy can have generator expressions that are per-config.
+    # use file(GENERATE ...) to evaluate the genexes, by writing it as a build file
+    # since GENERATE only happens during generate step, this is as far as we can go during
+    # configure.  It will be up to a build step to read these generated files back and
+    # do a final transform that removes things like absolute paths.
+    # note that we generate a file for every 3p target, as they must exist.
+    set(generate_content "set(target_name ${ALIAS_TARGET_NAME})\n")
+    if (copy_dependencies_source_file_path)
+        string(APPEND generate_content "set(copy_dependencies_source_file_path \"${copy_dependencies_source_file_path}\")\n")
+        string(APPEND generate_content "set(copy_dependencies_target_rel_path \"${copy_dependencies_target_rel_path}\")\n")
+    endif()
+
+    file(GENERATE OUTPUT  "${CMAKE_BINARY_DIR}/install/$<CONFIG>/${PAL_PLATFORM_NAME}/${CLEAN_TARGET_NAME}.cmake" 
+                  CONTENT "${generate_content}")
+    set(${OUTVAR_GENERATED_DATA_FILENAME} "${CMAKE_BINARY_DIR}/install/$<CONFIG>/${PAL_PLATFORM_NAME}/${CLEAN_TARGET_NAME}.cmake" PARENT_SCOPE)
+    set(${OUTVAR_FILE_NAME_TO_GENERATE} ${CLEAN_TARGET_NAME} PARENT_SCOPE)
+
+endfunction()
+
+# In "Script only mode", the 3p libraries are not downloaded at all.
+# But some of them (not all) have extraneous .so or .dll files that need to be deployed
+# into the final runtime package if you intend to ship a script-only runtime.
+# This function exports a file that is used only in script-only mode to supply that list
+# of extra DLLs to copy along with the game.
+function(ly_setup_3p_dependencies)
+
+    # 3p dependency generation is only relevant to installer builds, which is expected to happen only if no project is being built
+    # prevent this code from running in non-instlaler-builds, otherwise it will try to hang these commands off a non-existant generic
+    # game launcher target (which itself is also only relevant to installer builds for script-only mode.)
+    if (LY_PROJECTS)
+        return()
+    endif()
+
+    unset(list_of_files_to_process)
+    unset(expected_output_files)
+    set(final_3p_output_dir "${CMAKE_BINARY_DIR}/cmake/3rdParty/Platform/${PAL_PLATFORM_NAME}/${LY_BUILD_PERMUTATION}")
+    get_property(o3de_all_3rdparty_targets GLOBAL PROPERTY O3DE_ALL_3RDPARTY_TARGETS)
+
+    # call the ly_setup_3p_target for each 3p target.  It will create a GENERATE step
+    # that will output a file, and also return the file name of the generated file.
+    foreach(target_3p IN LISTS o3de_all_3rdparty_targets)
+        ly_setup_3p_target(file_to_process output_filename ${target_3p})
+        if (file_to_process)
+            list(APPEND list_of_files_to_process ${file_to_process})
+            list(APPEND expected_output_files ${final_3p_output_dir}/${output_filename}.cmake)
+        endif()
+    endforeach()
+    
+    # note that generate only occurs during the generate step.  The above file will not be available until the build step
+    # so a finalization build step needs to run a script to finalize it.
+    if (list_of_files_to_process)
+        add_custom_command(
+            COMMAND ${CMAKE_COMMAND} -P 
+                "${LY_ROOT_FOLDER}/cmake/3rdParty/script-only-mode/PostProcessScriptOnlyMappings.cmake" # Script to run
+                "${final_3p_output_dir}" # the output file to make
+                ${list_of_files_to_process}
+            OUTPUT ${expected_output_files}
+            COMMENT "Updating script-only mode 3rd Party library mappings..."
+            DEPENDS ${list_of_files_to_process} 
+                    "${LY_ROOT_FOLDER}/cmake/3rdParty/script-only-mode/PostProcessScriptOnlyMappings.cmake"
+            VERBATIM
+        )
+
+        # make a custom target that depends on the above output file.
+        add_custom_target(GenerateScriptOnlyMappings DEPENDS ${expected_output_files})
+
+        # make it so that at least one real target that actually gets built depends on the above target.
+        # or else cmake won't evaluate it since nothing hangs off it.
+        add_dependencies(O3DE.GameLauncher GenerateScriptOnlyMappings)
+
+        ly_install(FILES ${expected_output_files}
+            DESTINATION "cmake/3rdParty/Platform/${PAL_PLATFORM_NAME}/${LY_BUILD_PERMUTATION}"
+            COMPONENT ${LY_INSTALL_PERMUTATION_COMPONENT})
+    endif()
+endfunction()
+
 
 
 #! ly_setup_subdirectory: setup all targets in the subdirectory
 #! ly_setup_subdirectory: setup all targets in the subdirectory
 function(ly_setup_subdirectory absolute_target_source_dir)
 function(ly_setup_subdirectory absolute_target_source_dir)
@@ -651,7 +785,7 @@ endfunction()
 #! ly_setup_runtime_dependencies: install runtime dependencies
 #! ly_setup_runtime_dependencies: install runtime dependencies
 function(ly_setup_runtime_dependencies)
 function(ly_setup_runtime_dependencies)
 
 
-    # Common functions used by the bellow code
+    # Common functions used by the below code
     if(COMMAND ly_setup_runtime_dependencies_copy_function_override)
     if(COMMAND ly_setup_runtime_dependencies_copy_function_override)
         ly_setup_runtime_dependencies_copy_function_override()
         ly_setup_runtime_dependencies_copy_function_override()
     else()
     else()
@@ -975,6 +1109,7 @@ function(ly_setup_o3de_install)
     ly_setup_cmake_install()
     ly_setup_cmake_install()
     ly_setup_runtime_dependencies()
     ly_setup_runtime_dependencies()
     ly_setup_assets()
     ly_setup_assets()
+    ly_setup_3p_dependencies()
 
 
     # Misc
     # Misc
     ly_install(FILES
     ly_install(FILES

+ 17 - 12
cmake/Platform/Linux/LYWrappers_linux.cmake

@@ -9,19 +9,24 @@
 set(LY_STRIP_DEBUG_SYMBOLS FALSE CACHE BOOL "Flag to strip debug symbols from the (non-debug) output binaries")
 set(LY_STRIP_DEBUG_SYMBOLS FALSE CACHE BOOL "Flag to strip debug symbols from the (non-debug) output binaries")
 set(LY_DEBUG_SYMBOLS_FILE_EXTENSION "dbg" CACHE STRING "Extension for generated debug symbol files")
 set(LY_DEBUG_SYMBOLS_FILE_EXTENSION "dbg" CACHE STRING "Extension for generated debug symbol files")
 
 
-# Check if 'strip' is available so that debug symbols can be stripped from output libraries and executables.
-find_program(GNU_STRIP_TOOL strip)
-if (NOT GNU_STRIP_TOOL)
-    message(WARNING "Unable to locate 'strip' tool needed to strip debug symbols from the output target(s). "
-                    "Debug symbols will not be removed from output libraries and executables.")
-endif()
+# in script only mode, we have no compiler or compiler tools and are always in a situation
+# where a project is being built versus a pre-built version of the engine.  This means that
+# stripping and copying should not be attempted.
+if (NOT O3DE_SCRIPT_ONLY)
+    # Check if 'strip' is available so that debug symbols can be stripped from output libraries and executables.
+    find_program(GNU_STRIP_TOOL strip)
+    if (NOT GNU_STRIP_TOOL)
+        message(WARNING "Unable to locate 'strip' tool needed to strip debug symbols from the output target(s). "
+                        "Debug symbols will not be removed from output libraries and executables.")
+    endif()
 
 
-# Check if 'objcopy' is available so that debug symbols can be extracted from output libraries and executables.
-find_program(GNU_OBJCOPY objcopy)
-if (NOT GNU_OBJCOPY)
-    message(WARNING "Unable to locate 'objcopy' tool needed to extract debug symbols from the output target(s). "
-                    "Debug symbols will not be removed from output libraries and executables. Make sure that "
-                    "'objcopy' is installed.")
+    # Check if 'objcopy' is available so that debug symbols can be extracted from output libraries and executables.
+    find_program(GNU_OBJCOPY objcopy)
+    if (NOT GNU_OBJCOPY)
+        message(WARNING "Unable to locate 'objcopy' tool needed to extract debug symbols from the output target(s). "
+                        "Debug symbols will not be removed from output libraries and executables. Make sure that "
+                        "'objcopy' is installed.")
+    endif()
 endif()
 endif()
 
 
 
 

+ 8 - 3
scripts/o3de/ExportScripts/export_source_built_project.py

@@ -36,6 +36,7 @@ def export_standalone_project(ctx: exp.O3DEScriptExportContext,
                               should_build_server_launcher: bool = True,
                               should_build_server_launcher: bool = True,
                               should_build_unified_launcher: bool = True,
                               should_build_unified_launcher: bool = True,
                               should_build_headless_server_launcher: bool = True,
                               should_build_headless_server_launcher: bool = True,
+                              monolithic_build: bool = True,
                               allow_registry_overrides: bool = False,
                               allow_registry_overrides: bool = False,
                               tools_build_path: pathlib.Path | None =None,
                               tools_build_path: pathlib.Path | None =None,
                               launcher_build_path: pathlib.Path | None =None,
                               launcher_build_path: pathlib.Path | None =None,
@@ -67,6 +68,7 @@ def export_standalone_project(ctx: exp.O3DEScriptExportContext,
     :param should_build_server_launcher:            Option to build the server launcher package
     :param should_build_server_launcher:            Option to build the server launcher package
     :param should_build_unified_launcher:           Option to build the unified launcher package
     :param should_build_unified_launcher:           Option to build the unified launcher package
     :param should_build_headless_server_launcher:   Option to build the headless server launcher package
     :param should_build_headless_server_launcher:   Option to build the headless server launcher package
+    :param monolithic_build:                        Option to build the game binaries monolithically
     :param allow_registry_overrides:                Option to allow registry overrides in the build process
     :param allow_registry_overrides:                Option to allow registry overrides in the build process
     :param tools_build_path:                        Optional build path to build the tools. (Will default to build/tools if not supplied)
     :param tools_build_path:                        Optional build path to build the tools. (Will default to build/tools if not supplied)
     :param launcher_build_path:                     Optional build path to build the game launcher(s). (Will default to build/launcher if not supplied)
     :param launcher_build_path:                     Optional build path to build the game launcher(s). (Will default to build/launcher if not supplied)
@@ -131,6 +133,7 @@ def export_standalone_project(ctx: exp.O3DEScriptExportContext,
                                build_config=build_config,
                                build_config=build_config,
                                game_build_path=launcher_build_path,
                                game_build_path=launcher_build_path,
                                engine_centric=engine_centric,
                                engine_centric=engine_centric,
+                               monolithic_build=monolithic_build,
                                launcher_types=launcher_type,
                                launcher_types=launcher_type,
                                allow_registry_overrides=allow_registry_overrides,
                                allow_registry_overrides=allow_registry_overrides,
                                tool_config=tool_config,
                                tool_config=tool_config,
@@ -237,7 +240,7 @@ if "o3de_context" in globals():
         parser.add_argument('-a', '--archive-output',  type=str,
         parser.add_argument('-a', '--archive-output',  type=str,
                             help="Option to create a compressed archive the output. "
                             help="Option to create a compressed archive the output. "
                                  "Specify the format of archive to create from the output directory. If 'none' specified, no archiving will occur.",
                                  "Specify the format of archive to create from the output directory. If 'none' specified, no archiving will occur.",
-                            choices=["none", "zip", "gzip", "bz2", "xz"], default="none")
+                            choices=exp.ALL_AVAILABLE_ARCHIVE_FORMATS, default="none")
         parser.add_argument('-assets', '--should-build-assets', default=False, action='store_true',
         parser.add_argument('-assets', '--should-build-assets', default=False, action='store_true',
                             help='Toggles building all assets for the bundle.')
                             help='Toggles building all assets for the bundle.')
         parser.add_argument('-foa', '--fail-on-asset-errors', default=False, action='store_true',
         parser.add_argument('-foa', '--fail-on-asset-errors', default=False, action='store_true',
@@ -264,12 +267,13 @@ if "o3de_context" in globals():
                             help="When configuring cmake builds, this determines if the script allows for overriding registry settings from external sources.")
                             help="When configuring cmake builds, this determines if the script allows for overriding registry settings from external sources.")
         parser.add_argument('-abp', '--asset-bundling-path', type=pathlib.Path, default=None,
         parser.add_argument('-abp', '--asset-bundling-path', type=pathlib.Path, default=None,
                             help="Designates where the artifacts from the asset bundling process will be written to before creation of the package. If not specified, default is <o3de_project_path>/build/asset_bundling.")
                             help="Designates where the artifacts from the asset bundling process will be written to before creation of the package. If not specified, default is <o3de_project_path>/build/asset_bundling.")
-        parser.add_argument('-maxsize', '--max-bundle-size', type=int, default=2048, help='Specify the maximum size of a given asset bundle.')
+        parser.add_argument('-maxsize', '--max-bundle-size', type=int, default=2048, help='Specify the maximum size of a given asset bundle (in MiB).')
         parser.add_argument('-nogame', '--no-game-launcher', action='store_true', help='This flag skips building the Game Launcher on a platform if not needed.')
         parser.add_argument('-nogame', '--no-game-launcher', action='store_true', help='This flag skips building the Game Launcher on a platform if not needed.')
         parser.add_argument('-noserver', '--no-server-launcher', action='store_true', help='This flag skips building the Server Launcher on a platform if not needed.')
         parser.add_argument('-noserver', '--no-server-launcher', action='store_true', help='This flag skips building the Server Launcher on a platform if not needed.')
         parser.add_argument('-noheadless', '--no-headless-server-launcher', action='store_true', help='This flag skips building the Headless Server Launcher on a platform if not needed.')
         parser.add_argument('-noheadless', '--no-headless-server-launcher', action='store_true', help='This flag skips building the Headless Server Launcher on a platform if not needed.')
         parser.add_argument('-nounified', '--no-unified-launcher', action='store_true', help='This flag skips building the Unified Launcher on a platform if not needed.')
         parser.add_argument('-nounified', '--no-unified-launcher', action='store_true', help='This flag skips building the Unified Launcher on a platform if not needed.')
-        parser.add_argument('-pl', '--platform', type=str, default=exp.get_default_asset_platform(), choices=['pc', 'linux', 'mac'])
+        parser.add_argument('-nomonolithic', '--no-monolithic-build', action='store_true', help='Build the project binaries as shared libraries (as opposed to default monolithic build).')
+        parser.add_argument('-pl', '--platform', type=str, default=exp.get_default_asset_platform(), choices=['pc', 'linux', 'mac'], help="The asset platform to package (from the Cache folder)")
         parser.add_argument('-ec', '--engine-centric', action='store_true', default=False, help='Option use the engine-centric work flow to export the project.')
         parser.add_argument('-ec', '--engine-centric', action='store_true', default=False, help='Option use the engine-centric work flow to export the project.')
         parser.add_argument('-q', '--quiet', action='store_true', help='Suppresses logging information unless an error occurs.')
         parser.add_argument('-q', '--quiet', action='store_true', help='Suppresses logging information unless an error occurs.')
         if o3de_context is None:
         if o3de_context is None:
@@ -307,6 +311,7 @@ if "o3de_context" in globals():
                                   should_build_server_launcher=not args.no_server_launcher,
                                   should_build_server_launcher=not args.no_server_launcher,
                                   should_build_unified_launcher=not args.no_unified_launcher,
                                   should_build_unified_launcher=not args.no_unified_launcher,
                                   should_build_headless_server_launcher=not args.no_headless_server_launcher,
                                   should_build_headless_server_launcher=not args.no_headless_server_launcher,
+                                  monolithic_build=not args.no_monolithic_build,
                                   engine_centric=args.engine_centric,
                                   engine_centric=args.engine_centric,
                                   allow_registry_overrides=args.allow_registry_overrides,
                                   allow_registry_overrides=args.allow_registry_overrides,
                                   tools_build_path=args.tools_build_path,
                                   tools_build_path=args.tools_build_path,

+ 6 - 0
scripts/o3de/o3de/engine_template.py

@@ -1726,6 +1726,12 @@ def create_project(project_path: pathlib.Path,
         logger.error(f'Project name cannot be a restricted name. {project_name}')
         logger.error(f'Project name cannot be a restricted name. {project_name}')
         return 1
         return 1
 
 
+    # the generic launcher (and the engine, often) are referred to as o3de, so prevent the user from 
+    # accidentally creating a confusing error situation.
+    if project_name.lower() == 'o3de':
+        logger.error(f"Project name cannot be 'o3de' as this is reserved for the generic launcher.")
+        return 1
+
     # project restricted name
     # project restricted name
     if project_restricted_name and not project_restricted_path:
     if project_restricted_name and not project_restricted_path:
         gem_restricted_path = manifest.get_registered(restricted_name=project_restricted_name)
         gem_restricted_path = manifest.get_registered(restricted_name=project_restricted_name)

+ 12 - 4
scripts/o3de/o3de/export_project.py

@@ -25,7 +25,10 @@ from enum import IntEnum
 LOCAL_ENGINE_PATH  = pathlib.Path(__file__).parent.parent.parent.parent
 LOCAL_ENGINE_PATH  = pathlib.Path(__file__).parent.parent.parent.parent
 
 
 # Account for some windows-specific attributes
 # Account for some windows-specific attributes
-CURRENT_PLATFORM = platform.system().lower()
+CURRENT_PLATFORM_NAME_WITH_CASE = platform.system()  # used to find the Installer binaries folder.
+CURRENT_PLATFORM = CURRENT_PLATFORM_NAME_WITH_CASE.lower()
+
+ALL_AVAILABLE_ARCHIVE_FORMATS = ["none"] + [name for name, description in shutil.get_archive_formats()]
 
 
 if CURRENT_PLATFORM == 'windows':
 if CURRENT_PLATFORM == 'windows':
     EXECUTABLE_EXTENSION = '.exe'
     EXECUTABLE_EXTENSION = '.exe'
@@ -541,6 +544,7 @@ def build_game_targets(ctx: O3DEScriptExportContext,
                        build_config: str,
                        build_config: str,
                        game_build_path: pathlib.Path,
                        game_build_path: pathlib.Path,
                        engine_centric: bool,
                        engine_centric: bool,
+                       monolithic_build: bool,
                        launcher_types: int,
                        launcher_types: int,
                        allow_registry_overrides: bool,
                        allow_registry_overrides: bool,
                        tool_config: str = PREREQUISITE_TOOL_BUILD_CONFIG,
                        tool_config: str = PREREQUISITE_TOOL_BUILD_CONFIG,
@@ -552,6 +556,7 @@ def build_game_targets(ctx: O3DEScriptExportContext,
     @param build_config:                The build config to build (profile or release)
     @param build_config:                The build config to build (profile or release)
     @param game_build_path:             The cmake build folder target
     @param game_build_path:             The cmake build folder target
     @engine_centric:                    Option to generate/build an engine-centric workflow
     @engine_centric:                    Option to generate/build an engine-centric workflow
+    @monolithic_build:                  Option to build as one executable (smaller) or to use individual dll/shared libraries instead (larger)
     @additional_cmake_configure_options:List of additional configure arguments to pass to cmake during the cmake project generation process
     @additional_cmake_configure_options:List of additional configure arguments to pass to cmake during the cmake project generation process
     @param launcher_types:              The launcher type options (bit mask from the LauncherType enum) to specify which launcher types to build
     @param launcher_types:              The launcher type options (bit mask from the LauncherType enum) to specify which launcher types to build
     @param allow_registry_overrides:    Custom Flag argument for 'DALLOW_SETTINGS_REGISTRY_DEVELOPMENT_OVERRIDES' to pass down to the project generation
     @param allow_registry_overrides:    Custom Flag argument for 'DALLOW_SETTINGS_REGISTRY_DEVELOPMENT_OVERRIDES' to pass down to the project generation
@@ -589,10 +594,13 @@ def build_game_targets(ctx: O3DEScriptExportContext,
     if ctx.cmake_additional_configure_args:
     if ctx.cmake_additional_configure_args:
         cmake_configure_command.extend(ctx.cmake_additional_configure_args)
         cmake_configure_command.extend(ctx.cmake_additional_configure_args)
 
 
-    cmake_configure_command.extend(["-DLY_MONOLITHIC_GAME=1",
-                                    f"-DALLOW_SETTINGS_REGISTRY_DEVELOPMENT_OVERRIDES={'0' if not allow_registry_overrides else '1'}"])
+    cmake_configure_command.extend([
+            f"-DLY_MONOLITHIC_GAME={'0' if not monolithic_build else '1'}",
+            f"-DALLOW_SETTINGS_REGISTRY_DEVELOPMENT_OVERRIDES={'0' if not allow_registry_overrides else '1'}"
+        ])
+
     if logger:
     if logger:
-        logger.info(f"Generating (monolithic) project the build folder for project {ctx.project_name}")
+        logger.info(f"Generating {'monolithic' if monolithic_build else 'non-monolithic'} build folder for project {ctx.project_name}")
     ret = process_command(cmake_configure_command)
     ret = process_command(cmake_configure_command)
     if ret != 0:
     if ret != 0:
         raise ExportProjectError(f"Error generating projects for project {ctx.project_name}.")
         raise ExportProjectError(f"Error generating projects for project {ctx.project_name}.")

+ 1 - 0
scripts/o3de/tests/test_export_project.py

@@ -316,6 +316,7 @@ def test_build_game_targets(tmp_path, build_config, build_game_launcher, build_s
                            build_config=build_config,
                            build_config=build_config,
                            game_build_path=test_game_build_path,
                            game_build_path=test_game_build_path,
                            engine_centric=engine_centric,
                            engine_centric=engine_centric,
+                           monolithic_build=True,
                            launcher_types=launcher_types,
                            launcher_types=launcher_types,
                            allow_registry_overrides=allow_registry_overrides)
                            allow_registry_overrides=allow_registry_overrides)