Edgegap Instance ID Fix¶
Problem¶
The Nakama-Edgegap callback was never triggering because the dedicated server couldn't obtain its instance_id to send the READY event to Nakama.
Root Cause¶
The Nakama-Edgegap plugin has a design limitation:
- The instance_id (which is deployment.RequestId) is generated by Edgegap AFTER the deployment is created
- The environment variables (including NAKAMA_INSTANCE_METADATA) are set BEFORE the deployment response is received
- The plugin does not inject the instance_id into the metadata that gets passed to the dedicated server
- Result: NAKAMA_INSTANCE_METADATA was always "null" (empty JSON object)
Solution¶
Use Edgegap's built-in environment variable ARBITRIUM_REQUEST_ID
According to Edgegap documentation, they automatically inject this environment variable into every deployment:
ARBITRIUM_REQUEST_ID - e.g. f68e011bfb01
Unique deployment ID, also referred to as request ID.
This is exactly the instance_id that Nakama needs!
Changes Made¶
1. EdgegapInstanceReporter.cpp¶
Modified GetInstanceEventUrlAndId() to read ARBITRIUM_REQUEST_ID:
// 2) Try to get instance_id from Edgegap's ARBITRIUM_REQUEST_ID environment variable
const FString ArbitriumRequestId = FPlatformMisc::GetEnvironmentVariable(TEXT("ARBITRIUM_REQUEST_ID"));
if (!ArbitriumRequestId.IsEmpty())
{
OutInstanceId = ArbitriumRequestId;
CachedInstanceId = ArbitriumRequestId;
UE_LOG(LogEdgegapInstance, Log, TEXT("Using ARBITRIUM_REQUEST_ID as instance_id: %s"), *OutInstanceId);
return true;
}
Removed automatic READY event sending from SetInstanceId() - now it's just a simple setter.
2. TankGameState.cpp¶
Modified BeginPlay() to send READY event immediately when server starts:
if (GetNetMode() == NM_DedicatedServer)
{
UE_LOG(LogTemp, Log, TEXT("ARBITRIUM_REQUEST_ID = %s"),
*FPlatformMisc::GetEnvironmentVariable(TEXT("ARBITRIUM_REQUEST_ID")));
if (UEdgegapInstanceReporter::HasInstanceId())
{
TMap<FString, FString> ExtraMeta;
ExtraMeta.Add(TEXT("status"), TEXT("initialized"));
UEdgegapInstanceReporter::SendInstanceEvent(EEdgegapInstanceAction::Ready, TEXT("Server ready for players"), ExtraMeta);
UE_LOG(LogTemp, Log, TEXT("READY event sent to Nakama"));
}
}
3. TankGameMode.cpp¶
No changes needed - the InitGame() logic that parses instance_id from URL parameters is still there as a fallback, but won't be used since we now get the ID from the environment variable.
Expected Flow¶
- Nakama creates Edgegap deployment via matchmaking
- Edgegap generates
instance_id(deployment.RequestId) and starts server - Edgegap injects
ARBITRIUM_REQUEST_IDenvironment variable with the instance_id - Server starts and
TankGameState::BeginPlay()is called - Server reads
ARBITRIUM_REQUEST_IDand sends READY event to Nakama with the instance_id - Nakama receives READY event and triggers the callback
- Callback sends connection-info notifications to all matched players with server IP/port
- Clients receive notifications and travel to the dedicated server
Expected Logs¶
Server Logs (Success)¶
[LogTemp] NAKAMA_INSTANCE_EVENT_URL = https://nakamaapi.brickleaf.games/v2/rpc/edgegap_instance?http_key=defaultkey&unwrap
[LogTemp] NAKAMA_INSTANCE_METADATA = null
[LogTemp] ARBITRIUM_REQUEST_ID = f68e011bfb01
[LogEdgegapInstance] Using ARBITRIUM_REQUEST_ID as instance_id: f68e011bfb01
[LogEdgegapInstance] Sending instance event to https://...: {"instance_id":"f68e011bfb01","action":"READY",...}
[LogTemp] READY event sent to Nakama
[LogEdgegapInstance] Instance event OK: 200 ...
Nakama Logs (Success)¶
{"level":"info",...,"msg":"Requesting a new Deployment","runtime":"go"}
{"level":"info",...,"msg":"Edgegap instance ready id=f68e011bfb01 : Server ready for players","runtime":"go"}
{"level":"info",...,"msg":"Edgegap instance created: f68e011bfb01","runtime":"go"}
Next Steps¶
- Rebuild dedicated server with these changes
- Deploy to Edgegap (push new Docker image)
- Test matchmaking - the callback should now trigger properly
- Verify logs match the expected flow above
References¶
- Edgegap Documentation: https://docs.edgegap.com/learn/orchestration/deployments#injected-environment-variables
ARBITRIUM_REQUEST_IDis documented as the unique deployment ID