From d98438d043fe367169f4c11879f6938468ef9a4e Mon Sep 17 00:00:00 2001 From: Joseph Nicholas Date: Mon, 20 May 2019 16:53:57 +0100 Subject: [PATCH 1/9] Update map in LaunchServer.bat Updated server map in LaunchServer.bat to match server default map in editor config --- LaunchServer.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LaunchServer.bat b/LaunchServer.bat index 222bdcc6..702cdb6c 100644 --- a/LaunchServer.bat +++ b/LaunchServer.bat @@ -1,3 +1,3 @@ @echo off call "%~dp0ProjectPaths.bat" -"%UNREAL_HOME%\Engine\Binaries\Win64\UE4Editor.exe" "%~dp0%PROJECT_PATH%\%GAME_NAME%.uproject" ThirdPersonExampleMap -server -log -workerType UnrealWorker -stdout -nowrite -unattended -nologtimes -nopause -noin -messaging -SaveToUserDir -NoVerifyGC -windowed -resX=400 -resY=300 +"%UNREAL_HOME%\Engine\Binaries\Win64\UE4Editor.exe" "%~dp0%PROJECT_PATH%\%GAME_NAME%.uproject" FPS-Start_Medium -server -log -workerType UnrealWorker -stdout -nowrite -unattended -nologtimes -nopause -noin -messaging -SaveToUserDir -NoVerifyGC -windowed -resX=400 -resY=300 From 6c2e40419dd29d7a1b7c8ef7c772ef559231cdcd Mon Sep 17 00:00:00 2001 From: Ernest Oppetit Date: Mon, 20 May 2019 17:28:44 +0100 Subject: [PATCH 2/9] Readme image --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index da28ce0e..2bd472c6 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ - **LICENSE:** Use of the contents of this repository is subject to the [license](LICENSE.md) +![](https://commondatastorage.googleapis.com/improbable-docs/docs2/unreal/1467e0562596379c/assets/example-project/example-project-headline.png) + This project is an example shooter game which uses the [SpatialOS GDK for Unreal](https://github.com/spatialos/unrealGDK). The project contains gameplay and assets that are representative of a basic first-person shooter running on SpatialOS. If you want to make your own project from scratch, use the [Starter Template](https://docs.improbable.io/unreal/alpha/content/get-started/gdk-template). @@ -51,4 +53,4 @@ The GDK and related projects are available on GitHub. We are not currently accepting public contributions. However, we are accepting [issues](https://github.com/spatialos/UnrealGDK/issues) and we do want your feedback. -© 2019 Improbable \ No newline at end of file +© 2019 Improbable From f7d3d856d080e5c003ff0832a8176cd9842c0e8d Mon Sep 17 00:00:00 2001 From: Ernest Oppetit Date: Tue, 21 May 2019 10:48:47 +0100 Subject: [PATCH 3/9] Add example project image with logo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2bd472c6..f84c9498 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ - **LICENSE:** Use of the contents of this repository is subject to the [license](LICENSE.md) -![](https://commondatastorage.googleapis.com/improbable-docs/docs2/unreal/1467e0562596379c/assets/example-project/example-project-headline.png) +![Example Project](https://user-images.githubusercontent.com/2433131/58086122-f28af200-7bb5-11e9-9b96-b13b747130d0.png) This project is an example shooter game which uses the [SpatialOS GDK for Unreal](https://github.com/spatialos/unrealGDK). From 8f5db4bc4b04856e3af7f4388b3ed682671caae8 Mon Sep 17 00:00:00 2001 From: Ernest Oppetit Date: Tue, 21 May 2019 10:51:59 +0100 Subject: [PATCH 4/9] Image sizing --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f84c9498..f573b906 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # SpatialOS Unreal GDK Example Project -- **LICENSE:** Use of the contents of this repository is subject to the [license](LICENSE.md) + -![Example Project](https://user-images.githubusercontent.com/2433131/58086122-f28af200-7bb5-11e9-9b96-b13b747130d0.png) +- **LICENSE:** Use of the contents of this repository is subject to the [license](LICENSE.md) This project is an example shooter game which uses the [SpatialOS GDK for Unreal](https://github.com/spatialos/unrealGDK). From 6181182fb4d7b7b6822cc553b33613906f07e428 Mon Sep 17 00:00:00 2001 From: Ieva Vasiljeva Date: Wed, 29 May 2019 17:09:52 +0100 Subject: [PATCH 5/9] Check authority before making session state updates. --- .../Private/Game/GDKSessionGameState.cpp | 39 +++++++++++++++---- .../Public/Game/GDKSessionGameState.h | 6 +++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp index 0ca88a0f..ba970331 100644 --- a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp +++ b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp @@ -6,6 +6,7 @@ #include "UnrealNetwork.h" #include "SpatialNetDriver.h" #include "SpatialWorkerConnection.h" +#include "Interop/SpatialStaticComponentView.h" #include "c_worker.h" #include "c_schema.h" @@ -44,6 +45,15 @@ void AGDKSessionGameState::RemovePlayerState(APlayerState* PlayerState) void AGDKSessionGameState::OnRep_SessionProgress() { + USpatialNetDriver* SpatialNetDriver = Cast(GetWorld()->GetNetDriver()); + bool AuthoritativeOverSessionEntity = SpatialNetDriver->StaticComponentView->HasAuthority(SessionEntityId, SessionComponentId); + + if (AuthoritativeOverSessionEntity) + { + // There's an offset of 1 between the corresponding states of session progress and session state. + int SessionState = (int)SessionProgress + 1; + SendStateUpdate(SessionState); + } TimerEvent.Broadcast(SessionProgress, SessionTimer); } @@ -64,29 +74,43 @@ void AGDKSessionGameState::BeginTimer() void AGDKSessionGameState::TickGameTimer() { - if (GetNetMode() != NM_Client) + bool AuthoritativeOverSessionProgress = Role == ROLE_Authority; + + if (GetNetMode() != NM_Client && AuthoritativeOverSessionProgress) { SessionTimer--; + USpatialNetDriver* SpatialNetDriver = Cast(GetWorld()->GetNetDriver()); + bool AuthoritativeOverSessionEntity = SpatialNetDriver->StaticComponentView->HasAuthority(SessionEntityId, SessionComponentId); + if (SessionProgress == EGDKSessionProgress::Lobby && SessionTimer <= 0) { UE_LOG(LogGDK, Log, TEXT("Advance GameState to Running")); SessionProgress = EGDKSessionProgress::Running; - SendStateUpdate(2); + if (AuthoritativeOverSessionEntity) + { + SendStateUpdate(2); + } SessionTimer = GameSessionLength; } if (SessionProgress == EGDKSessionProgress::Running && SessionTimer <= 0) { UE_LOG(LogGDK, Log, TEXT("Advance GameState to Results")); SessionProgress = EGDKSessionProgress::Results; - SendStateUpdate(3); + if (AuthoritativeOverSessionEntity) + { + SendStateUpdate(3); + } SessionTimer = ResultsSessionLength; } if (SessionProgress == EGDKSessionProgress::Results && SessionTimer <= 0) { UE_LOG(LogGDK, Log, TEXT("Advance GameState to Finished")); SessionProgress = EGDKSessionProgress::Finished; - SendStateUpdate(4); + if (AuthoritativeOverSessionEntity) + { + SendStateUpdate(4); + } } } } @@ -98,13 +122,14 @@ void AGDKSessionGameState::SendStateUpdate(int NewState) return; } - Worker_EntityId target_entity_id = 39; + Worker_EntityId target_entity_id = SessionEntityId; Worker_ComponentUpdate component_update = {}; - component_update.component_id = 1000; - component_update.schema_type = Schema_CreateComponentUpdate(1000); + component_update.component_id = SessionComponentId; + component_update.schema_type = Schema_CreateComponentUpdate(SessionComponentId); Schema_Object* fields_object = Schema_GetComponentUpdateFields(component_update.schema_type); Schema_AddInt32(fields_object, 1, NewState); Cast(GetWorld()->GetNetDriver())->Connection->SendComponentUpdate(target_entity_id, &component_update); + UE_LOG(LogGDK, Warning, TEXT("Sending update for session component. State: %i; worker authority: %i"), NewState, Role.GetValue()); } diff --git a/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h b/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h index ff8f80e2..e243f23b 100644 --- a/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h +++ b/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h @@ -6,6 +6,9 @@ #include "GDKLogging.h" #include "Game/GDKGameState.h" #include "GDKSessionProgress.h" + +#include + #include "GDKSessionGameState.generated.h" DECLARE_EVENT_TwoParams(AGDKGameState, FSessionTimerEvent, EGDKSessionProgress, int); @@ -42,6 +45,9 @@ class GDKSHOOTER_API AGDKSessionGameState : public AGDKGameState UPROPERTY(EditAnywhere, Category = "Timers") int ResultsSessionLength = 60; + + Worker_EntityId SessionEntityId = 39; + Worker_ComponentId SessionComponentId = 1000; FTimerHandle TickTimer; From 3243f98a8a40a7b0f34fa7e70ed1ef620cbc717b Mon Sep 17 00:00:00 2001 From: Ieva Vasiljeva Date: Fri, 31 May 2019 13:47:08 +0100 Subject: [PATCH 6/9] Clean up imports and variable names. --- .../Private/Game/GDKSessionGameState.cpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp index ba970331..0bb1877c 100644 --- a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp +++ b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp @@ -2,14 +2,14 @@ #include "GDKSessionGameState.h" +#include "Interop/SpatialStaticComponentView.h" #include "TimerManager.h" #include "UnrealNetwork.h" #include "SpatialNetDriver.h" #include "SpatialWorkerConnection.h" -#include "Interop/SpatialStaticComponentView.h" -#include "c_worker.h" -#include "c_schema.h" +#include +#include void AGDKSessionGameState::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const { @@ -46,9 +46,9 @@ void AGDKSessionGameState::RemovePlayerState(APlayerState* PlayerState) void AGDKSessionGameState::OnRep_SessionProgress() { USpatialNetDriver* SpatialNetDriver = Cast(GetWorld()->GetNetDriver()); - bool AuthoritativeOverSessionEntity = SpatialNetDriver->StaticComponentView->HasAuthority(SessionEntityId, SessionComponentId); + bool bAuthoritativeOverSessionEntity = SpatialNetDriver->StaticComponentView->HasAuthority(SessionEntityId, SessionComponentId); - if (AuthoritativeOverSessionEntity) + if (bAuthoritativeOverSessionEntity) { // There's an offset of 1 between the corresponding states of session progress and session state. int SessionState = (int)SessionProgress + 1; @@ -74,20 +74,20 @@ void AGDKSessionGameState::BeginTimer() void AGDKSessionGameState::TickGameTimer() { - bool AuthoritativeOverSessionProgress = Role == ROLE_Authority; + const bool bAuthoritativeOverSessionProgress = HasAuthority(); - if (GetNetMode() != NM_Client && AuthoritativeOverSessionProgress) + if (GetNetMode() != NM_Client && bAuthoritativeOverSessionProgress) { SessionTimer--; USpatialNetDriver* SpatialNetDriver = Cast(GetWorld()->GetNetDriver()); - bool AuthoritativeOverSessionEntity = SpatialNetDriver->StaticComponentView->HasAuthority(SessionEntityId, SessionComponentId); + bool bAuthoritativeOverSessionEntity = SpatialNetDriver->StaticComponentView->HasAuthority(SessionEntityId, SessionComponentId); if (SessionProgress == EGDKSessionProgress::Lobby && SessionTimer <= 0) { UE_LOG(LogGDK, Log, TEXT("Advance GameState to Running")); SessionProgress = EGDKSessionProgress::Running; - if (AuthoritativeOverSessionEntity) + if (bAuthoritativeOverSessionEntity) { SendStateUpdate(2); } @@ -97,7 +97,7 @@ void AGDKSessionGameState::TickGameTimer() { UE_LOG(LogGDK, Log, TEXT("Advance GameState to Results")); SessionProgress = EGDKSessionProgress::Results; - if (AuthoritativeOverSessionEntity) + if (bAuthoritativeOverSessionEntity) { SendStateUpdate(3); } @@ -107,7 +107,7 @@ void AGDKSessionGameState::TickGameTimer() { UE_LOG(LogGDK, Log, TEXT("Advance GameState to Finished")); SessionProgress = EGDKSessionProgress::Finished; - if (AuthoritativeOverSessionEntity) + if (bAuthoritativeOverSessionEntity) { SendStateUpdate(4); } From eab326798c8e353856b86d65937e4bebda7627ce Mon Sep 17 00:00:00 2001 From: Ieva Vasiljeva Date: Fri, 31 May 2019 14:23:09 +0100 Subject: [PATCH 7/9] Slight refactor to when the offset between session progress and session game state is applied. --- .../Private/Game/GDKSessionGameState.cpp | 18 +++++++++--------- .../Public/Game/GDKSessionGameState.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp index 0bb1877c..6e9f989c 100644 --- a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp +++ b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp @@ -50,9 +50,7 @@ void AGDKSessionGameState::OnRep_SessionProgress() if (bAuthoritativeOverSessionEntity) { - // There's an offset of 1 between the corresponding states of session progress and session state. - int SessionState = (int)SessionProgress + 1; - SendStateUpdate(SessionState); + SendStateUpdate(SessionProgress); } TimerEvent.Broadcast(SessionProgress, SessionTimer); } @@ -89,7 +87,7 @@ void AGDKSessionGameState::TickGameTimer() SessionProgress = EGDKSessionProgress::Running; if (bAuthoritativeOverSessionEntity) { - SendStateUpdate(2); + SendStateUpdate(SessionProgress); } SessionTimer = GameSessionLength; } @@ -99,7 +97,7 @@ void AGDKSessionGameState::TickGameTimer() SessionProgress = EGDKSessionProgress::Results; if (bAuthoritativeOverSessionEntity) { - SendStateUpdate(3); + SendStateUpdate(SessionProgress); } SessionTimer = ResultsSessionLength; } @@ -109,27 +107,29 @@ void AGDKSessionGameState::TickGameTimer() SessionProgress = EGDKSessionProgress::Finished; if (bAuthoritativeOverSessionEntity) { - SendStateUpdate(4); + SendStateUpdate(SessionProgress); } } } } -void AGDKSessionGameState::SendStateUpdate(int NewState) +void AGDKSessionGameState::SendStateUpdate(EGDKSessionProgress SessionProgress) { if (!GetWorld()->GetNetDriver() || !GetWorld()->GetNetDriver()->IsA()) { return; } + // There's an offset of 1 between the corresponding states of session progress and session state. + int SessionState = (int)SessionProgress + 1; + Worker_EntityId target_entity_id = SessionEntityId; Worker_ComponentUpdate component_update = {}; component_update.component_id = SessionComponentId; component_update.schema_type = Schema_CreateComponentUpdate(SessionComponentId); Schema_Object* fields_object = Schema_GetComponentUpdateFields(component_update.schema_type); - Schema_AddInt32(fields_object, 1, NewState); + Schema_AddInt32(fields_object, 1, SessionState); Cast(GetWorld()->GetNetDriver())->Connection->SendComponentUpdate(target_entity_id, &component_update); - UE_LOG(LogGDK, Warning, TEXT("Sending update for session component. State: %i; worker authority: %i"), NewState, Role.GetValue()); } diff --git a/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h b/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h index e243f23b..375d9e35 100644 --- a/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h +++ b/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h @@ -61,7 +61,7 @@ class GDKSHOOTER_API AGDKSessionGameState : public AGDKGameState void TickGameTimer(); // Send a component update to the session manager entity to be picked up by the deployment manager - void SendStateUpdate(int NewState); + void SendStateUpdate(EGDKSessionProgress SessionProgress); // Begin progressing through the different stages of game session, if not already started void BeginTimer(); From d53c948a99ca3be29c83f6beeba80c0b49fa1a04 Mon Sep 17 00:00:00 2001 From: Ieva <33751053+ieva-improbable@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:15:26 +0100 Subject: [PATCH 8/9] Change cast to be static. Co-Authored-By: Michael Samiec --- Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp index 6e9f989c..9385adc0 100644 --- a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp +++ b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp @@ -121,7 +121,7 @@ void AGDKSessionGameState::SendStateUpdate(EGDKSessionProgress SessionProgress) } // There's an offset of 1 between the corresponding states of session progress and session state. - int SessionState = (int)SessionProgress + 1; + int SessionState = static_cast(SessionProgress) + 1; Worker_EntityId target_entity_id = SessionEntityId; Worker_ComponentUpdate component_update = {}; From 8c069adf642594ffdf657069e6b3cfd625fa85ee Mon Sep 17 00:00:00 2001 From: ieva-improbable Date: Wed, 5 Jun 2019 16:43:18 +0100 Subject: [PATCH 9/9] Updating variable names. --- Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp | 4 ++-- Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp index 9385adc0..aa13789c 100644 --- a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp +++ b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp @@ -113,7 +113,7 @@ void AGDKSessionGameState::TickGameTimer() } } -void AGDKSessionGameState::SendStateUpdate(EGDKSessionProgress SessionProgress) +void AGDKSessionGameState::SendStateUpdate(EGDKSessionProgress SessionProgressState) { if (!GetWorld()->GetNetDriver() || !GetWorld()->GetNetDriver()->IsA()) { @@ -121,7 +121,7 @@ void AGDKSessionGameState::SendStateUpdate(EGDKSessionProgress SessionProgress) } // There's an offset of 1 between the corresponding states of session progress and session state. - int SessionState = static_cast(SessionProgress) + 1; + int SessionState = static_cast(SessionProgressState) + 1; Worker_EntityId target_entity_id = SessionEntityId; Worker_ComponentUpdate component_update = {}; diff --git a/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h b/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h index 375d9e35..990d2ea6 100644 --- a/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h +++ b/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h @@ -61,7 +61,7 @@ class GDKSHOOTER_API AGDKSessionGameState : public AGDKGameState void TickGameTimer(); // Send a component update to the session manager entity to be picked up by the deployment manager - void SendStateUpdate(EGDKSessionProgress SessionProgress); + void SendStateUpdate(EGDKSessionProgress SessionProgressState); // Begin progressing through the different stages of game session, if not already started void BeginTimer();