# Assign each player a unique ID?

For my game's multiplayer matchmaking and back-end, every player is assigned a unique GlobalID and LocalID. The GlobalID is used for keeping track of all players and the LocalID is for keeping track of players in a specific room. How can I assign to each player a unique ID so that at any one time 2 players don't have the same GlobalIDs or LocalIDs? I think I can manage with assigning each player their own GlobalID and let them keep it after they log off but I definitely need to reuse LocalIDs Note: I'm using C# for my server which handles the IDs.

• Why do you need to reuse LocalIDs? – Vaillancourt Mar 16 '15 at 1:48
• In case players quit during matchmaking/in-game and others join. I'm using a byte to identify players locally. Overflow won't be very common but it's still a possibility with incrementally assigning IDs. – JPtheK9 Mar 16 '15 at 2:50
• Why even have local ids? Just use global id for everything. – John K Mar 16 '15 at 4:12
• So I can send less data :p – JPtheK9 Mar 16 '15 at 7:01
• You seem too have a large number of design constraints not in the question. Please edit your question to include them. – John K Mar 17 '15 at 3:43

## 4 Answers

If you're using a server, even if only for matchmaking, just assign them one. You can use a counter as they sign up for accounts. Alternately you could use a random number and check for duplicates. Or use their screen name as a unique id.

You can use a hash of their e-mail address or some other unique data.

Microsoft came up with a system of generating Globally Unique Identifiers, GUIDs. It uses local information plus some statistics to virtually guarantee that each identifier generated will be unique. Theses probably overkill for what you want. But since you're using c# you all ready have the code: https://msdn.microsoft.com/en-us/library/system.guid.newguid(v=vs.110).aspx

• A 128-bit ID sounds like overkill. I doubt I'll ever get more than 10k players at one time. I don't want to assign incrementally because eventually there'll be overflow. – JPtheK9 Mar 16 '15 at 2:48
• If you're worried about overflow then you need more bits. If you use any sort of randomness or hash, you'll need even more bits to reduce the probability of a collision. An int gets you 4 billion player IDs; I doubt you'll overflow that. I agree that 128 bits is overkill. I suggested it because Microsoft makes it easy to use GUIDs. – John K Mar 16 '15 at 4:10

Okay so I played around with the ID assignments a bit and came up with this:

After every player is assigned and ID, the number gets put in a list called TakenIDs. A for loop checks which number isn't contained in TakenIDs. As soon as a viable number pops up, the for loop is broken and that number is returned then added to TakenIDs. When a player leaves, his ID is taken off the TakenIDs list.

I added in an important optimization. When a player leaves, his ID is stored in a list called CachedIDs. When generating an ID, the generator first checks if there are any IDs in CachedIDs. If there is, then that number is returned and removed from CachedIDs. If there isn't, then proceed with incrementally searching. The list of CachedIDs is self-maintaining and increases to accommodate the player base.

• How did that go so far? I am going to implement similar features. Your approach seems good enough. But I am not sure its performance in production. – newguy May 9 '17 at 10:12
• It went well. I use it extensively in Lockstep Framework. – JPtheK9 May 10 '17 at 17:36

You could generate a random ID, compare it to the existing used IDs ingame, and if the generated ID matches one of the existing IDs, you restart the process. You keep doing this until you have a unique id. Here is an example in C#:

//Lets assume you're using an array named 'idArray' filled the existing IDs
Random rand = new Random();
int generatedID = -1;
do
{
generatedID = rand.Next(1, int.MaxValue);
foreach (int existingID in idArray)
{
if(generatedID == existingID)
{
generatedID = -1;
break;
}
}
} while (generatedID == -1);


If your players have names, you could use the name as the ID (since its multiplayer, I guess you'd prefer not having 2 players with the same name) or you could generate an ID with the name as the seed of the generator to make sure the you have a number generated from a unique source, a bit like how hashing works.

Here is an explaination of what hashing is if you are not familiar with it: http://mathworld.wolfram.com/HashFunction.html

• Eh, this sounds inefficient, especially if many IDs are already taken. Is it possible to generate a random number that excludes certain numbers as possibilities? – JPtheK9 Mar 16 '15 at 2:46
• You're not going to get more efficient than counting. Hashing/random is the next best thing. – John K Mar 16 '15 at 4:14
• I'm going to count. – JPtheK9 Mar 16 '15 at 20:27

If you're using a byte for Local IDs then create an ID array with 256 slots for each room. When a player enters the room assign their Global ID to the first empty slot in the array and their Local ID can be their position in the array. When they leave just set the array to a reserved Global ID that indicates it's unused. If Global IDs are 128bits a piece the entire array will take up 4kb of space on the server, and I can't think of why you'd need to transmit the whole list of IDs over the network so that's not 4kb of network traffic...

• That's basically what I posted 'cept the array isn't self maintaining (its size is preset and doesn't adapt to the needs of the game). – JPtheK9 Mar 16 '15 at 20:25