All network games need to send data from one machine to another. To make sense of this data, it is important to know which player it refers to.
For peer-to-peer games, this is trivial. When you call LocalNetworkGamer.ReceiveData, you get an output parameter telling you who the packet is from.
Client/server games do not have it so easy. When the server sends me a packet saying "Leto is dead, Paul is charging you with the shotgun, and Jessica is camping by the spawn point", he needs some way to refer to Leto, Paul, and Jessica, so we can both agree which players we are talking about.
The gamertag is not a good way to do this. For one thing, gamertags are strings, which are bulky to send over the network. For another, although LIVE gamertags are required to be unique, system link or Zune sessions can use local profiles, which may not have unique names.
In the 2.0 framework, the easiest solution was to send an index into the NetworkSession.AllGamers collection. The order of gamers is synchronized across machines, so these indices will always match up, except for one problem scenario:
This situation is rare, but would cause a brief glitch any time it occurred.
Of course you can fix this by allocating your own unique identifiers and writing code to manually synchronize them over the network, but that is fiddly and a pain to implement.
In the 3.0 framework, we added a new NetworkGamer.Id property to solve this problem. This is a byte identifier, unique for every gamer, which is automatically synchronized across all machines in the session. Because it is an arbitrary ID rather than an index, it will not change as other people join or leave the session, so it can reliably identify one gamer to another.
Coming soon to a website near you: an updated version of our client/server sample that uses this new property.