Browse Source

Converting Dynamic Vegetation and Gradient Signal tests to utilize prefab system (#7034)

* Adding on-disk prefabs for automated tests

Signed-off-by: jckand-amzn <[email protected]>

* Resolving import conflict with cherrypick

Signed-off-by: jckand-amzn <[email protected]>

* Updating DynVeg tests to use open_base_level function

Signed-off-by: jckand-amzn <[email protected]>

* Converting initial set of DynVeg tests to utilize prefab system

Signed-off-by: jckand-amzn <[email protected]>

* Finalizing DynVeg test conversion to use prefab system

Signed-off-by: jckand-amzn <[email protected]>

* Removing old test runners

Signed-off-by: jckand-amzn <[email protected]>

* Removing optimized suffix from optimized test runners

Signed-off-by: jckand-amzn <[email protected]>

* Removing unoptimized test runner

Signed-off-by: jckand-amzn <[email protected]>

* Removing optimized suffix from optimized test runner

Signed-off-by: jckand-amzn <[email protected]>

* Adding wait_for_condition on level save for E2E tests

Signed-off-by: jckand-amzn <[email protected]>
jckand-amzn 3 years ago
parent
commit
2c33240b72
71 changed files with 3047 additions and 914 deletions
  1. 129 0
      AutomatedTesting/Assets/Prefabs/Bush.prefab
  2. 2249 0
      AutomatedTesting/Assets/Prefabs/BushFlowerBlender.prefab
  3. 129 0
      AutomatedTesting/Assets/Prefabs/PurpleFlower.prefab
  4. 3 3
      AutomatedTesting/Assets/VegDescriptorLists/flower_pink.vegdescriptorlist
  5. 1 1
      AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py
  6. 3 3
      AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt
  7. 3 7
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude.py
  8. 3 6
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py
  9. 3 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude.py
  10. 32 12
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea.py
  11. 6 6
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetWeightSelector_InstancesExpressBasedOnWeight.py
  12. 5 6
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py
  13. 5 6
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py
  14. 5 5
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py
  15. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks.py
  16. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/EmptyInstanceSpawner_EmptySpawnerWorks.py
  17. 5 5
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/InstanceSpawnerPriority_LayerAndSubPriority.py
  18. 13 18
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py
  19. 5 6
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlocker_InstancesBlockedInConfiguredArea.py
  20. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py
  21. 13 12
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InheritBehaviorFlag.py
  22. 5 7
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesPlantInAllSupportedShapes.py
  23. 8 7
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py
  24. 5 7
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py
  25. 5 7
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py
  26. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_DependentOnMeshComponent.py
  27. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py
  28. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PhysXColliderSurfaceTagEmitter_E2E_Editor.py
  29. 5 5
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_AutoSnapToSurfaceWorks.py
  30. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets.py
  31. 9 7
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PrefabInstanceSpawner_Embedded_E2E.py
  32. 3 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PrefabInstanceSpawner_External_E2E.py
  33. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifierOverrides_InstancesRotateWithinRange.py
  34. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifier_InstancesRotateWithinRange.py
  35. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifierOverrides_InstancesProperlyScale.py
  36. 5 5
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifier_InstancesProperlyScale.py
  37. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py
  38. 5 5
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_InstancesPlantInAssignedShape.py
  39. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment.py
  40. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifier_InstanceSurfaceAlignment.py
  41. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope.py
  42. 37 42
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerPrefabs_PrefabCreationAndVisibilityToggleWorks.py
  43. 2 3
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceDataRefreshes_RemainsStable.py
  44. 5 5
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected.py
  45. 3 3
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_BasicSurfaceTagCreation.py
  46. 5 7
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_ExclusionList.py
  47. 5 7
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_InclusionList.py
  48. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorPointDensity.py
  49. 5 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorSize.py
  50. 6 4
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/VegetationInstances_DespawnWhenOutOfRange.py
  51. 158 8
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main.py
  52. 0 192
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py
  53. 5 265
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic.py
  54. 0 23
      AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py
  55. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientGenerators_Incompatibilities.py
  56. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientModifiers_Incompatibilities.py
  57. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin.py
  58. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_DefaultPinnedEntityIsSelf.py
  59. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSampling_GradientReferencesAddRemoveSuccessfully.py
  60. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_ComponentDependencies.py
  61. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py
  62. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithExpectedGradients.py
  63. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithSpawners.py
  64. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange.py
  65. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_RequiresShape.py
  66. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_ProcessedImageAssignedSuccessfully.py
  67. 1 2
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_RequiresShape.py
  68. 22 38
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic.py
  69. 0 57
      AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic_Optimized.py
  70. 44 1
      AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py
  71. 16 23
      AutomatedTesting/ScriptCanvas/instance_counter.scriptcanvas

+ 129 - 0
AutomatedTesting/Assets/Prefabs/Bush.prefab

@@ -0,0 +1,129 @@
+{
+    "ContainerEntity": {
+        "Id": "ContainerEntity",
+        "Name": "Bush",
+        "Components": {
+            "Component_[1140272189295067758]": {
+                "$type": "EditorInspectorComponent",
+                "Id": 1140272189295067758
+            },
+            "Component_[13437832196484687256]": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 13437832196484687256
+            },
+            "Component_[1553903646452669645]": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 1553903646452669645
+            },
+            "Component_[15914009348632444632]": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 15914009348632444632,
+                "Child Entity Order": [
+                    "Entity_[7511491868318]"
+                ]
+            },
+            "Component_[18046340308818780248]": {
+                "$type": "EditorPrefabComponent",
+                "Id": 18046340308818780248
+            },
+            "Component_[1948833233489872938]": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 1948833233489872938,
+                "Parent Entity": ""
+            },
+            "Component_[2903632350157981339]": {
+                "$type": "SelectionComponent",
+                "Id": 2903632350157981339
+            },
+            "Component_[48827510535192710]": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 48827510535192710
+            },
+            "Component_[5609536793322429681]": {
+                "$type": "EditorLockComponent",
+                "Id": 5609536793322429681
+            },
+            "Component_[5859168386298620990]": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 5859168386298620990
+            },
+            "Component_[6604616929271524505]": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 6604616929271524505
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[7511491868318]": {
+            "Id": "Entity_[7511491868318]",
+            "Name": "Bush",
+            "Components": {
+                "Component_[10227459330338484901]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 10227459330338484901,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 4998941225335869157
+                        },
+                        {
+                            "ComponentId": 9922994635792843826,
+                            "SortIndex": 1
+                        }
+                    ]
+                },
+                "Component_[10972351222359420947]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 10972351222359420947
+                },
+                "Component_[12101122374155214392]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 12101122374155214392
+                },
+                "Component_[1535264614652988260]": {
+                    "$type": "SelectionComponent",
+                    "Id": 1535264614652988260
+                },
+                "Component_[16367811417907891218]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 16367811417907891218
+                },
+                "Component_[17044216787716682880]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 17044216787716682880
+                },
+                "Component_[2129822594969629430]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 2129822594969629430
+                },
+                "Component_[2838015156782745450]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 2838015156782745450
+                },
+                "Component_[4998941225335869157]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 4998941225335869157,
+                    "Parent Entity": "ContainerEntity"
+                },
+                "Component_[8773358049076362578]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 8773358049076362578
+                },
+                "Component_[9922994635792843826]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 9922994635792843826,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{1201406D-FB20-5B5F-B9B5-6A6E8DE00A14}",
+                                    "subId": 276506120
+                                },
+                                "assetHint": "assets/objects/foliage/bush_privet_01.azmodel"
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

+ 2249 - 0
AutomatedTesting/Assets/Prefabs/BushFlowerBlender.prefab

@@ -0,0 +1,2249 @@
+{
+    "ContainerEntity": {
+        "Id": "ContainerEntity",
+        "Name": "BushFlowerBlender",
+        "Components": {
+            "Component_[10351434005293588180]": {
+                "$type": "EditorLockComponent",
+                "Id": 10351434005293588180
+            },
+            "Component_[10967554916960846519]": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 10967554916960846519
+            },
+            "Component_[14400678265986305456]": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 14400678265986305456
+            },
+            "Component_[15365520792759708998]": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 15365520792759708998
+            },
+            "Component_[16281192066639198814]": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 16281192066639198814,
+                "Child Entity Order": [
+                    "Entity_[263598916892318]"
+                ]
+            },
+            "Component_[16356049875968660722]": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 16356049875968660722,
+                "Parent Entity": ""
+            },
+            "Component_[16391695178646515457]": {
+                "$type": "SelectionComponent",
+                "Id": 16391695178646515457
+            },
+            "Component_[16407238476365087382]": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 16407238476365087382
+            },
+            "Component_[3542701736829700396]": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 3542701736829700396
+            },
+            "Component_[5160094530340900971]": {
+                "$type": "EditorInspectorComponent",
+                "Id": 5160094530340900971
+            },
+            "Component_[6432428663776737136]": {
+                "$type": "EditorPrefabComponent",
+                "Id": 6432428663776737136
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[263573147088542]": {
+            "Id": "Entity_[263573147088542]",
+            "Name": "BushSpawner",
+            "Components": {
+                "Component_[11886309121583108836]": {
+                    "$type": "EditorPositionModifierComponent",
+                    "Id": 11886309121583108836,
+                    "Configuration": {
+                        "GradientX": {
+                            "GradientId": "Entity_[263590326957726]"
+                        },
+                        "GradientY": {
+                            "GradientId": "Entity_[263590326957726]"
+                        },
+                        "GradientZ": {
+                            "GradientId": ""
+                        }
+                    }
+                },
+                "Component_[1240444912193942742]": {
+                    "$type": "{DD96FD51-A86B-48BC-A6AB-89183B538269} EditorSpawnerComponent",
+                    "Id": 1240444912193942742,
+                    "PreviewEntity": "Entity_[263573147088542]"
+                },
+                "Component_[12813702285187817973]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 12813702285187817973,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 18133156195370267728
+                        },
+                        {
+                            "ComponentId": 13450250419263773680,
+                            "SortIndex": 1
+                        },
+                        {
+                            "ComponentId": 8841963751527151666,
+                            "SortIndex": 2
+                        },
+                        {
+                            "ComponentId": 1240444912193942742,
+                            "SortIndex": 3
+                        },
+                        {
+                            "ComponentId": 17991239182321715249,
+                            "SortIndex": 4
+                        },
+                        {
+                            "ComponentId": 14175761523159824993,
+                            "SortIndex": 5
+                        },
+                        {
+                            "ComponentId": 2884829698060689565,
+                            "SortIndex": 6
+                        },
+                        {
+                            "ComponentId": 11886309121583108836,
+                            "SortIndex": 7
+                        }
+                    ]
+                },
+                "Component_[13179606361687972691]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 13179606361687972691
+                },
+                "Component_[13450250419263773680]": {
+                    "$type": "EditorReferenceShapeComponent",
+                    "Id": 13450250419263773680,
+                    "Configuration": {
+                        "ShapeEntityId": "Entity_[263607506826910]"
+                    }
+                },
+                "Component_[13688014277574607552]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 13688014277574607552
+                },
+                "Component_[14175761523159824993]": {
+                    "$type": "EditorDistributionFilterComponent",
+                    "Id": 14175761523159824993,
+                    "Configuration": {
+                        "ThresholdMin": 0.289000004529953,
+                        "ThresholdMax": 0.5690000057220459,
+                        "Gradient": {
+                            "GradientId": "Entity_[263603211859614]"
+                        }
+                    }
+                },
+                "Component_[14232774271081092639]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 14232774271081092639
+                },
+                "Component_[14811533745267383811]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 14811533745267383811
+                },
+                "Component_[17540078415915694273]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 17540078415915694273
+                },
+                "Component_[17991239182321715249]": {
+                    "$type": "EditorRotationModifierComponent",
+                    "Id": 17991239182321715249,
+                    "Configuration": {
+                        "GradientX": {
+                            "GradientId": ""
+                        },
+                        "GradientY": {
+                            "GradientId": ""
+                        },
+                        "GradientZ": {
+                            "GradientId": "Entity_[263590326957726]"
+                        }
+                    }
+                },
+                "Component_[18133156195370267728]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 18133156195370267728,
+                    "Parent Entity": "Entity_[263607506826910]"
+                },
+                "Component_[2884829698060689565]": {
+                    "$type": "EditorScaleModifierComponent",
+                    "Id": 2884829698060689565,
+                    "Configuration": {
+                        "RangeMin": 0.75,
+                        "RangeMax": 1.25,
+                        "Gradient": {
+                            "GradientId": "Entity_[263590326957726]"
+                        }
+                    }
+                },
+                "Component_[50628676751372416]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 50628676751372416,
+                    "Child Entity Order": [
+                        "Entity_[263603211859614]",
+                        "Entity_[263590326957726]"
+                    ]
+                },
+                "Component_[5689270312836823309]": {
+                    "$type": "SelectionComponent",
+                    "Id": 5689270312836823309
+                },
+                "Component_[7105803915999711758]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 7105803915999711758
+                },
+                "Component_[8841963751527151666]": {
+                    "$type": "EditorDescriptorListComponent",
+                    "Id": 8841963751527151666,
+                    "Configuration": {
+                        "Descriptors": [
+                            {
+                                "SpawnerType": "{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}",
+                                "InstanceSpawner": {
+                                    "$type": "PrefabInstanceSpawner",
+                                    "SpawnableAsset": {
+                                        "assetId": {
+                                            "guid": "{EE51E73C-D753-54AC-A1C0-4F29844FB6C3}",
+                                            "subId": 2740536329
+                                        },
+                                        "assetHint": "assets/prefabs/bush.spawnable"
+                                    }
+                                }
+                            }
+                        ]
+                    }
+                }
+            }
+        },
+        "Entity_[263577442055838]": {
+            "Id": "Entity_[263577442055838]",
+            "Name": "RandomNoise",
+            "Components": {
+                "Component_[13412023990029767074]": {
+                    "$type": "EditorRandomGradientComponent",
+                    "Id": 13412023990029767074,
+                    "PreviewEntity": "Entity_[263577442055838]"
+                },
+                "Component_[14048059127502350032]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 14048059127502350032,
+                    "Parent Entity": "Entity_[263581737023134]"
+                },
+                "Component_[15585968636846328006]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 15585968636846328006
+                },
+                "Component_[17356242264256499333]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 17356242264256499333
+                },
+                "Component_[2157320692130316849]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 2157320692130316849
+                },
+                "Component_[2167582872687341084]": {
+                    "$type": "EditorReferenceShapeComponent",
+                    "Id": 2167582872687341084,
+                    "Configuration": {
+                        "ShapeEntityId": "Entity_[263607506826910]"
+                    }
+                },
+                "Component_[2794166072748175035]": {
+                    "$type": "SelectionComponent",
+                    "Id": 2794166072748175035
+                },
+                "Component_[4784966656524567789]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 4784966656524567789
+                },
+                "Component_[6185400249317227261]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 6185400249317227261
+                },
+                "Component_[639949486729001685]": {
+                    "$type": "EditorGradientTransformComponent",
+                    "Id": 639949486729001685,
+                    "Configuration": {
+                        "ShapeReference": "",
+                        "Bounds": [
+                            50.0,
+                            50.0,
+                            1.0
+                        ]
+                    }
+                },
+                "Component_[7347819195697153472]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 7347819195697153472
+                },
+                "Component_[9225409585951117678]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 9225409585951117678,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 14048059127502350032
+                        },
+                        {
+                            "ComponentId": 2167582872687341084,
+                            "SortIndex": 1
+                        },
+                        {
+                            "ComponentId": 639949486729001685,
+                            "SortIndex": 2
+                        },
+                        {
+                            "ComponentId": 13412023990029767074,
+                            "SortIndex": 3
+                        }
+                    ]
+                },
+                "Component_[9667056664436803603]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 9667056664436803603
+                }
+            }
+        },
+        "Entity_[263581737023134]": {
+            "Id": "Entity_[263581737023134]",
+            "Name": "FlowerSpawner",
+            "Components": {
+                "Component_[10064436441176637741]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 10064436441176637741
+                },
+                "Component_[10418076448308581948]": {
+                    "$type": "EditorRotationModifierComponent",
+                    "Id": 10418076448308581948,
+                    "Configuration": {
+                        "GradientX": {
+                            "GradientId": ""
+                        },
+                        "GradientY": {
+                            "GradientId": ""
+                        },
+                        "GradientZ": {
+                            "GradientId": "Entity_[263577442055838]"
+                        }
+                    }
+                },
+                "Component_[12484622175138429315]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 12484622175138429315
+                },
+                "Component_[12590590072231203407]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 12590590072231203407
+                },
+                "Component_[13079591667184987458]": {
+                    "$type": "EditorScaleModifierComponent",
+                    "Id": 13079591667184987458,
+                    "Configuration": {
+                        "RangeMin": 0.75,
+                        "RangeMax": 1.25,
+                        "Gradient": {
+                            "GradientId": "Entity_[263577442055838]"
+                        }
+                    }
+                },
+                "Component_[13174773394274524631]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 13174773394274524631,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 1915862229814997128
+                        },
+                        {
+                            "ComponentId": 582800388831726963,
+                            "SortIndex": 1
+                        },
+                        {
+                            "ComponentId": 18006385801184712266,
+                            "SortIndex": 2
+                        },
+                        {
+                            "ComponentId": 6902499453501456890,
+                            "SortIndex": 3
+                        },
+                        {
+                            "ComponentId": 10418076448308581948,
+                            "SortIndex": 4
+                        },
+                        {
+                            "ComponentId": 13983302912005698250,
+                            "SortIndex": 5
+                        },
+                        {
+                            "ComponentId": 13079591667184987458,
+                            "SortIndex": 6
+                        },
+                        {
+                            "ComponentId": 7912787520673119502,
+                            "SortIndex": 7
+                        }
+                    ]
+                },
+                "Component_[13200009872392504010]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 13200009872392504010,
+                    "Child Entity Order": [
+                        "Entity_[263594621925022]",
+                        "Entity_[263577442055838]"
+                    ]
+                },
+                "Component_[13983302912005698250]": {
+                    "$type": "EditorDistributionFilterComponent",
+                    "Id": 13983302912005698250,
+                    "Configuration": {
+                        "ThresholdMin": 0.2879999876022339,
+                        "ThresholdMax": 0.5680000185966492,
+                        "Gradient": {
+                            "GradientId": "Entity_[263586031990430]"
+                        }
+                    }
+                },
+                "Component_[14726174657215669218]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 14726174657215669218
+                },
+                "Component_[18006385801184712266]": {
+                    "$type": "EditorDescriptorListComponent",
+                    "Id": 18006385801184712266,
+                    "Configuration": {
+                        "Descriptors": [
+                            {
+                                "SpawnerType": "{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}",
+                                "InstanceSpawner": {
+                                    "$type": "PrefabInstanceSpawner",
+                                    "SpawnableAsset": {
+                                        "assetId": {
+                                            "guid": "{80C0CF4E-9A5E-544B-B89E-BC980175A259}",
+                                            "subId": 3875079122
+                                        },
+                                        "assetHint": "assets/prefabs/pinkflower.spawnable"
+                                    }
+                                }
+                            },
+                            {
+                                "SpawnerType": "{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}",
+                                "InstanceSpawner": {
+                                    "$type": "PrefabInstanceSpawner",
+                                    "SpawnableAsset": {
+                                        "assetId": {
+                                            "guid": "{20DD1202-A434-5482-9FB9-AED4C78F6CBF}",
+                                            "subId": 2669863854
+                                        },
+                                        "assetHint": "assets/prefabs/purpleflower.spawnable"
+                                    }
+                                }
+                            },
+                            {
+                                "SpawnerType": "{23C40FD4-A55F-4BD3-BE5B-DC5423F217C2}",
+                                "InstanceSpawner": {
+                                    "$type": "EmptyInstanceSpawner"
+                                }
+                            }
+                        ]
+                    }
+                },
+                "Component_[1915862229814997128]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 1915862229814997128,
+                    "Parent Entity": "Entity_[263607506826910]"
+                },
+                "Component_[2123416208548010747]": {
+                    "$type": "SelectionComponent",
+                    "Id": 2123416208548010747
+                },
+                "Component_[4172073657954183661]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 4172073657954183661
+                },
+                "Component_[4297556504463195307]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 4297556504463195307
+                },
+                "Component_[582800388831726963]": {
+                    "$type": "EditorReferenceShapeComponent",
+                    "Id": 582800388831726963,
+                    "Configuration": {
+                        "ShapeEntityId": "Entity_[263607506826910]"
+                    }
+                },
+                "Component_[6902499453501456890]": {
+                    "$type": "{DD96FD51-A86B-48BC-A6AB-89183B538269} EditorSpawnerComponent",
+                    "Id": 6902499453501456890,
+                    "PreviewEntity": "Entity_[263581737023134]"
+                },
+                "Component_[7912787520673119502]": {
+                    "$type": "EditorPositionModifierComponent",
+                    "Id": 7912787520673119502,
+                    "Configuration": {
+                        "GradientX": {
+                            "GradientId": "Entity_[263577442055838]"
+                        },
+                        "GradientY": {
+                            "GradientId": "Entity_[263577442055838]"
+                        },
+                        "GradientZ": {
+                            "GradientId": ""
+                        }
+                    }
+                }
+            }
+        },
+        "Entity_[263586031990430]": {
+            "Id": "Entity_[263586031990430]",
+            "Name": "Invert",
+            "Components": {
+                "Component_[11123278080744920525]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 11123278080744920525
+                },
+                "Component_[1199715693160400161]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 1199715693160400161,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 7438979211266329827
+                        },
+                        {
+                            "ComponentId": 6027557066164356793,
+                            "SortIndex": 1
+                        },
+                        {
+                            "ComponentId": 8903771095804438921,
+                            "SortIndex": 2
+                        }
+                    ]
+                },
+                "Component_[12162816428693886169]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 12162816428693886169
+                },
+                "Component_[14493180089799969074]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 14493180089799969074
+                },
+                "Component_[16206759293595766479]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 16206759293595766479
+                },
+                "Component_[17566144032052847628]": {
+                    "$type": "SelectionComponent",
+                    "Id": 17566144032052847628
+                },
+                "Component_[17784057508127919200]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 17784057508127919200
+                },
+                "Component_[18377773171420051348]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 18377773171420051348
+                },
+                "Component_[6027557066164356793]": {
+                    "$type": "EditorReferenceShapeComponent",
+                    "Id": 6027557066164356793,
+                    "Configuration": {
+                        "ShapeEntityId": "Entity_[263607506826910]"
+                    }
+                },
+                "Component_[7438979211266329827]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 7438979211266329827,
+                    "Parent Entity": "Entity_[263594621925022]"
+                },
+                "Component_[8421650081106982664]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 8421650081106982664
+                },
+                "Component_[8903771095804438921]": {
+                    "$type": "EditorInvertGradientComponent",
+                    "Id": 8903771095804438921,
+                    "Configuration": {
+                        "Gradient": {
+                            "GradientId": "Entity_[263594621925022]"
+                        }
+                    },
+                    "PreviewEntity": "Entity_[263586031990430]"
+                }
+            }
+        },
+        "Entity_[263590326957726]": {
+            "Id": "Entity_[263590326957726]",
+            "Name": "RandomNoise",
+            "Components": {
+                "Component_[10420548607186596407]": {
+                    "$type": "SelectionComponent",
+                    "Id": 10420548607186596407
+                },
+                "Component_[11351507264577024072]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 11351507264577024072,
+                    "Parent Entity": "Entity_[263573147088542]"
+                },
+                "Component_[11576941520191560445]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11576941520191560445
+                },
+                "Component_[11787535428542045683]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 11787535428542045683
+                },
+                "Component_[11946132649485953311]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 11946132649485953311
+                },
+                "Component_[11970417753234451570]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 11970417753234451570
+                },
+                "Component_[13743879269876214143]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 13743879269876214143
+                },
+                "Component_[15614946697365576378]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 15614946697365576378
+                },
+                "Component_[17045174842161759045]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 17045174842161759045
+                },
+                "Component_[3107716031616536910]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 3107716031616536910,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 11351507264577024072
+                        },
+                        {
+                            "ComponentId": 6316453818295975755,
+                            "SortIndex": 1
+                        },
+                        {
+                            "ComponentId": 4846745402056100407,
+                            "SortIndex": 2
+                        },
+                        {
+                            "ComponentId": 8967153379180885152,
+                            "SortIndex": 3
+                        }
+                    ]
+                },
+                "Component_[4846745402056100407]": {
+                    "$type": "EditorGradientTransformComponent",
+                    "Id": 4846745402056100407,
+                    "Configuration": {
+                        "ShapeReference": "",
+                        "Bounds": [
+                            50.0,
+                            50.0,
+                            1.0
+                        ]
+                    }
+                },
+                "Component_[6316453818295975755]": {
+                    "$type": "EditorReferenceShapeComponent",
+                    "Id": 6316453818295975755,
+                    "Configuration": {
+                        "ShapeEntityId": "Entity_[263573147088542]"
+                    }
+                },
+                "Component_[8967153379180885152]": {
+                    "$type": "EditorRandomGradientComponent",
+                    "Id": 8967153379180885152,
+                    "PreviewEntity": "Entity_[263590326957726]"
+                }
+            }
+        },
+        "Entity_[263594621925022]": {
+            "Id": "Entity_[263594621925022]",
+            "Name": "PerlinNoise",
+            "Components": {
+                "Component_[15798567753940523121]": {
+                    "$type": "EditorPerlinGradientComponent",
+                    "Id": 15798567753940523121,
+                    "Configuration": {
+                        "randomSeed": 33,
+                        "frequency": 0.25
+                    },
+                    "PreviewEntity": "Entity_[263594621925022]"
+                },
+                "Component_[16035848776632936419]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 16035848776632936419
+                },
+                "Component_[16434108759160050253]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 16434108759160050253
+                },
+                "Component_[16805003046507210760]": {
+                    "$type": "EditorReferenceShapeComponent",
+                    "Id": 16805003046507210760,
+                    "Configuration": {
+                        "ShapeEntityId": "Entity_[263607506826910]"
+                    }
+                },
+                "Component_[17679463569742913027]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 17679463569742913027
+                },
+                "Component_[18285870860955961523]": {
+                    "$type": "SelectionComponent",
+                    "Id": 18285870860955961523
+                },
+                "Component_[2330427084045350198]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 2330427084045350198
+                },
+                "Component_[5921906930080711994]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 5921906930080711994,
+                    "Child Entity Order": [
+                        "Entity_[263586031990430]"
+                    ]
+                },
+                "Component_[764117453152842781]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 764117453152842781,
+                    "Parent Entity": "Entity_[263581737023134]"
+                },
+                "Component_[7701931249281891300]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 7701931249281891300
+                },
+                "Component_[7967070680905543315]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 7967070680905543315,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 764117453152842781
+                        },
+                        {
+                            "ComponentId": 16805003046507210760,
+                            "SortIndex": 1
+                        },
+                        {
+                            "ComponentId": 8029154041194694200,
+                            "SortIndex": 2
+                        },
+                        {
+                            "ComponentId": 15798567753940523121,
+                            "SortIndex": 3
+                        }
+                    ]
+                },
+                "Component_[8029154041194694200]": {
+                    "$type": "EditorGradientTransformComponent",
+                    "Id": 8029154041194694200,
+                    "Configuration": {
+                        "ShapeReference": "",
+                        "Bounds": [
+                            50.0,
+                            50.0,
+                            1.0
+                        ]
+                    }
+                },
+                "Component_[8660028910391135744]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 8660028910391135744
+                }
+            }
+        },
+        "Entity_[263598916892318]": {
+            "Id": "Entity_[263598916892318]",
+            "Name": "LandscapeCanvas",
+            "Components": {
+                "Component_[12967746135199800648]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 12967746135199800648
+                },
+                "Component_[13081062505162225823]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 13081062505162225823
+                },
+                "Component_[16021195931295059075]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 16021195931295059075
+                },
+                "Component_[16134261272053586014]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 16134261272053586014
+                },
+                "Component_[17500735767968801510]": {
+                    "$type": "EditorLandscapeCanvasComponent",
+                    "Id": 17500735767968801510,
+                    "Graph": {
+                        "m_nodes": [
+                            {
+                                "Key": 1,
+                                "Value": {
+                                    "$type": "CylinderShapeNode",
+                                    "m_propertySlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "EntityName"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string",
+                                                    "Value": "BushFlowerBlender"
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263607506826910]",
+                                    "m_componentId": 6683290476113150719
+                                }
+                            },
+                            {
+                                "Key": 2,
+                                "Value": {
+                                    "$type": "RandomNoiseGradientNode",
+                                    "m_propertySlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "EntityName"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string",
+                                                    "Value": "RandomNoise"
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "PreviewBounds"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263590326957726]",
+                                    "m_componentId": 8967153379180885152
+                                }
+                            },
+                            {
+                                "Key": 3,
+                                "Value": {
+                                    "$type": "SpawnerAreaNode",
+                                    "m_propertySlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "EntityName"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string",
+                                                    "Value": "BushSpawner"
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "PlacementBounds"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263573147088542]",
+                                    "m_componentId": 1240444912193942742
+                                }
+                            },
+                            {
+                                "Key": 4,
+                                "Value": {
+                                    "$type": "PerlinNoiseGradientNode",
+                                    "m_propertySlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "EntityName"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string",
+                                                    "Value": "PerlinNoise"
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "PreviewBounds"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263603211859614]",
+                                    "m_componentId": 10160640699095155981
+                                }
+                            },
+                            {
+                                "Key": 5,
+                                "Value": {
+                                    "$type": "RandomNoiseGradientNode",
+                                    "m_propertySlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "EntityName"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string",
+                                                    "Value": "RandomNoise"
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "PreviewBounds"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263577442055838]",
+                                    "m_componentId": 13412023990029767074
+                                }
+                            },
+                            {
+                                "Key": 6,
+                                "Value": {
+                                    "$type": "SpawnerAreaNode",
+                                    "m_propertySlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "EntityName"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string",
+                                                    "Value": "FlowerSpawner"
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "PlacementBounds"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263581737023134]",
+                                    "m_componentId": 6902499453501456890
+                                }
+                            },
+                            {
+                                "Key": 7,
+                                "Value": {
+                                    "$type": "AreaBlenderNode",
+                                    "m_propertySlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "EntityName"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string",
+                                                    "Value": "BushFlowerBlender"
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_extendableSlots": {
+                                        "InboundArea": [
+                                            {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            },
+                                            {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                },
+                                                "m_subId": 1
+                                            }
+                                        ]
+                                    },
+                                    "m_vegetationEntityId": "Entity_[263607506826910]",
+                                    "m_componentId": 7229206794941734410
+                                }
+                            },
+                            {
+                                "Key": 8,
+                                "Value": {
+                                    "$type": "PerlinNoiseGradientNode",
+                                    "m_propertySlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "EntityName"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string",
+                                                    "Value": "PerlinNoise"
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "PreviewBounds"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263594621925022]",
+                                    "m_componentId": 15798567753940523121
+                                }
+                            },
+                            {
+                                "Key": 9,
+                                "Value": {
+                                    "$type": "InvertGradientModifierNode",
+                                    "m_propertySlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "EntityName"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string",
+                                                    "Value": "Invert"
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradient"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        },
+                                        {
+                                            "Key": {
+                                                "m_name": "PreviewBounds"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263586031990430]",
+                                    "m_componentId": 8903771095804438921
+                                }
+                            },
+                            {
+                                "Key": 10,
+                                "Value": {
+                                    "$type": "RotationModifierNode",
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientX"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        },
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientY"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        },
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientZ"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263573147088542]",
+                                    "m_componentId": 17991239182321715249
+                                }
+                            },
+                            {
+                                "Key": 11,
+                                "Value": {
+                                    "$type": "DistributionFilterNode",
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradient"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263573147088542]",
+                                    "m_componentId": 14175761523159824993
+                                }
+                            },
+                            {
+                                "Key": 12,
+                                "Value": {
+                                    "$type": "ScaleModifierNode",
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradient"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263573147088542]",
+                                    "m_componentId": 2884829698060689565
+                                }
+                            },
+                            {
+                                "Key": 13,
+                                "Value": {
+                                    "$type": "PositionModifierNode",
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientX"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        },
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientY"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        },
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientZ"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263573147088542]",
+                                    "m_componentId": 11886309121583108836
+                                }
+                            },
+                            {
+                                "Key": 14,
+                                "Value": {
+                                    "$type": "RotationModifierNode",
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientX"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        },
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientY"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        },
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientZ"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263581737023134]",
+                                    "m_componentId": 10418076448308581948
+                                }
+                            },
+                            {
+                                "Key": 15,
+                                "Value": {
+                                    "$type": "DistributionFilterNode",
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradient"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263581737023134]",
+                                    "m_componentId": 13983302912005698250
+                                }
+                            },
+                            {
+                                "Key": 16,
+                                "Value": {
+                                    "$type": "ScaleModifierNode",
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradient"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263581737023134]",
+                                    "m_componentId": 13079591667184987458
+                                }
+                            },
+                            {
+                                "Key": 17,
+                                "Value": {
+                                    "$type": "PositionModifierNode",
+                                    "m_inputDataSlots": [
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientX"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        },
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientY"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        },
+                                        {
+                                            "Key": {
+                                                "m_name": "InboundGradientZ"
+                                            },
+                                            "Value": {
+                                                "m_value": {
+                                                    "$type": "EntityId",
+                                                    "Value": ""
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    "m_vegetationEntityId": "Entity_[263581737023134]",
+                                    "m_componentId": 7912787520673119502
+                                }
+                            }
+                        ],
+                        "m_connections": [
+                            {
+                                "m_sourceEndpoint": [
+                                    8,
+                                    {
+                                        "m_name": "OutboundGradient"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    9,
+                                    {
+                                        "m_name": "InboundGradient"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    3,
+                                    {
+                                        "m_name": "OutboundArea"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    7,
+                                    {
+                                        "m_name": "InboundArea"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    6,
+                                    {
+                                        "m_name": "OutboundArea"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    7,
+                                    {
+                                        "m_name": "InboundArea",
+                                        "m_subId": 1
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    1,
+                                    {
+                                        "m_name": "Bounds"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    3,
+                                    {
+                                        "m_name": "PlacementBounds"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    1,
+                                    {
+                                        "m_name": "Bounds"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    6,
+                                    {
+                                        "m_name": "PlacementBounds"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    2,
+                                    {
+                                        "m_name": "OutboundGradient"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    10,
+                                    {
+                                        "m_name": "InboundGradientZ"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    4,
+                                    {
+                                        "m_name": "OutboundGradient"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    11,
+                                    {
+                                        "m_name": "InboundGradient"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    2,
+                                    {
+                                        "m_name": "OutboundGradient"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    12,
+                                    {
+                                        "m_name": "InboundGradient"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    2,
+                                    {
+                                        "m_name": "OutboundGradient"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    13,
+                                    {
+                                        "m_name": "InboundGradientX"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    2,
+                                    {
+                                        "m_name": "OutboundGradient"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    13,
+                                    {
+                                        "m_name": "InboundGradientY"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    5,
+                                    {
+                                        "m_name": "OutboundGradient"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    14,
+                                    {
+                                        "m_name": "InboundGradientZ"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    9,
+                                    {
+                                        "m_name": "OutboundGradient"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    15,
+                                    {
+                                        "m_name": "InboundGradient"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    5,
+                                    {
+                                        "m_name": "OutboundGradient"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    16,
+                                    {
+                                        "m_name": "InboundGradient"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    5,
+                                    {
+                                        "m_name": "OutboundGradient"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    17,
+                                    {
+                                        "m_name": "InboundGradientX"
+                                    }
+                                ]
+                            },
+                            {
+                                "m_sourceEndpoint": [
+                                    5,
+                                    {
+                                        "m_name": "OutboundGradient"
+                                    }
+                                ],
+                                "m_targetEndpoint": [
+                                    17,
+                                    {
+                                        "m_name": "InboundGradientY"
+                                    }
+                                ]
+                            }
+                        ],
+                        "m_uiMetadata": {
+                            "m_sceneMetadata": {
+                                "ComponentData": {
+                                    "{5F84B500-8C45-40D1-8EFC-A5306B241444}": {
+                                        "$type": "SceneComponentSaveData",
+                                        "ViewParams": {
+                                            "Scale": 0.3771495156249999,
+                                            "AnchorX": -498.4760437011719,
+                                            "AnchorY": 808.6978149414063
+                                        }
+                                    }
+                                }
+                            },
+                            "m_nodeMetadata": [
+                                {
+                                    "Key": 2,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "GradientNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    100.0,
+                                                    580.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{2D583FA2-5659-491F-8914-6302420E3F0B}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 3,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "VegetationAreaNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    480.0,
+                                                    600.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{A26480C4-A80B-4B36-ADE1-918E4541EA2B}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 5,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "GradientNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    100.0,
+                                                    1540.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{6CE9EA8B-85E7-4E17-B1D6-CA97D9D65276}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 6,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "VegetationAreaNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    480.0,
+                                                    1560.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{8FABE49F-1D73-46FE-8616-A982EEE46DDD}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 7,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "VegetationAreaNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    840.0,
+                                                    1580.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{C5EEBC1D-B91B-4852-A41D-425C6FED3FB9}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 9,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "GradientModifierNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    480.0,
+                                                    2060.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{5EB76670-0CBE-4F2A-9AE7-F65709D0BE92}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 10,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "VegetationAreaNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    6.0,
+                                                    147.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{5CB69A73-F7BA-4F76-AB86-F343052C3D7D}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 11,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "VegetationAreaNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    6.0,
+                                                    367.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{235DEBEC-E3F8-43C1-BA7E-41475B834D70}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 12,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "VegetationAreaNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    6.0,
+                                                    288.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{9E56E7B6-2ECE-42F9-9A23-FF7D192209D2}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 13,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "VegetationAreaNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    6.0,
+                                                    6.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{61759FE6-E6F7-4F4B-819B-FBFE125D7389}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 14,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "VegetationAreaNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    6.0,
+                                                    147.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{0AC1C6C8-7CC1-4068-A87D-F4B92AE8FCAF}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 15,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "VegetationAreaNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    6.0,
+                                                    367.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{5D698B90-830F-46FE-ADD8-6164EA098C3E}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 16,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "VegetationAreaNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    6.0,
+                                                    288.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{9DE6DE4A-2E6F-44BA-B292-3CD2215C1D5B}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": 17,
+                                    "Value": {
+                                        "ComponentData": {
+                                            "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+                                                "$type": "NodeSaveData"
+                                            },
+                                            "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+                                                "$type": "GeneralNodeTitleComponentSaveData",
+                                                "PaletteOverride": "VegetationAreaNodeTitlePalette"
+                                            },
+                                            "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+                                                "$type": "GeometrySaveData",
+                                                "Position": [
+                                                    6.0,
+                                                    6.0
+                                                ]
+                                            },
+                                            "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+                                                "$type": "StylingComponentSaveData"
+                                            },
+                                            "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+                                                "$type": "PersistentIdComponentSaveData",
+                                                "PersistentId": "{57FA822D-629F-4949-A8D7-D675544EBC0A}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        },
+                        "m_nodeWrappings": [
+                            {
+                                "Key": 10,
+                                "Value": [
+                                    3,
+                                    1
+                                ]
+                            },
+                            {
+                                "Key": 11,
+                                "Value": [
+                                    3,
+                                    6
+                                ]
+                            },
+                            {
+                                "Key": 12,
+                                "Value": [
+                                    3,
+                                    2
+                                ]
+                            },
+                            {
+                                "Key": 13,
+                                "Value": [
+                                    3,
+                                    {}
+                                ]
+                            },
+                            {
+                                "Key": 14,
+                                "Value": [
+                                    6,
+                                    1
+                                ]
+                            },
+                            {
+                                "Key": 15,
+                                "Value": [
+                                    6,
+                                    6
+                                ]
+                            },
+                            {
+                                "Key": 16,
+                                "Value": [
+                                    6,
+                                    2
+                                ]
+                            },
+                            {
+                                "Key": 17,
+                                "Value": [
+                                    6,
+                                    {}
+                                ]
+                            }
+                        ]
+                    }
+                },
+                "Component_[17574651838531525263]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 17574651838531525263,
+                    "Child Entity Order": [
+                        "Entity_[263607506826910]"
+                    ]
+                },
+                "Component_[3086205760978540160]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 3086205760978540160
+                },
+                "Component_[3102230753208284750]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 3102230753208284750,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 5796173638130327223
+                        },
+                        {
+                            "ComponentId": 17500735767968801510,
+                            "SortIndex": 1
+                        }
+                    ]
+                },
+                "Component_[4695341524212000585]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 4695341524212000585
+                },
+                "Component_[5796173638130327223]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 5796173638130327223,
+                    "Parent Entity": "ContainerEntity"
+                },
+                "Component_[8278362871021770878]": {
+                    "$type": "SelectionComponent",
+                    "Id": 8278362871021770878
+                }
+            }
+        },
+        "Entity_[263603211859614]": {
+            "Id": "Entity_[263603211859614]",
+            "Name": "PerlinNoise",
+            "Components": {
+                "Component_[10006546776757889020]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 10006546776757889020
+                },
+                "Component_[10160640699095155981]": {
+                    "$type": "EditorPerlinGradientComponent",
+                    "Id": 10160640699095155981,
+                    "Configuration": {
+                        "randomSeed": 33,
+                        "frequency": 0.25
+                    },
+                    "PreviewEntity": "Entity_[263603211859614]"
+                },
+                "Component_[11506183926478566822]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 11506183926478566822
+                },
+                "Component_[13160180411150366392]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 13160180411150366392
+                },
+                "Component_[15083697380300161163]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 15083697380300161163
+                },
+                "Component_[15404456223257061245]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 15404456223257061245,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 6484803030406851652
+                        },
+                        {
+                            "ComponentId": 4912800286535654244,
+                            "SortIndex": 1
+                        },
+                        {
+                            "ComponentId": 2395166459126906105,
+                            "SortIndex": 2
+                        },
+                        {
+                            "ComponentId": 10160640699095155981,
+                            "SortIndex": 3
+                        }
+                    ]
+                },
+                "Component_[2395166459126906105]": {
+                    "$type": "EditorGradientTransformComponent",
+                    "Id": 2395166459126906105,
+                    "Configuration": {
+                        "ShapeReference": "",
+                        "Bounds": [
+                            50.0,
+                            50.0,
+                            1.0
+                        ]
+                    }
+                },
+                "Component_[4417011400526470160]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 4417011400526470160
+                },
+                "Component_[4601061670472962302]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 4601061670472962302
+                },
+                "Component_[4912800286535654244]": {
+                    "$type": "EditorReferenceShapeComponent",
+                    "Id": 4912800286535654244,
+                    "Configuration": {
+                        "ShapeEntityId": "Entity_[263607506826910]"
+                    }
+                },
+                "Component_[6233982345083723563]": {
+                    "$type": "SelectionComponent",
+                    "Id": 6233982345083723563
+                },
+                "Component_[6484803030406851652]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 6484803030406851652,
+                    "Parent Entity": "Entity_[263573147088542]"
+                },
+                "Component_[6813813525871080299]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 6813813525871080299
+                }
+            }
+        },
+        "Entity_[263607506826910]": {
+            "Id": "Entity_[263607506826910]",
+            "Name": "BushFlowerBlender",
+            "Components": {
+                "Component_[13725600808872754587]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 13725600808872754587
+                },
+                "Component_[15959807606564505710]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 15959807606564505710,
+                    "Parent Entity": "Entity_[263598916892318]"
+                },
+                "Component_[1596826146661515925]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 1596826146661515925
+                },
+                "Component_[4525591661239956058]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 4525591661239956058
+                },
+                "Component_[6683290476113150719]": {
+                    "$type": "EditorCylinderShapeComponent",
+                    "Id": 6683290476113150719,
+                    "CylinderShape": {
+                        "Configuration": {
+                            "Radius": 25.0
+                        }
+                    }
+                },
+                "Component_[6879394931668195375]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 6879394931668195375,
+                    "Child Entity Order": [
+                        "Entity_[263573147088542]",
+                        "Entity_[263581737023134]"
+                    ]
+                },
+                "Component_[7229206794941734410]": {
+                    "$type": "EditorAreaBlenderComponent",
+                    "Id": 7229206794941734410,
+                    "Configuration": {
+                        "Operations": [
+                            "Entity_[263573147088542]",
+                            "Entity_[263581737023134]"
+                        ]
+                    },
+                    "PreviewEntity": "Entity_[263607506826910]"
+                },
+                "Component_[8772711204845372843]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 8772711204845372843
+                },
+                "Component_[8959345022109725835]": {
+                    "$type": "SelectionComponent",
+                    "Id": 8959345022109725835
+                },
+                "Component_[9094488642973843583]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 9094488642973843583
+                },
+                "Component_[9112960617967513749]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 9112960617967513749,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 15959807606564505710
+                        },
+                        {
+                            "ComponentId": 7229206794941734410,
+                            "SortIndex": 1
+                        },
+                        {
+                            "ComponentId": 6683290476113150719,
+                            "SortIndex": 2
+                        }
+                    ]
+                },
+                "Component_[9541665258597207652]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 9541665258597207652
+                }
+            }
+        }
+    }
+}

+ 129 - 0
AutomatedTesting/Assets/Prefabs/PurpleFlower.prefab

@@ -0,0 +1,129 @@
+{
+    "ContainerEntity": {
+        "Id": "ContainerEntity",
+        "Name": "PurpleFlower",
+        "Components": {
+            "Component_[10519928302743666073]": {
+                "$type": "EditorPrefabComponent",
+                "Id": 10519928302743666073
+            },
+            "Component_[13894087802180240181]": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 13894087802180240181,
+                "Parent Entity": ""
+            },
+            "Component_[15788541052719571801]": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 15788541052719571801
+            },
+            "Component_[15842981265136092481]": {
+                "$type": "SelectionComponent",
+                "Id": 15842981265136092481
+            },
+            "Component_[16360384897559021149]": {
+                "$type": "EditorInspectorComponent",
+                "Id": 16360384897559021149
+            },
+            "Component_[16713545675046303279]": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 16713545675046303279
+            },
+            "Component_[1806734194268113785]": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 1806734194268113785
+            },
+            "Component_[5392020700593853313]": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 5392020700593853313,
+                "Child Entity Order": [
+                    "Entity_[14335611090324]"
+                ]
+            },
+            "Component_[5995854518752659458]": {
+                "$type": "EditorLockComponent",
+                "Id": 5995854518752659458
+            },
+            "Component_[6963022284400845376]": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 6963022284400845376
+            },
+            "Component_[8055275578170091546]": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 8055275578170091546
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[14335611090324]": {
+            "Id": "Entity_[14335611090324]",
+            "Name": "PurpleFlower",
+            "Components": {
+                "Component_[10887353073528055802]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 10887353073528055802
+                },
+                "Component_[12641127425852859189]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 12641127425852859189,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{D493A670-6D82-5AE9-A2C8-A2EB02684F71}",
+                                    "subId": 284799939
+                                },
+                                "assetHint": "assets/objects/foliage/grass_flower_purple.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[14406733303466080015]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14406733303466080015,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 9231452352781000222
+                        },
+                        {
+                            "ComponentId": 12641127425852859189,
+                            "SortIndex": 1
+                        }
+                    ]
+                },
+                "Component_[1452384341905923012]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 1452384341905923012
+                },
+                "Component_[2215454016415585892]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 2215454016415585892
+                },
+                "Component_[4104108067383423623]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 4104108067383423623
+                },
+                "Component_[4197335450471807917]": {
+                    "$type": "SelectionComponent",
+                    "Id": 4197335450471807917
+                },
+                "Component_[6877680739064997650]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 6877680739064997650
+                },
+                "Component_[7372550507186490390]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 7372550507186490390
+                },
+                "Component_[7673532337364366244]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 7673532337364366244
+                },
+                "Component_[9231452352781000222]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 9231452352781000222,
+                    "Parent Entity": "ContainerEntity"
+                }
+            }
+        }
+    }
+}

+ 3 - 3
AutomatedTesting/Assets/VegDescriptorLists/flower_pink.vegdescriptorlist

@@ -2,11 +2,11 @@
 	<Class name="DescriptorListAsset" type="{60961B36-E3CA-4877-B197-1462C1363F6E}">
 		<Class name="AZStd::vector" field="Descriptors" type="{FC36C5E0-6152-5B06-AF30-3FC494B85FAB}">
 			<Class name="Descriptor" field="element" version="8" type="{A5A5E7F7-FC36-4BD1-8A93-21362574B9DA}">
-				<Class name="AZ::Uuid" field="SpawnerType" value="{BBA5CC1E-B4CA-4792-89F7-93711E98FBD1}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
+				<Class name="AZ::Uuid" field="SpawnerType" value="{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
 				<Class name="AZStd::shared_ptr" field="InstanceSpawner" type="{7C7046DE-F8B1-529D-AD8C-829C6C0E2FCD}">
-					<Class name="DynamicSliceInstanceSpawner" field="element" type="{BBA5CC1E-B4CA-4792-89F7-93711E98FBD1}">
+					<Class name="PrefabInstanceSpawner" field="element" type="{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}">
 						<Class name="InstanceSpawner" field="BaseClass1" type="{01AD0758-B04A-4B43-BC2B-BDCD77F4EF6A}"/>
-						<Class name="Asset" field="SliceAsset" value="id={EBFE34EB-D0A8-5E51-8234-3BE38082B28C}:2,type={78802ABF-9595-463A-8D2B-D022F906F9B1},hint={slices/pinkflower.dynamicslice}" version="1" type="{77A19D40-8731-4D3C-9041-1B43047366A4}"/>
+						<Class name="Asset" field="SpawnableAsset" value="id={80C0CF4E-9A5E-544B-B89E-BC980175A259}:e6f903d2,type={855E3021-D305-4845-B284-20C3F7FDF16B},hint={Assets/Prefabs/PinkFlower.prefab},loadBehavior=1" version="2" type="{77A19D40-8731-4D3C-9041-1B43047366A4}"/>
 					</Class>
 				</Class>
 				<Class name="float" field="Weight" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>

+ 1 - 1
AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py

@@ -5,9 +5,9 @@ For complete copyright and license terms please see the LICENSE at the root of t
 SPDX-License-Identifier: Apache-2.0 OR MIT
 """
 
+import collections.abc
 from typing import List
 from math import isclose
-import collections.abc
 
 import azlmbr.bus as bus
 import azlmbr.editor as editor

+ 3 - 3
AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt

@@ -14,7 +14,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
         NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized
         TEST_SERIAL
         TEST_SUITE main
-        PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main_Optimized.py
+        PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main.py
         RUNTIME_DEPENDENCIES
             AZ::AssetProcessor
             Legacy::Editor
@@ -27,7 +27,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
         NAME AutomatedTesting::DynamicVegetationTests_Periodic_Optimized
         TEST_SERIAL
         TEST_SUITE periodic
-        PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic_Optimized.py
+        PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic.py
         RUNTIME_DEPENDENCIES
             AZ::AssetProcessor
             Legacy::Editor
@@ -58,7 +58,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
         NAME AutomatedTesting::GradientSignalTests_Periodic_Optimized
         TEST_SERIAL
         TEST_SUITE periodic
-        PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal/TestSuite_Periodic_Optimized.py
+        PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal/TestSuite_Periodic.py
         RUNTIME_DEPENDENCIES
             AZ::AssetProcessor
             Legacy::Editor

+ 3 - 7
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude.py

@@ -51,22 +51,18 @@ def AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude():
 
     import os
 
-    import azlmbr.asset as asset
     import azlmbr.editor as editor
     import azlmbr.legacy.general as general
     import azlmbr.bus as bus
     import azlmbr.math as math
-    import azlmbr.prefab as prefab
 
     import editor_python_test_tools.hydra_editor_utils as hydra
-    from editor_python_test_tools.prefab_utils import Prefab
     from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
     from editor_python_test_tools.utils import Report
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("", "Base")
+    hydra.open_base_level()
 
     # Set view of planting area for visual debugging
     general.set_current_view_position(512.0, 500.0, 38.0)
@@ -76,9 +72,9 @@ def AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude():
     center_point = math.Vector3(512.0, 512.0, 32.0)
 
     flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
-    flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "PinkFlower")[0]
+    flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "AltFilter_PinkFlower")[0]
 
-    spawner_entity = dynveg.create_prefab_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0, flower_prefab)
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0, flower_prefab)
 
     # Add a Vegetation Altitude Filter
     spawner_entity.add_component("Vegetation Altitude Filter")

+ 3 - 6
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py

@@ -32,9 +32,7 @@ def AltitudeFilter_FilterStageToggle():
     import os
 
     import azlmbr.legacy.general as general
-    import azlmbr.bus as bus
     import azlmbr.math as math
-    import azlmbr.prefab as prefab
 
     import editor_python_test_tools.hydra_editor_utils as hydra
     from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
@@ -45,17 +43,16 @@ def AltitudeFilter_FilterStageToggle():
     POSTPROCESS_INSTANCE_COUNT = 34
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("", "Base")
+    hydra.open_base_level()
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # Create basic vegetation entity
     position = math.Vector3(512.0, 512.0, 32.0)
 
     flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
-    flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "PinkFlower")[0]
+    flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "AltFilter_PinkFlower2")[0]
 
-    vegetation = dynveg.create_prefab_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, flower_prefab)
+    vegetation = dynveg.create_temp_prefab_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, flower_prefab)
 
     # Add a Vegetation Altitude Filter to the vegetation area entity
     vegetation.add_component("Vegetation Altitude Filter")

+ 3 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude.py

@@ -56,8 +56,7 @@ def AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("", "Base")
+    hydra.open_base_level()
 
     # Set view of planting area for visual debugging
     general.set_current_view_position(512.0, 500.0, 38.0)
@@ -67,9 +66,9 @@ def AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude():
     center_point = math.Vector3(512.0, 512.0, 32.0)
 
     flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
-    flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "PinkFlower")[0]
+    flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "AltFilter_PinkFlower3")[0]
 
-    spawner_entity = dynveg.create_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 16.0, flower_prefab)
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 16.0, flower_prefab)
 
     # Add a Vegetation Altitude Filter
     spawner_entity.add_component("Vegetation Altitude Filter")

+ 32 - 12
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea.py

@@ -56,19 +56,21 @@ def AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea():
     """
 
     import os
+    from pathlib import Path
 
     import azlmbr.bus as bus
     import azlmbr.editor as editor
     import azlmbr.legacy.general as general
     import azlmbr.math as math
     import azlmbr.vegetation as vegetation
+    import azlmbr.prefab as prefab
 
     import editor_python_test_tools.hydra_editor_utils as hydra
     from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
     from editor_python_test_tools.utils import Report
     from editor_python_test_tools.utils import TestHelper as helper
 
-    def create_asset_list_entity(name, center, dynamic_slice_asset_path):
+    def create_asset_list_entity(name, center, target_prefab):
         asset_list_entity = hydra.Entity(name)
         asset_list_entity.create_entity(
             center,
@@ -77,18 +79,34 @@ def AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea():
         if asset_list_entity.id.IsValid():
             print(f"'{asset_list_entity.name}' created")
 
-        # Set the Asset List to a Dynamic Slice spawner with a specific slice asset selected
-        dynamic_slice_spawner = vegetation.DynamicSliceInstanceSpawner()
-        dynamic_slice_spawner.SetSliceAssetPath(dynamic_slice_asset_path)
+        if target_prefab:
+            # Get the in-memory spawnable asset id if exists
+            spawnable_name = Path(target_prefab.file_path).stem
+            spawnable_asset_id = prefab.PrefabPublicRequestBus(bus.Broadcast, 'GetInMemorySpawnableAssetId',
+                                                               spawnable_name)
+
+            # Create the in-memory spawnable asset from given prefab if the spawnable does not exist
+            if not spawnable_asset_id.is_valid():
+                create_spawnable_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'CreateInMemorySpawnableAsset',
+                                                                        target_prefab.file_path,
+                                                                        spawnable_name)
+                assert create_spawnable_result.IsSuccess(), \
+                    f"Prefab operation 'CreateInMemorySpawnableAssets' failed. Error: {create_spawnable_result.GetError()}"
+                spawnable_asset_id = create_spawnable_result.GetValue()
+        else:
+            spawnable_asset_id = None
+
+        # Set the vegetation area to a prefab instance spawner with a specific prefab asset selected
         descriptor = hydra.get_component_property_value(asset_list_entity.components[0],
-                                                        "Configuration|Embedded Assets|[0]")
-        descriptor.spawner = dynamic_slice_spawner
+                                                        'Configuration|Embedded Assets|[0]')
+        prefab_spawner = vegetation.PrefabInstanceSpawner()
+        prefab_spawner.SetPrefabAssetId(spawnable_asset_id)
+        descriptor.spawner = prefab_spawner
         asset_list_entity.get_set_test(0, "Configuration|Embedded Assets|[0]", descriptor)
         return asset_list_entity
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Set view of planting area for visual debugging
     general.set_current_view_position(512.0, 500.0, 38.0)
@@ -96,11 +114,13 @@ def AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea():
 
     # 2) Create 3 entities with Vegetation Asset List components set to spawn different descriptors
     center_point = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    asset_path2 = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    asset_list_entity = create_asset_list_entity("Asset List 1", center_point, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "AssetList_PinkFlower")[0]
+    purple_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    purple_flower_prefab = dynveg.create_temp_mesh_prefab(purple_flower_asset_path, "AssetList_PurpleFlower")[0]
+    asset_list_entity = create_asset_list_entity("Asset List 1", center_point, pink_flower_prefab)
     asset_list_entity2 = create_asset_list_entity("Asset List 2", center_point, None)
-    asset_list_entity3 = create_asset_list_entity("Asset List 3", center_point, asset_path2)
+    asset_list_entity3 = create_asset_list_entity("Asset List 3", center_point, purple_flower_prefab)
 
     # 3) Create a planting surface and add a Vegetation System Settings level component with instances set to spawn
     # on center instead of corner

+ 6 - 6
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AssetWeightSelector_InstancesExpressBasedOnWeight.py

@@ -56,8 +56,7 @@ def AssetWeightSelector_InstancesExpressBasedOnWeight():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Set view of planting area for visual debugging
     general.set_current_view_position(512.0, 500.0, 38.0)
@@ -66,14 +65,15 @@ def AssetWeightSelector_InstancesExpressBasedOnWeight():
     # 2) Create a new instance spawner entity with multiple Dynamic Slice Instance Spawner descriptors, one set to a
     # valid slice entity, and one set to None
     spawner_center_point = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
-                                                                               asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "AssetWeight_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
+                                                               pink_flower_prefab)
     desc_asset = hydra.get_component_property_value(spawner_entity.components[2],
                                                     "Configuration|Embedded Assets")[0]
     desc_list = [desc_asset, desc_asset]
     spawner_entity.get_set_test(2, "Configuration|Embedded Assets", desc_list)
-    spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[1]|Instance|Slice Asset", None)
+    spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[1]|Instance|Prefab Asset", None)
 
     # Add an Asset Weight Selector component to the spawner entity
     spawner_entity.add_component("Vegetation Asset Weight Selector")

+ 5 - 6
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py

@@ -64,16 +64,15 @@ def DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius():
     instance_query_point_c = math.Vector3(515.0, 512.5, 32.0)
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
-
+    hydra.open_base_level()
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # 2) Create a new entity with required vegetation area components
     spawner_center_point = math.Vector3(520.0, 520.0, 32.0)
-    asset_path = os.path.join("Slices", "1m_cube.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
-                                                                               asset_path)
+    cube_asset_path = os.path.join("testdata", "multi-mat_fbx", "multi-mat_1m_cube.azmodel")
+    cube_prefab = dynveg.create_temp_mesh_prefab(cube_asset_path, "DistanceBetween_1m_cube2")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
+                                                               cube_prefab)
 
     # 3) Create a surface to plant on
     surface_center_point = math.Vector3(512.0, 512.0, 32.0)

+ 5 - 6
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py

@@ -62,16 +62,15 @@ def DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius():
     instance_query_point_c = math.Vector3(515.0, 512.5, 32.0)
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
-
+    hydra.open_base_level()
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # 2) Create a new entity with required vegetation area components
     spawner_center_point = math.Vector3(520.0, 520.0, 32.0)
-    asset_path = os.path.join("Slices", "1m_cube.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
-                                                                               asset_path)
+    cube_asset_path = os.path.join("testdata", "multi-mat_fbx", "multi-mat_1m_cube.azmodel")
+    cube_prefab = dynveg.create_temp_mesh_prefab(cube_asset_path, "DistanceBetween_1m_cube")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point,
+                                                               16.0, 16.0, 16.0, cube_prefab)
 
     # 3) Create a surface to plant on
     surface_center_point = math.Vector3(512.0, 512.0, 32.0)

+ 5 - 5
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py

@@ -39,11 +39,11 @@ def DynVegUtils_TempPrefabCreationWorks():
     with Tracer() as error_tracer:
         # Create dictionary for prefab filenames and paths to create using helper function
         mesh_prefabs = {
-            "PinkFlower": os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel"),
-            "PurpleFlower": os.path.join("assets", "objects", "foliage", "grass_flower_purple.azmodel"),
-            "1m_Cube": os.path.join("objects", "_primitives", "_box_1x1.azmodel"),
-            "CedarTree": os.path.join("assets", "objects", "foliage", "cedar.azmodel"),
-            "Bush": os.path.join("assets", "objects", "foliage", "bush_privet_01.azmodel"),
+            "UtilsTest_PinkFlower": os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel"),
+            "UtilsTest_PurpleFlower": os.path.join("assets", "objects", "foliage", "grass_flower_purple.azmodel"),
+            "UtilsTest_1m_Cube": os.path.join("objects", "_primitives", "_box_1x1.azmodel"),
+            "UtilsTest_CedarTree": os.path.join("assets", "objects", "foliage", "cedar.azmodel"),
+            "UtilsTest_Bush": os.path.join("assets", "objects", "foliage", "bush_privet_01.azmodel"),
                    }
 
         # 1) Open an existing simple level

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks.py

@@ -71,8 +71,7 @@ def DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # Grab the UUID that we need for creating an Dynamic Slice Instance Spawner

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/EmptyInstanceSpawner_EmptySpawnerWorks.py

@@ -57,8 +57,7 @@ def EmptyInstanceSpawner_EmptySpawnerWorks():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # Grab the UUID that we need for creating an Empty Spawner

+ 5 - 5
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/InstanceSpawnerPriority_LayerAndSubPriority.py

@@ -60,8 +60,7 @@ def InstanceSpawnerPriority_LayerAndSubPriority():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Set view of planting area for visual debugging
     general.set_current_view_position(512.0, 500.0, 38.0)
@@ -69,9 +68,10 @@ def InstanceSpawnerPriority_LayerAndSubPriority():
 
     # 2) Create overlapping areas: 1 instance spawner area, and 1 blocker area
     spawner_center_point = math.Vector3(508.0, 508.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 1.0,
-                                                                               asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "Priority_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 1.0,
+                                                               pink_flower_prefab)
     blocker_center_point = math.Vector3(516.0, 516.0, 32.0)
     blocker_entity = dynveg.create_blocker_area("Instance Blocker", blocker_center_point, 16.0, 16.0, 1.0)
 

+ 13 - 18
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py

@@ -85,18 +85,14 @@ def LayerBlender_E2E_Editor():
 
     # 2) Create 2 vegetation areas with different meshes
     purple_position = math.Vector3(504.0, 512.0, 32.0)
-    purple_asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    spawner_entity_1 = dynveg.create_dynamic_slice_vegetation_area("Purple Spawner",
-                                                                                 purple_position,
-                                                                                 16.0, 16.0, 1.0,
-                                                                                 purple_asset_path)
+    purple_flower_prefab_path = os.path.join("assets", "prefabs", "PurpleFlower.spawnable")
+    spawner_entity_1 = dynveg.create_prefab_vegetation_area("Purple Spawner", purple_position, 16.0, 16.0, 1.0,
+                                                            purple_flower_prefab_path)
 
     pink_position = math.Vector3(520.0, 512.0, 32.0)
-    pink_asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity_2 = dynveg.create_dynamic_slice_vegetation_area("Pink Spawner",
-                                                                                 pink_position,
-                                                                                 16.0, 16.0, 1.0,
-                                                                                 pink_asset_path)
+    pink_flower_prefab_path = os.path.join("assets", "prefabs", "PinkFlower.spawnable")
+    spawner_entity_2 = dynveg.create_prefab_vegetation_area("Pink Spawner", pink_position, 16.0, 16.0, 1.0,
+                                                            pink_flower_prefab_path)
 
     base_position = math.Vector3(512.0, 512.0, 32.0)
     dynveg.create_surface_entity("Surface Entity",
@@ -135,11 +131,11 @@ def LayerBlender_E2E_Editor():
     pink_count = 0
     purple_count = 0
     for instance in instances:
-        purple_asset_path = purple_asset_path.replace("\\", "/").lower()
-        pink_asset_path = pink_asset_path.replace("\\", "/").lower()
-        if instance.descriptor.spawner.GetSliceAssetPath() == pink_asset_path:
+        purple_flower_prefab_path = purple_flower_prefab_path.replace("\\", "/").lower()
+        pink_flower_prefab_path = pink_flower_prefab_path.replace("\\", "/").lower()
+        if instance.descriptor.spawner.GetPrefabAssetPath() == pink_flower_prefab_path:
             pink_count += 1
-        elif instance.descriptor.spawner.GetSliceAssetPath() == purple_asset_path:
+        elif instance.descriptor.spawner.GetPrefabAssetPath() == purple_flower_prefab_path:
             purple_count += 1
     Report.result(Tests.instances_blended, pink_count == purple_count and (pink_count + purple_count == num_expected))
 
@@ -152,11 +148,10 @@ def LayerBlender_E2E_Editor():
     components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
     azlmbr.components.TransformBus(bus.Event, "SetLocalRotation", search_entity_ids[0], cam_rot_degrees_vector)
 
-    # 6) Save and export to engine
+    # 6) Save the created level
     general.save_level()
-    general.export_to_engine()
-    pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
-    success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
+    level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable")
+    success = helper.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0)
     Report.result(Tests.saved_and_exported, success)
 
 

+ 5 - 6
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlocker_InstancesBlockedInConfiguredArea.py

@@ -17,7 +17,6 @@ class Tests:
     )
 
 
-
 def LayerBlocker_InstancesBlockedInConfiguredArea():
     """
     Summary:
@@ -58,8 +57,7 @@ def LayerBlocker_InstancesBlockedInConfiguredArea():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Set view of planting area for visual debugging
     general.set_current_view_position(512.0, 500.0, 38.0)
@@ -67,9 +65,10 @@ def LayerBlocker_InstancesBlockedInConfiguredArea():
 
     # 2) Create a new instance spawner entity
     spawner_center_point = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
-                                                                               asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "Blocker_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point,
+                                                               16.0, 16.0, 16.0, pink_flower_prefab)
 
     # 3) Create surface for planting on
     dynveg.create_surface_entity("Surface Entity", spawner_center_point, 32.0, 32.0, 1.0)

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py

@@ -42,16 +42,17 @@ def LayerSpawner_FilterStageToggle():
     POSTPROCESS_INSTANCE_COUNT = 19
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(500.49, 498.69, 46.66)
     general.set_current_view_rotation(-42.05, 0.00, -36.33)
 
     # Create a vegetation area with all needed components
     position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    vegetation_entity = dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerFilter_PinkFlower")[0]
+    vegetation_entity = dynveg.create_temp_prefab_vegetation_area("vegetation", position, 16.0, 16.0, 16.0,
+                                                                  pink_flower_prefab)
     vegetation_entity.add_component("Vegetation Altitude Filter")
     vegetation_entity.add_component("Vegetation Position Modifier")
 

+ 13 - 12
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InheritBehaviorFlag.py

@@ -42,19 +42,16 @@ def LayerSpawner_InheritBehaviorFlag():
 
     SURFACE_TAG = "test_tag"
 
-    def set_dynamic_slice_asset(entity_obj, component_index, dynamic_slice_asset_path):
-        dynamic_slice_spawner = vegetation.DynamicSliceInstanceSpawner()
-        dynamic_slice_spawner.SetSliceAssetPath(dynamic_slice_asset_path)
-        descriptor = hydra.get_component_property_value(
-            entity_obj.components[component_index], "Configuration|Embedded Assets|[0]"
-        )
-        descriptor.spawner = dynamic_slice_spawner
+    def set_prefab_asset(entity_obj, component_index, spawnable_prefab):
+        descriptor = hydra.get_component_property_value(entity_obj.components[component_index],
+                                                        "Configuration|Embedded Assets|[0]")
+        prefab_spawner = vegetation.PrefabInstanceSpawner()
+        prefab_spawner.SetPrefabAssetId(spawnable_prefab)
+        descriptor.spawner = prefab_spawner
         entity_obj.get_set_test(2, "Configuration|Embedded Assets|[0]", descriptor)
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
-
+    hydra.open_base_level()
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # Create Emitter entity and add the required components
@@ -80,7 +77,9 @@ def LayerSpawner_InheritBehaviorFlag():
     veg_1.create_entity(
         position, ["Vegetation Layer Spawner", "Shape Reference", "Vegetation Asset List"]
     )
-    set_dynamic_slice_asset(veg_1, 2, os.path.join("Slices", "PinkFlower.dynamicslice"))
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerInheritBehavior_PinkFlower")[0]
+    set_prefab_asset(veg_1, 2, pink_flower_prefab)
     veg_1.get_set_test(1, "Configuration|Shape Entity Id", blender_entity.id)
 
     # Create second vegetation area and assign a valid asset
@@ -88,7 +87,9 @@ def LayerSpawner_InheritBehaviorFlag():
     veg_2.create_entity(
         position, ["Vegetation Layer Spawner", "Shape Reference", "Vegetation Asset List"]
     )
-    set_dynamic_slice_asset(veg_2, 2, os.path.join("Slices", "PurpleFlower.dynamicslice"))
+    purple_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    purple_flower_prefab = dynveg.create_temp_mesh_prefab(purple_flower_asset_path, "temp_PurpleFlower")[0]
+    set_prefab_asset(veg_2, 2, purple_flower_prefab)
     veg_2.get_set_test(1, "Configuration|Shape Entity Id", blender_entity.id)
 
     # Assign the vegetation areas to the Blender entity

+ 5 - 7
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesPlantInAllSupportedShapes.py

@@ -56,16 +56,14 @@ def LayerSpawner_InstancesPlantInAllSupportedShapes():
         Report.result(success, result)
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # 2) Create basic vegetation area entity and set the properties
     entity_position = math.Vector3(125.0, 136.0, 32.0)
-    asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    vegetation = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner",
-                                                                           entity_position,
-                                                                           10.0, 10.0, 10.0,
-                                                                           asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerShapePlant_PinkFlower")[0]
+    vegetation = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0,
+                                                           pink_flower_prefab)
     vegetation.remove_component("Box Shape")
     vegetation.add_component("Shape Reference")
 

+ 8 - 7
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py

@@ -43,13 +43,13 @@ def LayerSpawner_InstancesRefreshUsingCorrectViewportCamera():
     import azlmbr.legacy.general as general
     import azlmbr.math as math
 
+    import editor_python_test_tools.hydra_editor_utils as hydra
     from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
     from editor_python_test_tools.utils import Report
     from editor_python_test_tools.utils import TestHelper as helper
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Set up a test environment to validate that switching viewports correctly changes which camera
     # the vegetation system uses.
@@ -100,11 +100,12 @@ def LayerSpawner_InstancesRefreshUsingCorrectViewportCamera():
                                                          surface_height)
 
     # Create the two vegetation areas
-    test_slice_asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    first_veg_entity = dynveg.create_dynamic_slice_vegetation_area("Veg Area 1", first_entity_center_point, box_size, box_size,
-                                                                                 box_size, test_slice_asset_path)
-    second_veg_entity = dynveg.create_dynamic_slice_vegetation_area("Veg Area 2", second_entity_center_point, box_size, box_size,
-                                                                                  box_size, test_slice_asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerViewportRefresh_PinkFlower")[0]
+    first_veg_entity = dynveg.create_temp_prefab_vegetation_area("Veg Area 1", first_entity_center_point, box_size, box_size,
+                                                                 box_size, pink_flower_prefab)
+    second_veg_entity = dynveg.create_temp_prefab_vegetation_area("Veg Area 2", second_entity_center_point, box_size, box_size,
+                                                                  box_size, pink_flower_prefab)
 
     # When the first viewport is active, the first area should be full of instances, and the second should be empty
     general.set_active_viewport(0)

+ 5 - 7
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py

@@ -50,19 +50,17 @@ def MeshBlocker_InstancesBlockedByMesh():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(500.49, 498.69, 46.66)
     general.set_current_view_rotation(-42.05, 0.00, -36.33)
 
     # Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
     entity_position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner",
-                                                                               entity_position,
-                                                                               10.0, 10.0, 10.0,
-                                                                               asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "MeshBlocker_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0,
+                                                               pink_flower_prefab)
 
     # Create surface entity to plant on
     dynveg.create_surface_entity("Surface Entity", entity_position, 10.0, 10.0, 1.0)

+ 5 - 7
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py

@@ -53,19 +53,17 @@ def MeshBlocker_InstancesBlockedByMeshHeightTuning():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(500.49, 498.69, 46.66)
     general.set_current_view_rotation(-42.05, 0.00, -36.33)
 
     # 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
     entity_position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner",
-                                                                               entity_position,
-                                                                               10.0, 10.0, 10.0,
-                                                                               asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "MeshBlocker_PinkFlower2")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0,
+                                                               pink_flower_prefab)
 
     # 3) Create surface entity to plant on
     dynveg.create_surface_entity("Surface Entity", entity_position, 10.0, 10.0, 1.0)

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_DependentOnMeshComponent.py

@@ -58,8 +58,7 @@ def MeshSurfaceTagEmitter_DependentOnMeshComponent():
         return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # 2) Create a new entity with component "Mesh Surface Tag Emitter"
     entity_position = math.Vector3(125.0, 136.0, 32.0)

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py

@@ -47,8 +47,7 @@ def MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     #  2) Create a new entity with components "Mesh Surface Tag Emitter", "Mesh"
     entity_position = math.Vector3(125.0, 136.0, 32.0)

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PhysXColliderSurfaceTagEmitter_E2E_Editor.py

@@ -55,8 +55,7 @@ def PhysXColliderSurfaceTagEmitter_E2E_Editor():
         return behavior_context_test_success
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Verify all of the BehaviorContext API:
     behavior_context = (
@@ -90,8 +89,10 @@ def PhysXColliderSurfaceTagEmitter_E2E_Editor():
     dynveg.create_surface_entity("Baseline Surface", entity_center_point, 32.0, 32.0, 1.0)
 
     # Create a new entity with required vegetation area components
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Veg Area", entity_center_point, 32.0, 32.0, 32.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "PhysXCollider_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_center_point, test_box_size,
+                                                               test_box_size, test_box_size, pink_flower_prefab)
 
     # Add a Vegetation Surface Mask Filter component to the spawner entity and set it to include the "test" tag
     spawner_entity.add_component("Vegetation Surface Mask Filter")

+ 5 - 5
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_AutoSnapToSurfaceWorks.py

@@ -64,8 +64,7 @@ def PositionModifier_AutoSnapToSurfaceWorks():
                                'Configuration|Position Z|Range Min', 'Configuration|Position Z|Range Max']
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Set view of planting area for visual debugging
     general.set_current_view_position(512.0, 500.0, 38.0)
@@ -73,9 +72,10 @@ def PositionModifier_AutoSnapToSurfaceWorks():
 
     # 2) Create a new entity with required vegetation area components and a Position Modifier
     spawner_center_point = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
-                                                                               asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "PosMod_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0,
+                                                               16.0, pink_flower_prefab)
 
     # Add a Vegetation Position Modifier and set offset values to 0
     spawner_entity.add_component("Vegetation Position Modifier")

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets.py

@@ -102,16 +102,17 @@ def PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets():
         return offset_success and offset_success2
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Set view of planting area for visual debugging
     general.set_current_view_position(16.0, -5.0, 32.0)
 
     # 2) Create a new entity with required vegetation area components
     spawner_center_point = math.Vector3(16.0, 16.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 1.0, 1.0, 1.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "PosMod_PinkFlower2")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 1.0, 1.0,
+                                                               1.0, pink_flower_prefab)
 
     # Add a Vegetation Position Modifier and set offset values to 0
     spawner_entity.add_component("Vegetation Position Modifier")

+ 9 - 7
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py → AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PrefabInstanceSpawner_Embedded_E2E.py

@@ -63,12 +63,14 @@ def DynamicSliceInstanceSpawner_Embedded_E2E():
     import azlmbr.entity as entity
     import azlmbr.math as math
     import azlmbr.paths as paths
+    import azlmbr.vegetation as vegetation
 
     import editor_python_test_tools.hydra_editor_utils as hydra
     from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
     from editor_python_test_tools.utils import Report
     from editor_python_test_tools.utils import TestHelper as helper
 
+
     # 1) Create a new, temporary level
     lvl_name = "tmp_level"
     helper.init_idle()
@@ -79,13 +81,14 @@ def DynamicSliceInstanceSpawner_Embedded_E2E():
 
     # 2) Create a new entity with required vegetation area components and Script Canvas component for launcher test
     center_point = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0, asset_path)
+    pink_flower_prefab_path = os.path.join("assets", "prefabs", "PinkFlower.spawnable")
+    spawner_entity = dynveg.create_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0,
+                                                          pink_flower_prefab_path)
     spawner_entity.add_component("Script Canvas")
     instance_counter_path = os.path.join("scriptcanvas", "instance_counter.scriptcanvas")
     instance_counter_script = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", instance_counter_path,
                                                            math.Uuid(), False)
-    spawner_entity.get_set_test(3, "Script Canvas Asset|Script Canvas Asset", instance_counter_script)
+    spawner_entity.get_set_test(3, "Properties", instance_counter_script)
     Report.result(Tests.spawner_entity_created, spawner_entity.id.IsValid() and hydra.has_components(spawner_entity.id,
                                                                                                      ["Script Canvas"]))
 
@@ -106,11 +109,10 @@ def DynamicSliceInstanceSpawner_Embedded_E2E():
     search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
     components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
 
-    # 6) Save and export to engine
+    # 6) Save the created level
     general.save_level()
-    general.export_to_engine()
-    pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
-    success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
+    level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable")
+    success = helper.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0)
     Report.result(Tests.saved_and_exported, success)
 
 

+ 3 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py → AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/PrefabInstanceSpawner_External_E2E.py

@@ -128,11 +128,10 @@ def DynamicSliceInstanceSpawner_External_E2E():
     search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
     components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
 
-    # 6) Save and export to engine
+    # 6) Save the created level
     general.save_level()
-    general.export_to_engine()
-    pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
-    success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
+    level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable")
+    success = helper.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0)
     Report.result(Tests.saved_and_exported, success)
 
 

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifierOverrides_InstancesRotateWithinRange.py

@@ -81,14 +81,15 @@ def RotationModifierOverrides_InstancesRotateWithinRange():
         return result
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # 2) Create vegetation entity and add components
     entity_position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", entity_position, 16.0, 16.0, 16.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "RotMod_PinkFlower2")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 16.0, 16.0, 16.0,
+                                                               pink_flower_prefab)
     spawner_entity.add_component("Vegetation Rotation Modifier")
     # Our default vegetation settings places 20 instances per 16 meters, so we expect 20 * 20 total instances.
     num_expected = 20 * 20

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/RotationModifier_InstancesRotateWithinRange.py

@@ -120,13 +120,14 @@ def RotationModifier_InstancesRotateWithinRange():
 
     # Main Script
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # 2) Set up vegetation entities
-    asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", LEVEL_CENTER, 2.0, 2.0, 2.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "RotMod_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", LEVEL_CENTER, 2.0, 2.0, 2.0,
+                                                               pink_flower_prefab)
 
     additional_components = [
         "Vegetation Rotation Modifier"

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifierOverrides_InstancesProperlyScale.py

@@ -91,16 +91,17 @@ def ScaleModifierOverrides_InstancesProperlyScale():
         return False
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(500.49, 498.69, 46.66)
     general.set_current_view_rotation(-42.05, 0.00, -36.33)
 
     # 2) Create a new entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
     entity_position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", entity_position, 16.0, 16.0, 10.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ScaleMod_PinkFlower2")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 16.0, 16.0, 16.0,
+                                                               pink_flower_prefab)
 
     # Create a surface to plant on and add a Vegetation Debugger Level component to allow refreshes
     dynveg.create_surface_entity("Surface Entity", entity_position, 20.0, 20.0, 1.0)

+ 5 - 5
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ScaleModifier_InstancesProperlyScale.py

@@ -84,8 +84,7 @@ def ScaleModifier_InstancesProperlyScale():
         return False
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(500.49, 498.69, 46.66)
     general.set_current_view_rotation(-42.05, 0.00, -36.33)
@@ -93,9 +92,10 @@ def ScaleModifier_InstancesProperlyScale():
     # 2) Create a new entity with components Vegetation Layer Spawner, Vegetation Asset List, Box Shape and
     # Vegetation Scale Modifier
     entity_position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", entity_position, 16.0, 16.0, 16.0,
-                                                                               asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ScaleMod_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 16.0, 16.0, 16.0,
+                                                               pink_flower_prefab)
     spawner_entity.add_component("Vegetation Scale Modifier")
 
     # Create a surface to plant on and add a Vegetation Debugger Level component to allow refreshes

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py

@@ -49,15 +49,16 @@ def ShapeIntersectionFilter_FilterStageToggle():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # Create basic vegetation entity
     position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    vegetation = dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ShapeIntersection_PinkFlower")[0]
+    vegetation = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", position, 16.0, 16.0, 16.0,
+                                                           pink_flower_prefab)
 
     # Create Surface for instances to plant on
     dynveg.create_surface_entity("Surface_Entity_Parent", position, 16.0, 16.0, 1.0)

+ 5 - 5
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_InstancesPlantInAssignedShape.py

@@ -60,8 +60,7 @@ def ShapeIntersectionFilter_InstancesPlantInAssignedShape():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Set view of planting area for visual debugging
     general.set_current_view_position(512.0, 500.0, 38.0)
@@ -69,9 +68,10 @@ def ShapeIntersectionFilter_InstancesPlantInAssignedShape():
 
     # 2) Create a new entity with required vegetation area components and Vegetation Shape Intersection Filter
     center_point = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0,
-                                                                               asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ShapeIntersection_PinkFlower2")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0,
+                                                               pink_flower_prefab)
     spawner_entity.add_component("Vegetation Shape Intersection Filter")
 
     # Create a planting surface

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment.py

@@ -58,15 +58,16 @@ def SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment():
         return False
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # Create a spawner entity setup with all needed components
     center_point = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SlopeAlign_PinkFlower2")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0,
+                                                               pink_flower_prefab)
 
     # Create a sloped mesh surface for the instances to plant on
     center_point = math.Vector3(502.0, 512.0, 24.0)

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeAlignmentModifier_InstanceSurfaceAlignment.py

@@ -59,15 +59,16 @@ def SlopeAlignmentModifier_InstanceSurfaceAlignment():
         return False
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # Create a spawner entity setup with all needed components
     center_point = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SlopeAlign_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0,
+                                                               pink_flower_prefab)
 
     # Create a sloped mesh surface for the instances to plant on
     center_point = math.Vector3(502.0, 512.0, 24.0)

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope.py

@@ -63,16 +63,17 @@ def SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Set view of planting area for visual debugging
     general.set_current_view_position(512.0, 475.0, 38.0)
 
     # 2) Create a new entity with required vegetation area components
     center_point = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "Slope_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0,
+                                                               pink_flower_prefab)
 
     # Add a Vegetation Slope Filter
     spawner_entity.add_component("Vegetation Slope Filter")

+ 37 - 42
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerSlices_SliceCreationAndVisibilityToggleWorks.py → AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SpawnerPrefabs_PrefabCreationAndVisibilityToggleWorks.py

@@ -7,21 +7,21 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
 
 
 class Tests:
-    spawner_slice_created = (
-        "Spawner slice created successfully",
-        "Failed to create Spawner slice"
+    spawner_prefab_created = (
+        "Spawner prefab created successfully",
+        "Failed to create Spawner prefab"
     )
     instance_count_unhidden = (
         "Initial instance counts are as expected",
         "Found an unexpected number of initial instances"
     )
     instance_count_hidden = (
-        "Instance counts upon hiding the Spawner slice are as expected",
-        "Unexpectedly found instances with the Spawner slice hidden"
+        "Instance counts upon hiding the Spawner prefab are as expected",
+        "Unexpectedly found instances with the Spawner prefab hidden"
     )
-    blender_slice_created = (
-        "Blender slice created successfully",
-        "Failed to create Blender slice"
+    blender_prefab_created = (
+        "Blender prefab created successfully",
+        "Failed to create Blender prefab"
     )
 
 
@@ -43,81 +43,76 @@ def SpawnerSlices_SliceCreationAndVisibilityToggleWorks():
 
     import azlmbr.math as math
     import azlmbr.legacy.general as general
-    import azlmbr.slice as slice
     import azlmbr.bus as bus
     import azlmbr.editor as editor
-    import azlmbr.asset as asset
 
     import editor_python_test_tools.hydra_editor_utils as hydra
     from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
+    from editor_python_test_tools.editor_entity_utils import EditorEntity
     from editor_python_test_tools.utils import Report
     from editor_python_test_tools.utils import TestHelper as helper
-
-    def path_is_valid_asset(asset_path):
-        asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False)
-        return asset_id.invoke("IsValid")
+    from editor_python_test_tools.prefab_utils import Prefab
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
     general.set_current_view_position(512.0, 480.0, 38.0)
 
-    # 2) C2627900 Verifies if a slice containing the Vegetation Layer Spawner component can be created.
+    # 2) Verifies if a prefab containing the Vegetation Layer Spawner component can be created.
     # 2.1) Create basic vegetation entity
     position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    veg_1 = dynveg.create_dynamic_slice_vegetation_area("vegetation_1", position, 16.0, 16.0, 16.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerPrefab_PinkFlower")[0]
+    veg_1 = dynveg.create_temp_prefab_vegetation_area("vegetation_1", position, 16.0, 16.0, 16.0,
+                                                      pink_flower_prefab)
 
-    # 2.2) Create slice from the entity
-    slice_path = os.path.join("slices", "TestSlice_1.slice")
-    slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", veg_1.id, slice_path)
+    # 2.2) Create prefab from the entity
+    spawner_prefab_filename = "TestPrefab_1"
+    spawner_prefab, spawner_prefab_instance = Prefab.create_prefab([veg_1], spawner_prefab_filename)
 
-    # 2.3) Verify if the slice has been created successfully
-    spawner_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 10.0)
-    Report.result(Tests.spawner_slice_created, spawner_slice_success)
+    # Verify if prefab is created
+    Report.result(Tests.spawner_prefab_created, spawner_prefab.is_prefab_loaded(spawner_prefab_filename))
 
-    # 3) C2627904: Hiding a slice containing the component clears any visuals from the Viewport
+    # 3) Hiding a prefab containing the component clears any visuals from the Viewport
     # 3.1) Create Surface for instances to plant on
     dynveg.create_surface_entity("Surface_Entity", position, 16.0, 16.0, 1.0)
 
-    # 3.2) Initially verify instance count before hiding slice
+    # 3.2) Initially verify instance count before hiding prefab
     initial_count_success = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 16.0, 400), 5.0)
     Report.result(Tests.instance_count_unhidden, initial_count_success)
 
-    # 3.3) Hide the slice and verify instance count
-    editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", veg_1.id, False)
+    # 3.3) Hide the prefab and verify instance count
+    editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", spawner_prefab_instance.container_entity.id, False)
     hidden_instance_count = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 16.0, 0), 5.0)
     Report.result(Tests.instance_count_hidden, hidden_instance_count)
 
     # 3.4) Unhide the slice
-    editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", veg_1.id, True)
+    editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", spawner_prefab_instance.container_entity.id, True)
 
-    # 4) C2627905 A slice containing the Vegetation Layer Blender component can be created.
+    # 4) A slice containing the Vegetation Layer Blender component can be created.
     # 4.1) Create another vegetation entity to add to blender component
-    veg_2 = dynveg.create_dynamic_slice_vegetation_area("vegetation_2", position, 1.0, 1.0, 1.0, "")
+    veg_2 = dynveg.create_empty_vegetation_area("vegetation_2", position, 1.0, 1.0, 1.0)
 
     # 4.2) Create entity with Vegetation Layer Blender
     components_to_add = ["Box Shape", "Vegetation Layer Blender"]
-    blender_entity = hydra.Entity("blender_entity")
-    blender_entity.create_entity(position, components_to_add)
+    blender_entity = EditorEntity.create_editor_entity("blender_entity")
+    blender_entity.add_components(components_to_add)
 
     # 4.3) Pin both the vegetation areas to the blender entity
-    pte = hydra.get_property_tree(blender_entity.components[1])
+    pte = blender_entity.components[1].get_property_tree()
     path = "Configuration|Vegetation Areas"
     pte.update_container_item(path, 0, veg_1.id)
     pte.add_container_item(path, 1, veg_2.id)
 
     # 4.4) Drag the simple vegetation areas under the Vegetation Layer Blender entity to create an entity hierarchy.
     veg_1.set_test_parent_entity(blender_entity)
-    veg_2.set_test_parent_entity(blender_entity)
+    veg_2.set_parent_entity(blender_entity.id)
 
-    # 4.5) Create slice from blender entity
-    slice_path = os.path.join("slices", "TestSlice_2.slice")
-    slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", blender_entity.id, slice_path)
+    # 4.5) Create prefab from blender entity
+    blender_prefab_filename = "TestPrefab_2"
+    blender_prefab, blender_prefab_instance = Prefab.create_prefab([veg_2], blender_prefab_filename)
 
-    # 4.6) Verify if the slice has been created successfully
-    blender_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0)
-    Report.result(Tests.blender_slice_created, blender_slice_success)
+    # 4.6) Verify if the prefab has been created successfully
+    Report.result(Tests.blender_prefab_created, blender_prefab.is_prefab_loaded(blender_prefab_filename))
 
 
 if __name__ == "__main__":

+ 2 - 3
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceDataRefreshes_RemainsStable.py

@@ -34,13 +34,12 @@ def SurfaceDataRefreshes_RemainsStable():
     import azlmbr.legacy.general as general
     import azlmbr.math as math
 
+    import editor_python_test_tools.hydra_editor_utils as hydra
     from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
     from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     world_center = math.Vector3(512.0, 512.0, 32.0)
 

+ 5 - 5
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected.py

@@ -67,8 +67,7 @@ def SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected():
                         surface_data.SurfaceTag("test_tag3")]
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Set view of planting area for visual debugging
     general.set_current_view_position(512.0, 500.0, 38.0)
@@ -76,9 +75,10 @@ def SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected():
 
     # 2) Create a new instance spawner entity with multiple Dynamic Slice Instance Spawner descriptors
     spawner_center_point = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
-                                                                               asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SurfaceMaskOverrides_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0,
+                                                               16.0, pink_flower_prefab)
     asset_list_component = spawner_entity.components[2]
     desc_asset = hydra.get_component_property_value(asset_list_component,
                                                     "Configuration|Embedded Assets")[0]

+ 3 - 3
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_BasicSurfaceTagCreation.py

@@ -39,12 +39,12 @@ def SurfaceMaskFilter_BasicSurfaceTagCreation():
     """
 
     import azlmbr.surface_data as surface_data
+
+    import editor_python_test_tools.hydra_editor_utils as hydra
     from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     tag1 = surface_data.SurfaceTag()
     tag2 = surface_data.SurfaceTag()

+ 5 - 7
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_ExclusionList.py

@@ -91,18 +91,16 @@ def SurfaceMaskFilter_ExclusionList():
             Report.info(f"Failed to add Generated surface tag of {surface_tag}")
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
     entity_position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner",
-                                                                               entity_position,
-                                                                               10.0, 10.0, 10.0,
-                                                                               asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SurfaceMaskTagExclusion_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0,
+                                                               pink_flower_prefab)
 
     # 3) Add a Vegetation Surface Mask Filter component to the entity.
     spawner_entity.add_component("Vegetation Surface Mask Filter")

+ 5 - 7
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_InclusionList.py

@@ -92,18 +92,16 @@ def SurfaceMaskFilter_InclusionList():
             Report.info(f"Failed to add Generated surface tag of {surface_tag}")
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
     entity_position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner",
-                                                                               entity_position,
-                                                                               10.0, 10.0, 10.0,
-                                                                               asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SurfaceMaskTagInclusion_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0,
+                                                               pink_flower_prefab)
 
     # 3) Add a Vegetation Surface Mask Filter component to the entity.
     spawner_entity.add_component("Vegetation Surface Mask Filter")

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorPointDensity.py

@@ -47,15 +47,16 @@ def SystemSettings_SectorPointDensity():
     INSTANCE_COUNT_AFTER_DENSITY_CHANGE = 100
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # Create basic vegetation entity
     position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 1.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SectorPoint_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", position, 16.0, 16.0, 1.0,
+                                                               pink_flower_prefab)
     dynveg.create_surface_entity("Surface_Entity", position, 16.0, 16.0, 1.0)
 
     # Count the number of vegetation instances in the vegetation area

+ 5 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SystemSettings_SectorSize.py

@@ -43,15 +43,16 @@ def SystemSettings_SectorSize():
     VEGETATION_INSTANCE_COUNT = 400
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     general.set_current_view_position(512.0, 480.0, 38.0)
 
     # Create basic vegetation entity
     position = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
-    vegetation = dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 1.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SectorSize_PinkFlower")[0]
+    vegetation = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", position, 16.0, 16.0, 1.0,
+                                                               pink_flower_prefab)
     dynveg.create_surface_entity("Surface_Entity", position, 16.0, 16.0, 1.0)
 
     # Add the Vegetation Debugger component to the Level Inspector

+ 6 - 4
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/VegetationInstances_DespawnWhenOutOfRange.py

@@ -43,18 +43,20 @@ def VegetationInstances_DespawnWhenOutOfRange():
     import azlmbr.legacy.general as general
     import azlmbr.math as math
 
+    import editor_python_test_tools.hydra_editor_utils as hydra
     from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
     from editor_python_test_tools.utils import Report
     from editor_python_test_tools.utils import TestHelper as helper
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Create vegetation layer spawner
     world_center = math.Vector3(512.0, 512.0, 32.0)
-    asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
-    spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Instance", world_center, 16.0, 16.0, 16.0, asset_path)
+    pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
+    pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "RangeDespawn_PinkFlower")[0]
+    spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", world_center, 16.0, 16.0, 16.0,
+                                                               pink_flower_prefab)
 
     # Create a surface to spawn on
     dynveg.create_surface_entity("Spawner Entity", world_center, 16.0, 16.0, 1.0)

+ 158 - 8
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main.py

@@ -7,21 +7,171 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
 
 import os
 import pytest
-import sys
 
-sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
-from base import TestAutomationBase
+import ly_test_tools.environment.file_system as file_system
+from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
 
 
 @pytest.mark.SUITE_main
 @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
 @pytest.mark.parametrize("project", ["AutomatedTesting"])
-class TestAutomation(TestAutomationBase):
+class TestAutomation(EditorTestSuite):
 
-    def test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(self, request, workspace, editor, launcher_platform):
+    # Helpers for test asset cleanup
+    def cleanup_test_level(self, workspace):
+        file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
+                           True, True)
+
+    class test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(EditorSharedTest):
+        from .EditorScripts import AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude as test_module
+    
+    class test_AltitudeFilter_FilterStageToggle(EditorSharedTest):
+        from .EditorScripts import AltitudeFilter_FilterStageToggle as test_module
+
+    class test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(EditorSharedTest):
+        from .EditorScripts import AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude as test_module
+
+    class test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(EditorSharedTest):
+        from .EditorScripts import AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea as test_module
+
+    class test_AssetWeightSelector_InstancesExpressBasedOnWeight(EditorSharedTest):
+        from .EditorScripts import AssetWeightSelector_InstancesExpressBasedOnWeight as test_module
+
+    @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
+    class test_DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(EditorSharedTest):
+        from .EditorScripts import DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius as test_module
+
+    @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
+    class test_DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(EditorSharedTest):
+        from .EditorScripts import DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius as test_module
+
+    class test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(EditorSharedTest):
         from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
 
-    def test_EmptyInstanceSpawner_EmptySpawnerWorks(self, request, workspace, editor, launcher_platform):
+    class test_EmptyInstanceSpawner_EmptySpawnerWorks(EditorSharedTest):
         from .EditorScripts import EmptyInstanceSpawner_EmptySpawnerWorks as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
+
+    class test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(EditorSharedTest):
+        from .EditorScripts import InstanceSpawnerPriority_LayerAndSubPriority as test_module
+
+    class test_LayerBlender_E2E_Editor(EditorSingleTest):
+        from .EditorScripts import LayerBlender_E2E_Editor as test_module
+
+        # Custom setup/teardown to remove test level created during test
+        def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
+            TestAutomation.cleanup_test_level(self, workspace)
+
+        def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
+            TestAutomation.cleanup_test_level(self, workspace)
+
+    class test_LayerBlocker_InstancesBlockedInConfiguredArea(EditorSharedTest):
+        from .EditorScripts import LayerBlocker_InstancesBlockedInConfiguredArea as test_module
+
+    class test_LayerSpawner_FilterStageToggle(EditorSharedTest):
+        from .EditorScripts import LayerSpawner_FilterStageToggle as test_module
+
+    class test_LayerSpawner_InheritBehaviorFlag(EditorSharedTest):
+        from .EditorScripts import LayerSpawner_InheritBehaviorFlag as test_module
+
+    class test_LayerSpawner_InstancesPlantInAllSupportedShapes(EditorSharedTest):
+        from .EditorScripts import LayerSpawner_InstancesPlantInAllSupportedShapes as test_module
+
+    @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/6549")
+    class test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(EditorSharedTest):
+        from .EditorScripts import LayerSpawner_InstancesRefreshUsingCorrectViewportCamera as test_module
+
+    class test_MeshBlocker_InstancesBlockedByMesh(EditorSharedTest):
+        from .EditorScripts import MeshBlocker_InstancesBlockedByMesh as test_module
+
+    class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorSharedTest):
+        from .EditorScripts import MeshBlocker_InstancesBlockedByMeshHeightTuning as test_module
+
+    class test_MeshSurfaceTagEmitter_DependentOnMeshComponent(EditorSharedTest):
+        from .EditorScripts import MeshSurfaceTagEmitter_DependentOnMeshComponent as test_module
+
+    class test_MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(EditorSharedTest):
+        from .EditorScripts import MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
+
+    class test_PhysXColliderSurfaceTagEmitter_E2E_Editor(EditorSharedTest):
+        from .EditorScripts import PhysXColliderSurfaceTagEmitter_E2E_Editor as test_module
+
+    class test_PositionModifier_AutoSnapToSurfaceWorks(EditorSharedTest):
+        from .EditorScripts import PositionModifier_AutoSnapToSurfaceWorks as test_module
+
+    class test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(EditorSharedTest):
+        from .EditorScripts import \
+            PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets as test_module
+
+    class test_PrefabInstanceSpawner_Embedded_E2E_Editor(EditorSingleTest):
+        from .EditorScripts import PrefabInstanceSpawner_Embedded_E2E as test_module
+
+        # Custom setup/teardown to remove test level created during test
+        def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
+            TestAutomation.cleanup_test_level(self, workspace)
+
+        def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
+            TestAutomation.cleanup_test_level(self, workspace)
+
+    class test_PrefabInstanceSpawner_External_E2E_Editor(EditorSingleTest):
+        from .EditorScripts import PrefabInstanceSpawner_External_E2E as test_module
+
+        # Custom setup/teardown to remove test level created during test
+        def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
+            TestAutomation.cleanup_test_level(self, workspace)
+
+        def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
+            TestAutomation.cleanup_test_level(self, workspace)
+
+    class test_RotationModifier_InstancesRotateWithinRange(EditorSharedTest):
+        from .EditorScripts import RotationModifier_InstancesRotateWithinRange as test_module
+
+    class test_RotationModifierOverrides_InstancesRotateWithinRange(EditorSharedTest):
+        from .EditorScripts import RotationModifierOverrides_InstancesRotateWithinRange as test_module
+
+    class test_ScaleModifier_InstancesProperlyScale(EditorSharedTest):
+        from .EditorScripts import ScaleModifier_InstancesProperlyScale as test_module
+
+    class test_ScaleModifierOverrides_InstancesProperlyScale(EditorSharedTest):
+        from .EditorScripts import ScaleModifierOverrides_InstancesProperlyScale as test_module
+
+    class test_ShapeIntersectionFilter_FilterStageToggle(EditorSharedTest):
+        from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module
+
+    class test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(EditorSharedTest):
+        from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module
+
+    class test_SlopeAlignmentModifier_InstanceSurfaceAlignment(EditorSharedTest):
+        from .EditorScripts import SlopeAlignmentModifier_InstanceSurfaceAlignment as test_module
+
+    class test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(EditorSharedTest):
+        from .EditorScripts import SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment as test_module
+
+    class test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(EditorSharedTest):
+        from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module
+
+    class test_SpawnerPrefabs_PrefabCreationAndVisibilityToggleWorks(EditorSharedTest):
+        from .EditorScripts import SpawnerPrefabs_PrefabCreationAndVisibilityToggleWorks as test_module
+
+    class test_SurfaceDataRefreshes_RemainsStable(EditorSharedTest):
+        from .EditorScripts import SurfaceDataRefreshes_RemainsStable as test_module
+
+    class test_SurfaceMaskFilter_BasicSurfaceTagCreation(EditorSharedTest):
+        from .EditorScripts import SurfaceMaskFilter_BasicSurfaceTagCreation as test_module
+
+    class test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(EditorSharedTest):
+        from .EditorScripts import SurfaceMaskFilter_ExclusionList as test_module
+
+    class test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(EditorSharedTest):
+        from .EditorScripts import SurfaceMaskFilter_InclusionList as test_module
+
+    class test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(EditorSharedTest):
+        from .EditorScripts import SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected as test_module
+
+    class test_SystemSettings_SectorPointDensity(EditorSharedTest):
+        from .EditorScripts import SystemSettings_SectorPointDensity as test_module
+
+    class test_SystemSettings_SectorSize(EditorSharedTest):
+        from .EditorScripts import SystemSettings_SectorSize as test_module
+
+    class test_VegetationInstances_DespawnWhenOutOfRange(EditorSharedTest):
+        from .EditorScripts import VegetationInstances_DespawnWhenOutOfRange as test_module

+ 0 - 192
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py

@@ -1,192 +0,0 @@
-"""
-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
-"""
-
-import os
-import pytest
-
-import ly_test_tools.environment.file_system as file_system
-from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
-
-
[email protected]_main
[email protected]("launcher_platform", ['windows_editor'])
[email protected]("project", ["AutomatedTesting"])
-class TestAutomation(EditorTestSuite):
-    class test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(EditorParallelTest):
-        from .EditorScripts import AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude as test_module
-    
-    class test_AltitudeFilter_FilterStageToggle(EditorParallelTest):
-        from .EditorScripts import AltitudeFilter_FilterStageToggle as test_module
-
-    class test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(EditorParallelTest):
-        from .EditorScripts import AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude as test_module
-
-
[email protected]_main
[email protected]("launcher_platform", ['windows_editor'])
[email protected]("project", ["AutomatedTesting"])
-class TestAutomation_PrefabNotEnabled(EditorTestSuite):
-
-    enable_prefab_system = False
-
-    # Helpers for test asset cleanup
-    def cleanup_test_level(self, workspace):
-        file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
-                           True, True)
-
-    def cleanup_test_slices(self, workspace):
-        file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
-                                         "TestSlice_1.slice")], True, True)
-        file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
-                                         "TestSlice_2.slice")], True, True)
-    
-    class test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(EditorParallelTest):
-        from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module
-
-    class test_EmptyInstanceSpawner_EmptySpawnerWorks(EditorParallelTest):
-        from .EditorScripts import EmptyInstanceSpawner_EmptySpawnerWorks as test_module
-
-    class test_SpawnerSlices_SliceCreationAndVisibilityToggleWorks(EditorSingleTest):
-        # Custom teardown to remove slice asset created during test
-        def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
-            TestAutomation_PrefabNotEnabled.cleanup_test_slices(self, workspace)
-        from .EditorScripts import SpawnerSlices_SliceCreationAndVisibilityToggleWorks as test_module
-
-    class test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(EditorParallelTest):
-        from .EditorScripts import AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea as test_module
-
-    class test_AssetWeightSelector_InstancesExpressBasedOnWeight(EditorParallelTest):
-        from .EditorScripts import AssetWeightSelector_InstancesExpressBasedOnWeight as test_module
-
-    @pytest.mark.skip(reason="https://github.com/o3de/o3de/issues/4155")
-    class test_DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(EditorParallelTest):
-        from .EditorScripts import DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius as test_module
-
-    @pytest.mark.skip(reason="https://github.com/o3de/o3de/issues/4155")
-    class test_DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(EditorParallelTest):
-        from .EditorScripts import DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius as test_module
-
-    class test_SurfaceDataRefreshes_RemainsStable(EditorParallelTest):
-        from .EditorScripts import SurfaceDataRefreshes_RemainsStable as test_module
-
-    class test_VegetationInstances_DespawnWhenOutOfRange(EditorParallelTest):
-        from .EditorScripts import VegetationInstances_DespawnWhenOutOfRange as test_module
-
-    class test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(EditorParallelTest):
-        from .EditorScripts import InstanceSpawnerPriority_LayerAndSubPriority as test_module
-
-    class test_LayerBlocker_InstancesBlockedInConfiguredArea(EditorParallelTest):
-        from .EditorScripts import LayerBlocker_InstancesBlockedInConfiguredArea as test_module
-
-    class test_LayerSpawner_InheritBehaviorFlag(EditorParallelTest):
-        from .EditorScripts import LayerSpawner_InheritBehaviorFlag as test_module
-
-    class test_LayerSpawner_InstancesPlantInAllSupportedShapes(EditorParallelTest):
-        from .EditorScripts import LayerSpawner_InstancesPlantInAllSupportedShapes as test_module
-
-    class test_LayerSpawner_FilterStageToggle(EditorParallelTest):
-        from .EditorScripts import LayerSpawner_FilterStageToggle as test_module
-
-    @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2038")
-    class test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(EditorParallelTest):
-        from .EditorScripts import LayerSpawner_InstancesRefreshUsingCorrectViewportCamera as test_module
-
-    class test_MeshBlocker_InstancesBlockedByMesh(EditorParallelTest):
-        from .EditorScripts import MeshBlocker_InstancesBlockedByMesh as test_module
-
-    class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorParallelTest):
-        from .EditorScripts import MeshBlocker_InstancesBlockedByMeshHeightTuning as test_module
-
-    class test_MeshSurfaceTagEmitter_DependentOnMeshComponent(EditorParallelTest):
-        from .EditorScripts import MeshSurfaceTagEmitter_DependentOnMeshComponent as test_module
-
-    class test_MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(EditorParallelTest):
-        from .EditorScripts import MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
-
-    class test_PhysXColliderSurfaceTagEmitter_E2E_Editor(EditorParallelTest):
-        from .EditorScripts import PhysXColliderSurfaceTagEmitter_E2E_Editor as test_module
-
-    class test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(EditorParallelTest):
-        from .EditorScripts import PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets as test_module
-
-    class test_PositionModifier_AutoSnapToSurfaceWorks(EditorParallelTest):
-        from .EditorScripts import PositionModifier_AutoSnapToSurfaceWorks as test_module
-
-    class test_RotationModifier_InstancesRotateWithinRange(EditorParallelTest):
-        from .EditorScripts import RotationModifier_InstancesRotateWithinRange as test_module
-
-    class test_RotationModifierOverrides_InstancesRotateWithinRange(EditorParallelTest):
-        from .EditorScripts import RotationModifierOverrides_InstancesRotateWithinRange as test_module
-
-    class test_ScaleModifier_InstancesProperlyScale(EditorParallelTest):
-        from .EditorScripts import ScaleModifier_InstancesProperlyScale as test_module
-
-    class test_ScaleModifierOverrides_InstancesProperlyScale(EditorParallelTest):
-        from .EditorScripts import ScaleModifierOverrides_InstancesProperlyScale as test_module
-
-    class test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(EditorParallelTest):
-        from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module
-
-    class test_ShapeIntersectionFilter_FilterStageToggle(EditorParallelTest):
-        from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module
-
-    class test_SlopeAlignmentModifier_InstanceSurfaceAlignment(EditorParallelTest):
-        from .EditorScripts import SlopeAlignmentModifier_InstanceSurfaceAlignment as test_module
-
-    class test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(EditorParallelTest):
-        from .EditorScripts import SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment as test_module
-
-    class test_SurfaceMaskFilter_BasicSurfaceTagCreation(EditorParallelTest):
-        from .EditorScripts import SurfaceMaskFilter_BasicSurfaceTagCreation as test_module
-
-    class test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(EditorParallelTest):
-        from .EditorScripts import SurfaceMaskFilter_ExclusionList as test_module
-
-    class test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(EditorParallelTest):
-        from .EditorScripts import SurfaceMaskFilter_InclusionList as test_module
-
-    class test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(EditorParallelTest):
-        from .EditorScripts import SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected as test_module
-
-    class test_SystemSettings_SectorPointDensity(EditorParallelTest):
-        from .EditorScripts import SystemSettings_SectorPointDensity as test_module
-
-    class test_SystemSettings_SectorSize(EditorParallelTest):
-        from .EditorScripts import SystemSettings_SectorSize as test_module
-
-    class test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(EditorParallelTest):
-        from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module
-
-    class test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(EditorSingleTest):
-        from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module
-
-        # Custom setup/teardown to remove test level created during test
-        def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
-            TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)
-
-        def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
-            TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)
-
-    class test_DynamicSliceInstanceSpawner_External_E2E_Editor(EditorSingleTest):
-        from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module
-
-        # Custom setup/teardown to remove test level created during test
-        def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
-            TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)
-
-        def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
-            TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)
-
-    class test_LayerBlender_E2E_Editor(EditorSingleTest):
-        from .EditorScripts import LayerBlender_E2E_Editor as test_module
-
-        # Custom setup/teardown to remove test level created during test
-        def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
-            TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)
-
-        def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
-            TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)

+ 5 - 265
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic.py

@@ -7,277 +7,17 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
 
 import os
 import pytest
-import sys
 
-import ly_test_tools.environment.waiter as waiter
 import ly_test_tools.environment.file_system as file_system
-import editor_python_test_tools.hydra_test_utils as hydra
-from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole
-
-sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
-from base import TestAutomationBase
-
-
[email protected]
-def remove_test_slice(request, workspace, project):
-    file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_1.slice")], True,
-                       True)
-    file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_2.slice")], True,
-                       True)
-
-    def teardown():
-        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_1.slice")], True,
-                           True)
-        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_2.slice")], True,
-                           True)
-    request.addfinalizer(teardown)
-
-
[email protected]
-def remote_console_instance(request):
-    console = RemoteConsole()
-
-    def teardown():
-        if console.connected:
-            console.stop()
-
-    request.addfinalizer(teardown)
-    return console
+from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
 
 
 @pytest.mark.SUITE_periodic
 @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
 @pytest.mark.parametrize("project", ["AutomatedTesting"])
-class TestAutomation(TestAutomationBase):
-
-    def test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_AltitudeFilter_FilterStageToggle(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import AltitudeFilter_FilterStageToggle as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_SpawnerSlices_SliceCreationAndVisibilityToggleWorks(self, request, workspace, editor, remove_test_slice, launcher_platform):
-        from .EditorScripts import SpawnerSlices_SliceCreationAndVisibilityToggleWorks as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_AssetWeightSelector_InstancesExpressBasedOnWeight(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import AssetWeightSelector_InstancesExpressBasedOnWeight as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
-    def test_DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
-    def test_DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_SurfaceDataRefreshes_RemainsStable(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import SurfaceDataRefreshes_RemainsStable as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_VegetationInstances_DespawnWhenOutOfRange(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import VegetationInstances_DespawnWhenOutOfRange as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import InstanceSpawnerPriority_LayerAndSubPriority as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_LayerBlocker_InstancesBlockedInConfiguredArea(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import LayerBlocker_InstancesBlockedInConfiguredArea as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_LayerSpawner_InheritBehaviorFlag(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import LayerSpawner_InheritBehaviorFlag as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_LayerSpawner_InstancesPlantInAllSupportedShapes(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import LayerSpawner_InstancesPlantInAllSupportedShapes as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_LayerSpawner_FilterStageToggle(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import LayerSpawner_FilterStageToggle as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2038")
-    def test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import LayerSpawner_InstancesRefreshUsingCorrectViewportCamera as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_MeshBlocker_InstancesBlockedByMesh(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import MeshBlocker_InstancesBlockedByMesh as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_MeshBlocker_InstancesBlockedByMeshHeightTuning(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import MeshBlocker_InstancesBlockedByMeshHeightTuning as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_MeshSurfaceTagEmitter_DependentOnMeshComponent(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import MeshSurfaceTagEmitter_DependentOnMeshComponent as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_PhysXColliderSurfaceTagEmitter_E2E_Editor(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import PhysXColliderSurfaceTagEmitter_E2E_Editor as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_PositionModifier_AutoSnapToSurfaceWorks(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import PositionModifier_AutoSnapToSurfaceWorks as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_RotationModifier_InstancesRotateWithinRange(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import RotationModifier_InstancesRotateWithinRange as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_RotationModifierOverrides_InstancesRotateWithinRange(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import RotationModifierOverrides_InstancesRotateWithinRange as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_ScaleModifier_InstancesProperlyScale(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import ScaleModifier_InstancesProperlyScale as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_ScaleModifierOverrides_InstancesProperlyScale(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import ScaleModifierOverrides_InstancesProperlyScale as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_ShapeIntersectionFilter_FilterStageToggle(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_SlopeAlignmentModifier_InstanceSurfaceAlignment(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import SlopeAlignmentModifier_InstanceSurfaceAlignment as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_SurfaceMaskFilter_BasicSurfaceTagCreation(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import SurfaceMaskFilter_BasicSurfaceTagCreation as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import SurfaceMaskFilter_ExclusionList as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import SurfaceMaskFilter_InclusionList as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_SystemSettings_SectorPointDensity(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import SystemSettings_SectorPointDensity as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_SystemSettings_SectorSize(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import SystemSettings_SectorSize as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-
[email protected]_periodic
[email protected]("project", ["AutomatedTesting"])
[email protected]("level", ["tmp_level"])
-class TestAutomationE2E(TestAutomationBase):
-
-    # The following tests must run in order, please do not move tests out of order
-
-    @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
-    def test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(self, request, workspace, project, level, editor, launcher_platform):
-        # Ensure our test level does not already exist
-        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
-
-        from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    @pytest.mark.parametrize("launcher_platform", ['windows'])
-    def test_DynamicSliceInstanceSpawner_Embedded_E2E_Launcher(self, workspace, launcher, level,
-                                                               remote_console_instance, project, launcher_platform):
-
-        expected_lines = [
-            "Instances found in area = 400"
-        ]
-
-        hydra.launch_and_validate_results_launcher(launcher, level, remote_console_instance, expected_lines, launch_ap=False)
-
-        # Cleanup our temp level
-        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
-
-    @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
-    def test_DynamicSliceInstanceSpawner_External_E2E_Editor(self, request, workspace, project, level, editor, launcher_platform):
-        # Ensure our test level does not already exist
-        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
-
-        from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    @pytest.mark.parametrize("launcher_platform", ['windows'])
-    def test_DynamicSliceInstanceSpawner_External_E2E_Launcher(self, workspace, launcher, level,
-                                                               remote_console_instance, project, launcher_platform):
-
-        expected_lines = [
-            "Instances found in area = 400"
-        ]
-
-        hydra.launch_and_validate_results_launcher(launcher, level, remote_console_instance, expected_lines, launch_ap=False)
-
-        # Cleanup our temp level
-        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
-
-    @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
-    def test_LayerBlender_E2E_Editor(self, request, workspace, project, level, editor, launcher_platform):
-        # Ensure our test level does not already exist
-        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
-
-        from .EditorScripts import LayerBlender_E2E_Editor as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    @pytest.mark.parametrize("launcher_platform", ['windows'])
-    @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4170")
-    def test_LayerBlender_E2E_Launcher(self, workspace, launcher, level,
-                                                               remote_console_instance, project, launcher_platform):
-
-        launcher.args.extend(["-rhi=Null"])
-        launcher.start(launch_ap=False)
-        assert launcher.is_alive(), "Launcher failed to start"
-
-        # Wait for test script to quit the launcher. If wait_for returns exc, test was not successful
-        waiter.wait_for(lambda: not launcher.is_alive(), timeout=300)
+class TestAutomation(EditorTestSuite):
 
-        # Verify launcher quit successfully and did not crash
-        ret_code = launcher.get_returncode()
-        assert ret_code == 0, "Test failed. See Game.log for details"
+    global_extra_cmdline_args = ["-BatchMode", "-autotest_mode"]
 
-        # Cleanup our temp level
-        file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+    class test_DynVegUtils_TempPrefabCreationWorks(EditorSharedTest):
+        from .EditorScripts import DynVegUtils_TempPrefabCreationWorks as test_module

+ 0 - 23
AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py

@@ -1,23 +0,0 @@
-"""
-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
-"""
-
-import os
-import pytest
-
-import ly_test_tools.environment.file_system as file_system
-from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
-
-
[email protected]_main
[email protected]("launcher_platform", ['windows_editor'])
[email protected]("project", ["AutomatedTesting"])
-class TestAutomation(EditorTestSuite):
-
-    global_extra_cmdline_args = ["-BatchMode", "-autotest_mode"]
-
-    class test_DynVegUtils_TempPrefabCreationWorks(EditorSharedTest):
-        from .EditorScripts import DynVegUtils_TempPrefabCreationWorks as test_module

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientGenerators_Incompatibilities.py

@@ -65,8 +65,7 @@ def GradientGenerators_Incompatibilities():
     }
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # For every gradient generator component, verify that they are incompatible
     # which each vegetation area component

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientModifiers_Incompatibilities.py

@@ -74,8 +74,7 @@ def GradientModifiers_Incompatibilities():
     }
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # For every gradient modifier component, verify that they are incompatible
     # which each vegetation area and gradient generator/modifier component

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin.py

@@ -86,8 +86,7 @@ def GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin():
         return entity
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # 2) Create entity with Random Noise gradient and verify gradient position after clearing pinned entity
     clear_entityid_check_position(

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_DefaultPinnedEntityIsSelf.py

@@ -90,8 +90,7 @@ def GradientPreviewSettings_DefaultPinnedEntityIsSelf():
     ]
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     for param in param_list:
         execute_test(param.required_components[param.accessed_component],

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSampling_GradientReferencesAddRemoveSuccessfully.py

@@ -61,8 +61,7 @@ def GradientSampling_GradientReferencesAddRemoveSuccessfully():
         Report.result(gradient_cleared_from_modifier, entity.Equal(EntityId.EntityId()))
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # 2) Create a new entity with components "Random Noise Gradient", "Gradient Transform Modifier" and "Box Shape"
     entity_position = math.Vector3(125.0, 136.0, 32.0)

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_ComponentDependencies.py

@@ -42,8 +42,7 @@ def GradientSurfaceTagEmitter_ComponentDependencies():
         return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Create an entity with Gradient Surface Tag Emitter component
     position = math.Vector3(512.0, 512.0, 32.0)

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully.py

@@ -36,8 +36,7 @@ def GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # 2) Create an entity with Gradient Surface Tag Emitter and Reference Gradient components.
     entity_position = math.Vector3(125.0, 136.0, 32.0)

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithExpectedGradients.py

@@ -46,8 +46,7 @@ def GradientTransform_ComponentIncompatibleWithExpectedGradients():
         return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # 2) Create a new entity with components Gradient Transform Modifier and Box Shape
     entity_position = math.Vector3(125.0, 136.0, 32.0)

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_ComponentIncompatibleWithSpawners.py

@@ -44,8 +44,7 @@ def GradientTransform_ComponentIncompatibleWithSpawners():
         return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # 2) Create a new entity with components Gradient Transform Modifier and Box Shape
     entity_position = math.Vector3(125.0, 136.0, 32.0)

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange.py

@@ -54,8 +54,7 @@ def GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # 2) Create entity
     entity_position = math.Vector3(125.0, 136.0, 32.0)

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_RequiresShape.py

@@ -47,8 +47,7 @@ def GradientTransform_RequiresShape():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Create a new Entity in the level
     entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_ProcessedImageAssignedSuccessfully.py

@@ -56,8 +56,7 @@ def ImageGradient_ProcessedImageAssignedSuccessfully():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # 1) Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # 2) Create an entity with Image Gradient and Gradient Transform Modifier components
     components_to_add = ["Image Gradient", "Gradient Transform Modifier", "Box Shape"]

+ 1 - 2
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_RequiresShape.py

@@ -47,8 +47,7 @@ def ImageGradient_RequiresShape():
     from editor_python_test_tools.utils import TestHelper as helper
 
     # Open an existing simple level
-    helper.init_idle()
-    helper.open_level("Physics", "Base")
+    hydra.open_base_level()
 
     # Create a new Entity in the level
     entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())

+ 22 - 38
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic.py

@@ -5,67 +5,51 @@ For complete copyright and license terms please see the LICENSE at the root of t
 SPDX-License-Identifier: Apache-2.0 OR MIT
 """
 
-import os
 import pytest
-import sys
 
-sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
-from base import TestAutomationBase
+from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
 
 
 @pytest.mark.SUITE_periodic
 @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
 @pytest.mark.parametrize("project", ["AutomatedTesting"])
-class TestAutomation(TestAutomationBase):
+class TestAutomation(EditorTestSuite):
 
-    def test_GradientGenerators_Incompatibilities(self, request, workspace, editor, launcher_platform):
+    class test_GradientGenerators_Incompatibilities(EditorSharedTest):
         from .EditorScripts import GradientGenerators_Incompatibilities as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
 
-    def test_GradientModifiers_Incompatibilities(self, request, workspace, editor, launcher_platform):
+    class test_GradientModifiers_Incompatibilities(EditorSharedTest):
         from .EditorScripts import GradientModifiers_Incompatibilities as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
 
-    def test_GradientPreviewSettings_DefaultPinnedEntityIsSelf(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import GradientPreviewSettings_DefaultPinnedEntityIsSelf as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin(self, request, workspace, editor, launcher_platform):
+    class test_GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin(EditorSharedTest):
         from .EditorScripts import GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
 
-    def test_GradientSampling_GradientReferencesAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
+    class test_GradientPreviewSettings_DefaultPinnedEntityIsSelf(EditorSharedTest):
+        from .EditorScripts import GradientPreviewSettings_DefaultPinnedEntityIsSelf as test_module
+
+    class test_GradientSampling_GradientReferencesAddRemoveSuccessfully(EditorSharedTest):
         from .EditorScripts import GradientSampling_GradientReferencesAddRemoveSuccessfully as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
 
-    def test_GradientSurfaceTagEmitter_ComponentDependencies(self, request, workspace, editor, launcher_platform):
+    class test_GradientSurfaceTagEmitter_ComponentDependencies(EditorSharedTest):
         from .EditorScripts import GradientSurfaceTagEmitter_ComponentDependencies as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
 
-    def test_GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
+    class test_GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(EditorSharedTest):
         from .EditorScripts import GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
 
-    def test_GradientTransform_RequiresShape(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import GradientTransform_RequiresShape as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
-
-    def test_GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
+    class test_GradientTransform_ComponentIncompatibleWithExpectedGradients(EditorSharedTest):
+        from .EditorScripts import GradientTransform_ComponentIncompatibleWithExpectedGradients as test_module
 
-    def test_GradientTransform_ComponentIncompatibleWithSpawners(self, request, workspace, editor, launcher_platform):
+    class test_GradientTransform_ComponentIncompatibleWithSpawners(EditorSharedTest):
         from .EditorScripts import GradientTransform_ComponentIncompatibleWithSpawners as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
 
-    def test_GradientTransform_ComponentIncompatibleWithExpectedGradients(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import GradientTransform_ComponentIncompatibleWithExpectedGradients as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
+    class test_GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange(EditorSharedTest):
+        from .EditorScripts import GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange as test_module
 
-    def test_ImageGradient_RequiresShape(self, request, workspace, editor, launcher_platform):
-        from .EditorScripts import ImageGradient_RequiresShape as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
+    class test_GradientTransform_RequiresShape(EditorSharedTest):
+        from .EditorScripts import GradientTransform_RequiresShape as test_module
 
-    def test_ImageGradient_ProcessedImageAssignedSuccessfully(self, request, workspace, editor, launcher_platform):
+    class test_ImageGradient_ProcessedImageAssignedSuccessfully(EditorSharedTest):
         from .EditorScripts import ImageGradient_ProcessedImageAssignedSuccessfully as test_module
-        self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
+
+    class test_ImageGradient_RequiresShape(EditorSharedTest):
+        from .EditorScripts import ImageGradient_RequiresShape as test_module

+ 0 - 57
AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic_Optimized.py

@@ -1,57 +0,0 @@
-"""
-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
-"""
-
-import pytest
-
-from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
-
-
[email protected]_periodic
[email protected]("launcher_platform", ['windows_editor'])
[email protected]("project", ["AutomatedTesting"])
-class TestAutomation(EditorTestSuite):
-
-    enable_prefab_system = False
-
-    class test_GradientGenerators_Incompatibilities(EditorSharedTest):
-        from .EditorScripts import GradientGenerators_Incompatibilities as test_module
-
-    class test_GradientModifiers_Incompatibilities(EditorSharedTest):
-        from .EditorScripts import GradientModifiers_Incompatibilities as test_module
-
-    class test_GradientPreviewSettings_DefaultPinnedEntityIsSelf(EditorSharedTest):
-        from .EditorScripts import GradientPreviewSettings_DefaultPinnedEntityIsSelf as test_module
-
-    class test_GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin(EditorSharedTest):
-        from .EditorScripts import GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin as test_module
-
-    class test_GradientSampling_GradientReferencesAddRemoveSuccessfully(EditorSharedTest):
-        from .EditorScripts import GradientSampling_GradientReferencesAddRemoveSuccessfully as test_module
-
-    class test_GradientSurfaceTagEmitter_ComponentDependencies(EditorSharedTest):
-        from .EditorScripts import GradientSurfaceTagEmitter_ComponentDependencies as test_module
-
-    class test_GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(EditorSharedTest):
-        from .EditorScripts import GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
-
-    class test_GradientTransform_RequiresShape(EditorSharedTest):
-        from .EditorScripts import GradientTransform_RequiresShape as test_module
-
-    class test_GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange(EditorSharedTest):
-        from .EditorScripts import GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange as test_module
-
-    class test_GradientTransform_ComponentIncompatibleWithSpawners(EditorSharedTest):
-        from .EditorScripts import GradientTransform_ComponentIncompatibleWithSpawners as test_module
-
-    class test_GradientTransform_ComponentIncompatibleWithExpectedGradients(EditorSharedTest):
-        from .EditorScripts import GradientTransform_ComponentIncompatibleWithExpectedGradients as test_module
-
-    class test_ImageGradient_RequiresShape(EditorSharedTest):
-        from .EditorScripts import ImageGradient_RequiresShape as test_module
-
-    class test_ImageGradient_ProcessedImageAssignedSuccessfully(EditorSharedTest):
-        from .EditorScripts import ImageGradient_ProcessedImageAssignedSuccessfully as test_module

+ 44 - 1
AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py

@@ -114,7 +114,8 @@ def create_dynamic_slice_vegetation_area(name, center_point, box_size_x, box_siz
     return spawner_entity
 
 
-def create_prefab_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_z, target_prefab):
+def create_temp_prefab_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_z, target_prefab):
+    """Creates a vegetation area using in-memory prefabs. Use when test is solely contained to Editor"""
     # Create a vegetation area entity to use as our test vegetation spawner
     spawner_entity = hydra.Entity(name)
     spawner_entity.create_entity(
@@ -148,6 +149,31 @@ def create_prefab_vegetation_area(name, center_point, box_size_x, box_size_y, bo
     return spawner_entity
 
 
+def create_prefab_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_z, prefab_path):
+    """Creates a vegetation area using on-disk spawnable prefabs. Use when test requires saving/loading in Launcher"""
+    # Create a vegetation area entity to use as our test vegetation spawner
+    prefab_asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", prefab_path, math.Uuid(),
+                                                   False)
+    spawner_entity = hydra.Entity(name)
+    spawner_entity.create_entity(
+        center_point,
+        ["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List"]
+    )
+    if spawner_entity.id.IsValid():
+        print(f"'{spawner_entity.name}' created")
+    spawner_entity.get_set_test(1, "Box Shape|Box Configuration|Dimensions", math.Vector3(box_size_x, box_size_y,
+                                                                                          box_size_z))
+
+    # Set the vegetation area to a prefab instance spawner with a specific prefab asset selected
+    descriptor = hydra.get_component_property_value(spawner_entity.components[2],
+                                                    'Configuration|Embedded Assets|[0]')
+    prefab_spawner = vegetation.PrefabInstanceSpawner()
+    prefab_spawner.SetPrefabAssetId(prefab_asset_id)
+    descriptor.spawner = prefab_spawner
+    spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]", descriptor)
+    return spawner_entity
+
+
 def create_blocker_area(name, center_point, box_size_x, box_size_y, box_size_z):
     # Create a Vegetation Layer Blocker area
     blocker_entity = hydra.Entity(name)
@@ -162,6 +188,23 @@ def create_blocker_area(name, center_point, box_size_x, box_size_y, box_size_z):
     return blocker_entity
 
 
+def create_empty_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_z):
+    # Create a vegetation area entity to use as our test vegetation spawner
+    spawner_entity = EditorEntity.create_editor_entity_at(center_point, name=name)
+    spawner_entity.add_components(["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List"])
+    if spawner_entity.id.IsValid():
+        print(f"'{spawner_entity.get_name()}' created")
+    spawner_entity.components[1].set_component_property_value("Box Shape|Box Configuration|Dimensions",
+                                                              math.Vector3(box_size_x, box_size_y, box_size_z))
+
+    # Set the vegetation area to an empty spawner
+    empty_spawner = vegetation.EmptyInstanceSpawner()
+    descriptor = spawner_entity.components[2].get_component_property_value("Configuration|Embedded Assets|[0]")
+    descriptor.spawner = empty_spawner
+    spawner_entity.components[2].set_component_property_value("Configuration|Embedded Assets|[0]", descriptor)
+    return spawner_entity
+
+
 def validate_instance_count(center, radius, num_expected):
     # Verify that we have the correct number of instances in the given area. This creates a bounding box based on a
     # sphere radius

+ 16 - 23
AutomatedTesting/ScriptCanvas/instance_counter.scriptcanvas

@@ -5,7 +5,7 @@
     "ClassData": {
         "m_scriptCanvas": {
             "Id": {
-                "id": 3744110453276
+                "id": 337666590525276931
             },
             "Name": "instance_counter",
             "Components": {
@@ -87,7 +87,6 @@
                                         ],
                                         "Datums": [
                                             {
-                                                "isOverloadedStorage": false,
                                                 "scriptCanvasType": {
                                                     "m_type": 3
                                                 },
@@ -228,7 +227,6 @@
                                         ],
                                         "Datums": [
                                             {
-                                                "isOverloadedStorage": false,
                                                 "scriptCanvasType": {
                                                     "m_type": 1
                                                 },
@@ -237,7 +235,7 @@
                                                 "value": {
                                                     "id": 2901262558
                                                 },
-                                                "label": "Source"
+                                                "label": "EntityID: 0"
                                             }
                                         ],
                                         "methodType": 0,
@@ -340,7 +338,6 @@
                                         ],
                                         "Datums": [
                                             {
-                                                "isOverloadedStorage": false,
                                                 "scriptCanvasType": {
                                                     "m_type": 3
                                                 },
@@ -587,26 +584,10 @@
                     "m_assetType": "{3E2AC8CD-713F-453E-967F-29517F331784}",
                     "versionData": {
                         "_grammarVersion": 1,
-                        "_runtimeVersion": 1
+                        "_runtimeVersion": 1,
+                        "_fileVersion": 1
                     },
                     "GraphCanvasData": [
-                        {
-                            "Key": {
-                                "id": 3744110453276
-                            },
-                            "Value": {
-                                "ComponentData": {
-                                    "{5F84B500-8C45-40D1-8EFC-A5306B241444}": {
-                                        "$type": "SceneComponentSaveData",
-                                        "ViewParams": {
-                                            "Scale": 0.9218543514249998,
-                                            "AnchorX": 50.98419189453125,
-                                            "AnchorY": -272.27728271484375
-                                        }
-                                    }
-                                }
-                            }
-                        },
                         {
                             "Key": {
                                 "id": 3748405420572
@@ -757,6 +738,18 @@
                                     }
                                 }
                             }
+                        },
+                        {
+                            "Key": {
+                                "id": 337666590525276931
+                            },
+                            "Value": {
+                                "ComponentData": {
+                                    "{5F84B500-8C45-40D1-8EFC-A5306B241444}": {
+                                        "$type": "SceneComponentSaveData"
+                                    }
+                                }
+                            }
                         }
                     ],
                     "StatisticsHelper": {