Quick answer: Use GameState for shared state. GameMode is server-only by design.
Round timer in GameMode. Clients don’t see countdown. GameMode exists only on server.
The Fix
AGameStateBase subclass:
UPROPERTY(Replicated)
float RoundTimeRemaining = 300.f;
virtual void GetLifetimeReplicatedProps(...)
DOREPLIFETIME(AMyGameState, RoundTimeRemaining);
GameMode (server only):
Tick: GetGameState<AMyGameState>()->RoundTimeRemaining -= dt;
Client:
AGameStateBase* gs = GetWorld()->GetGameState();
Read replicated value to update UI.
GameMode runs server-only. GameState replicates. Pattern: GameMode mutates, GameState carries.
Verifying
Two clients see same timer. Without GameState: only server-side counts down.
“GameMode server. GameState shared.”
Related Issues
For replication scope, see scope. For OnlineSubsystem session, see session.
GameMode private. GameState public.