An Epic Online Services (EOS) integration for Netick, featuring support for relays and lobbies. Built on EOS Plugin for Unity - refer to its documentation to integrate additional EOS services.
- EOS relay networking (free cross-platform relay)
- Lobby creation and discovery through EOS
- NAT punchthrough and relay fallback
This package and its dependencies can be installed via Unity Package Manager using Git URLs.
Dependencies:
All dependencies can be installed via Unity Package Manager using Git URLs. For detailed instructions on installing packages from Git repositories, see the Unity documentation on installing from a Git URL.
Quick Installation Steps:
- Open Unity Package Manager (Window > Package Manager)
- Click the + button in the top-left corner
- Select Add package from git URL...
- Add the following packages in order:
- First, add EOS Plugin:
https://github.com/EOS-Contrib/eos_plugin_for_unity_upm.git - Then, add Netick for Unity:
https://github.com/NetickNetworking/NetickForUnity.git - Finally, add this package:
https://github.com/NetickNetworking/NetickEOSTransport.git
- First, add EOS Plugin:
- Click Add for each package
Before using this transport, you need to configure EOS through the Epic Developer Portal:
- Visit the Epic Games Developer Portal
- Create a new application or use an existing one
- Note your Product Name, Product ID, Sandbox ID, and Deployment ID
In your EOS application settings:
- Navigate to Product Settings > Clients
- Create a new client or configure an existing one
- Note your Client ID and Client Secret
- Set the Client Policy to include:
- P2P networking permissions
- Lobby permissions
- Configure your sandbox environment in the Developer Portal
- Ensure the sandbox is set to the correct deployment
Once the EOS Plugin for Unity is installed:
- Open the EOS configuration window in Unity
- Enter your credentials:
- Product Name
- Product ID
- Sandbox ID
- Deployment ID
- Client ID
- Client Secret
- Save the configuration
Note
Please note that 'Sandbox' refers here to an EOS-specific concept and is distinct from the sandbox terminology used in Netick
- In Unity, right-click in the Project window
- Navigate to Create > Netick > Transport > EOSTransportProvider
- Name the asset (e.g., "EOSTransportProvider")
- Configure any transport-specific settings in the Inspector
Create a GameObject to manage EOS:
- Create a new GameObject in your scene (e.g., name it "EOS")
- Add the EOSManager component to it
- This component handles EOS initialization and must be present
- Add the EOSGameStarter component to the same GameObject (optional, for testing)
- This is an example script that demonstrates login, lobby creation, and joining
- Assign the
EOSTransportProviderasset you created to the transport field
Important: The EOSManager component must be in your scene for EOS to initialize properly. The EOSGameStarter is optional and serves as a reference implementation for how to use the transport.
The EOSGameStarter component provides a complete reference implementation demonstrating the typical workflow for using this transport. It handles the entire process from authentication through lobby management to establishing Netick connections.
The example script shows the complete integration flow:
- Authentication: How to log in using either Device ID or Epic Account credentials
- Lobby Creation: Creating and configuring lobbies with custom attributes
- Lobby Discovery: Searching for and listing available lobbies
- Joining Lobbies: Connecting to existing lobbies found through search
- Netick Integration: Starting Netick as host or client and establishing connections
To test the transport using EOSGameStarter:
- Add the component to your EOS GameObject (alongside
EOSManager) - Assign your
EOSTransportProviderasset to the Transport field - Configure your preferred authentication method in the Inspector
- Enter Play mode and use the provided UI to:
- Log in with your chosen authentication method
- Create a new lobby or search for existing lobbies
- Join a lobby and establish a connection
The script provides a functional starting point that you can reference when implementing your own lobby and matchmaking systems.
EOS provides two main authentication flows:
Device ID authentication creates a hardware-tied persistent identity without requiring an Epic Games account. This method is ideal for testing and works well for mobile or standalone applications where Epic account integration is not required.
EOSManager.Instance.StartConnectLoginWithDeviceToken("User", (connectInfo) =>
{
if (connectInfo.ResultCode == Result.Success)
{
// Successfully authenticated
}
});Epic Account authentication integrates with Epic Games accounts and supports multiple credential types for different deployment scenarios:
Credential Types:
- Developer: Uses the DevAuthTool for local development and testing
- AccountPortal: Opens a browser for user login with Epic Games credentials
- ExchangeCode: Authenticates using a one-time exchange code
- PersistentAuth: Uses cached credentials from previous sessions
- Password: Direct username/password authentication (requires special permissions)
- ExternalAuth: Integrates with external platforms (Steam, PlayStation, Xbox, etc.)
Implementation:
var credentials = new Epic.OnlineServices.Auth.Credentials
{
Type = Epic.OnlineServices.Auth.LoginCredentialType.Developer,
Id = "localhost:8888",
Token = "YourDevUsername"
};
var loginOptions = new Epic.OnlineServices.Auth.LoginOptions()
{
Credentials = credentials,
ScopeFlags = Epic.OnlineServices.Auth.AuthScopeFlags.BasicProfile
};
EOSManager.Instance.GetEOSAuthInterface().Login(ref loginOptions, null, (authCallback) =>
{
if (authCallback.ResultCode == Result.Success)
{
EOSManager.Instance.StartConnectLoginWithEpicAccount(authCallback.LocalUserId, (connectInfo) =>
{
if (connectInfo.ResultCode == Result.Success)
{
// Successfully authenticated
}
});
}
});Note: Epic Account authentication requires two steps: first authenticate with Epic Account Services, then connect to EOS using the resulting credentials.
For proper local testing of the lobby system, you need two distinct authenticated users. This is because a user who creates a lobby cannot join that same lobby as a client - you need separate identities to test the host-client relationship.
Recommended Configuration for Local Testing:
- Instance 1 (Host): Device ID authentication
- Instance 2 (Client): Epic Account authentication with DevAuthTool
DevAuthTool Setup:
- Download DevAuthTool from the Epic Online Services documentation
- Launch the tool and authenticate with your Epic Games account
- Note the displayed credentials (typically
localhost:8888with a username) - Configure your second instance with:
- Credential Type: Developer
- ID: Address from DevAuthTool (e.g.,
localhost:8888) - Token: Username from DevAuthTool
This configuration provides two distinct EOS identities on a single machine, enabling you to properly test lobby creation (with one user) and lobby joining (with another user).
For production deployments:
- Use AccountPortal or ExternalAuth for optimal user experience
- Reserve Device ID for mobile applications or games not requiring Epic accounts
- Restrict Developer authentication to development environments only
Lobbies provide matchmaking functionality, allowing players to create, find, and join game sessions. All lobby operations require prior authentication.
Configure and create lobbies using the EOSLobbyManager:
Lobby newLobby = new Lobby
{
MaxNumLobbyMembers = 4,
LobbyPermissionLevel = LobbyPermissionLevel.Publicadvertised,
BucketId = "DefaultBucket",
PresenceEnabled = true,
RTCRoomEnabled = false,
AllowInvites = true
};
newLobby.Attributes.Add(new LobbyAttribute
{
Key = "LOBBYNAME",
AsString = "My Game Lobby",
Visibility = LobbyAttributeVisibility.Public
});
lobbyManager.CreateLobby(newLobby, (result) =>
{
if (result == Result.Success)
{
// Lobby created successfully
}
});Configuration Parameters:
- MaxNumLobbyMembers: Maximum player capacity
- LobbyPermissionLevel: Access control settings
Publicadvertised: Publicly visible and joinableJoinviapresence: Accessible through friend presenceInviteonly: Requires explicit invitation
- BucketId: Organizational identifier for grouping lobbies (e.g., game version, mode)
- Attributes: Custom metadata for filtering and display purposes
The lobby search system provides flexible filtering capabilities:
Basic Search:
var lobbyInterface = EOSManager.Instance.GetEOSLobbyInterface();
var searchOptions = new CreateLobbySearchOptions { MaxResults = 20 };
lobbyInterface.CreateLobbySearch(ref searchOptions, out LobbySearch searchHandle);
var bucketParam = new LobbySearchSetParameterOptions
{
Parameter = new AttributeData
{
Key = "bucket",
Value = new AttributeDataValue { AsUtf8 = "DefaultBucket" }
},
ComparisonOp = ComparisonOp.Equal
};
searchHandle.SetParameter(ref bucketParam);
var findOptions = new LobbySearchFindOptions
{
LocalUserId = EOSManager.Instance.GetProductUserId()
};
searchHandle.Find(ref findOptions, null, (ref LobbySearchFindCallbackInfo data) =>
{
if (data.ResultCode == Result.Success)
{
ProcessSearchResults(searchHandle);
}
});Advanced Filtering:
// Filter by lobby name
var nameParam = new LobbySearchSetParameterOptions
{
Parameter = new AttributeData
{
Key = "LOBBYNAME",
Value = new AttributeDataValue { AsUtf8 = "Specific Lobby Name" }
},
ComparisonOp = ComparisonOp.Equal
};
searchHandle.SetParameter(ref nameParam);
// Filter by custom attributes
var modeParam = new LobbySearchSetParameterOptions
{
Parameter = new AttributeData
{
Key = "GAMEMODE",
Value = new AttributeDataValue { AsUtf8 = "DeathMatch" }
},
ComparisonOp = ComparisonOp.Equal
};
searchHandle.SetParameter(ref modeParam);
// Filter by available capacity
var slotsParam = new LobbySearchSetParameterOptions
{
Parameter = new AttributeData
{
Key = "AVAILABLESLOTS",
Value = new AttributeDataValue { AsInt64 = 1 }
},
ComparisonOp = ComparisonOp.Greaterthanorequal
};
searchHandle.SetParameter(ref slotsParam);Processing Results:
private void ProcessSearchResults(LobbySearch search)
{
var countOptions = new LobbySearchGetSearchResultCountOptions();
uint count = search.GetSearchResultCount(ref countOptions);
var indexOptions = new LobbySearchCopySearchResultByIndexOptions();
for (uint i = 0; i < count; i++)
{
indexOptions.LobbyIndex = i;
if (search.CopySearchResultByIndex(ref indexOptions, out LobbyDetails details) == Result.Success)
{
Lobby lobby = new Lobby();
lobby.InitFromLobbyDetails(details);
string lobbyId = lobby.Id;
uint maxPlayers = lobby.MaxNumLobbyMembers;
uint currentPlayers = (uint)lobby.Members.Count;
foreach (var attr in lobby.Attributes)
{
if (attr.Key == "LOBBYNAME")
{
string lobbyName = attr.AsString;
// Display or store lobby information
}
}
// Retain LobbyDetails reference for joining
}
}
}Important: Preserve the LobbyDetails object returned from search results - it is required for joining operations. Always release search handles after use:
searchHandle.Release();Join discovered lobbies using the stored LobbyDetails reference:
lobbyManager.JoinLobby(lobbyId, lobbyDetails, true, (result) =>
{
if (result == Result.Success)
{
// Successfully joined lobby
}
});- Version Control: Use BucketId to separate incompatible game versions
BucketId = Application.version
- Result Limiting: Constrain search results to manageable quantities (10-20 initially)
- Resource Management: Always release search handles to prevent memory leaks
- Reference Retention: Store
LobbyDetailsfrom search results for joining operations - Meaningful Metadata: Include relevant attributes (game mode, map, region, skill level)
- Attribute Maintenance: Update lobby attributes when state changes
- Empty Result Handling: Provide appropriate user feedback when searches return no results
After authentication and lobby setup, establish Netick connections using the EOS transport.
Host Setup:
lobbyManager.CreateLobby(newLobby, (result) =>
{
if (result == Result.Success)
{
Network.StartAsHost(EOSTransportProvider, default, SandboxPrefab);
}
});The host may be started immediately after lobby creation or deferred based on game requirements (e.g., minimum player count, manual start trigger). Lobby creation and Netick host initialization are independent operations.
Client Setup:
lobbyManager.JoinLobby(lobbyId, lobbyDetails, true, (result) =>
{
if (result == Result.Success)
{
var client = Network.StartAsClient(EOSTransportProvider, default, SandboxPrefab);
string hostId = lobbyManager.GetCurrentLobby().LobbyOwner.ToString();
client.Connect(default, hostId);
}
});Critical: The connection string must be the lobby owner's ProductUserId (converted to string). This identifier enables the EOS transport to establish connections with the correct peer. The lobby owner's ID is accessible via lobby.LobbyOwner after successful lobby join operations.
- Ensure EOS application configuration is correct before testing
- Authentication is required before accessing lobby functionality
- Lobby attributes enable custom matchmaking and filtering logic
- Connection quality depends on relay server proximity and network conditions
- BucketId should be used to prevent version incompatibility issues
- Verify your Product Name, Product ID, Sandbox ID, Client ID, and Client Secret are correct
- Ensure the EOS Plugin is properly installed
- Check that your client policy includes the necessary permissions
- Device ID: Ensure unique credentials per instance for proper testing
- Epic Account: Verify DevAuthTool is running (for Developer credential type)
- Confirm credential accuracy
- Validate client policy authentication permissions
- Confirm you're logged into EOS successfully
- Verify your sandbox is correctly configured
- Check that lobby permissions are enabled in your client policy
- Ensure both peers are authenticated
- Verify P2P networking permissions in client policy
- Check firewall configuration
- Confirm correct ProductUserId usage in connection string
- Verify you're searching the correct BucketId
- Check that lobbies exist with
LobbyPermissionLevel.Publicadvertised - Ensure you're authenticated before searching
- Try searching without filters to see all available lobbies
For EOS Plugin or Unity-specific issues: EOS Plugin for Unity Repository
For Netick-related questions: Discord Server
For EOS platform documentation: Epic Online Services Documentation