Skip to content

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

  1. Nakama creates Edgegap deployment via matchmaking
  2. Edgegap generates instance_id (deployment.RequestId) and starts server
  3. Edgegap injects ARBITRIUM_REQUEST_ID environment variable with the instance_id
  4. Server starts and TankGameState::BeginPlay() is called
  5. Server reads ARBITRIUM_REQUEST_ID and sends READY event to Nakama with the instance_id
  6. Nakama receives READY event and triggers the callback
  7. Callback sends connection-info notifications to all matched players with server IP/port
  8. 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

  1. Rebuild dedicated server with these changes
  2. Deploy to Edgegap (push new Docker image)
  3. Test matchmaking - the callback should now trigger properly
  4. Verify logs match the expected flow above

References

  • Edgegap Documentation: https://docs.edgegap.com/learn/orchestration/deployments#injected-environment-variables
  • ARBITRIUM_REQUEST_ID is documented as the unique deployment ID