Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MultiplayerSample CompileDef based Client/Server split #200

Merged
merged 9 commits into from
Jan 12, 2023
127 changes: 118 additions & 9 deletions Gem/Code/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}")

ly_add_target(
NAME MultiplayerSample.Static STATIC
NAME MultiplayerSample.Client.Static STATIC
NAMESPACE Gem
FILES_CMAKE
multiplayersample_files.cmake
multiplayersample_autogen_files.cmake
multiplayersample_files.cmake
${pal_dir}/multiplayersample_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Expand All @@ -22,28 +22,130 @@ ly_add_target(
Include
BUILD_DEPENDENCIES
PUBLIC
AZ::AzGameFramework
AZ::AzNetworking
Gem::Multiplayer
Gem::DebugDraw
Gem::LyShine
Gem::StartingPointInput
Gem::EMotionFXStaticLib
Gem::PhysX
Gem::Multiplayer.Client
PRIVATE
Gem::LmbrCentral.Static
Gem::Multiplayer.Client.Static
Gem::PhysX.Static
Gem::DebugDraw.Static
Gem::ImGui.Static
Gem::LyShine.Static
Gem::GameState.Static
AUTOGEN_RULES
*.AutoComponent.xml,AutoComponent_Header.jinja,$path/$fileprefix.AutoComponent.h
*.AutoComponent.xml,AutoComponent_Source.jinja,$path/$fileprefix.AutoComponent.cpp
*.AutoComponent.xml,AutoComponentTypes_Header.jinja,$path/AutoComponentTypes.h
*.AutoComponent.xml,AutoComponentTypes_Source.jinja,$path/AutoComponentTypes.cpp
)

ly_add_target(
NAME MultiplayerSample.Server.Static STATIC
NAMESPACE Gem
FILES_CMAKE
multiplayersample_autogen_files.cmake
multiplayersample_files.cmake
${pal_dir}/multiplayersample_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Source
.
PUBLIC
Include
BUILD_DEPENDENCIES
PUBLIC
Gem::StartingPointInput
Gem::EMotionFXStaticLib
Gem::PhysX
Gem::Multiplayer.Server
PRIVATE
Gem::LmbrCentral.Static
Gem::Multiplayer.Server.Static
Gem::PhysX.Static
Gem::GameState.Static
AUTOGEN_RULES
*.AutoComponent.xml,AutoComponent_Header.jinja,$path/$fileprefix.AutoComponent.h
*.AutoComponent.xml,AutoComponent_Source.jinja,$path/$fileprefix.AutoComponent.cpp
*.AutoComponent.xml,AutoComponentTypes_Header.jinja,$path/AutoComponentTypes.h
*.AutoComponent.xml,AutoComponentTypes_Source.jinja,$path/AutoComponentTypes.cpp
)

ly_add_target(
NAME MultiplayerSample.Unified.Static STATIC
NAMESPACE Gem
FILES_CMAKE
multiplayersample_autogen_files.cmake
multiplayersample_files.cmake
${pal_dir}/multiplayersample_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Source
.
PUBLIC
Include
BUILD_DEPENDENCIES
PUBLIC
Gem::DebugDraw
Gem::LyShine
Gem::StartingPointInput
Gem::EMotionFXStaticLib
Gem::PhysX
Gem::Multiplayer
PRIVATE
Gem::LmbrCentral.Static
Gem::Multiplayer.Static
Gem::Multiplayer.Unified.Static
Gem::PhysX.Static
Gem::DebugDraw.Static
Gem::ImGui.Static
Gem::LyShine.Static
Gem::GameState.Static
AUTOGEN_RULES
*.AutoComponent.xml,AutoComponent_Header.jinja,$path/$fileprefix.AutoComponent.h
*.AutoComponent.xml,AutoComponent_Source.jinja,$path/$fileprefix.AutoComponent.cpp
*.AutoComponent.xml,AutoComponentTypes_Header.jinja,$path/AutoComponentTypes.h
*.AutoComponent.xml,AutoComponentTypes_Source.jinja,$path/AutoComponentTypes.cpp
)

ly_add_target(
NAME MultiplayerSample.Client ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
FILES_CMAKE
multiplayersample_shared_files.cmake
../../multiplayersample_asset_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Source
.
PUBLIC
Include
BUILD_DEPENDENCIES
PRIVATE
Gem::MultiplayerSample.Client.Static
Gem::Atom_AtomBridge.Static
)

ly_add_target(
NAME MultiplayerSample.Server ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
FILES_CMAKE
multiplayersample_shared_files.cmake
../../multiplayersample_asset_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Source
.
PUBLIC
Include
BUILD_DEPENDENCIES
PRIVATE
Gem::MultiplayerSample.Server.Static
Gem::Atom_AtomBridge.Static
)

ly_add_target(
NAME MultiplayerSample ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
Expand All @@ -58,15 +160,16 @@ ly_add_target(
Include
BUILD_DEPENDENCIES
PRIVATE
Gem::MultiplayerSample.Static
Gem::MultiplayerSample.Unified.Static
Gem::Atom_AtomBridge.Static
)

# if enabled, MultiplayerSample is used by all kinds of applications
ly_create_alias(NAME MultiplayerSample.Builders NAMESPACE Gem TARGETS Gem::MultiplayerSample)
ly_create_alias(NAME MultiplayerSample.Tools NAMESPACE Gem TARGETS Gem::MultiplayerSample)
ly_create_alias(NAME MultiplayerSample.Clients NAMESPACE Gem TARGETS Gem::MultiplayerSample)
ly_create_alias(NAME MultiplayerSample.Servers NAMESPACE Gem TARGETS Gem::MultiplayerSample)
ly_create_alias(NAME MultiplayerSample.Clients NAMESPACE Gem TARGETS Gem::MultiplayerSample.Client)
ly_create_alias(NAME MultiplayerSample.Servers NAMESPACE Gem TARGETS Gem::MultiplayerSample.Server)
ly_create_alias(NAME MultiplayerSample.Unified NAMESPACE Gem TARGETS Gem::MultiplayerSample)

################################################################################
# Gem dependencies
Expand All @@ -80,5 +183,11 @@ if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
set_property(GLOBAL APPEND PROPERTY LY_LAUNCHER_SERVER_PROJECTS MultiplayerSample)
endif()

# If we build a server, then add the project name to the list of server launcher projects
if(PAL_TRAIT_BUILD_UNIFIED_SUPPORTED)
set_property(GLOBAL APPEND PROPERTY LY_LAUNCHER_UNIFIED_PROJECTS MultiplayerSample)
endif()

set_property(TARGET MultiplayerSample APPEND PROPERTY GAMELAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS "--console-command-file=\"launch_client.cfg\"")
set_property(TARGET MultiplayerSample APPEND PROPERTY SERVERLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS "--console-command-file=\"launch_server.cfg\"")
set_property(TARGET MultiplayerSample APPEND PROPERTY UNIFIEDLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS "--console-command-file=\"launch_server.cfg\"")
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
OverrideInclude="Source/Components/NetworkRandomComponent.h"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<NetworkProperty Type="uint64_t" Init="0" Name="Seed" ReplicateFrom="Authority" ReplicateTo="Client" Container="Object" IsPublic="true" IsRewindable="false" IsPredictable="false" ExposeToEditor="false" ExposeToScript="false" GenerateEventBindings="false" Description="The RNG seed" />
<NetworkProperty Type="uint64_t" Init="0" Name="Seed" ReplicateFrom="Authority" ReplicateTo="Client" Container="Object" IsPublic="true" IsRewindable="false" IsPredictable="true" ExposeToEditor="false" ExposeToScript="false" GenerateEventBindings="false" Description="The RNG seed" />
AMZN-puvvadar marked this conversation as resolved.
Show resolved Hide resolved

</Component>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
OverrideInclude="Source/Components/PerfTest/NetworkRandomTranslateComponent.h"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<ComponentRelation Constraint="Required" HasController="false" Name="NetworkTransformComponent" Namespace="Multiplayer" Include="Multiplayer/Components/NetworkTransformComponent.h" />
<ComponentRelation Constraint="Required" HasController="false" Name="NetworkTransformComponent" Namespace="Multiplayer" Include="Multiplayer/Components/NetworkTransformComponent.h" />

<ArchetypeProperty Type="float" Name="MovementDuration" Init="2.f" ExposeToEditor="true" Description="The number of seconds it takes to make a move."/>
<ArchetypeProperty Type="float" Name="MaxMoveDistance" Init="10.f" ExposeToEditor="true" Description="The max distance to move in a period."/>
Expand Down
26 changes: 2 additions & 24 deletions Gem/Code/Source/Components/NetworkAiComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,7 @@ namespace MultiplayerSample
{
}

void NetworkAiComponentController::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
{
if (GetEnabled())
{
Multiplayer::LocalPredictionPlayerInputComponentController* playerInputController = GetLocalPredictionPlayerInputComponentController();
if (playerInputController != nullptr)
{
playerInputController->ForceEnableAutonomousUpdate();
}
}
}

void NetworkAiComponentController::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
{
if (GetEnabled())
{
Multiplayer::LocalPredictionPlayerInputComponentController* playerInputController = GetLocalPredictionPlayerInputComponentController();
if (playerInputController != nullptr)
{
playerInputController->ForceDisableAutonomousUpdate();
}
}
}

#if AZ_TRAIT_SERVER
void NetworkAiComponentController::TickMovement(NetworkPlayerMovementComponentController& movementController, float deltaTime)
{
// TODO: Execute this tick only if this component is owned by this endpoint (currently ticks on server only)
Expand Down Expand Up @@ -145,4 +122,5 @@ namespace MultiplayerSample
SetActionIntervalMaxMs(actionIntervalMaxMs);
m_lcg.SetSeed(seed);
}
#endif
}
9 changes: 7 additions & 2 deletions Gem/Code/Source/Components/NetworkAiComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,23 @@ namespace MultiplayerSample
public:
NetworkAiComponentController(NetworkAiComponent& parent);

void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
void OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {};
void OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {};

#if AZ_TRAIT_SERVER
void TickMovement(NetworkPlayerMovementComponentController& movementController, float deltaTime);
void TickWeapons(NetworkWeaponsComponentController& weaponsController, float deltaTime);
#endif

private:
friend class NetworkStressTestComponentController;

#if AZ_TRAIT_SERVER
void ConfigureAi(
float fireIntervalMinMs, float fireIntervalMaxMs, float actionIntervalMinMs, float actionIntervalMaxMs, uint64_t seed);

// TODO: Technically this guy should also be authority to autonomous so we don't roll different values after a migration..
AZ::SimpleLcgRandom m_lcg;
#endif
};
}
2 changes: 2 additions & 0 deletions Gem/Code/Source/Components/NetworkHealthComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ namespace MultiplayerSample
;
}

#if AZ_TRAIT_SERVER
void NetworkHealthComponentController::HandleSendHealthDelta([[maybe_unused]] AzNetworking::IConnection* invokingConnection, const float& healthDelta)
{
float health = GetHealth();
health = AZStd::max(0.0f, AZStd::min(GetMaxHealth(), health + healthDelta));
SetHealth(health);
}
#endif
}
2 changes: 2 additions & 0 deletions Gem/Code/Source/Components/NetworkHealthComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ namespace MultiplayerSample
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;

#if AZ_TRAIT_SERVER
void HandleSendHealthDelta(AzNetworking::IConnection* invokingConnection, const float& healthDelta) override;
#endif
};
}
2 changes: 2 additions & 0 deletions Gem/Code/Source/Components/NetworkPlayerMovementComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,12 @@ namespace MultiplayerSample

void NetworkPlayerMovementComponentController::UpdateAI()
{
#if AZ_TRAIT_SERVER
float deltaTime = static_cast<float>(m_updateAI.TimeInQueueMs()) / 1000.f;
if (m_networkAiComponentController != nullptr)
{
m_networkAiComponentController->TickMovement(*this, deltaTime);
}
#endif
}
} // namespace MultiplayerSample
2 changes: 2 additions & 0 deletions Gem/Code/Source/Components/NetworkRandomComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ namespace MultiplayerSample
NetworkRandomComponentController::NetworkRandomComponentController(NetworkRandomComponent& parent)
: NetworkRandomComponentControllerBase(parent)
{
#if AZ_TRAIT_SERVER
if (IsNetEntityRoleAuthority())
{
// Setup seed on authority for proxies to pull
Expand All @@ -49,6 +50,7 @@ namespace MultiplayerSample
seedGenerator.GetRandom(seed);
SetSeed(seed);
};
#endif
}

void NetworkRandomComponentController::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
Expand Down
12 changes: 12 additions & 0 deletions Gem/Code/Source/Components/NetworkStressTestComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ namespace MultiplayerSample

NetworkStressTestComponentController::NetworkStressTestComponentController(NetworkStressTestComponent& owner)
: NetworkStressTestComponentControllerBase(owner)
#if AZ_TRAIT_SERVER
, m_autoSpawnTimer([this]() { HandleSpawnAiEntity(); }, AZ::Name("StressTestSpawner Event"))
#endif
{
;
}
Expand All @@ -61,10 +63,12 @@ namespace MultiplayerSample
break;
}

#if AZ_TRAIT_SERVER
if (GetAutoSpawnIntervalMs() > AZ::Time::ZeroTimeMs)
{
m_autoSpawnTimer.Enqueue(GetAutoSpawnIntervalMs(), true);
}
#endif
}

void NetworkStressTestComponentController::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
Expand All @@ -74,11 +78,13 @@ namespace MultiplayerSample
#endif
}

#if AZ_TRAIT_SERVER
void NetworkStressTestComponentController::HandleSpawnAiEntity()
{
const uint64_t seed = m_seed == 0 ? static_cast<uint64_t>(AZ::Interface<AZ::ITime>::Get()->GetElapsedTimeMs()) : m_seed;
HandleSpawnAIEntity(nullptr, m_fireIntervalMinMs, m_fireIntervalMaxMs, m_actionIntervalMinMs, m_actionIntervalMaxMs, seed, m_teamID);
}
#endif

#if defined(IMGUI_ENABLED)
void NetworkStressTestComponentController::OnImGuiMainMenuUpdate()
Expand Down Expand Up @@ -121,6 +127,7 @@ namespace MultiplayerSample
{
if (m_isServer)
{
#if AZ_TRAIT_SERVER
HandleSpawnAIEntity(
nullptr,
m_fireIntervalMinMs,
Expand All @@ -129,16 +136,19 @@ namespace MultiplayerSample
m_actionIntervalMaxMs,
seed + i,
m_teamID);
#endif
}
else
{
#if AZ_TRAIT_CLIENT
SpawnAIEntity(
m_fireIntervalMinMs,
m_fireIntervalMaxMs,
m_actionIntervalMinMs,
m_actionIntervalMaxMs,
seed + i,
m_teamID);
#endif
}
}
}
Expand All @@ -153,6 +163,7 @@ namespace MultiplayerSample
{
}

#if AZ_TRAIT_SERVER
void NetworkStressTestComponentController::HandleSpawnAIEntity(
AzNetworking::IConnection* invokingConnection,
const float& fireIntervalMinMs,
Expand Down Expand Up @@ -190,4 +201,5 @@ namespace MultiplayerSample
}
createdEntity.Activate();
}
#endif
} // namespace MultiplayerSample