Initialization And Lifecycle

Initialization And Lifecycle

DiscordPulse exposes UDiscordPresenceSubsystem, a Game Instance subsystem. One instance exists for each active Game Instance.

Recommended Lifecycle

Local player starts
  -> Get valid Discord Presence Subsystem
  -> Bind events
  -> Initialize Discord Presence
  -> Publish initial activity
Game state changes
  -> Publish updated activity
Game Instance ends
  -> Subsystem shuts down automatically

The plugin owns callback polling. Do not create a separate Discord callback timer.

Blueprint Startup Timing

Do Not Use Game Instance Event Init

In UE 5.7, the Game Instance startup order is:

Blueprint Game Instance Event Init
  -> Game Instance Subsystems are created

Therefore, Get Game Instance Subsystem returns None inside Blueprint Game Instance Event Init.

Recommended Blueprint Location

Use the local Player Controller:

Player Controller: Event BeginPlay
  -> Is Local Controller
  -> Branch (True)
  -> Get Game Instance Subsystem (Discord Presence Subsystem)
  -> Is Valid
  -> Initialize Discord Presence

The local-controller check prevents server instances and remote controllers from owning the machine's Discord activity.

For a single-player project, a persistent startup actor or main-menu BeginPlay also works, provided the subsystem target is valid.

Initialize Discord Presence

InputDescription
ApplicationIdRequired positive numeric Discord Application ID
OptionalSteamAppIdOptional numeric Steam App ID used for Discord launch registration
Auto RegisterRegisters a launch command when no Steam App ID is supplied
Require Discord RunningFails early if the best-effort process check cannot find Discord desktop

Initialization with the same Application ID is idempotent. Initializing with a different ID performs a restart.

What Success Means

An initialization Success means:

  • The Application ID passed local validation.
  • The Social SDK runtime loaded.
  • The local SDK client was created.
  • The connection process started.

An activity node's immediate Success means the request was submitted locally. Use On Discord Activity Updated or On Discord Error for the final asynchronous result.

Runtime State

Node/EventMeaning
Is Discord Presence InitializedA valid local SDK client exists
Is Discord RunningBest-known Discord state, including best-effort process detection
On Discord InitializedLocal initialization completed
On Discord Initialization FailedInitialization failed
On Discord Activity UpdatedDiscord accepted an activity update
On Discord DisconnectedDiscord became unavailable after being known as running
On Discord ErrorA plugin or SDK operation failed

Multiplayer And PIE

  • Run DiscordPulse only for the local player.
  • Dedicated servers should not initialize Discord Rich Presence.
  • Listen-server PIE with one player may show only Server: Blueprint prints.
  • Use Standalone PIE for the simplest first test.
  • Each PIE Game Instance owns a separate DiscordPresence subsystem.
  • Do not keep subsystem references across PIE sessions.

Restart

Use Restart Discord Presence when changing the Application ID or intentionally rebuilding the SDK session.

Shutdown Discord Presence
  -> Initialize Discord Presence

Clear And Shutdown

Clear Presence requests removal of the visible activity while leaving the subsystem initialized.

Shutdown Discord Presence:

  • Stops callback polling
  • Clears local pending join requests and desired activity
  • Requests Rich Presence cleanup when possible
  • Disconnects and destroys the SDK client
  • Releases the SDK runtime

Shutdown is safe to call more than once. Normal Game Instance destruction also shuts down the subsystem.

C++ Game Instance Initialization

C++ may initialize from a custom Game Instance after Super::Init() returns:

#include "DiscordPresenceSubsystem.h"
 
void UMyGameInstance::Init()
{
	Super::Init();
 
	if (UDiscordPresenceSubsystem* Discord = GetSubsystem<UDiscordPresenceSubsystem>())
	{
		Discord->InitializeDiscordPresence(TEXT("123456789012345678"));
		Discord->SetSimplePresence(TEXT("Playing My Game"), TEXT("Main Menu"));
	}
}

Unlike Blueprint Event Init, code after Super::Init() runs after Game Instance Subsystems are created.