Player Management
Handling players -- connecting, spawning, identifying, and occasionally removing them -- is a core part of any multiplayer world. Here's how HELIX gives you control over the player lifecycle.
Player Connections
When a player connects to your world, the server fires an event you can hook into. This is where you set up their character, load their data, or send them a welcome message.
- Blueprint
- Lua
- JavaScript
// Override in your GameMode
void AMyGameMode::OnPostLogin(AController* NewPlayer)
{
Super::OnPostLogin(NewPlayer);
// Spawn a character for the new player
FVector SpawnLocation = GetRandomSpawnPoint();
AMyCharacter* NewCharacter = GetWorld()->SpawnActor<AMyCharacter>(
CharacterClass, SpawnLocation
);
NewPlayer->Possess(NewCharacter);
UE_LOG(LogTemp, Log, TEXT("Player connected: %s"), *NewPlayer->GetName());
}
-- Listen for new player connections
RegisterServerEvent('HEvent:PlayerReady', function(player)
-- Player is ready to play
print("Player connected: " .. player:GetName())
end)
// JavaScript uses the endpoint/call model for server communication.
// Player lifecycle events are handled through Lua or Blueprint.
// Use Helix.server() and Helix.endpoint() for server-side logic.
Helix.server(async () => {
// Register endpoints for player-related actions
Helix.endpoint('player:getData', async (helixId) => {
const data = await loadPlayerData(helixId);
return data;
});
});
Getting Player Info
Every connected player has a unique ID, a display name, and various properties you can query.
- Blueprint
- Lua
- JavaScript
// Get player details from a PlayerController
FString PlayerName = PlayerController->GetPlayerName();
FString PlayerID = PlayerController->GetUniqueNetId();
int32 Ping = PlayerController->GetPing();
-- Access player info
local name = player:GetName()
local ping = player:GetPing()
local is_local = player:IsLocalPlayer()
print(name .. " - Ping: " .. ping .. "ms")
// Access player info via Helix JS
const id = Helix.Player.helixId();
// Use endpoints to request player data from the server
const data = await Helix.call('player:getInfo', id.toString());
Iterating Over Players
Need to loop through everyone online? Maybe for a scoreboard, or to apply an effect to all players:
- Blueprint
- Lua
- JavaScript
// Loop through all connected players
for (auto It = GetWorld()->GetPlayerControllerIterator(); It; ++It)
{
APlayerController* PC = It->Get();
// Do something with each player
}
-- Get all connected players
local all_players = HPlayer:GetAll()
for _, p in ipairs(all_players) do
print(p:GetName() .. " is online")
end
// JavaScript: use an endpoint to get player list from the server
const players = await Helix.call('player:getAll');
Kicking Players
Sometimes you need to remove someone -- whether it's for bad behavior or because the round ended.
- Blueprint
- Lua
- JavaScript
// Kick a player with a reason
AGameModeBase* GM = GetWorld()->GetAuthGameMode();
GM->GameSession->KickPlayer(PlayerController, FText::FromString("Kicked by admin"));
-- Kick a player from the server
player:Kick("Kicked by admin")
// Kick a player from the server
player.Kick("Kicked by admin");
Disconnect Handling
Don't forget to clean up when players leave. Destroy their character, save their data, and free up resources.
- Blueprint
- Lua
- JavaScript
void AMyGameMode::Logout(AController* Exiting)
{
// Save player data, clean up their character
SavePlayerData(Exiting);
Super::Logout(Exiting);
}
RegisterServerEvent('HEvent:PlayerUnloaded', function(player)
print(player:GetName() .. " disconnected")
-- Save data, clean up resources
SavePlayerData(player)
end)
// Player lifecycle events are handled through Lua or Blueprint.
// Use Helix.endpoint() on the server to persist player data
// when called from client-side disconnect handlers.
Always handle disconnects gracefully -- players can drop unexpectedly due to network issues, not only from intentional logouts.