diff --git a/.buildkite/nightly.definition.yaml b/.buildkite/nightly.definition.yaml new file mode 100644 index 00000000..f696ee5d --- /dev/null +++ b/.buildkite/nightly.definition.yaml @@ -0,0 +1,11 @@ +agent_queue_id: trigger-pipelines +description: Nightly build and deployment of Unreal Example project +github: + branch_configuration: [] + default_branch: master + pull_request_branch_filter_configuration: [] +teams: +- name: Everyone + permission: BUILD_AND_READ +- name: gbu/develop/unreal + permission: MANAGE_BUILD_AND_READ diff --git a/.buildkite/nightly.steps.yaml b/.buildkite/nightly.steps.yaml new file mode 100644 index 00000000..5b543d74 --- /dev/null +++ b/.buildkite/nightly.steps.yaml @@ -0,0 +1,25 @@ +common: &common + agents: + - "agent_count=1" + - "capable_of_building=gdk-for-unreal" + - "environment=production" + - "machine_type=quad" + - "permission_set=builder" + - "platform=windows" + - "scaler_version=2" + - "queue=${CI_WINDOWS_BUILDER_QUEUE:-v3-1569490589-f9345a43b21a6cec-------z}" + timeout_in_minutes: 60 # TODO(ENG-548): reduce timeout once agent-cold-start is optimised. + retry: + automatic: + # This is designed to trap and retry failures because agent lost connection. Agent exits with -1 in this case. + - exit_status: -1 + limit: 3 + plugins: + - ca-johnson/taskkill#v4.1: ~ + +steps: + - label: "build-and-deploy-:windows:" + command: powershell -NoProfile -NonInteractive -InputFormat Text -Command ./ci/setup-and-build.ps1 + <<: *common # This folds the YAML named anchor into this step. Overrides, if any, should follow, not precede. + artifact_paths: + - "UnrealEngine/Engine/Programs/AutomationTool/Saved/Logs/*" diff --git a/FindEngine.bat b/FindEngine.bat index 6bcae7e4..6b41ed9f 100644 --- a/FindEngine.bat +++ b/FindEngine.bat @@ -7,7 +7,7 @@ set UNREAL_ENGINE="" set UPROJECT="" rem First find the .uproject -for /f "delims=" %%A in (' powershell -Command "Get-ChildItem %~dp0 -Depth 1 -Filter *.uproject -File | %% {$_.FullName}" ') do set UPROJECT="%%A" +for /f "delims=" %%A in (' powershell -Command "Get-ChildItem '%~dp0' -Depth 1 -Filter *.uproject -File | %% {$_.FullName}" ') do set UPROJECT="%%A" if %UPROJECT%=="" ( echo Error: Could not find uproject. Please make sure you have passed in the project directory correctly. @@ -18,7 +18,7 @@ if %UPROJECT%=="" ( echo Using uproject: %UPROJECT% rem Get the Engine association from the uproject. -for /f "delims=" %%A in (' powershell -Command "(Get-Content %UPROJECT% | ConvertFrom-Json).EngineAssociation" ') do set ENGINE_ASSOCIATION=%%A +for /f "delims=" %%A in (' powershell -Command "(Get-Content '%UPROJECT%' | ConvertFrom-Json).EngineAssociation" ') do set ENGINE_ASSOCIATION=%%A echo Engine association for uproject is: %ENGINE_ASSOCIATION% diff --git a/Game/Config/DefaultEngine.ini b/Game/Config/DefaultEngine.ini index c146213c..bd2e3e2a 100644 --- a/Game/Config/DefaultEngine.ini +++ b/Game/Config/DefaultEngine.ini @@ -50,6 +50,9 @@ DefaultGraphicsPerformance=Maximum [/Script/SpatialGDK.SpatialGameInstance] bPreventAutoConnectWithLocator=False +[/Script/NavigationSystem.NavigationSystemV1] +bAllowClientSideNavigation=True + [/Script/Engine.PhysicsSettings] DefaultGravityZ=-1960.000000 DefaultTerminalVelocity=4000.000000 @@ -93,6 +96,3 @@ InitialAverageFrameRate=0.016667 PhysXTreeRebuildRate=10 DefaultBroadphaseSettings=(bUseMBPOnClient=False,bUseMBPOnServer=False,MBPBounds=(Min=(X=0.000000,Y=0.000000,Z=0.000000),Max=(X=0.000000,Y=0.000000,Z=0.000000),IsValid=0),MBPNumSubdivs=2) -[/Script/NavigationSystem.NavigationSystemV1] -bAllowClientSideNavigation=True - diff --git a/Game/Config/DefaultSpatialGDKEditorSettings.ini b/Game/Config/DefaultSpatialGDKEditorSettings.ini index 5651a92d..64ccb316 100644 --- a/Game/Config/DefaultSpatialGDKEditorSettings.ini +++ b/Game/Config/DefaultSpatialGDKEditorSettings.ini @@ -3,6 +3,6 @@ bDeleteDynamicEntities=True bGenerateDefaultLaunchConfig=True bStopSpatialOnExit=False SpatialOSSnapshotFile=default.snapshot -LaunchConfigDesc=(Template="w2_r0500_e5",World=(Dimensions=(X=2000,Y=2000),ChunkEdgeLengthMeters=5,StreamingQueryIntervalSeconds=4,SnapshotWritePeriodSeconds=0,LegacyFlags=(("bridge_qos_max_timeout", "0"),("bridge_soft_handover_enabled", "false"),("enable_chunk_interest", "false")),LegacyJavaParams=()),ServerWorkers=((WorkerTypeName="UnrealWorker"),(WorkerTypeName="AIWorker"),(WorkerTypeName="CrashBotWorker"))) +LaunchConfigDesc=(Template="w2_r0500_e5",World=(Dimensions=(X=2000,Y=2000),ChunkEdgeLengthMeters=5,SnapshotWritePeriodSeconds=0,LegacyFlags=(("bridge_qos_max_timeout", "0"),("bridge_soft_handover_enabled", "false")),LegacyJavaParams=()),ServerWorkers=((WorkerTypeName="UnrealWorker"))) bGeneratePlaceholderEntitiesInSnapshot=True diff --git a/Game/Config/DefaultSpatialGDKSettings.ini b/Game/Config/DefaultSpatialGDKSettings.ini index 19490179..d25367ba 100644 --- a/Game/Config/DefaultSpatialGDKSettings.ini +++ b/Game/Config/DefaultSpatialGDKSettings.ini @@ -8,7 +8,8 @@ ActorReplicationRateLimit=0 EntityCreationRateLimit=0 OpsUpdateRate=1000.000000 bEnableHandover=True -bUsingQBI=True +MaxNetCullDistanceSquared=900000000.000000 +QueuedIncomingRPCWaitTime=1.000000 PositionUpdateFrequency=1.000000 PositionDistanceThreshold=100.000000 bEnableMetrics=True @@ -17,18 +18,15 @@ MetricsReportRate=2.000000 bUseFrameTimeAsLoad=False bCheckRPCOrder=False bBatchSpatialPositionUpdates=True +MaxDynamicallyAttachedSubobjectsPerClass=3 bEnableServerQBI=True -bPackUnreliableRPCs=True +bPackRPCs=True +DefaultReceptionistHost=127.0.0.1 bUseDevelopmentAuthenticationFlow=False DevelopmentAuthenticationToken= DevelopmentDeploymentToConnect= DefaultWorkerType=(WorkerTypeName="UnrealWorker") bEnableOffloading=False -ActorGroups=(("AI", (OwningWorkerType=(WorkerTypeName="AIWorker"),ActorClasses=(/Game/Characters/Turret/BP_Turret_Base.BP_Turret_Base_C,/Game/Controllers/BP_TurretController.BP_TurretController_C,/Game/Characters/Turret/BP_TurretShield.BP_TurretShield_C,/Game/Blueprints/Weapons/BP_HeavyMachineGun_ForTurret.BP_HeavyMachineGun_ForTurret_C,/Game/Blueprints/Weapons/Grenades/Turret_Rocket_Propelled.Turret_Rocket_Propelled_C,/Game/Blueprints/Weapons/BP_RocketLauncher_Continuous.BP_RocketLauncher_Continuous_C))),("CrashBot", (OwningWorkerType=(WorkerTypeName="CrashBotWorker"),ActorClasses=(/Game/Characters/BP_CrashBot.BP_CrashBot_C,/Game/Controllers/BP_CrashBotController.BP_CrashBotController_C)))) -ServerWorkerTypes=("UnrealWorker","AIWorker","CrashBotWorker") -MaxDynamicallyAttachedSubobjectsPerClass=3 -bPackRPCs=True -DefaultReceptionistHost=127.0.0.1 -MaxNetCullDistanceSquared=900000000.000000 - +ActorGroups=() +ServerWorkerTypes=("UnrealWorker") diff --git a/Game/Content/Blueprints/Weapons/BP_Crashbot_Rifle.uasset b/Game/Content/Blueprints/Weapons/BP_Crashbot_Rifle.uasset new file mode 100644 index 00000000..39198616 Binary files /dev/null and b/Game/Content/Blueprints/Weapons/BP_Crashbot_Rifle.uasset differ diff --git a/Game/Content/Characters/BP_CrashBot.uasset b/Game/Content/Characters/BP_CrashBot.uasset index 8158cb5f..88d92aaf 100644 Binary files a/Game/Content/Characters/BP_CrashBot.uasset and b/Game/Content/Characters/BP_CrashBot.uasset differ diff --git a/Game/Content/Characters/BP_CrashBot_PlacedInWorld.uasset b/Game/Content/Characters/BP_CrashBot_PlacedInWorld.uasset index 6b9877cb..5a8eafd0 100644 Binary files a/Game/Content/Characters/BP_CrashBot_PlacedInWorld.uasset and b/Game/Content/Characters/BP_CrashBot_PlacedInWorld.uasset differ diff --git a/Game/Content/Controllers/BP_CrashBotController.uasset b/Game/Content/Controllers/BP_CrashBotController.uasset index 3aef406e..f70214ee 100644 Binary files a/Game/Content/Controllers/BP_CrashBotController.uasset and b/Game/Content/Controllers/BP_CrashBotController.uasset differ diff --git a/Game/Content/GameMode/BP_DeathmatchGameState.uasset b/Game/Content/GameMode/BP_DeathmatchGameState.uasset index b5ace0f7..d934f38e 100644 Binary files a/Game/Content/GameMode/BP_DeathmatchGameState.uasset and b/Game/Content/GameMode/BP_DeathmatchGameState.uasset differ diff --git a/Game/Content/Maps/CrashBot_Gym.umap b/Game/Content/Maps/CrashBot_Gym.umap index 87bbbd2d..65d056d5 100644 Binary files a/Game/Content/Maps/CrashBot_Gym.umap and b/Game/Content/Maps/CrashBot_Gym.umap differ diff --git a/Game/Content/Maps/Offloading_Gym.umap b/Game/Content/Maps/Offloading_Gym.umap deleted file mode 100644 index abc74a4b..00000000 Binary files a/Game/Content/Maps/Offloading_Gym.umap and /dev/null differ diff --git a/Game/Content/Maps/Offloading_Gym_BuiltData.uasset b/Game/Content/Maps/Offloading_Gym_BuiltData.uasset deleted file mode 100644 index e4a3fb33..00000000 Binary files a/Game/Content/Maps/Offloading_Gym_BuiltData.uasset and /dev/null differ diff --git a/Game/Content/Splash/EdSplash.bmp b/Game/Content/Splash/EdSplash.bmp index df1fe444..c68189d0 100644 Binary files a/Game/Content/Splash/EdSplash.bmp and b/Game/Content/Splash/EdSplash.bmp differ diff --git a/Game/Content/Splash/Splash.bmp b/Game/Content/Splash/Splash.bmp index d946743e..dbda6901 100644 Binary files a/Game/Content/Splash/Splash.bmp and b/Game/Content/Splash/Splash.bmp differ diff --git a/Game/Source/GDKShooter.Target.cs b/Game/Source/GDKShooter.Target.cs index b8677abd..e3d35404 100644 --- a/Game/Source/GDKShooter.Target.cs +++ b/Game/Source/GDKShooter.Target.cs @@ -9,7 +9,5 @@ public GDKShooterTarget(TargetInfo Target) : base(Target) { Type = TargetType.Game; ExtraModuleNames.Add("GDKShooter"); - // TODO: UNR-1791 for long-term fix - GlobalDefinitions.Add("UE_ALLOW_MAP_OVERRIDE_IN_SHIPPING=1"); } } diff --git a/Game/Source/GDKShooter/Private/Characters/Components/ShootingComponent.cpp b/Game/Source/GDKShooter/Private/Characters/Components/ShootingComponent.cpp index 88a8e218..88630aba 100644 --- a/Game/Source/GDKShooter/Private/Characters/Components/ShootingComponent.cpp +++ b/Game/Source/GDKShooter/Private/Characters/Components/ShootingComponent.cpp @@ -33,7 +33,8 @@ void UShootingComponent::BeginPlay() if (!bHasTraceProvider) { - UE_LOG(LogGDK, Error, TEXT("Shooting Component Exists without a Trace Providing component, please add an Actor Component that implements ITraceProvider.")); + UE_LOG(LogGDK, Error, TEXT("Shooting Component on %s exists without a Trace Providing component, please add an Actor Component that implements ITraceProvider."), + *GetPathNameSafe(GetOwner())); } } diff --git a/Game/Source/GDKShooter/Private/Deployments/DeploymentSnapshotTemplate.cpp b/Game/Source/GDKShooter/Private/Deployments/DeploymentSnapshotTemplate.cpp index a204aae5..2bbcd247 100644 --- a/Game/Source/GDKShooter/Private/Deployments/DeploymentSnapshotTemplate.cpp +++ b/Game/Source/GDKShooter/Private/Deployments/DeploymentSnapshotTemplate.cpp @@ -28,13 +28,13 @@ bool UDeploymentSnapshotTemplate::WriteToSnapshotOutput(Worker_SnapshotOutputStr // Serialize Session component data Worker_ComponentData SessionComponentData{}; SessionComponentData.component_id = 1000; - SessionComponentData.schema_type = Schema_CreateComponentData(1000); + SessionComponentData.schema_type = Schema_CreateComponentData(); Schema_Object* SessionComponentDataObject = Schema_GetComponentDataFields(SessionComponentData.schema_type); Schema_AddInt32(SessionComponentDataObject, 1, 1); Worker_ComponentData DeploymentComponentData{}; DeploymentComponentData.component_id = 1001; - DeploymentComponentData.schema_type = Schema_CreateComponentData(1001); + DeploymentComponentData.schema_type = Schema_CreateComponentData(); Components.Add(SpatialGDK::Position(SpatialGDK::Origin).CreatePositionData()); Components.Add(SpatialGDK::Metadata(TEXT("Session")).CreateMetadataData()); @@ -46,7 +46,8 @@ bool UDeploymentSnapshotTemplate::WriteToSnapshotOutput(Worker_SnapshotOutputStr SessionEntity.component_count = Components.Num(); SessionEntity.components = Components.GetData(); - bool success = Worker_SnapshotOutputStream_WriteEntity(OutputStream, &SessionEntity) != 0; + Worker_SnapshotOutputStream_WriteEntity(OutputStream, &SessionEntity); + bool success = Worker_SnapshotOutputStream_GetState(OutputStream).stream_state == WORKER_STREAM_STATE_GOOD; if (success) { NextEntityId++; } diff --git a/Game/Source/GDKShooter/Private/Game/Components/LobbyTimerComponent.cpp b/Game/Source/GDKShooter/Private/Game/Components/LobbyTimerComponent.cpp index f3c2e884..7c9582b0 100644 --- a/Game/Source/GDKShooter/Private/Game/Components/LobbyTimerComponent.cpp +++ b/Game/Source/GDKShooter/Private/Game/Components/LobbyTimerComponent.cpp @@ -3,14 +3,21 @@ #include "LobbyTimerComponent.h" #include "GDKLogging.h" #include "GameFramework/Actor.h" +#include "Misc/CommandLine.h" void ULobbyTimerComponent::BeginPlay() { +#if !UE_BUILD_SHIPPING + // Developer cheat so you don't have to wait for a long time before entering a match. + const TCHAR* CommandLine = FCommandLine::Get(); + FParse::Value(CommandLine, TEXT("lobbytime"), DefaultTimerDuration); + FParse::Value(CommandLine, TEXT("lobbyminplayers"), MinimumPlayersToStartCountdown); +#endif bAutoStart = (MinimumPlayersToStartCountdown == 0); Super::BeginPlay(); } -void ULobbyTimerComponent::InformOfPlayerCount(int32 PlayerCount) +void ULobbyTimerComponent::ServerInformOfPlayerCount_Implementation(int32 PlayerCount) { if (bHasTimerFinished || !GetOwner()->HasAuthority()) { diff --git a/Game/Source/GDKShooter/Private/Game/Components/MatchTimerComponent.cpp b/Game/Source/GDKShooter/Private/Game/Components/MatchTimerComponent.cpp index 7a5879c8..948846c3 100644 --- a/Game/Source/GDKShooter/Private/Game/Components/MatchTimerComponent.cpp +++ b/Game/Source/GDKShooter/Private/Game/Components/MatchTimerComponent.cpp @@ -1,5 +1,14 @@ // Copyright (c) Improbable Worlds Ltd, All Rights Reserved #include "MatchTimerComponent.h" +#include "Misc/CommandLine.h" - +void UMatchTimerComponent::BeginPlay() +{ +#if !UE_BUILD_SHIPPING + // Developer cheat so you can run an arbitrarily long match for testing. + const TCHAR* CommandLine = FCommandLine::Get(); + FParse::Value(CommandLine, TEXT("matchtime"), DefaultTimerDuration); +#endif + Super::BeginPlay(); +} diff --git a/Game/Source/GDKShooter/Private/Game/Components/SpatialSessionStateComponent.cpp b/Game/Source/GDKShooter/Private/Game/Components/SpatialSessionStateComponent.cpp index 73e7a631..aa1771d6 100644 --- a/Game/Source/GDKShooter/Private/Game/Components/SpatialSessionStateComponent.cpp +++ b/Game/Source/GDKShooter/Private/Game/Components/SpatialSessionStateComponent.cpp @@ -33,7 +33,7 @@ void USpatialSessionStateComponent::SendStateUpdate(EGDKSessionProgress SessionP Worker_EntityId target_entity_id = SessionEntityId; Worker_ComponentUpdate component_update = {}; component_update.component_id = SessionComponentId; - component_update.schema_type = Schema_CreateComponentUpdate(SessionComponentId); + component_update.schema_type = Schema_CreateComponentUpdate(); Schema_Object* fields_object = Schema_GetComponentUpdateFields(component_update.schema_type); Schema_AddInt32(fields_object, 1, SessionState); SpatialNetDriver->Connection->SendComponentUpdate(target_entity_id, &component_update); diff --git a/Game/Source/GDKShooter/Public/Deployments/DeploymentSnapshotTemplate.h b/Game/Source/GDKShooter/Public/Deployments/DeploymentSnapshotTemplate.h index 435bb49d..fc7218cb 100644 --- a/Game/Source/GDKShooter/Public/Deployments/DeploymentSnapshotTemplate.h +++ b/Game/Source/GDKShooter/Public/Deployments/DeploymentSnapshotTemplate.h @@ -4,6 +4,8 @@ #include "CoreMinimal.h" #include "Utils/SnapshotGenerationTemplate.h" +#include + #include "DeploymentSnapshotTemplate.generated.h" diff --git a/Game/Source/GDKShooter/Public/Game/Components/LobbyTimerComponent.h b/Game/Source/GDKShooter/Public/Game/Components/LobbyTimerComponent.h index d0afd5e2..c9deaba2 100644 --- a/Game/Source/GDKShooter/Public/Game/Components/LobbyTimerComponent.h +++ b/Game/Source/GDKShooter/Public/Game/Components/LobbyTimerComponent.h @@ -13,8 +13,8 @@ class GDKSHOOTER_API ULobbyTimerComponent : public UTimerComponent public: - UFUNCTION(BlueprintCallable) - void InformOfPlayerCount(int32 PlayerCount); + UFUNCTION(CrossServer, Reliable, BlueprintCallable) + void ServerInformOfPlayerCount(int32 PlayerCount); UPROPERTY(EditDefaultsOnly) int32 MinimumPlayersToStartCountdown = 1; diff --git a/Game/Source/GDKShooter/Public/Game/Components/MatchTimerComponent.h b/Game/Source/GDKShooter/Public/Game/Components/MatchTimerComponent.h index 008f77a0..e67e5892 100644 --- a/Game/Source/GDKShooter/Public/Game/Components/MatchTimerComponent.h +++ b/Game/Source/GDKShooter/Public/Game/Components/MatchTimerComponent.h @@ -12,4 +12,6 @@ class GDKSHOOTER_API UMatchTimerComponent : public UTimerComponent { GENERATED_BODY() +protected: + virtual void BeginPlay() override; }; diff --git a/ci/common.ps1 b/ci/common.ps1 new file mode 100644 index 00000000..3d409533 --- /dev/null +++ b/ci/common.ps1 @@ -0,0 +1,58 @@ +function Write-Log() { + param( + [string] $msg, + [Parameter(Mandatory=$false)] [bool] $expand = $false + ) + if ($expand) { + Write-Output "+++ $($msg)" + } else { + Write-Output "--- $($msg)" + } +} + +function Start-Event() { + param( + [string] $event_name, + [string] $event_parent + ) + + # Start this tracing span. + Start-Process -NoNewWindow "imp-ci" -ArgumentList @(` + "events", "new", ` + "--name", "$($event_name)", ` + "--child-of", "$($event_parent)" + ) | Out-Null + + Write-Log "--- $($event_name)" +} + +function Finish-Event() { + param( + [string] $event_name, + [string] $event_parent + ) + + # Emit the end marker for this tracing span. + Start-Process -NoNewWindow "imp-ci" -ArgumentList @(` + "events", "new", ` + "--name", "$($event_name)", ` + "--child-of", "$($event_parent)" + ) | Out-Null +} + +## Checks whether the specified environment variable has been set. If it has, return its value. Else return the default value. +function Get-Env-Variable-Value-Or-Default() { + param( + [string] $environment_variable_name, + [string] $default_value + ) + + If (Test-Path env:$environment_variable_name) { + $environment_variable_value = Get-Content -Path env:$environment_variable_name + return $environment_variable_value + } Else { + return $default_value + } +} + +$ErrorActionPreference = 'Stop' \ No newline at end of file diff --git a/ci/deploy.ps1 b/ci/deploy.ps1 new file mode 100644 index 00000000..47e725bc --- /dev/null +++ b/ci/deploy.ps1 @@ -0,0 +1,140 @@ +param( + [string] $launch_deployment = "false", + [string] $gdk_branch_name = "master" +) + +. "$PSScriptRoot\common.ps1" + +Start-Event "deploy-game" "build-unreal-gdk-example-project-:windows:" + # Use the shortened commit hash gathered during GDK plugin clone and the current date and time to distinguish the deployment + $date_and_time = Get-Date -Format "MMdd_HHmm" + $deployment_name = "exampleproject_${date_and_time}_$($gdk_commit_hash)" + $assembly_name = "$($deployment_name)_asm" + +pushd "spatial" + + Start-Event "build-worker-configurations" "deploy-unreal-gdk-example-project-:windows:" + $build_configs_process = Start-Process -Wait -PassThru -NoNewWindow -FilePath "spatial" -ArgumentList @(` + "build", ` + "build-config" + ) + + if ($build_configs_process.ExitCode -ne 0) { + Write-Log "Failed to build worker configurations for the project. Error: $($build_configs_process.ExitCode)" + Throw "Failed to build worker configurations" + } + Finish-Event "build-worker-configurations" "deploy-unreal-gdk-example-project-:windows:" + + Start-Event "prepare-for-run" "deploy-unreal-gdk-example-project-:windows:" + $prepare_for_run_process = Start-Process -Wait -PassThru -NoNewWindow -FilePath "spatial" -ArgumentList @(` + "prepare-for-run", ` + "--log_level=debug" + ) + + if ($prepare_for_run_process.ExitCode -ne 0) { + Write-Log "Failed to prepare for a Spatial cloud launch. Error: $($prepare_for_run_process.ExitCode)" + Throw "Spatial prepare for run failed" + } + Finish-Event "prepare-for-run" "deploy-unreal-gdk-example-project-:windows:" + + Start-Event "upload-assemblies" "deploy-unreal-gdk-example-project-:windows:" + $upload_assemblies_process = Start-Process -Wait -PassThru -NoNewWindow -FilePath "spatial" -ArgumentList @(` + "cloud", ` + "upload", ` + "$assembly_name", ` + "--project_name=$project_name", ` + "--log_level=debug", ` + "--force" + ) + + if ($upload_assemblies_process.ExitCode -ne 0) { + Write-Log "Failed to upload assemblies to cloud. Error: $($upload_assemblies_process.ExitCode)" + Throw "Failed to upload assemblies" + } + Finish-Event "upload-assemblies" "deploy-unreal-gdk-example-project-:windows:" + + Start-Event "launch-deployment" "deploy-unreal-gdk-example-project-:windows:" + # Determine whether deployment should be launched (it will by default) + if ($launch_deployment -eq "true") { + $launch_deployment_process = Start-Process -Wait -PassThru -NoNewWindow -FilePath "spatial" -ArgumentList @(` + "cloud", ` + "launch", ` + "$assembly_name", ` + "$deployment_launch_configuration", ` + "$deployment_name", ` + "--project_name=$project_name", ` + "--snapshot=$deployment_snapshot_path", ` + "--cluster_region=$deployment_cluster_region", ` + "--log_level=debug", ` + "--tags=ttl_1_hours" + ) + + if ($launch_deployment_process.ExitCode -ne 0) { + Write-Log "Failed to launch a Spatial cloud deployment. Error: $($launch_deployment_process.ExitCode)" + Throw "Deployment launch failed" + } + + # Send a Slack notification with a link to the new deployment and to the build. + # Read Slack webhook secret from the vault and extract the Slack webhook URL from it. + $slack_webhook_secret = "$(imp-ci secrets read --environment=production --buildkite-org=improbable --secret-type=slack-webhook --secret-name=unreal-gdk-slack-web-hook)" + $slack_webhook_url = $slack_webhook_secret | ConvertFrom-Json | %{$_.url} + + $deployment_url = "https://console.improbable.io/projects/${project_name}/deployments/${deployment_name}/overview" + $gdk_commit_url = "https://github.com/spatialos/UnrealGDK/tree/${gdk_commit_hash}" + $build_url = "$env:BUILDKITE_BUILD_URL" + + $json_message = [ordered]@{ + text = "Example Project build created by $env:BUILDKITE_BUILD_CREATOR succeeded and a deployment has been launched." + attachments= @( + @{ + fallback = "Find deployment here: $deployment_url and build here: $build_url" + color = "good" + fields= @( + @{ + title = "GDK branch" + value = "$gdk_branch_name" + short = "true" + } + @{ + title = "Example Project branch" + value = "$env:BUILDKITE_BRANCH" + short = "true" + } + ) + actions= @( + @{ + type = "button" + text = "Take me to the deployment" + url = "$deployment_url" + style = "primary" + } + @{ + type = "button" + text = "Take me to the GDK commit" + url = "$gdk_commit_url" + style = "primary" + } + @{ + type = "button" + text = "Take me to the build" + url = "$build_url" + style = "primary" + } + ) + } + ) + } + + $json_request = $json_message | ConvertTo-Json -Depth 10 + + Invoke-WebRequest -UseBasicParsing "$slack_webhook_url" -ContentType "application/json" -Method POST -Body "$json_request" + + } + else { + Write-Log "Deployment will not be launched as you have passed in an argument specifying that it should not be (START_DEPLOYMENT=${launch_deployment}). Remove it to have your build launch a deployment." + } + + Finish-Event "launch-deployment" "deploy-unreal-gdk-example-project-:windows:" + +popd +Finish-Event "deploy-game" "build-unreal-gdk-example-project-:windows:" diff --git a/ci/setup-and-build.ps1 b/ci/setup-and-build.ps1 new file mode 100644 index 00000000..97414de2 --- /dev/null +++ b/ci/setup-and-build.ps1 @@ -0,0 +1,151 @@ +param( + [string] $exampleproject_home = (get-item "$($PSScriptRoot)").parent.FullName, ## The root of the repo + [string] $gdk_repo = "git@github.com:spatialos/UnrealGDK.git", + [string] $gcs_publish_bucket = "io-internal-infra-unreal-artifacts-production/UnrealEngine", + [string] $deployment_launch_configuration = "one_worker_test.json", + [string] $deployment_snapshot_path = "snapshots/FPS-Start_Small.snapshot", + [string] $deployment_cluster_region = "eu", + [string] $project_name = "unreal_gdk" +) + +. "$PSScriptRoot\common.ps1" + +# When a build is launched custom environment variables can be specified. +# Parse them here to use the set value or the default. +$gdk_branch_name = Get-Env-Variable-Value-Or-Default -environment_variable_name "GDK_BRANCH" -default_value "master" +$launch_deployment = Get-Env-Variable-Value-Or-Default -environment_variable_name "START_DEPLOYMENT" -default_value "true" + +$gdk_home = "${exampleproject_home}\Game\Plugins\UnrealGDK" + +pushd "$exampleproject_home" + Start-Event "clone-gdk-plugin" "build-unreal-gdk-example-project-:windows:" + pushd "Game" + New-Item -Name "Plugins" -ItemType Directory -Force + pushd "Plugins" + Start-Process -Wait -PassThru -NoNewWindow -FilePath "git" -ArgumentList @(` + "clone", ` + "$gdk_repo", ` + "--depth 1", ` + "-b $gdk_branch_name" + ) + popd + popd + Finish-Event "clone-gdk-plugin" "build-unreal-gdk-example-project-:windows:" + + Start-Event "get-gdk-head-commit" "build-unreal-gdk-example-project-:windows:" + pushd $gdk_home + # Get the short commit hash of this gdk build for later use in assembly name + $gdk_commit_hash = (git rev-parse HEAD).Substring(0,7) + Write-Log "GDK at commit: $gdk_commit_hash on branch $gdk_branch_name" + popd + Finish-Event "get-gdk-head-commit" "build-unreal-gdk-example-project-:windows:" + + Start-Event "set-up-gdk-plugin" "build-unreal-gdk-example-project-:windows:" + pushd $gdk_home + # Invoke the GDK's setup script + &"$($gdk_home)\ci\setup-gdk.ps1" + popd + Finish-Event "set-up-gdk-plugin" "build-unreal-gdk-example-project-:windows:" + + # Use the cached engine version or set it up if it has not been cached yet. + Start-Event "set-up-engine" "build-unreal-gdk-example-project-:windows:" + + $engine_directory = "${exampleproject_home}\UnrealEngine" + &"$($gdk_home)\ci\get-engine.ps1" -unreal_path "$engine_directory" + + Finish-Event "set-up-engine" "build-unreal-gdk-example-project-:windows:" + + + Start-Event "associate-uproject-with-engine" "build-unreal-gdk-example-project-:windows:" + pushd $engine_directory + $unreal_version_selector_path = "Engine\Binaries\Win64\UnrealVersionSelector.exe" + + $find_engine_process = Start-Process -Wait -PassThru -NoNewWindow -FilePath $unreal_version_selector_path -ArgumentList @(` + "-switchversionsilent", ` + "${exampleproject_home}\Game\GDKShooter.uproject", ` + "$engine_directory" + ) + + if ($find_engine_process.ExitCode -ne 0) { + Write-Log "Failed to set Unreal Engine association for the project. Error: $($find_engine_process.ExitCode)" + Throw "Failed to set Engine association" + } + popd + Finish-Event "associate-uproject-with-engine" "build-unreal-gdk-example-project-:windows:" + + + $build_script_path = "$($gdk_home)\SpatialGDK\Build\Scripts\BuildWorker.bat" + + Start-Event "build-editor" "build-unreal-gdk-example-project-:windows:" + # Build the project editor to allow the snapshot and schema commandlet to run + $build_editor_proc = Start-Process -PassThru -NoNewWindow -FilePath $build_script_path -ArgumentList @(` + "GDKShooterEditor", ` + "Win64", ` + "Development", ` + "GDKShooter.uproject" + ) + + # Explicitly hold on to the process handle. + # This works around an issue whereby Wait-Process would fail to find build_editor_proc + $build_editor_handle = $build_editor_proc.Handle + + Wait-Process -Id (Get-Process -InputObject $build_editor_proc).id + if ($build_editor_proc.ExitCode -ne 0) { + Write-Log "Failed to build Win64 Development Editor. Error: $($build_editor_proc.ExitCode)" + Throw "Failed to build Win64 Development Editor" + } + Finish-Event "build-editor" "build-unreal-gdk-example-project-:windows:" + + # Invoke the GDK commandlet to generate schema and snapshot. Note: this needs to be run prior to cooking + Start-Event "generate-schema" "build-unreal-gdk-example-project-:windows:" + pushd "UnrealEngine/Engine/Binaries/Win64" + Start-Process -Wait -PassThru -NoNewWindow -FilePath ((Convert-Path .) + "\UE4Editor.exe") -ArgumentList @(` + "$($exampleproject_home)/Game/GDKShooter.uproject", ` + "-run=GenerateSchemaAndSnapshots", ` + "-MapPaths=`"/Maps/FPS-Start_Small`"" + ) + + # TODO (GV-29) this is also being done as part of setup.bat. We should look into calling setup.bat instead of this, but need to make sure it doesn't brake if called after setup-gdk.ps1 + $core_gdk_schema_path = "$($gdk_home)\SpatialGDK\Extras\schema\*" + $schema_std_lib_path = "$($gdk_home)\SpatialGDK\Binaries\ThirdParty\Improbable\Programs\schema\*" + New-Item -Path "$($exampleproject_home)\spatial\schema\unreal" -Name "gdk" -ItemType Directory -Force + New-Item -Path "$($exampleproject_home)\spatial" -Name "\build\dependencies\schema\standard_library" -ItemType Directory -Force + Copy-Item "$($core_gdk_schema_path)" -Destination "$($exampleproject_home)\spatial\schema\unreal\gdk" -Force -Recurse + Copy-Item "$($schema_std_lib_path)" -Destination "$($exampleproject_home)\spatial\build\dependencies\schema\standard_library" -Force -Recurse + popd + Finish-Event "generate-schema" "build-unreal-gdk-example-project-:windows:" + + Start-Event "build-win64-client" "build-unreal-gdk-example-project-:windows:" + $build_client_proc = Start-Process -PassThru -NoNewWindow -FilePath $build_script_path -ArgumentList @(` + "GDKShooter", ` + "Win64", ` + "Development", ` + "GDKShooter.uproject" + ) + $build_client_handle = $build_client_proc.Handle + Wait-Process -Id (Get-Process -InputObject $build_client_proc).id + if ($build_client_proc.ExitCode -ne 0) { + Write-Log "Failed to build Win64 Development Client. Error: $($build_client_proc.ExitCode)" + Throw "Failed to build Win64 Development Client" + } + Finish-Event "build-win64-client" "build-unreal-gdk-example-project-:windows:" + + Start-Event "build-linux-worker" "build-unreal-gdk-example-project-:windows:" + $build_server_proc = Start-Process -PassThru -NoNewWindow -FilePath $build_script_path -ArgumentList @(` + "GDKShooterServer", ` + "Linux", ` + "Development", ` + "GDKShooter.uproject" + ) + $build_server_handle = $build_server_proc.Handle + Wait-Process -Id (Get-Process -InputObject $build_server_proc).id + + if ($build_server_proc.ExitCode -ne 0) { + Write-Log "Failed to build Linux Development Server. Error: $($build_server_proc.ExitCode)" + Throw "Failed to build Linux Development Server" + } + Finish-Event "build-linux-worker" "build-unreal-gdk-example-project-:windows:" + + # Deploy the project to SpatialOS + &$PSScriptRoot"\deploy.ps1" -launch_deployment "$launch_deployment" -gdk_branch_name "$gdk_branch_name" +popd \ No newline at end of file diff --git a/spatial/default_launch.json b/spatial/default_launch.json index 84be46d1..1e34cccf 100644 --- a/spatial/default_launch.json +++ b/spatial/default_launch.json @@ -15,10 +15,6 @@ { "name": "bridge_soft_handover_enabled", "value": "false" - }, - { - "name": "enable_chunk_interest", - "value": "false" } ], "snapshots": { diff --git a/spatial/one_worker_test.json b/spatial/one_worker_test.json index d6522819..bc1ce21d 100644 --- a/spatial/one_worker_test.json +++ b/spatial/one_worker_test.json @@ -9,10 +9,6 @@ { "name": "bridge_soft_handover_enabled", "value": "false" - }, - { - "name": "enable_chunk_interest", - "value": "false" } ], "dimensions": { diff --git a/spatial/spatialos.json b/spatial/spatialos.json index 5ebacfa2..e5e5f760 100644 --- a/spatial/spatialos.json +++ b/spatial/spatialos.json @@ -1,11 +1,11 @@ { "name": "your_project_name_here", "project_version": "0.0.1", - "sdk_version": "13.8.1", + "sdk_version": "14.1.0", "dependencies": [ { "name": "standard_library", - "version": "13.8.1" + "version": "14.1.0" } ] } diff --git a/spatial/workers/deployment-manager/spatialos.DeploymentManager.worker.json b/spatial/workers/deployment-manager/spatialos.DeploymentManager.worker.json index 27b64638..e11a1f38 100644 --- a/spatial/workers/deployment-manager/spatialos.DeploymentManager.worker.json +++ b/spatial/workers/deployment-manager/spatialos.DeploymentManager.worker.json @@ -21,11 +21,6 @@ "DeploymentManager" ] }, - "entity_interest": { - "range_entity_interest": { - "radius": 500 - } - }, "component_delivery": { "default": "RELIABLE_ORDERED", "checkoutAllInitially": true diff --git a/spatial/workers/improbable/spatialos.SimulatedPlayerCoordinator.worker.json b/spatial/workers/improbable/spatialos.SimulatedPlayerCoordinator.worker.json index 277201c4..e2f5dd4d 100644 --- a/spatial/workers/improbable/spatialos.SimulatedPlayerCoordinator.worker.json +++ b/spatial/workers/improbable/spatialos.SimulatedPlayerCoordinator.worker.json @@ -24,11 +24,6 @@ "SimulatedPlayerCoordinator" ] }, - "entity_interest": { - "range_entity_interest": { - "radius": 50 - } - }, "component_delivery": { "default": "RELIABLE_ORDERED", "checkout_all_initially": true diff --git a/spatial/workers/unreal/spatialos.AIWorker.worker.json b/spatial/workers/unreal/spatialos.AIWorker.worker.json deleted file mode 100644 index b6a4c824..00000000 --- a/spatial/workers/unreal/spatialos.AIWorker.worker.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "build": { - "tasks": [ - { - "name": "codegen", - "description": "required by spatial worker build build-config.", - "steps": [{"name": "No-op", "command": "echo", "arguments": ["No-op."]}] - }, - { - "name": "build", - "description": "required by spatial worker build build-config.", - "steps": [{"name": "No-op", "command": "echo", "arguments": ["No-op."]}] - }, - { - "name": "clean", - "description": "required by spatial worker build build-config.", - "steps": [{"name": "No-op", "command": "echo", "arguments": ["No-op."]}] - } - ] - }, - "bridge": { - "worker_attribute_set": { - "attributes": [ - "AIWorker" - ] - }, - "entity_interest": { - "range_entity_interest": { - "radius": 50 - } - }, - "streaming_query": [ - { - "global_component_streaming_query": { - "component_name": "unreal.SingletonManager" - } - }, - { - "global_component_streaming_query": { - "component_name": "unreal.Singleton" - } - } - ], - "component_delivery": { - "default": "RELIABLE_ORDERED", - "checkout_all_initially": true - } - }, - "managed": { - "windows": { - "artifact_name": "UnrealEditor@Windows.zip", - "command": "StartEditor.bat", - "arguments": [ - "ThirdPersonExampleMap", - "-server", - "-stdout", - "-nowrite", - "-unattended", - "-nologtimes", - "-nopause", - "-messaging", - "-SaveToUserDir", - "+appName", - "${IMPROBABLE_PROJECT_NAME}", - "+receptionistHost", - "${IMPROBABLE_RECEPTIONIST_HOST}", - "+receptionistPort", - "${IMPROBABLE_RECEPTIONIST_PORT}", - "+workerType", - "${IMPROBABLE_WORKER_NAME}", - "+workerId", - "${IMPROBABLE_WORKER_ID}", - "+linkProtocol", - "Tcp", - "-abslog=${IMPROBABLE_LOG_FILE}", - "-NoVerifyGC" - ] - }, - "linux": { - "artifact_name": "UnrealWorker@Linux.zip", - "command": "StartWorker.sh", - "arguments": [ - "${IMPROBABLE_WORKER_ID}", - "${IMPROBABLE_LOG_FILE}", - "ThirdPersonExampleMap", - "+appName", - "${IMPROBABLE_PROJECT_NAME}", - "+receptionistHost", - "${IMPROBABLE_RECEPTIONIST_HOST}", - "+receptionistPort", - "${IMPROBABLE_RECEPTIONIST_PORT}", - "+workerType", - "${IMPROBABLE_WORKER_NAME}", - "+workerId", - "${IMPROBABLE_WORKER_ID}", - "+linkProtocol", - "Tcp", - "-NoVerifyGC", - "-OverrideSpatialNetworking" - ] - } - } -} diff --git a/spatial/workers/unreal/spatialos.CrashBotWorker.worker.json b/spatial/workers/unreal/spatialos.CrashBotWorker.worker.json deleted file mode 100644 index 179cb622..00000000 --- a/spatial/workers/unreal/spatialos.CrashBotWorker.worker.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "build": { - "tasks": [ - { - "name": "codegen", - "description": "required by spatial worker build build-config.", - "steps": [{"name": "No-op", "command": "echo", "arguments": ["No-op."]}] - }, - { - "name": "build", - "description": "required by spatial worker build build-config.", - "steps": [{"name": "No-op", "command": "echo", "arguments": ["No-op."]}] - }, - { - "name": "clean", - "description": "required by spatial worker build build-config.", - "steps": [{"name": "No-op", "command": "echo", "arguments": ["No-op."]}] - } - ] - }, - "bridge": { - "worker_attribute_set": { - "attributes": [ - "CrashBotWorker" - ] - }, - "entity_interest": { - "range_entity_interest": { - "radius": 50 - } - }, - "streaming_query": [ - { - "global_component_streaming_query": { - "component_name": "unreal.SingletonManager" - } - }, - { - "global_component_streaming_query": { - "component_name": "unreal.Singleton" - } - } - ], - "component_delivery": { - "default": "RELIABLE_ORDERED", - "checkout_all_initially": true - } - }, - "managed": { - "windows": { - "artifact_name": "UnrealEditor@Windows.zip", - "command": "StartEditor.bat", - "arguments": [ - "ThirdPersonExampleMap", - "-server", - "-stdout", - "-nowrite", - "-unattended", - "-nologtimes", - "-nopause", - "-messaging", - "-SaveToUserDir", - "+appName", - "${IMPROBABLE_PROJECT_NAME}", - "+receptionistHost", - "${IMPROBABLE_RECEPTIONIST_HOST}", - "+receptionistPort", - "${IMPROBABLE_RECEPTIONIST_PORT}", - "+workerType", - "${IMPROBABLE_WORKER_NAME}", - "+workerId", - "${IMPROBABLE_WORKER_ID}", - "+linkProtocol", - "Tcp", - "-abslog=${IMPROBABLE_LOG_FILE}", - "-NoVerifyGC" - ] - }, - "linux": { - "artifact_name": "UnrealWorker@Linux.zip", - "command": "StartWorker.sh", - "arguments": [ - "${IMPROBABLE_WORKER_ID}", - "${IMPROBABLE_LOG_FILE}", - "ThirdPersonExampleMap", - "+appName", - "${IMPROBABLE_PROJECT_NAME}", - "+receptionistHost", - "${IMPROBABLE_RECEPTIONIST_HOST}", - "+receptionistPort", - "${IMPROBABLE_RECEPTIONIST_PORT}", - "+workerType", - "${IMPROBABLE_WORKER_NAME}", - "+workerId", - "${IMPROBABLE_WORKER_ID}", - "+linkProtocol", - "Tcp", - "-NoVerifyGC", - "-OverrideSpatialNetworking" - ] - } - } -} diff --git a/spatial/workers/unreal/spatialos.UnrealClient.worker.json b/spatial/workers/unreal/spatialos.UnrealClient.worker.json index 236dfb8d..c320e172 100644 --- a/spatial/workers/unreal/spatialos.UnrealClient.worker.json +++ b/spatial/workers/unreal/spatialos.UnrealClient.worker.json @@ -24,23 +24,6 @@ "UnrealClient" ] }, - "entity_interest": { - "range_entity_interest": { - "radius": 50 - } - }, - "streaming_query": [ - { - "global_component_streaming_query": { - "component_name": "unreal.SingletonManager" - } - }, - { - "global_component_streaming_query": { - "component_name": "unreal.Singleton" - } - } - ], "component_delivery": { "default": "RELIABLE_ORDERED", "checkout_all_initially": true diff --git a/spatial/workers/unreal/spatialos.UnrealWorker.worker.json b/spatial/workers/unreal/spatialos.UnrealWorker.worker.json index c887d063..92f2e8e4 100644 --- a/spatial/workers/unreal/spatialos.UnrealWorker.worker.json +++ b/spatial/workers/unreal/spatialos.UnrealWorker.worker.json @@ -24,23 +24,6 @@ "UnrealWorker" ] }, - "entity_interest": { - "range_entity_interest": { - "radius": 50 - } - }, - "streaming_query": [ - { - "global_component_streaming_query": { - "component_name": "unreal.SingletonManager" - } - }, - { - "global_component_streaming_query": { - "component_name": "unreal.Singleton" - } - } - ], "component_delivery": { "default": "RELIABLE_ORDERED", "checkout_all_initially": true